4
$\begingroup$

I suspect this would require advanced MMA skills, but it would be very useful if one could modify the front end so that any MMA defined function calls in a Compile[] could be flagged if they are not compilable, because uncompilable functions would cause slow compiled code through calls to MainEvaluate[].

Question 1096 shows how to get lists of compilable functions.

How might the functions in a Compile[] definition be dynamically checked against such a list (i.e. as the user types them) and highlighted in some way if they are/are not compilable?

(I have not yet got around to calling a compiled function from a compiled function, but the obvious next step would be to maintain a secondary list of user defined functions that can be called in a Compile[] and to provide similar highlighting.

Would someone exceedingly smart be able to see how to do both these things?)

UPDATE/Amendment

It has been pointed out in comments and through a linked question, whose significant content I have quoted, that "compilable?" is not a simple question to answer. I would therefore like to amend the question as follows:

How could one customize the front-end (so that feedback is immediate on typing) so that MMA defined functions that are not listed as compilable (whether conditionally or not) are highlighted if used inside a Compile[]?

Rationale: one cannot easily say a function is compilable, but given that there are lists of MMA functions that may be compilable, any function not on that list may be assumed non-compilable and the sooner one can see that the less effort one is likely to waste writing a function for compilation that, ultimately, cannot compile. [The other suggestions may then be incorporated to ease the process of determining whether compilation then actually succeeded without calls to MainEvaluate]

$\endgroup$
  • $\begingroup$ I don't insist, I just didn't know there might be other options; I do however want the feedback to be immediate so I don't spend time building a complete definition only to find it is inappropriate (I am using CompiledFunctionTools`CompilePrint[] at the moment to do precisely that), and I am tired of scanning the lists with Mk I eyeball. $\endgroup$ – Julian Moore Oct 12 '16 at 12:18
  • $\begingroup$ Perhaps SetSystemOptions["CompileOptions" -> "CompileReportExternal" -> True] would be somewhat helpful. $\endgroup$ – Michael E2 Oct 12 '16 at 13:02
  • $\begingroup$ @MichaelE2 That's an interesting additional tool, thanks; the linked question also gives the quote "It (compiling) is not as simple as just a list of functions. For a number of functions, some uses of the function are supported and others are not. Thus, the list of functions is a starting point, but does not give the whole story." Hmmmm. $\endgroup$ – Julian Moore Oct 12 '16 at 13:09
  • 2
    $\begingroup$ Are you aware that the answer to "Is f compilable?" is usually not a simple yes/no? There are often restrictions on the compilable syntax, sometimes very narrow restrictions. $\endgroup$ – Szabolcs Oct 12 '16 at 15:55
  • $\begingroup$ The function FastCompiledFunctionQ in (24595 ) is a perhaps more efficient version of Julien's CompileEx. $\endgroup$ – Michael E2 Oct 12 '16 at 15:56
3
$\begingroup$

One idea is to use the AutoStyleWords option of cells to color selected words. For example, the following stylesheet colors all words given by Compile`CompilerFunctions the color RGBColor[.3, .5, .5] indicating that they are acceptable compiler functions, and other words will remain black, indicating that they are probably not compiler functions:

SetOptions[
    EvaluationNotebook[],
    StyleDefinitions -> Notebook[
        {
        Cell[StyleData[StyleDefinitions->"Default.nb"]],
        Cell[StyleData["CompileInput", StyleDefinitions->StyleData["Input"]],
            AutoStyleWords->(SymbolName[#]->"CompiledFunction"&/@Compile`CompilerFunctions[])
        ]
        ,
        Cell[StyleData["CompiledFunction"], FontColor->RGBColor[.3,.5,.5]]
        },
        StyleDefinitions->"PrivateStylesheetFormatting.nb"
    ]
]

Then, here's an example of a compiled function using the "CompileInput" style:

enter image description here

You can see that IntegerQ and MatchQ have been flagged as noncompilable functions.

$\endgroup$
  • $\begingroup$ Thanks, I'm still naive about StyleDefinitions stuff so will need to digest this and mod so that I can put it in my own named stylesheets. Puzzled by the fact that I have to manually apply the CompileInput style to see the result as shown above; I must be misunderstanding how it works - to me it looks as though Input is modified as well (my ignorance)...But it does do exactly what I wanted, thank you - accepting on that basis. $\endgroup$ – Julian Moore Jun 16 at 8:34
4
$\begingroup$

Okay so this is not an answer (it's to big to write a comment for) to your exact question but a dirty workaround. But it works.

We can write a simple wrapper for Compile which warns us if we get MainEvaluates and Prints them.

Attributes[CompileEx]={HoldAll};
CompileEx[a___]:=Module[{cf,printString,meCases},
cf=Compile[a];
Needs["CompiledFunctionTools`"];
printString=CompiledFunctionTools`CompilePrint[cf];
meCases=StringCases[printString,"MainEvaluate["~~pattern:Repeated[Except["\n"]]~~"]":>pattern];
If[Length[meCases]>0,Print[ToString[Length[meCases]]<>" MainEvaluates detected.\n\n"<>StringJoin[Riffle[meCases,"\n\n"]]]];
cf
]

This does only printing but its easy to let it throw an error or something you would prefer.

A Testrun:

CompileEx[{{i}},If[MatchQ[i,_?OddQ],If[MatchQ[i,_?IntegerQ],Sin[i]^2,0],0]]

2 MainEvaluates detected.

Function[{i}, MatchQ[i, _?OddQ]][ R0]

Function[{i}, MatchQ[i, _?IntegerQ]][ R0]

CompiledFunction[...]

You can save the definition of CompileEx to a package and load it or save it in the kernel/init.m to have it always by you.

I know its not the best solution but hey, better than nothing. But i'm sure, someone here is able to tweek the FrontEnd to do what you want.

$\endgroup$
  • $\begingroup$ That's also useful, thank you - even though it doesn't do the dynamic parsing it would save a bit of manual checking. $\endgroup$ – Julian Moore Oct 12 '16 at 13:11

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.