4
$\begingroup$

I've noticed that if I try to define a Function within a Module within Compile, I get errors of (* Compiled expression Function[...] should be a machine-size real number *) IF those functions are local variables within the Module AND I don't assign the Module itself to a variable name within Compile. Weird, no? I know about using the trailing ..., {{Pattern, _Type}} syntax, but I don't think that's applicable here (besides, I'm not sure that a type of Function is listed in the supported types, anyways... -- yet it does appear that they can be used within Compile).

I'm still too new to Compile to know whether putting the Functions within a Module is even advised, but I read elsewhere that using symbols that aren't shielded within something like a Module causes calls to MainEvaluate[], which considerably slows performance.

Any idea why this happens?

Compile[{},
  f1 = Function[{}, 1.0]; (* Fine! *)
  f2 = 1.0 &; (* Fine! *)
  
  Module[{f3, f4},
   (*f3=Function[{},1.0];*)
   (* ABOVE: Compiled expression Function[{}, 1.`] should be a machine-size real number *)
   (*f4=1.0&;*) (* Same *)
   f5 = Function[{}, 1.0]; (* Fine! *)
   f6 = 1.0 &; (* Fine! *)
   {f5[], f6[]}
   ];
  mod = Module[{f7, f8},
    f7 = Function[{}, 1.0]; (* Fine! *)
    f8 = 1.0 &; (* Fine! *)
    {f7[], f8[]}
    ];
  mod
  ][]
```
$\endgroup$
0
3
$\begingroup$

In your case using With is enough:

With[{f3 = Function[y, y^4], f1 = Function[y, y^2]},
c1 = Compile[{x},
       f1[x];
       {Function[y, y^3][x], f3[x]}   
     ]
];
Needs["CompiledFunctionTools`"]
compiledOKQ = StringFreeQ[CompiledFunctionTools`CompilePrint[#1], "MainEvaluate"]&;
compiledOKQ[c1]

gives True

$\endgroup$
3
$\begingroup$

I think I answered my own question via CompilePrint (just learned about this); will post for posterity:

ClearAll[f1, f2, f3, f4, f5, f6, f7, f8]
f3 := Function[y, y^4];
c1 = Compile[{x},
   m1 = Module[{f1},
     f1 = Function[y, y^2];
     f1[x]
     ];
   Module[{},
    {Function[y, y^3][x], f3[x]}
    ]
   ];
c1[2]
m1
Needs["CompiledFunctionTools`"]
CompilePrint[c1]
1   V17 = MainEvaluate[                                                 \
  2
Function[{x}, m1 = Module[{f1}, f1 = Function[y, y ]; f1[x]]][ R0]]
2   R2 = R0
3   R1 = Power[ R2, I0]
4   R2 = MainEvaluate[ Hold[f3][ R0]]
5   T(R1)0 = {R1, R2}
6   Return

It looks like the versions that I thought were "working" were just running in non-compiled mode (not just the assignments, either -- the whole step). I'm used to getting an error/warning in such cases, but I had to look at CompilePrint to see it this time.

I guess you just have to use anonymous functions exclusively. It looks like BOTH the methods in my original post AND defining the Function outside of Compile altogether (as I indicated I was unsure-about in my original post) cause MainEvaluate[] to be used...

I could've sworn I'd come across other examples on StackOverflow where a function was defined outside of Compile and then used within it, but I'll have to educate myself further.

$\endgroup$
1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.