Check whether a working CCompiler is installed

10

3

Let me give a bit background: As many of my answers imply, I often use the auto-parallelization (meaning, that Mathematica distributes the calculation automatically over several cores when list-arguments are given) of Compile and I often compile to "C". Therefore, in my packages there are things like the following

$adjustGraylevelFunc := ($adjustGraylevelFunc = Compile[{{values, _Real, 1}},
  Map[Floor[255.0 * Min[Max[0.0, #], 1.0]^(0.25) + 0.5] &, values, {1}],
  RuntimeAttributes -> {Listable}, Parallelization -> True,
  RuntimeOptions -> "Speed", CompilationTarget -> "C"
]);

When the package is loaded, this delayed assignment evaluates instantly, because the function is not compiled until first use. Therefore, the loading of the package is very fast, compared to when all functions in it would be compiled on the Get call. Evaluate the next line two times and see the effect

$adjustGraylevelFunc[RandomReal[1, {5, 5, 3}]]

However, I cannot assume that all people have a running C compile installed. Therefore, I would like a short and simple way to test whether I can use C-compiling.

Without research, two possibilities come to my mind:

  1. Loading the CCompilerDriver` package and use CCompilers to check. This has two drawbacks. I have to load an additional package which is not really used, except for this one tiny test. More importantly, an installed C-compiler does not indicate whether Mathematica can really create library code with it. I have seen this often (especially on Windows machines) that installed C-compilers could not be used.

  2. Compile a small test function which sets a package variable. Such a check could be as simple as

    If[Quiet[Check[TrueQ[Compile[{}, 0, CompilationTarget -> "C"][] == 0], False]],
      $compileTarget = CompilationTarget -> "C",
      $compileTarget = CompilationTarget -> "MVM"
    ]
    

Are there other possibilities? Maybe Mathematica already does this kind of check on startup and the result can be accessed somehow?

halirutan

Posted 2014-01-05T02:59:28.450

Reputation: 109 574

I'm not totally sure what you mean by auto-vectorization. If you mean what I think you mean, note that gcc is called with only -O2 by default. Regarding the package loading--it'll have to be loaded if you want to compile the functions anyway, so I don't think this will really harm anything. Personally I would choose option 2 here, but maybe verifying not only that the function can be compiled, but if it can, also that it produces the expected output. – Oleksandr R. – 2014-01-05T03:46:38.143

@OleksandrR. "auto-vectorization" it totally wrong. I must have one of these moments (btw, it's 4:54 here). I'll fix this. – halirutan – 2014-01-05T03:56:10.023

Okay! Well, I should probably also mention then that auto-parallelization isn't dependent on compiling to C. The main restriction on it (apart from listable) is that the functions should be completely compiled and mustn't call back to the main evaluation loop (opcode 47 mechanism is okay, I think). – Oleksandr R. – 2014-01-05T04:10:22.570

@OleksandrR. Do you have time for a short chat about that? Because on my system, it doesn't run in parallel when I don't compile to C, even if your restrictions are met. – halirutan – 2014-01-05T04:22:03.423

5+1 for an interesting question, but I cannot see how any solution is going to be simpler than your second method; after all compilation must be tested to be sure, right? – Mr.Wizard – 2014-01-05T08:53:58.487

@Mr.Wizard There are often situations where I'm stunned what kind of hidden information are brought to daylight by the users here. Therefore, I wanted to throw the question into the round. If no one has a better idea, I'll go with my second suggestion. – halirutan – 2014-01-05T09:41:54.537

No answers