LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Wire value changes on output tunnel

Thanks for the relevant link to sorta similar tunnel weirdness.

 

I'm still not persuaded that even *if* the behavior in that linked thread is considered not-a-bug, that the same reasoning would apply to the situation in our thread here.  

 

   In the linked thread, the item passing through the tunnel is an array.  The array comes out of a dll call where it was passed in and out by pointer.  The external code apparently holds onto this pointer value and will later use it to access and modify the array's memory space even after the dll call involving the array has returned.

   Back in LabVIEW-land, the array wire comes out from the dll call and passes into a loop via tunnel.  The array coming out of the tunnel inside the loop ends up showing changing values from one iteration to the next, contrary to normal LabVIEW tunnel behavior.

   One can argue that the "misbehavior" is the fault of the dll code for capturing and retaining the array pointer and using it after the dll function call has returned.  LabVIEW makes the arguably reasonable (but incorrect) assumption that *it* now has ownership of that array and its memory space once the dll call returns.  It thus decides that the indexing operations inside the loop can be done "in place" without data copies.  Meanwhile, behind LabVIEW's back, the external code is also operating on the same memory space "in place".

 

   One difference in our thread here is that everything is in LabVIEW-land all the time.  Any "misbehavior" can only be caused by the LabVIEW compiler itself.  And it would be caused directly, not due to a mistaken assumption about external code.

 

   I agree that mcduff has assessed what *does* happen and that it differs for array access vs array element access.  I'm just not yet convinced the compiler should *let it* behave that way on data that's fully in LabVIEW's control at all times.

 

 

-Kevin P

ALERT! LabVIEW's subscription-only policy coming to an end (finally!). Permanent license pricing remains WIP. Tread carefully.
Message 21 of 33
(1,209 Views)

Seems like another clear-cut case of  buffer-reuse.  Always copy fixes the problem, which is a very good indicator of what is going on.  I have seen many cases where AC fixes a bug, but have yet to see any cases where it changes correct behavior.  If the current behavior is the lesser of several evils, I'd be satisfied with nothing else but a little indication on output tunnels of the IPES to expect the unexpected.

 

My preferred way of getting data out of an IPES is the following:

 

IPES_Swap.png

Message 22 of 33
(1,207 Views)

Here's a good read here link

 

It explains reading before modifying and when a copy of the data will occur.

 

Maybe @nathand will read this post and chime in.

 

mcduff

Message 23 of 33
(1,202 Views)

@mcduff wrote:

Here is a shift register version to consider. (It is also why I think read always occurs before rewrite.)

 

Snap1.png

  1. Wire lengths should be irrelevant, you can resize the the wires to have different lengths.
  2. I am indexing and replacing an element in an array in place.
  3. I can rewrite the memory address of the element or I can read the memory address of the element. According to the diagram, there should be no order of precedence, the values from the wire should appear instantaneously at both the read and write node.
  4. Yet, it appears that I always read the element before writing it, otherwise at some times the boolean would false, but it is always true.
  5. That is why I believe there is a compiler rule, read first then write is there is something ambiguous, similar to the IPE structure.

Hello mcduff,

you are absolutely right that the compiler is smart enough to read before write. This paragraph is form the LabVIEW help "VI Memory Usage":

https://zone.ni.com/reference/en-XX/help/371361R-01/lvconcepts/vi_memory_usage/

"Finally, consider the following block diagram.

loc_bd_funcmod.gif

In this case, the input branches to two functions, one of which modifies the data. There is no dependency between the two functions. Therefore, you can predict that at least one copy needs to be made so the Replace Array Subset function can safely modify the data. In this case, however, the compiler schedules the execution of the functions in such a way that the function that reads the data executes first, and the function that modifies the data executes last. This way, the Replace Array Subset function reuses the incoming array buffer without generating a duplicate array, making the data for this function in-place. If the ordering of the nodes is important, make the ordering explicit by using either a sequence or an output of one node for the input of another.

In practice, the analysis of block diagrams by the compiler is not perfect. In some cases, the compiler might not be able to determine the optimal method for reusing block diagram memory."

 

 

Message 24 of 33
(1,127 Views)

@UliB wrote:

Hello mcduff,

thank you for


@mcduff wrote:

EDIT: The indicator is pointing to a memory location that is changed after the in-place swap.


I suppose the compiler is not making a copy of the array in this case. If I insert an 'Always Copy' node all is working as expected again.

I understand now what happens, but still I find it strange to see two different values on one wire.


Wouldn't it be kind of silly if "In place operations" worked with copies? Also, you only want the "always copy" on the scalar, not the array, at least if the array is large. As you're using IPS i assume the data is large, else the ordinary array functions are better.

/Y

G# - Award winning reference based OOP for LV, for free! - Qestit VIPM GitHub

Qestit Systems
Certified-LabVIEW-Developer
0 Kudos
Message 25 of 33
(1,121 Views)

@UliB wrote:

Today I opened a SRQ with NI.


Meanwhile I received CAR number 737887.
I still don't know if it is considered a bug, but I think R&D will investigate.

UliB

0 Kudos
Message 26 of 33
(1,064 Views)

Any news on CAR #737887?

 

Just a little <bump> to the thread because most of the discussion took place when a lot of knowledgeable people were tied up with NI Week.

 

Can or should this be considered correct behavior?   Why or why not?  It seems wrong to me, based on my expectation that tunnels carry by-value semantics, as described in msg #15.

 

 

-Kevin P

ALERT! LabVIEW's subscription-only policy coming to an end (finally!). Permanent license pricing remains WIP. Tread carefully.
0 Kudos
Message 27 of 33
(992 Views)

I see no harm in doing this, but if I'm breaking some rule of the forum by doing it, then please let me know.  I ran across this thread via response to my thread.  This where I first heard about the Always Copy tool. 

 

I have experienced this bug of the CAR 737887 but it in a different way:

 

3d0g_0-1697578739003.png

 

In the above I placed the Always Copy recommended as the solution, by NI, on the line that loses its data (except for the array size.)  At the time of this there were 10,000,000 elements of data in the array.  On the other side it was all gone and replaced by zeroes.

 

A workaround I found is this:

 

3d0g_1-1697578912842.png

 

Here it can be seen I used a local variable to read the data.  Then after the array had exited I used the local variable to write the data to the array, again.

 

Note: There are four shift registered array lines.  The other lines are fine.  No need for local variable workarounds on those. 

 

 

0 Kudos
Message 28 of 33
(531 Views)

@Kevin_Price wrote:

One writes, the other reads, and there's no constraint to guarantee which one happens first.

 

-Kevin P


There is, though. Dataflow. The diagram dictates that the first array element is taken from the original unchanged array. The scalar copy needs to be made before the in-place element substitution.

I would definitely call this a bug.

Message 29 of 33
(487 Views)

@Kevin_Price wrote:

 

Can or should this be considered correct behavior?   Why or why not? 

 

 

-Kevin P


No. Because that would go against all of the rules of dataflow. Chipping away of the core of what makes LabVIEW good in order to get out of calling incorrect behaviour a bug sounds like a really really bad idea.

Message 30 of 33
(484 Views)