6

I'm confused as to why the following leads to unpacking of a PackedArray:

Needs["Developer`"]
On["Packing"]
a = ToPackedArray@{RandomReal[], RandomReal[]};
a // PackedArrayQ (* returns True*)

b f[a] b + f[a]

Both of the last commands produce a FromPackedArray::unpack warning, specifically:

FromPackedArray: Unpacking array in call to Times.

and

FromPackedArray: Unpacking array in call to Plus.

(And one can verify that in the produced output a is no longer a PackedArray e.g. using PackedArrayQ[(b + f[a])[[2, 1]]].)

This was tested in Mathematica 12.1. In Mathematica 12.3, the above code does not lead to unpacking. However, if b is replaced by a number, for example 2 f[a] and 2 + f[a], then unpacking occurs in version 12.3 as well. No unpacking occurs in 12.3 when b is replaced by an extact numerical quantity (that is not an integer) such as inSqrt[2] + f[a]


This behaviour to me is unexpected. Since a is inside the f wrapper, I would not expect a to interact with the Plus and Times operations. If anybody can shed some light on why this happens, I would be most grateful. Even better would be tips on how to shield the PackedArray from unpacking in this type of situation.

TimRias
  • 3,160
  • 13
  • 17
  • I do not get the unpacking message with your example. I used M12.3 on macOS, tried in a fresh kernel. – Szabolcs Jun 23 '21 at 08:19
  • I can echo @Szabolcs' comment, M12.3 on Win 10. – ciao Jun 23 '21 at 08:19
  • @Szabolcs Interesting, I'll try some different versions. This was on 12.1 on Windows – TimRias Jun 23 '21 at 08:20
  • I can indeed reproduce this in 12.1. – Szabolcs Jun 23 '21 at 08:29
  • I can reproduce the same problem in 12.3 with 1 + f[a] but not with b + f[a]. Additionally, (1 + f[a])[[2, 1]] // PackedArrayQ is False and (b + f[a])[[2, 1]] // PackedArrayQ is True in M12.3, consistent with the unpacking message. Can you update the question with this new info @mmeent, or is it okay if I make the edit? – Szabolcs Jun 23 '21 at 08:32
  • Feel free to make the edit. (I'm busy installing 12.3) @Szabolcs – TimRias Jun 23 '21 at 08:33
  • Possibly related: https://mathematica.stackexchange.com/q/120522/12 Once I got a semi-explanation for that in another thread, or maybe on Wolfram Community, but I cannot find it, and I do not recall what it was (only that I was unconvinced) – Szabolcs Jun 23 '21 at 08:38

1 Answers1

5

I do not know why this happens, but I know of ways to prevent it. I ran into a very similar problem while working on the BoolEval package:

Unfortunately, I do not recall the details, but I said in a comment under that question that WRI responded to me about the issue (I can't find the exchange anymore) and the ultimate conclusion was that this behaviour is unlikely to change due to how the system is designed. Sorry for not being able to recall more.

Some ways to get around the problem:

Presumably, eventually you will give b and f definitions, and let the arithmetic expression evaluate.

Until you do that, you may keep the expression held: Hold[b + f[a]] does not unpack. This is what I use in BoolEval.

Alternatively, the value of the array variable can be removed for the time while you manipulate the arithmetic expression: Block[{a}, manipulate[ b + f[a] ] ]. In this example, I expect that by the time manipulate finishes, b and f will have definitions. The value of a will be inserted only afterwards.

Szabolcs
  • 234,956
  • 30
  • 623
  • 1,263
  • Thanks. I don't this particular work around will help my current purpose, but the improved behaviour of 12.3 seems sufficient for the moment. – TimRias Jun 23 '21 at 12:03