CompilationTarget
The CompilationTarget option of Compile specifies the target runtime system for the compiled function. The default setting is "MVM", which creates code for the traditional Wolfram Language virtual machine. This virtual machine is described in detail in the section on compiled function operation.
However, you can use CompilationTarget to generate C code as shown in the following.
The function works in the same way as a compiled function running in the Wolfram Language virtual machine.
However, the InputForm shows that the compiled function actually contains a LibraryFunction.
You can call the LibraryFunction directly.
If the generated code needs to make an external call, this works as expected.
Note that if you do not have a suitable C compiler then you will not be able to set CompilationTarget to C. If you try, you will receive a warning message.
Computation Speedup
A main reason for setting CompilationTarget to C is to speed up the computation. This works well in many cases.
The following example shows how C code runs faster than the traditional Wolfram Language virtual machine.
The speed acceleration will not always be so large. If an expensive internal function such as matrix-matrix multiplication was called, the time for this would be similar for both C and the Wolfram Language virtual machine, and in this case there would be no speed benefit.
As is the case for traditional compiled function execution, external calls can also lead to inefficiencies when using the Wolfram System compiler. In particular, undefined external calls should be avoided.
Other factors that can have an effect include the use of RuntimeOptions such as CatchMachineOverflow, and CatchMachineIntegerOverflow. As explained, these can all have an influence on the efficiency of a compiled function.
Listability and Parallelization
You can use set listability and parallelization for Compile in conjunction with C execution. The following creates and executes a listable compiled function.
If you target C for the same function, a significant acceleration takes place.
Running the computation in parallel gives yet another speedup.
The last example shows one of the fastest ways to compute results from a Wolfram Language function.
Lifecycle
When CompilationTarget is set to C, it creates LibraryFunction and embeds this in the compiled function. You can see the LibraryFunction by using InputForm.
The conversion uses the CCodeGenerator package to generate C code for a Wolfram library and then the CCompilerDriver package (using CreateLibrary) to compile the code into an actual library. The libraries are all placed into a folder that is unique for each session of the Wolfram System.
The default settings are such that all temporary files are removed when compilation finishes. In addition, when the kernel session finishes, all the generated libraries are removed.
If you want to change option settings for the call to CreateLibrary you can do this with Compile`$CCompilerOptions. This is useful for various reasons such as inspecting and debugging generated code.
Inspecting Generated Code
To inspect the generated code you need to change the default behavior of CreateLibrary. This will clean any intermediate files that are generated and is controlled by the "CleanIntermediate" option. A change is shown below.
Now you can generate a compiled function with CompilationTarget set to C.
This locates the C code that was used.
This displays the C code; the meaning of some of these terms is explained in the CCodeGenerator documentation.
Note that when you prevent deletion of intermediate files, this will interfere with tidying of the generated code folders when the Wolfram System session is terminated. At this point you might wish to delete the files yourself.
Output when Generating Code
To see output from the C compiler when generating code you need to add options to CreateLibrary. This is done by setting the "ShellOutputFunction" to Print and is shown in the following.
Now you can see the output when the C compiler runs.
C Compiler Commands when Generating Code
To see the commands given to the C compiler when generating code you need to add options to CreateLibrary. This is done by setting the "ShellCommandFunction" to Print and is shown in the following.
Now you can see the commands given to run the C compiler.
Debugging Generated Code
To debug the generated code you need to add debugging options to CreateLibrary. These are different for different C compilers. For Visual Studio, you can set the following.
It is necessary to set "CleanIntermediate" to False so that the intermediate files are saved and also set "CompileOptions" to insert debugging information in the resulting library.
Now you should be able to launch a debugging environment and connect to the Wolfram System process. You can then open the C code and set a breakpoint.