18

11

This question is tightly related to the answer Shaving the last 50 ms off NMinimize.

There @OleksandR shows how inlined closures can be used to eliminate calls to `MainEvaluate`

. This is crucial for my application, since I need every last drop of performance mma can offer. Here is an extremely simplified working example (before you run this code, make sure to evaluate this package, containing the NelderMeadMinimize code):

```
Needs["CompiledFunctionTools`"]
With[{minimizer =
NelderMeadMinimize`Dump`CompiledNelderMead[
Function[{a, b, c}, (a - d1)^2 + (b - d2)^2 + (c - d3)^2], {a, b, c},
"ReturnValues" -> "OptimizedParameters"],
epsilon = $MachineEpsilon},
orgFitter =
Compile[{{d1, _Real, 0}, {d2, _Real, 0}, {d3, _Real, 0}},
minimizer[RandomReal[{0, 1}, {3 + 1, 3}], epsilon, -1],
CompilationOptions -> {"InlineCompiledFunctions" -> True},
RuntimeOptions -> {"Speed", "EvaluateSymbolically" -> False}]];
StringMatchQ[CompilePrint[orgFitter], "*MainEvaluate*"]
(* -> False *)
orgFitter[12, 2, 3]
```

Now, if I change `(a - d1)^2 + (b - d2)^2 + (c - d3)^2`

to calling a compiled function the calls to `MainEvalute`

are not eliminated! Please, instead of the simple `myHi2`

imagine a monster of a compiled procedure containing several hundred lines.

```
myHi2 = Compile[{{a, _Real, 0}, {b, _Real, 0}, {c, _Real,
0}, {d1, _Real, 0}, {d2, _Real, 0}, {d3, _Real,
0}}, (a - d1)^2 + (b - d2)^2 + (c - d3)^2];
With[{minimizer =
NelderMeadMinimize`Dump`CompiledNelderMead[
Function[{a, b, c}, myHi2[a, b, c, d1, d2, d3]], {a, b, c},
"ReturnValues" -> "OptimizedParameters"],
epsilon = $MachineEpsilon},
orgFitter =
Compile[{{d1, _Real, 0}, {d2, _Real, 0}, {d3, _Real, 0}},
minimizer[RandomReal[{0, 1}, {3 + 1, 3}], epsilon, -1],
CompilationOptions -> {"InlineCompiledFunctions" -> True,
"InlineExternalDefinitions" -> True},
RuntimeOptions -> {"Speed", "EvaluateSymbolically" -> False}]];
StringMatchQ[CompilePrint[orgFitter], "*MainEvaluate*"]
(* -> True *)
orgFitter[12., 2., 3.]
```

**How can I eliminate this calls to MainEvaluate?**

Also, could someone help me understand, why this does not compile:

```
orgFitter = Compile[{{d1, _Real, 0}, {d2, _Real, 0}, {d3, _Real, 0}},
With[{minimizer =
NelderMeadMinimize`Dump`CompiledNelderMead[
Function[{a, b, c}, (a - d1)^2 + (b - d2)^2 + (c - d3)^2], {a,
b, c}, "ReturnValues" -> "OptimizedParameters"],
epsilon = $MachineEpsilon},
minimizer[RandomReal[{0, 1}, {3 + 1, 3}], epsilon, -1]],
CompilationOptions -> {"InlineCompiledFunctions" -> True,
"InlineExternalDefinitions" -> True},
RuntimeOptions -> {"Speed", "EvaluateSymbolically" -> False}];
CompilePrint[orgFitter]
```

Thank you for the great answer! What exactly does lexically mean in this context? In my original example I thought that the

`With`

block would inject the minimize inside the`Compile`

block before anything else happens, so that myHi2 would effectively appear inside`Compile`

. Well obviously I was wrong and it's not that simple:) – Ajasja – 2012-10-19T13:48:29.003Also, regarding my last example that has

`Compile`

on the outside. Do you think it would be possible to use`Internal`

CompileValues`to make`

NelderMeadMinimize`Dump`

CompiledNelderMead` compilable? (asking purely out of curiosity, since you have already presented 3 solutions to my problem:) – Ajasja – 2012-10-19T13:52:03.880@Ajasja your

`With`

didsuccessfully inject the minimizer into the compiled code--but you hadn't followed that through to its logical conclusion and injected`myHi2`

into the minimizer (remember,`Function`

is`HoldAll`

too). Once you've dealt with all the dependencies, everything should work out automatically. BTW, I forgot to mention that inlining like this avoids the need for`CompilationOptions -> "InlineCompiledFunctions" -> True`

in all cases (AFAIK)exceptthat of compiled closures, which won't work otherwise (and also aren't supported prior to version 8). – Oleksandr R. – 2012-10-21T03:04:31.510@Ajasja as far as using

`Internal`CompileValues`

goes, the answer is probably yes but I'm not certain how to do it. These values are only looked at fairly deep inside`Compile`

and after a lot of preprocessing has already been done, so I don't really know exactly what's supported using this mechanism. The function`Internal`CompileInline`

probably has something to do with what you're after, but I've no idea how to use it. – Oleksandr R. – 2012-10-21T03:10:10.923