From 04:00 PM CDT – 08:00 PM CDT (09:00 PM UTC – 01:00 AM UTC) Tuesday, April 16, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Bug in In Range and Coerce when used with malleable VI

Solved!
Go to solution

Hi,

I'm experiencing unexpected behaviour, when using IR&C with a VIM in an Action Engine (Functional Global):


IRaC Bug.png

When the middle input comes from a uninitialized SR, the boolean array wire breaks when wiring into a VIM.

It does not break when wiring into other sinks for a boolean array though.

Also boolean array is the intended input for that terminal of the VIM, and works in other scenarios as can be seen in the snippet above.

Version 17.0f2 (32 bit) on Win 7 Home Premium (64 bit)

0 Kudos
Message 1 of 21
(3,144 Views)

I think the problem is the Uninitialized Shift Register, and a possibly-inintended-consequence of VIM Functionality.  Look at the input wires to the VIM when the Shift Register is initialized.  They are something like 1-D Array of Numeric (either "Dbl" or "Boolean").  Now delete the initialization Array and check again -- the top input has now acquired a Name, True Elements (1-D Array of Numeric), while the bottom input is still 1-D Numeric, un-named.  Where did the "True Elements" name come from?  It came from the output of the VIM, looping around through the Shift Register with nothing on the Input side to over-ride it.

 

Particularly with a VIM, where the code adapts to the Type of the Input, it is at least a "logical flaw" to provide an input that is not defined until after the VIM runs, which makes the definition circular at best, and (logically) ambiguous.  Don't Do That!

 

Bob Schor

 

P.S. -- I've passed on a suggestion to the Developers that something about "Be sure the Inputs to VIMs are defined", including a note about Uninitialized Shift Registers, is either put in the Documentation or dealt with in some other fashion.

Message 2 of 21
(3,125 Views)

Let me suggest a different format for your FGV.  Instead of a FOR loop with a shift register, just use a Feedback Node (no loop required).  Then you can Initialize the data type and avoid this issue.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
Message 3 of 21
(3,107 Views)

I was expecting the undefined SR type caused by circular definition, but it does not seem to be the case (see image).

 

+ It's also not the "In Range And Coerce", any compare has the problem.

+ As for a workaround, a build array set to concatenate solves it.

+ Apparently this will define (even better) that the Booleans are an array?

+ It does recognize Booleans when they where created at the other end of the SR.

+ A cast also helps, but only if defined by a constant.

 

Vim weirdness.png

 

All kinds of weirdness!

 

Guess not all types are defined equally.

Message 4 of 21
(3,099 Views)

The key step is "Then you can Initialize the data type", which is (functionally) equivalent to initializing the Shift Register.  If you build the Construct with a Feedback Loop and remove the Input Array to the Coerce function (which kind of defeats the purpose, as that's the "input"), the Boolean wire in the VIM breaks in the same way.

 

So I guess a Broken Wire here is warning you that you may be doing something that doesn't make (logical) sense.

 

Bob Schor

Message 5 of 21
(3,096 Views)

@wiebe@CARYA 

any compare has the problem

 

I wonder if this is the case because compare can be set to two different modes: Compare elements or compare aggregates, may be the VIM is unsure of the type arriving, a scalar or array.

 

Something like this may work. PLEASE TEST, have not tested.

First CaseFirst Case

 

Second CaseSecond Case

 

 

mcduff

 

Message 6 of 21
(3,085 Views)

Not related to the bug, but the VIM itself.  That is an interesting way to get True and False elements out of an array, but I think or more efficient method would be to use the conditional index terminal.  I made a VIM that does this over on LAVA for just the true elements, but do see value in getting the false ones as well and may update it.  All that is needed is a NOT and a second tunnel.  The VIM in that LAVA package is the Conditional Auto-Indexing Tunnel, and was intended to mirror the OpenG functionality.

 

Edit: Nevermind that VIM doesn't use conditional terminals, it should and I'll be updating it.

Message 7 of 21
(3,083 Views)

@mcduff wrote:

 

 

Second CaseSecond Case 


I'm not convinced that

a) this will help with the problem. The .vim already accepts a Boolean and a Boolean array (even integer and integer arrays), that's not the problem. Problem is it can't determine what to use.

b) that it will do what the user expects. If you wire a Boolean, there will be a one element array, while the integer array can be larger. I'd expect a true\false to be applied on all elements, not just the first. The total amount of elements (true+false) will be one (even if the input array is empty!).

 

It's a very complicated way to separate an array based on a Boolean:

Vim weirdness alt.png

But that doesn't solve the problem (.vim behaves the same), and it's OT as well.

 

 

Message 8 of 21
(3,042 Views)

@mcduff@mcduff wrote:

@wiebe@CARYA 

any compare has the problem

 

I wonder if this is the case because compare can be set to two different modes: Compare elements or compare aggregates, may be the VIM is unsure of the type arriving, a scalar or array.

 mcduff


I haven't fully fleshed this out, but I think this is basically correct. The in-range and coerce primitive can accept multiple combinations of input types (array or scalar on both the input and limit terminals) and using the output of a VIM (with an input that is not well-defined) to define the shift register type doesn't sound like something that should work.

 

Worth noting, if you manually change the compare mode, it is no longer broken. It doesn't immediately make sense to me why that works. (I kind of think it actually shouldn't.)

--------------------------------------
Message 9 of 21
(3,019 Views)

Thanks a lot for all the contributions so far.

 

I initially neglected to clarify: The snippet I posted is a stripped down version of my FG, just highlighting my issue (you probably guessed that, though).
The actual code has a case structure inside the loop, as to perform different operations on the data set depending on a mode selector input. It has e.g. an "init" case feeding array constants into the SRs - I wasn't aware that this isn't enough to type the SRs. At least, in my actual code, the type isn't defined circularly through the VIM alone. It is more akin to the upper left example in the snippet in wiebe@CARYA's first post.
I must admit I am confused about under which circumstances the type is defined well enough. If I do anything but connect a VIM to the array created by the comparison, LabVIEW "seems" to be certain about the type of the wire at edit time. If I create an indicator for the output it will be an array of booleans. How can that certainty be lost by connecting a sink? At first glance it's counterintuitive that connecting a sink with variable type should affect the type determined upstream.

 

Thanks for the suggestion, crossrulz.
I sometimes code my simpler FGs like that.
In this case, there are actually multiple SRs in the real code and replacing them would have to be done outside the case structure mentioned above. That would cause me to have a stack of FNs with wires all around my code. I'll probalby still do it like you suggested - it just won't be as tidy as I'd like. 😉

 

OT1 @Hoooovahh and wiebe@CARYA:
Fair point about the implementation. I think I benchmarked the code for my use case a long time and probably several LabVIEW versions ago. IIRC it was faster for large arrays, presumably because it calls the memory manager only a handfull of times while dynamically growing the output arrays does that a lot. I first saw this method in the array xnodes I was hoping to replace with the VIM..
Anyway - I should repeat the benchmarks some time.

 

OT2 suggestion:
For this problem it would be nice to be able to set specific inputs of a VIM to a certain type - i.e. exculding them from malleability. Sure, I can check for the type inside the VIM with unsupported features - but I guess that would still leave me with the broken wire in this case.
Also, I don't always want to be required to forge my code to handle all possible inputs that don't break the code outright. I want the bottom input of my filter array to always be an array of booleans, to keep the code simple.

0 Kudos
Message 10 of 21
(3,005 Views)