Hot answers tagged

34

A bit late to the discussion but I had the chance to ask Wolfram's North America sales manager about this. I had forwarded him the list of compilable functions "Compile`CompilerFunctions[]". He asked one of his engineers about this. They came back with some information that I thought would add to this question. I don't think that is the correct ...


34

Okay, this is a bit of an embarassment. Here is a very small modification of the original code. I simply made explicit option settings, made a denominator to Sin explicitly real, that kind of thing. My tests show the same timing as the original, give or take an iota. ie = 200; ez = ConstantArray[0., {ie + 1}]; hy = ConstantArray[0., {ie}]; fdtd1d = ...


33

Leonid Shifrin has already given an excellent answer for the question but it's so… long and may be frustrating for someone just beginning to learn the usage of Compile so I decided to post this as an answer. Recently (OK… actually it's more than a year ago) I found that Ted Ersek's Mathematica tricks(.nb version can be found here) contains a brief but ...


33

Use pure functions (Function) and "InlineExternalDefinitions" -> True: g = #^2 &; f = # + 1 &; compiledFunction = Compile[{{x, _Real, 0}}, f@g[x], CompilationOptions -> {"InlineExternalDefinitions" -> True}]; CompilePrint[compiledFunction] 1 argument 1 Integer register 4 Real registers Underflow ...


32

This is because Table automatically compiles its argument above a certain length limit. SystemOptions["CompileOptions" -> "TableCompileLength"] (* {"CompileOptions" -> {"TableCompileLength" -> 250}} *) It does not seem to realize that the code modifies global variables because that behaviour is hidden behind code. Notice that the following both ...


31

Yes there is a way to use functions that use external non compiled functions. It uses the step function of Mr.Wizard defined in the post How do I evaluate only one step of an expression?, in order to recursively expand the code that we want to compile until it uses only functions that Mathematica can compile. The technique discussed in the post How to ...


28

Here is another compiled implementation: hammingDistanceCompiled = Compile[{{nums, _Integer, 1}}, Block[{x = BitXor[nums[[1]], nums[[2]]], n = 0}, While[x > 0, x = BitAnd[x, x - 1]; n++]; n ], RuntimeAttributes -> Listable, Parallelization -> True, CompilationTarget -> "C", RuntimeOptions -> "Speed" ]; This appears to ...


27

First off, your function is very simple without any hard number-crunching, so it will always be hard to get a large speedup for the compiled version. Secondly, your Parallelization option for Compile is useless because it doesn't do any parallelization this way. Let me give slightly changed versions of your examples and explain how you can achieve a large ...


26

The default SumCompileLength is 250. You can increase this number for example to 500 using SetSystemOptions["CompileOptions" -> {"SumCompileLength" -> 500}] or to infinity using SetSystemOptions["CompileOptions" -> {"SumCompileLength" -> ∞}] What is "SumCompileLength" for? For sums with a finite number of at least "SumCompileLength" elements ...


26

One of the biggest differences between main kernel evaluation and compiled evaluation in the "Wolfram Virtual Machine" (WVM) is that in the kernel, arbitrary expressions are allowed that are rewritten according to pattern-matching rules and in the WVM things are much more restricted and predictable. For instance, the types of all variables are ...


24

It is important to Compile that it has always the same return type, no matter what happens at runtime. Note that Which returns Null as default value. Since the return value of the function is meant to be a 4-vector in some cases, we have to assign also a 4-vector (e.g., {0., 0., 0., 0.}) as default return value of Which. So this should work: ...


22

Maybe two advises for the start: Use the fact that Sin is Listable and you can call Sin[{1,2,3,4,..}] to get a list of results. Don't calculate the sum twice. Calculate the sine part only once and make the multiplication with i in the first sum as vectorized multiplication. Taking this into account give in a first try something like fHal = Compile[{{n, ...


21

This is a tricky case indeed, because what you basically ask for is compile-time evaluation (macro-style). Generally, the answer is to use meta-programming, to assemble the compiled expression at run-time. The reason your attempt did not work is that the expression you want to evaluate is too deep for Evaluate to be effective. Solution using in-place ...


21

The Wolfram Virtual Machine's CompiledFunctionCall opcode is a fast way to let one compiled function call another. The speed advantage is largely because the call can be made without leaving the virtual machine. Sometimes inlining can be fast, especially for functions with very small function bodies, but you would simply need to test both ways to know ...


21

Yes, there is! Mathematica creates a LibraryFunction when compiling to C, but puts it in a temporary directory. If you can recover the library, you can load it as often as you like! First let's define the function as in the question: generatef[opt_] := Compile[{}, Module[{j = 0}, Do[j++, {i, 10^8}]; j], CompilationTarget -> opt]; f2 = generatef["C"]; ...


19

Another option to the answer posted by Andy Ross cropped up in a recent question of mine about corrupting an image with Poisson noise. In my own answer, I made use of LibraryLink to utilise the distributions built into C++. This was especially useful in my case because Poisson noise in an image otherwise relies on a call to RandomVariate for each pixel (...


19

Looking at CompilePrint[compiledGlynnAlgorithm], there are some lines with CopyTensor in it which aren't really needed. There's also a few CoerceTensor lines in there when it might be faster to just coerce the integer matrix once at the beginning. By slightly adjusting the function, all instances of CopyTensor and CoerceTensor go away, giving a small ...


18

If you look at the generated code (CompilePrint, for example), the procedure is as follows: All the program's constants are placed into separate registers (regardless of their location in the program, they can be in the r.h.s.of variable initialization in scoping constructs, or they can be statements in their bodies. Actually, same constants found in ...


18

Congratulations! You find one of subnormal positive double :) Another example f = Compile[{{t, _Real}}, 2.0^t]; f[-1074] f[-1075] 5.*10^-324 0 MachineNumberQ@f[-1074] True This doesn't mean that CompiledFunction can work with arbitrary-precision numbers. Update Normally Mathematica prevents such numbers 2.^-1074. % // MachineNumberQ 4.940656458413*...


18

No, it is not possible. With code converted to a LibraryLink library by way of Compile you are limited to using functions that either can be expressed directly in C, or exist in the runtime library; unfortunately, FindFit is not included in either category. When present in code passed to Compile, FindFit results in a call back to the top level, and it is ...


18

Based on the experience obtained here: friction = Compile[{{v, _Real}, {vt, _Real}}, If[v > vt, -v*3.0, -vt*3.0*Sign[v]]]; simulateSpring = Compile[{{x0, _Real}, {t, _Real}, {dt, _Real}, {vt, _Real}}, Module[{τ, times, positions, v = 0.0, a = 0.0, x = x0}, τ = t; times = Range[0.0, t, dt]; positions = Table[0.0, {Length@times}]; ...


17

First, if you use := in your assignment, then the compilation is not done instantly but every time you call winding2. That's btw the reason why you get the error message when you try to call the function because it is not compiled until then and the error is a compilation error. Secondly, as the error messages sais, @@ can only be used with Times, Plus or ...


17

Using Compile with CompilationTarget->"C" does generate C-Code to be compiled in a generalized way, the resulting code will contain some overhead due to that compared to hand-written code which can easily explain any difference in runtimes. Even for cases where that overhead is minimal or non-existent automatic code generation will always produce ...


16

In version 8, the callback into the interpreter (also known as MainEvaluate or WolframCompileLibrary_Functions->evaluateFunctionExpression) looks like Function[{iCompile$1}, Block[{i = iCompile$1}, {Print[i], i}]][register] where register is the (integer, scalar) register that contains the value of i. This looks correct to me, although I'll admit that I ...


16

(This is not an answer, but only a phenomenon I observed. And I think it might be a bug.) I think in version 9, Mathematica fails to compile the Fold for $n\geq 166$ where $n$ is the integer number in Range. The precise threshold may be different from OS to OS, but I suspect this phenomenon exists in all version 9. Note the default "FoldCompileLength" is ...


16

Compilation of Total As pointed out in a comment, it seems that the compensated summation form of Total can't be compiled. You can check this using CompilePrint - note the call to MainEvaluate. Needs["CompiledFunctionTools`"] CompilePrint@f2 (* from your question *) Summation in Mathematica There seem to be plenty of options for summing a list in ...


16

Here is the original code. logisticMap[x0_, μ_, n_] := Module[{i}, RecurrenceTable[{x[i + 1] == μ x[i] (1 - x[i]), x[1] == x0}, x, {i, 1, n}]] We'll show an example so we can test other variants for correctness. In[316]:= logisticMap[0.1, 3.55, 10] Out[316]= {0.1, 0.3195, 0.7718401125, 0.625165483988, 0.831884285744, \ 0.49647751411, 0....


16

Extended comment.. I've never come across specifics of what Compile[] specifically does. That said, a definition re: programming languages in general provides some insight/understanding: Compiling is the transformation from Source Code (human readable) into machine code (computer executable). ... A compiler takes the recipe (code) for a new program (written ...


15

The reason for this behavior is that autocompilation always uses settings equivalent to "RuntimeOptions" -> {"Quality", "WarningMessages" -> False}. As previously noted in Silvia's answer, the automatic compilation is invoked for input exceeding SystemOptions["CompileOptions" -> "FoldCompileLength"] (* {"CompileOptions" -> {"FoldCompileLength"...


15

It appears that LibraryFunction occurs if the function being called inside the other compiled function is a function that has been compiled to C, provided this function has been called with the right type of arguments. It seems that in other cases there is a CompiledFunctionCall. As pointed out by Simon Woods in the comments below, there is a type mismatch ...


Only top voted, non community-wiki answers of a minimum length are eligible