Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I'm trying to speed up a section of a Mathematica 9.0.1 notebook by performing some calculations in C++ with the Cilk Plus and Threading Building Blocks tools available for the Intel C++ 14.0 compiler [in Intel Parallel Studio XE 2013 SP1, installed with VS 2012 Professional, running under Windows 8.1 Pro]. I would like to avoid using MathLink to access the C++ code, if possible, and "get away with" using the CreateExecutable and CreateLibrary functions of Mathematica. I've had no success with CreateLibrary, as yet, but I have had one "success" and one failure with CreateExecutable. I'm trying to understand my one success as a way of possibly fixing the failures.

The simple Cilk-enhanced C++ code below adds the number 7 to itself one trillion times in about 8 seconds on a 4-core, 3.5 GHz clock, laptop. This code is not useful from the standpoint of the result it computes, but it quickly makes the fan run and serves to test whether or not Cilk-enhanced C++ code can be incorporated within a Mathematica notebook. So, apparently, it is possible to run Cilk-enhanced C++ code from Mathematica.

The code works if I first write the Cilk-enhanced C++ code string, CilkMain, to a file with the extension .cpp, and then use that .cpp file as the first (list) argument of CreateExecutable. When I use the ShellCommandFunction and ShellOutputFunction options of CreateExecutable to look at what happened, it seems that Mathematica looked at the .cpp extension, forwarded a .cpp file to the Intel compiler, and everything worked.

In[1]:= nbdir = NotebookDirectory[];
    Needs["CCompilerDriver`"]
    CCompilers[Full];
    $CCompiler = {"Compiler" -> CCompilerDriver`IntelCompiler`IntelCompiler,
    "CompilerInstallation" -> "C:\\Program Files (x86)\\Intel\\Composer XE 2013 
    SP1"};

In[5]:= cilkMain = "
    #include<cilk/cilk.h>
    #include<cilk/reducer_opadd.h>
    #include<stdio.h>

    int main()
    {
    cilk::reducer_opadd<long long>j(0);
    long long size=(long long)(1000)*(long long)(1000*1000*1000);

             cilk_for(long long i=0;i<size;i++) j+=7;

    printf(\"The value of j is %14lld\\n\",j.get_value());
    return 0;
    }";

In[6]:= Export[nbdir <> "cilkMain.cpp", cilkMain, "Text"];

In[7]:= cilkExe = CreateExecutable[{nbdir <> "cilkMain.cpp"}, "cilkExeFile"];

In[8]:= AbsoluteTiming[Import["!" <> QuoteFile[cilkExe], "Text"]]

Out[8]= {8.165778, "The value of j is  7000000000000"}

In[9]:= cilkExe = CreateExecutable[cilkMain, "cilkExeFile"]
        cilkExe = CreateExecutable[cilkMain, "cilkExeFile", "Language" -> "C++"]

Out[9]= $Failed

Out[10]= $Failed

But if I give the Cilk-enhanced code string directly to CreateExecutable as its first (non-list form is required for a string) argument, with or without the "Language" option set to "C++", the code fails. The printed results from the ShellCommandFunction and ShellOutputFunction options show that for a string argument, a file with extension .c is forwarded to the Intel compiler, which leads to failure because the Cilk functions require C++ compilation.

Is there a direct way to tell CreateExecutable and CreateLibrary to forward code for C++ (not C) compilation? There is little documentation of the "Language" option in the Mathematica help, and no examples. What you see in the notebook above is merely my best guess as to how to force C++ compilation. Clearly, it is an incorrect guess, likely based on incorrect understanding.

I don't like resorting to tricks, such as writing a string to a file with a special extension, in order to fool a Mathematica function. What is the right way to do this? Learning the right way may well set me on the road to fixing the failures.

P.S. Thanks for the quick replies. Will look at CCompilerDriver` code, then move on to trying to trick CreateLibrary in a similar way.

share|improve this question
1  
Looks to me like the problem lies in the CCompilerDriver` package, or more specifically in CCompilerDriverBase.m. The definition for BaseDriver["ResolveCodeFile"][otherargs___] is hard-coded to write the code to a file with extension .c regardless of the language specification. You can presumably implement a fix for this (override the method in the Intel driver rather than falling through to the base driver). –  Oleksandr R. Jun 17 at 22:29
    
I've seen this problem before, but didn't have the time or motivation to try to create a proper fix. I will usually end up putting C/C++ code in separate files anyway. You can try to report this to support (I didn't take the time to do so). –  Szabolcs Jun 17 at 22:31
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.