3
$\begingroup$

I'm trying to minimize the computation time of problem which is too long to post. I use compilein order to gain some speed. To increase speed I would like to use the options Parallelization -> Trueand RuntimeAttributes -> {Listable} among others. The problem is now that some built-in functions I use, such as Map, do not have the attribute Listable. Thus, it seems that my code produces an error once the input is e.g. a list instead of a real number. To gain some insights I post some toy-code.

toy=Compile[{{h1,_Real},{list,_Real,1}},
leg=Length[list];
Map[Total[{list[[#]]}]/h1&, Range[leg]],
 CompilationTarget->"C",
 Parallelization->True,
 RuntimeAttributes->{Listable},
 RuntimeOptions -> "Speed"];

What this code does is it divides each element of list by h1. Please notice that this code does not have any meaning but to show the problem of using a non-listable function within a compile function. Now, let h1 be some real and list be some random list. Then,

 h1=0.1; list=RandomReal[{-1., 1.}, 100]; toy[h1, list]

works just fine. However, if one sets

h1={0.1,0.2}; toy[h1, list] 

results in an error.

My question is whether one of you knows a simple way to make this compiled function listable.

One may use e.g. a Do-loop to get the result, but this is too slow. Thanks in advance I really appreciate it.

$\endgroup$

2 Answers 2

7
$\begingroup$

I hope your toy function really is just a toy-function because neither the Map nor the pure function is required to calculate what you want.

The problem with your code is that you did not localize leg! If you do so, the code runs fine.

toy = Compile[{{h1, _Real}, {list, _Real, 1}},
   Module[{leg = Length[list]},
    Map[Total[{list[[#]]}]/h1 &, Range[leg]]
    ]
   , CompilationTarget -> "C", Parallelization -> True, 
   RuntimeAttributes -> {Listable}, RuntimeOptions -> "Speed"];

If you don't localize all variables, Mathematica assumes you mean the global symbol leg and calls the kernel from within the compiled function to evaluate it. You should therefore always check your compiled code with:

<< CompiledFunctionTools`
CompilePrint[toy]

and ensure, that there are no (unwanted) MainEvaluate[..] calls in it.

$\endgroup$
2
  • 1
    $\begingroup$ There is a led blinking in the text where someone's leg should be. $\endgroup$ Commented Feb 11, 2013 at 10:58
  • $\begingroup$ @halirutan: Thanks for your help. Usually, I do indeed localize all variables but for some reason I get an error once I localize the relevant variable in the "non-toy" code. The error reads: "nontensor object generated". I don't know why this error occurs. $\endgroup$
    – chris
    Commented Feb 11, 2013 at 15:32
0
$\begingroup$

After some debugging I found an answer to my question which I would like to share. I seems very basic and has to do with ragged lists that I created. These lists look e.g. like {{0,1},{1,2,3}}. Compileis not able to handle these lists. I tried to avoid this using Flattenbut this does not work. Why did I create ragged lists in the first place? To save time. I was aware that I could achieve the same results using a loop and AppendTo`, however, this function is very slow.

I found this very nice thread Internal`Bag inside Compile. It is basically an alternative to AppendTo but much much faster. Now, Compileseems more intuitive then before.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.