LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Why does converting a SGL to SGL get rid of coersion dots?

I was answering a Q on the RT forum when I found a coercion behaviour that I simply can not explain.

Maybe there is something subtle happening here that is escaping me.

What I am trying to do is enusre that a shift register is a SGL. After some investigation I found the part I can not explain. This is illustrated in the LV 6.1 version of the attached code. It turns out that if you insert a "to SGL..." into the bottom wire feeding the subtract node, ALL OF THE COERCION DOTS GO AWAY!

For those of you that can not take a look at my example, I will try to explain what I have.

I have a action engine that stores a running sum of X^2 values. In one of the actions, the oldest value is deleted from an
array being used as a circular buffer and the running sum of X^2 is updated.

The math used to track this running sum is stored in an un-inititialized SR. As long as I do not wire the output of the final subtract node to the output tunnel of the case, the SR is a SGL. Once I wire the subtract to the output tunnel of that action (case) the tunnel becomes a DBL, the SR becomes a DBL and coercion dots pop-up everywhere.

My best guesses are;
1) The default data type of the subtract or Index array is being used AND the help window AND coercion dots are lying to us.
or

2) While completing the wiring to the output tunnel from the subtract node, the data type of the output tunnel is undefined and LV defaluts it to a DBL.
or

3) Least likely, the Multiply nodes are confussing the data types.

4) There is something subtle that I am missing.

If you can explain this, please enlighten me!

Ben

(My question is in bright yellow)
Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
0 Kudos
Message 1 of 16
(5,441 Views)
Hi, Ben!

Its an interesting question. I think, its not a bug, but something definitively wrong.
The main problem (my opinion), that LabVIEW cannot decide properly, which type of data must be used for Shift Register. May be its only problem with visualization of Block Diagram.
Look at my example. I have added only Select structure with constant.
Now buffer was allocated on the output of Select structure, and this type defined as SGL by constant. And now all coercion dots are removed. (It's not solution, of course, but only one more step for understanding this situation). But I think, only NI Engineers can explain this behavior clearly for us.

With best regards;
Message 2 of 16
(5,441 Views)
Hi again,

In attachment - some While-loops with Shift Registers. Sometimes with coertion dots, and sometimes without. Take a short look inside.
0 Kudos
Message 3 of 16
(5,441 Views)
My interpretation is this:

The math functions have double as their default output. They do not change this unless both of their inputs have another type or if it's definite that you want the output to be of a specific other applicable type - here SGL. When wiring the shift register to one of the inputs and the type of the shift register is decided by the output of the math function it does not have any definite reasons to change the output from it's default so it uses a double. However if you wire a conversion to SGL on one of the inputs it's definite that SGL is wanted as the output, or if you wire it to the output to the double - both inputs becomes SGL and the funtion changes it's output accordingly.

The rules behind this sometimes fail to give what the
user wants. Especially the increment and decrement functions have an irritating tendency to use double as it's output even though the input is an integer and so change the type of the shift register that receives it's result to a double (which is could be sais to be even worse than this case...).

One solution would be for LV to look at inputs directly from a shift register as seconday to inputs from other sources. In this case it should then let the SGL input override the other input simply because that one comes from a shift register, however I'm sure that would cause other and perhaps even worse problems...
Message 4 of 16
(5,441 Views)
"Take a short look inside."

Well after looking at and editing your example for about 3.5 hrs... I now think I am getting where! please don't ask me where quite yet.

See below and be reply to Mads (to follow).

"Its an interesting question."
Thank you. I was hoping it would end up being an interseting riddle and not old age.

"I think, its not a bug, but something definitively wrong."
I was of the same opinion until I started playing with your example. It may still work out that this behaviour can be explained but there are number of exceptions that came out of my experiments based on your example. Some of the odd things are illustrated in the new eaxample I am posting now. These a briefly listed below.

1)LV needs help figuring ou
t what data type is coming from an index array
In the rather complcated case of an arithetic node being feed by a shift register that in-turn feeds itself, a "to SGL..." will help LV avaoid an undesired coercion.

2)Add node has same coercion that Subtract did but compund arithmatic>>> does not show coercion dots.
The unexpected coercion occurs when using normal arithetic operations. The Add coerces the same way as the Subtract, Multiple, etc. If a Compound Arithmatic configured to "add", the corecion behaviour is different.

3) I appears all data types that are smaller than DBL exibit the same coercion behaviour while data type larger than DBL behaves as expected.



4)"NO Math", "No Problem!"

"(It's not solution, of course, but only one more step for understanding this situation)."

It was an excellent step! I thank you sir!
Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
0 Kudos
Message 5 of 16
(5,441 Views)
Hi Mads!

Between your reply and Andrey's example I picked up some insight that is illustrated in the example I posted to Andrey's reply.

The oddeset part of this riddle is that the Compund Arithmatic functions as I would expect. The bit about data types larger than DBL not behaving the same way is also un-expected.

I do not think I can call this issue a bug. It is definately un-expected and inconsistent.

What do you think?

Ben
Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
0 Kudos
Message 6 of 16
(5,441 Views)
One more thought.

Could data type promotion be coming into play here?

Ben
Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
0 Kudos
Message 7 of 16
(5,441 Views)
None of your shift registers are initialized. So Labview will use default values on the outputs of math functions. The multiply function defaults to a double for its output. If you initialize the top shift register with a single (value=0), and initialize the next shift register with an array of singles, then all the coercion dots will go away. This is because the data type has been defined from the very beginning. It is good practice to always initialize shift registers. Do this by wiring the appropriate value and type to the inputs (right side) of every shift register.
- tbob

Inventor of the WORM Global
0 Kudos
Message 8 of 16
(5,441 Views)
Hi tbob!

Thank you for replying to my question.
You Answered;

"None of your shift registers are initialized."
Correct! This is a standard LV programing construct that has been around since LV2 or there abouts. It goes by a number of different names, LV2 global, Functional global, USR (USR),... This consturct behaves like a "static local" (?) in C. This techniques is used any time you want to use the results of the previous call of a VI in subsequent calls of a VI. You can read more about this in the Dr. VI (I believe this is really Greg McKaskle) article that can be found here;

http://www.ni.com/devzone/lvzone/dr_vi_archived1.htm


You went on to say;
"So Labview will use default values on the outputs of math functions. The multiply function defaults to a double for its output."
If you carefully compare the various examples I included in the code I posted, you will see that it does not always use the default output type. Look at the examples that use EXT for example. Also please look at the example that used the "Compound arithmatic" function. That diagram behaves as expected.

YOu went on to say;
"If you initialize the top shift register with a single (value=0), and initialize the next shift register with an array of singles, then all the coercion dots will go away. This is because the data type has been defined from the very beginning."
Again please look at the example I posted. by inserting a "to SGL..." the coercion dots go away without loosing the USR functionality. After having thought about this more, I am leaning toward another answer to this puzzle. Please bear with me while I share my thoughts.

When LV is trying to determine what the data type of the SR should be it starts tracing back the connections to the arithmatic node. The top leg is fed from the same shift register we are trying to define. This leads to a circlular reference and I am guessing that that path is abandoned. It then traces back the other leg looking for a data type. When it finds my "to SGL...", there is only one data type available as an output of that node so it uses a SGL, and all of corecion goes away.

Without the "to SGL..." it traces the wire back to the "index array" which is a polymorphic function so it can not get the data type from there. It then has to chace back the array feeding the "Index array" only to find that it is feed from a shift register that is un-initialized.

At this point I get confused with my current theory. IF the type is larger than a DBL then the coercion goes away. If it is smaller (i.e. SGL U8, U16, etc) it apears to act differently!

"It is good practice to always initialize shift registers."
Provided it is not a USR yes!

Please let me know if you have other thoughts.

Still looking for the answer to my riddle,

Ben
Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
0 Kudos
Message 9 of 16
(5,441 Views)
Sorry, I had no idea you were using this as a function global. You are correct in that the shift registers should not be initialized for this purpose. As for your mystery, without the shift registers being initialized to a specific data type, it seems that there are various combinations of data type inputs and outputs for the math functions. Labview must use some sort of algorithm to ensure that the data type of each node will hold all information, without cutting a DBL into a SGL and losing higher bytes. This mystery can only be answered by someone familiar with the algorithm. It must be a good one as I have never seen an instance where a DBL was misconverted into a SGL losing higher byte information.
- tbob

Inventor of the WORM Global
0 Kudos
Message 10 of 16
(5,441 Views)