2
$\begingroup$

The following code is a minimal model of an error I am getting. It returns the error Compiled expression {{0,2},{2,0}} should be a machine-size real number. and Could not complete external evaluation at instruction 1; proceeding with uncompiled evaluation.. However the same code runs without error if I remove the line s=1;, which ostensibly is doing nothing.

Naturally, I don't understand what is going on. Any pointers appreciated. Running v13.1.0.0 on Mac OS X x86 (64-bit).

Module[{fmn},
 
 fmn = Compile[{{m, _Integer}, {n, _Integer}},
   
   Sum[
    Module[{s},
     
     s = 1;
     
     {{0, 1}, {1, 0}}
     
     ]
    , {j, 1, 2}]
   
   ];
 
 ArrayFlatten@Table[fmn[m, n], {m, 0, 1}, {n, 0, 1}]
 
 ]
$\endgroup$

1 Answer 1

1
$\begingroup$

First load the package so we can do CompilePrint

Needs["CompiledFunctionTools`"]

Simplifying your minimal model further we see that Compile does not like Sum with s as a symbol; MainEvaluate gets called.

f = Compile[
   {{m, _Integer}, {n, _Integer}},
   Sum[
    Module[
     {s},
     s = 1;
     {{0, 1}, {1, 0}}
     ],
    {j, 1, 2}
    ]
   ];

f[1, 1]  (* {{0, 2}, {2, 0}} with error message *)
CompilePrint[f]
  2 arguments
  3 Integer registers
  1 Real register
  1 Tensor register
  Underflow checking off
  Overflow checking off
  Integer overflow checking on
  RuntimeAttributes -> {}

  I0 = A1
  I1 = A2
  I2 = 1
  T(I2)0 = {{0, 1}, {1, 0}}
  Result = R0

  1   R0 = MainEvaluate[ Function[{m, n}, Sum[Module[{s}, s = 1; {{0, 1}, \
  {1, 0}}], {j, 1, 2}]][ I0, I1]]
  2   Return

If we initialise s=1 in the Module Compile is happier and can proceed with the Sum

g = Compile[
  {{m, _Integer}, {n, _Integer}},
  Sum[
   Module[
    {s = 1},
    {{0, 1}, {1, 0}}
    ],
   {j, 1, 2}
   ]
  ]

g[1, 1] (* {{0, 2}, {2, 0}} *)
CompilePrint[g]
  2 arguments
  15 Integer registers
  4 Tensor registers
  Underflow checking off
  Overflow checking off
  Integer overflow checking on
  RuntimeAttributes -> {}

  I0 = A1
  I1 = A2
  I12 = 0
  I14 = 2
  I2 = 1
  T(I2)0 = {{0, 1}, {1, 0}}
  Result = T(I2)3

  1   T(I3)1 = {T(I2)0}
  2   T(I2)3 = Part[ T(I3)1, I2]
  3   I8 = Length[ T(I2)3]
  4   T(I3)3 = {T(I2)0}
  5   T(I2)1 = Part[ T(I3)3, I2]
  6   T(I1)3 = Part[ T(I2)1, I2]
  7   I10 = Length[ T(I1)3]
  8   I3 = I12
  9   T(I2)3 = Table[ I8, I10]
  10  I6 = I12
  11  goto 16
  12  I9 = I12
  13  goto 15
  14  Element[ T(I2)3, I3] = I12
  15  if[ ++ I9 <= I10] goto 14
  16  if[ ++ I6 <= I8] goto 12
  17  I4 = I14
  18  I5 = I12
  19  goto 22
  20  T(I2)1 = T(I2)3 + T(I2)0
  21  T(I2)3 = CopyTensor[ T(I2)1]]
  22  if[ ++ I5 <= I4] goto 20
  23  Return
$\endgroup$
3
  • $\begingroup$ Thank you for unpicking this. I see that initialising s with a value fixed the error. Is that a general principle? Should one always avoid uninitialised variables in compiled code? Is it because the type of s was unclear to the compiler? $\endgroup$ Nov 3, 2022 at 14:53
  • $\begingroup$ I think that is generally a good idea. $\endgroup$ Nov 3, 2022 at 15:55
  • $\begingroup$ In this particular instance, I suspect it's because of Sum which typically expects a function as the first argument. eg foo = Compile[{{m, _Integer}}, Table[Module[{s}, s = 1; {{0, 1}, {1, 0}}], {j, 1, 2}]] has no errors $\endgroup$ Nov 3, 2022 at 15:57

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.