1
$\begingroup$

I'm tring to use Compile in the following code, but it gives me an error message that I don't understand:

m = Table[i*j, {i, 1, 2}, {j, 1, 2}];
res = Table[0.0, {i, 1, 2}];
g[a_] := m.a

fun = Compile[{},
  res[[1]] = {{1}, {2}};
  p = Apply[Plus, Flatten[res[[1]]]];
  res[[1]] = If[p > 5, {{1}, {2}}, g[res[[1]]]];
  ]

(*Compile::cplist: res[[1]] should be a tensor of type Integer, Real, or Complex; evaluation will use the uncompiled function. >>*)
(*Compile::cplist: {0.,0.}[[1]] should be a tensor of type Integer, Real, or Complex; evaluation will use the uncompiled function. >>*)

My actual code includes a Do loop in the compile but I've removed it here to make the working example simpler. If I take out the first two lines in the Compile, then the error disappears:

m = Table[i*j, {i, 1, 2}, {j, 1, 2}];
res = Table[0.0, {i, 1, 2}];
g[a_] := m.a

res[[1]] = {{1}, {2}};
p = Apply[Plus, Flatten[res[[1]]]];

fun = Compile[{},

  res[[1]] = If[p > 5, {{1}, {2}}, g[res[[1]]]];
  ]

Where does the error message in the first example come from?

$\endgroup$
  • $\begingroup$ There are multiple issues with your code. If is not the problem and your last fun just calls MainEvaluate. This tutorial should be helpful. $\endgroup$ – Karsten 7. Dec 21 '14 at 6:43
  • $\begingroup$ And though not well documented, the multiple issues have been well discussed in this site actually. I really suggest you to have a look at those posts tagged with "compile" first. You may also interested in this page, though it's based on v4, the 6 principles mentioned therein are still valid today. (The only difference might be that the number of compiliable functions has increased a little. Also see here for an up-to-date list.) $\endgroup$ – xzczd Dec 22 '14 at 4:11
3
$\begingroup$

To get you started, here are two examples that do work

m = Table[i*j, {i, 1, 2}, {j, 1, 2}];
res = {{{1}, {2}}, {{3}, {4}}};

Note that res must have the correct rank.

Needs["CompiledFunctionTools`"]

Example 1:

cfun2 = Compile[{{x, _Real, 2}},
  If[Total@Flatten[x] > 5, {{1}, {2}}, m.x], 
  CompilationOptions -> {"InlineExternalDefinitions" -> True}]

CompilePrint@cfun2
    1 argument
    1 Boolean register
    4 Integer registers
    3 Real registers
    6 Tensor registers
    Underflow checking off
    Overflow checking off
    Integer overflow checking on
    RuntimeAttributes -> {}

    T(R2)0 = A1
    T(I2)3 = {{1, 2}, {2, 4}}
    I2 = 5
    I1 = 12
    I0 = 1
    R2 = 7.
    T(I2)2 = {{1}, {2}}
    I3 = 3
    Result = T(R2)1

1 T(R1)1 = Flatten[ T(R2)0, I0]]
2   R0 = TotalAll[ T(R1)1, I1]]
3   R1 = I2
4   B0 = R0 > R1 (tol R2)
5   if[ !B0] goto 9
6   T(R2)5 = CoerceTensor[ I3, T(I2)2]]
7   T(R2)1 = CopyTensor[ T(R2)5]]
8   goto 12
9   T(R2)1 = CoerceTensor[ I3, T(I2)3]]
10  T(R2)4 = Dot[ T(R2)1, T(R2)0, I1]]
11  T(R2)1 = CopyTensor[ T(R2)4]]
12  Return

Now you can use cfun2 in the following way

res[[1]] = cfun2[res[[1]]]
{{5.}, {10.}}
res[[1]] = cfun2[res[[1]]]
{{1.}, {2.}}

Or define a helper function

fun2[n_Integer] := (res[[n]] = cfun2[res[[n]]];)

fun2[1]
res[[1]]
{{5.}, {10.}}

Example 2:

Make the compiled function Listable and use Parallelization:

cfun3 = Compile[{{x, _Real, 2}},
  If[Total@Flatten[x] > 5, {{1}, {2}}, m.x], 
  CompilationOptions -> {"InlineExternalDefinitions" -> True}, 
  CompilationTarget -> "C", RuntimeAttributes -> {Listable}, Parallelization -> True]

And now

res = cfun3[res]
{{{5.}, {10.}}, {{1.}, {2.}}}
res = cfun3[res]
{{{1.}, {2.}}, {{5.}, {10.}}}
$\endgroup$

Your Answer

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

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