I address the second question.
Every now and then, questions turn up in connection with the autocompilation property of the function Map
, this one being the latest. In the comments, it was mentioned by @Karsten7 that the CompileOptions
can be set such that messages are generated if something goes wrong. That in fact answers more ore less the above question on how we can test if a function autocompiles one of its arguments.
Let us first inspect the CompileOptions.
SystemOptions["CompileOptions"]
(*
{CompileOptions->{ApplyCompileLength->\[Infinity],ArrayCompileLength->250,AutoCompileAllowCoercion->False,AutoCompileProtectValues->False,AutomaticCompile->False,BinaryTensorArithmetic->False,CompileAllowCoercion->True,CompileConfirmInitializedVariables->True,CompiledFunctionArgumentCoercionTolerance->2.10721,CompiledFunctionMaxFailures->3,CompileDynamicScoping->False,CompileEvaluateConstants->True,CompileOptimizeRegisters->False,CompileParallelizationThreshold->10,CompileReportCoercion->False,CompileReportExternal->False,CompileReportFailure->False,CompileValuesLast->True,FoldCompileLength->100,InternalCompileMessages->False,ListableFunctionCompileLength->250,MapCompileLength->100,NestCompileLength->100,NumericalAllowExternal->False,ProductCompileLength->250,ReuseTensorRegisters->True,SumCompileLength->250,SystemCompileOptimizations->All,TableCompileLength->250}}
*)
We see three options that could produce messages: CompileReportExternal
, CompileReportFailure
, InternalCompileMessages
. The last one generates a message when the compilation fails, and the second one takes care that it is reported. When we set them to True
, we will see a message when the compilation fails. Therefore, our test to see if a function autocompiles will simply be to use an argument for which the compilation fails. When we see the message, it autocompiles and otherwise not.
We also see some options that end on CompileLength
and have the name of a Mathematica function in front: Array
, Fold
, Map
, Nest
, Product
, Sum
, Table
. These are functions that do autocompile when the relevant argument is at least as long as the value given in the option.
Here is a demonstration. It is simple to construct a function that cannot be compiled. Just use a symbol without a value in the function body.
SetSystemOptions["CompileOptions" -> {"CompileReportFailure"->True, "InternalCompileMessages"->True}];
Clear[zz];
Array[#+zz&, {250}];
Fold[#+zz&, 0, Range[100]];
Map[#+zz&, Range[100]];
Nest[#+zz&, 0, 100];
Product[x+zz, {x, 1, 250}];
Sum[x+zz, {x, 1, 250}, Method->"Procedural"];
Table[x+zz, {x, 1, 250}];
(* During evaluation of In[4]:= Compile::compfail: Compilation of Array[#1+zz&,{250}] failed because zz was not a form suitable for the compiler.*)
(* other results skipped *)
All commands show a compilation error, similar to the one above. The function Sum
can be used with a lot of options. For many of them, there is nothing numerical to do, so then there is no autocompilation.
Of course, many more functions autocompile. For example:
NIntegrate[x+zz,{x,0,1}]
(* During evaluation of In[26]:= Compile::compfail: Compilation of x+zz failed because zz was not a form suitable for the compiler, etc *)
NSum[x+zz, {x, 1, 1}]
(* During evaluation of In[28]:= Compile::compfail: Compilation of x+zz failed because zz was not a form suitable for the compiler, etc *)
Plot[x+zz,{x,0,1}]
(* During evaluation of In[20]:= Compile::compfail: Compilation of x+zz failed because zz was not a form suitable for the compiler, etc *)
A little bit surprising: Table
does autocompile, but Do
does not:
Do[x+zz, {x, 1, 5000}]
(* no message *)
Do[Sqrt[3] a/2, {100000}] // AbsoluteTiming -> .7
. Why the interpreter can't readily see that that thing doesn't need to be reevaluated is a good question. $\endgroup$Trace[ ]
them) except the second one is "shorter" because thebase
symbol is. $\endgroup$number of symbolic nodes that Mathematica needs to "move" from one step to the next
. You mean the total step thatTrace
shows, right? $\endgroup$