0
$\begingroup$

I precompute an expression which takes pretty long to evaluate (i.e. for my real problem tmp[2] takes quite long) and I want to see if runtime can be improved using Compile. Consider expr below which can in my case either be a vector or a matrix. It is then "transformed" into a function like tmp[t]. Using Compile I ran into the following issue:

ClearAll[tmp, fun, fun2, fun3, expr];
expr = {Sin[t], Cos[t]};
tmp[t_] = expr;
fun = Compile[{{t, _Real}}, tmp[t]];
fun2 = Compile[{{t, _Real}}, expr];
fun3 = Compile[{{t, _Real}}, {Sin[t], Cos[t]}];

Now evaluating the three variants yields

Option 1:

fun[2.]

CompiledFunction::cfex: Could not complete external evaluation at instruction 1; proceeding with uncompiled evaluation.

(* {0.909297, -0.416147} *)

Option 2:

fun2[2.]

CompiledFunction::cfte: Compiled expression {Sin[t],Cos[t]} should be a rank 1 tensor of machine-size real numbers. CompiledFunction::cfex: Could not complete external evaluation at instruction 1; proceeding with uncompiled evaluation.

(* {Sin[t], Cos[t]} *)

Option 3:

fun3[2.]
(* {0.909297, -0.416147} *)

Considering that

ClearAll[fun4,tmp2];
tmp2[t_] = expr[[1]];
fun4 = Compile[{{t, _Real}}, tmp2[t]];
fun4[2.]
(* 0.909297 *)

Concluding, I could apply Compile to all elements of my list and then merge the compiled functions into a single function, but that seems rather complicated and possibly what I need, i.e. something along the lines of fun, is easily realized if one knows how.

So the question is: Can anyone please let me know how to run Compile on a list that is stored in some precomputed expression?

Edit & Update

I have just found something related but I cannot get a solution out of it. The issue might be related to packed vs unpacked arrays, at least this is what I guess from the linked question.

Needs["CompiledFunctionTools`"];
CompilePrint[fun]
CompilePrint[fun3]

shows that fun has a call to MainEvaluate whilst fun3 does not:

(* output for fun *)
1 argument
        2 Real registers
        Underflow checking off
        Overflow checking off
        Integer overflow checking on
        RuntimeAttributes -> {}

        R0 = A1
        Result = R1

1   R1 = MainEvaluate[ Hold[tmp][ R0]]
2   Return


(* output for fun3 *)
1 argument
        3 Real registers
        1 Tensor register
        Underflow checking off
        Overflow checking off
        Integer overflow checking on
        RuntimeAttributes -> {}

        R0 = A1
        Result = T(R1)0

1   R1 = Sin[ R0]
2   R2 = Cos[ R0]
3   T(R1)0 = {R1, R2}
4   Return
$\endgroup$
  • 2
    $\begingroup$ You need With[] for injecting code: fun4 = With[{e = expr}, Compile[{{t, _Real}}, e]]. Or, some trickery with Hold[]/ReleaseHold[]: fun5 = ReleaseHold[Hold[Compile][{{t, _Real}}, expr]]. $\endgroup$ – J. M. will be back soon Mar 19 '18 at 17:13
  • $\begingroup$ @J.M. Thank you very much for this suggestion! If you wish you can turn it into an answer and I will accept. Unfortunately I now run into another error related to a numerical error when evaluating the CompiledFunction of my actual problem. Is it better to rewrite the question (shorten its current content) and extend it by the real expression I am working with, or should I rather open a second question purely focussing on that specific issue? $\endgroup$ – Lukas Mar 19 '18 at 17:32
  • $\begingroup$ I am pretty sure this is a dupe, but I am unable to recall where the original is. Your new error ought to be a separate question, I think. $\endgroup$ – J. M. will be back soon Mar 19 '18 at 17:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.