10
$\begingroup$

I get an error referring to "instruction 9223372036854775807" as follows.

I run the code

ClearAll[comp3]

comp3 = Compile[{{x, _Integer}, {y, _Integer}},

  DeleteCases[
   Flatten[Outer[If[True, {#1, #2}, {0, 0}] &, {0., 0.}, {0., 0.}], 1],
   {0., 0.}], 

  RuntimeAttributes -> {Listable}]

and I get the expected CompiledFunction output with no errors.

Then I run the code comp3[Range[2], {3, 1}]. The output is {{}, {}} and I get the following error.

error 1

  1. I understand the error in general and why it was cast. My question is specifically about "instruction 9223372036854775807". This exceeds the total of all instructions from any computer. What's going on here?

On the other hand, if I delete {x, _Integer}, {y, _Integer} and leave the first argument to Compile as {}, then run comp3[], I get the output {} with the following error.

error 2

  1. The minor change causes an error that refers to the more modest "instruction 53". What accounts for the difference? Why did such a minor change cause a drastic shift in the instruction number being referenced?

Notes


Update

There seems to be three bugs here.

  1. The reference to "instruction 9223372036854775807" is a bug that appears when applying a listable compiled function to a list.

  2. DeleteCases is not permitted to return an empty tensor when deleting elements from a tensor of rank > 1, though Compile can return an empty tensor. A minimal example demonstrating this was contributed by Michael E2 in the comments and is reproduced below. Notice the crazy instruction number bug is not reproduced in this example though.

comp3 = Compile[{x, y}, DeleteCases[{{0., 0.}}, {0., 0.}], 
   RuntimeAttributes -> {Listable}];

comp3[1, 1];

minimal example

I saw this too. I interpreted it as one of Mathematica's unfortunate quirks but agree now with Michael it is a bug.

  1. There is a third bug I missed and refer the reader to Michael's answer as he addresses it (as well as the others) well. He mentions it in his third written paragraph.
$\endgroup$
12
  • 2
    $\begingroup$ I would report this to Wolfram Support. $\endgroup$
    – Szabolcs
    Sep 5 '21 at 7:21
  • 2
    $\begingroup$ I replicated this on v12.2 Win7x64. $\endgroup$
    – Syed
    Sep 5 '21 at 8:05
  • 1
    $\begingroup$ 9223372036854775807 is most likely a side-effect of applying the Listable property, since comp3[1, 3] and comp3[2, 1] both give the instr. 53 error, which seems to me the central issue. You can inspect it with CompiledFunctionTools`CompilePrint[comp3]. $\endgroup$
    – Michael E2
    Sep 5 '21 at 15:19
  • 3
    $\begingroup$ To clarify my comment, from the perspective of this site, the wrong instruction number in an error message is a most uninteresting bug; but it should still be reported to WRI. It pales in comparison to the other bug, which is serious even if only mildly interesting from a site perspective (= how to use Mma). Here's a minimal example that reproduces the bugs: comp3 = Compile[{x, y}, DeleteCases[{{0., 0.}}, {0., 0.}], RuntimeAttributes -> {Listable}] $\endgroup$
    – Michael E2
    Sep 6 '21 at 16:19
  • 1
    $\begingroup$ Error replicated on 12.3.1 with Windows 10. $\endgroup$
    – Edmund
    Sep 11 '21 at 21:16
11
$\begingroup$

I think it's a bug that DeleteCases does not work; more specifically, it is not permitted to return an empty tensor when deleting elements from an tensor of rank > 1. Compile can return an empty tensor, but certain internal functions cannot. In particular Table in this case, but also Part. It seems a complicated situation, would take a long time to explain, and I'm not sure my explanation would be entirely correct. I'm still unsure whether "null tensor" is an empty tensor or some other exception, like a null pointer.

The simplest example is Compile[{}, Table[5., 0, 2]][], in which the offending instruction is T(R2)0 = Table[ I2, I4], where I2 is 0 and I4 is 2. (This instruction preallocates an array that is then filled with a double loop emulating Table[5., I2, I4].) It produces the CompiledFunction::cfnlts error with the correct instruction number 4. Since Table is so basic, I assume this is a design choice, although I am not privy to why it cannot return an empty tensor of the appropriate rank. It's an irritating choice since it breaks DeleteCases when it deletes all elements of the array. You can create empty tensors of ranks greater than 1 inside the WVM as follows, so why can't Table?:

Compile[{}, Dimensions[Most@{{0, 0}}]][] (* rank 2 *)
Compile[{}, Dimensions[{}]][]            (* rank 1 by default *)
(*  {0, 2}  *)
(*  {0}     *)

The OP's main interest seems to be the crazy instruction number in the error message when it occurs in applying a listable compiled function to a list. Here's a minimal example that seems to reveal yet another bug (see third example):

mwe = Compile[{{x, _Integer}, {y, _Integer}},
   Table[5., x, y], RuntimeAttributes -> {Listable}
   ];
(* example            output     err/instr. number       *)
mwe[1, 0]          (* {{}}       no error                *)
mwe[0, 1]          (* {}         yes/4                   *)
mwe[{1,0}, {0,1}]  (* {{}, {}}   yes/9223372036854775807 *)
MapThread[         (* {{{}}, {}} yes/4                   *)
  mwe, 
  {{1,0}, {0,1}}] 

The outputs of the third and fourth commands should agree, I think. Their first parts should be the same as mwe[1, 0]. The third one seems wrong.

One difference I noticed is that some errors have two messages, one with an instruction number and one without. The ones without instruction numbers are used when the compiled function is listable and called on a list. The error in the OP's case, CompiledFunction::cfnlts, is missing its mate:

CompiledFunction::cfex   (* ...instruction `1`... *)
CompiledFunction::cfexe  (* no instruction number *)

CompiledFunction::cfn    (* ...instruction `1`... *)
CompiledFunction::cfne   (* no instruction number *)

CompiledFunction::cfnlts (* ...instruction `1`... *) 
(* No CompiledFunction::cfnltse *)

Appendix

Here's a compiled version of DeleteCases. You could probably inline it (for a specific array depth) in another compiled function, though I haven't tested that yet. Just in case someone needs it in Compile sometime.

(* Compiled DeleteCases *)
ClearAll[dc];
mem : dc[n_Integer?Positive] :=
  With[{n0 = n, n1 = n - 1},
   mem = Compile[{{array, _Real, n0}, {elem, _Real, n1}},
     Block[{keepBAG = Internal`Bag@Most@{0}, keepIDCS},
      Do[
       If[array[[j]] != elem,
        Internal`StuffBag[keepBAG, j]],
       {j, Length@array}];
      keepIDCS = Internal`BagPart[keepBAG, All];
      If[Length@keepIDCS > 0, (* keepIDCS = {} leads *)
       array[[keepIDCS]],     (* to cfnlts error here *)
       Most@{elem}            (* array[[{}]] not compilable *)
       ]
      ]
     ]
   ];
dc[a_?ArrayQ, elem_] := dc[ArrayDepth[a]][a, elem];
$\endgroup$
1
  • $\begingroup$ Clever use of Pattern in mem : ...! $\endgroup$
    – b3m2a1
    Sep 14 '21 at 5:25

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.