I have simple function I would like to compile, but I get a warning and a call to MainEvaluate. I would like to avoid both.
ClearAll[MakeInPeriodicCell]
On["CompilerWarnings"]
MakeInPeriodicCell =
Compile[{x, cellwidth},
First@Sort[{x, x - cellwidth, x + cellwidth}, Abs[#1] < Abs[#2] &]];
CompiledFunctionTools`CompilePrint[MakeInPeriodicCell]
(*Compile::noinfo: No information is available for compilation of
Sort[{x,x cellwidth,x+cellwidth},Abs[#1]<Abs[#2]&].
The compiler will use an external evaluation and make assumptions about the return type.*)
(*
...
5 T(R1)2 = MainEvaluate[ Function[{x, cellwidth}, Sort[{x, x - \
cellwidth, x + cellwidth}, Abs[#1] < Abs[#2] & ]][ R0, R1]]
...
*)
EDIT
(I got the correct syntax for the subexpression from an answer that got deleted?) I tried setting the type of a subexpression like this:
MakeInPeriodicCell =
Compile[{x, cellwidth},
First@Sort[{x, x - cellwidth, x + cellwidth},
Abs[#1] < Abs[#2] &], {{Sort[_,_], _Real,1}}]
This gets rid of the warning, but the call to MainEvaluate remains.
Can this snippet be compiled without a call to MainEvaluate?
EDIT 1
Since compile is always about speed, here is some benchmark info. (the code is here, as it clutters the question a bit)
data = RandomReal[{-100, 100}, 100000];
(*Original implementation*)
m0 = MakeInPeriodicCellOrig[data, 30]; // AbsoluteTiming (*0.8370473*)
(*my revritten*)
m1 = MakeInPeriodicCellImp[data, 30]; // AbsoluteTiming (*0.0360021*)
(*F'x answer*)
m2 = MakeInPeriodicCellFx[data, 30]; // AbsoluteTiming (*0.0140008*)
m0 == m1 == m2 (*True*)
So getting read of MainEvaluate gives you about 20x speed-up and changing to a better algorithm another 3x. I usually have a million to ten million points, so the speed-up is very welcome.
SetSystemOptions["CompileOptions" -> "CompileReportExternal" -> True]
the warning does not go away. Out of curiosity, have you read these two questions? $\endgroup$ – rcollyer Apr 5 '12 at 15:36