09-07-2020 10:39 AM
The output of the arithmetic operation is not correct when performing simple arithmetic operation over large arrays.
Seems the total number of elements in the array should be larger than some number between 2E+9 and 3E+9 (probably Max(I32)=2^31-1).
The bug exists in LabVIEW 2017, 2018, 2019 and 2020, but not in LabVIEW 2016 (all 64 bits).
32-bit LabVIEW is not applicable.
Attached is the sample VI (for LabVIEW 2016) to reproduce the bug.
Instructions:
Run the VI with default values of the controls: dimension size = 1000, dimension size 2 = 3000000.
The output should be 11.
In LabVIEW 2017 and above the output remains unchanged (1).
When dimension size 2 = 2000000, the out result is correct (11).
The bug still exists, when:
09-07-2020
11:31 AM
- last edited on
05-05-2025
09:22 AM
by
Content Cleaner
Bug exists on my LV2020 64 bit as well. I messed with changing the indexes to try to figure out exactly where the issue lies, and you can reduce the dimension size 1 to 10 and increase dimension size 2 to 214748365 and still get the bug. Dropping to 21474364 gets you the right answer.
It appears that the issue is when the number of array elements exceeds the max value for an I32 (2147483647). I assume this is related to how LV stores arrays in memory:
https://www.ni.com/docs/en-US/bundle/labview/page/how-labview-stores-data-in-memory.html
It uses an I32 internally to store the size.
Definitely looks like a bug to me. Can I ask what it is you're actually "doing" with datasets this big? If my math is right, this is something like a 16 gigabyte array (4 billion values x 4 bytes each = 16 billion bytes). I can't help but wonder if it would be simpler to reduce this data size somewhat.
09-07-2020 12:13 PM
@BertMcMahan wrote:
It uses an I32 internally to store the size.
But is it I32 per dimension, so it is not obvious why it would fail here, (especially since it seems to work correctly in LabVIEW 2016)*. My guess is that the total number of elements (i.e. the product of all dimension sizes) is limited to I32 and the two indices are just used to calculate the I32 offset in the flattened data in memory. Allowing more than max(I32) elements opens a can of worms, e.g. if somebody would try to reshape the 2D array to 1D.
Interesting edge case. I assume not only the first element is affected (sorry, only 32bit here, so I cannot test).
*Are you sure it works correctly for all elements in LabVIEW 2016? Could it be that 2016 is simply more ignorant about possible limitations and does not realize that something is exceeded. Try to get the last element instead.
09-07-2020 12:20 PM - edited 09-07-2020 12:27 PM
I ran your VI in 2017 and got the correct result. 2017 64 bit Professional, Windows 10 Enterprise, 64GB onboard RAM.
edit: took a hot minute (like 45 seconds) but I was able to get the correct result even after changing dim1 to 10,000. I imagine adding 10 to 30 billion elements is quite taxing but it happened, correctly.
Saying "Thanks that fixed it" or "Thanks that answers my question" and not giving a Kudo or Marked Solution, is like telling your waiter they did a great job and not leaving a tip. Please, tip your waiters.
09-07-2020 01:10 PM
@altenbach wrote:
@BertMcMahan wrote:
It uses an I32 internally to store the size.
But is it I32 per dimension, so it is not obvious why it would fail here, (especially since it seems to work correctly in LabVIEW 2016)*. My guess is that the total number of elements (i.e. the product of all dimension sizes) is limited to I32 and the two indices are just used to calculate the I32 offset in the flattened data in memory. Allowing more than max(I32) elements opens a can of worms, e.g. if somebody would try to reshape the 2D array to 1D.
You're right, I was guessing they might store the total memory size as an I32 and store dimensions separately, but I didn't read it thoroughly. They explicitly say that they store the dimension sizes as I32's in memory, then the data, and nothing else. The issue is probably that it appears to store the elements linearly, at least for 1D or 2D arrays:
If it uses an I32 for the memory offset, then "total size" matters, not just each element, because accessing the last member would be at offset i*j*k*l. Since each dimension is indeed an I32, then it would make sense to keep the product an I32.
This would also explain why it doesn't matter what datatype you use; it's not about the data in memory, it's about the pointer to the data in memory. I know LV does some stuff to keep arrays fast (for example, I think reversing a 1D array doesn't change the values, just the pointers somehow).
09-08-2020 03:32 AM
Since arrays are one 1D-array in memory (as it's continuous), i guess the indexing simply multiplies the dimensions to get the offset as a I32 (U32?) and breaks if there's >2.1G (4G?) elements on a 32 bit LV.
Since it seems to work in the 64 bit version, i take it either Array sizes are stored as I64 and/or the indexing calculation uses it.
I'm not really surprised, there's Always limits somewhere and for those data sizes 64 bit should be used. 🙂
In order to use it on a 32 bit system you'll have to e.g. use an Array of cluster of arrays where you store each row as 1D.
09-08-2020 03:52 AM - edited 09-08-2020 03:55 AM
@ngene wrote:The output should be 11.
Totally besides the point, but shouldn't the result be 247?
09-08-2020 06:00 AM
Initially we've got this bug with large 4D SGL array. Here, we just simplified it enough to be able to reproduce the bug on machines with lower amount of (kind of) RAM. That's why we print only the first element.
The application is Deep Learning where we read a large dataset of images and store them as 4D SGL, and the bug appeared when the dataset is normalized from 0..255 (pixel values) to (-1..+1) range, before feeding to the neural network for the training.
The workaround was to normalize the values in per image (volume) manner, before assembling them into 4D. Just it took us some time until we revealed the issue (in the less obvious place of the code :)).
09-08-2020 06:02 AM
09-08-2020 06:19 AM
@FireFist-Redhawk wrote:
I ran your VI in 2017 and got the correct result. 2017 64 bit Professional, Windows 10 Enterprise, 64GB onboard RAM.
Interesting and more confusing.
These are the results we get for different array dimensions in LV17.
(dimension size) x (dimension size 2) >> Output
1k x 3M >> 1 (incorrect)
2k x 3M >> 11 (correct)
3k x 3M >> 11 (correct)
4k x 3M >> 1 (incorrect)
5k x 3M >> 11 (correct)
5.1k x 3M >> 1 (incorrect)