From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, 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: 

Using cluster type for SubVI output

Dear All,

Could you please help with a simple question. I want to use my user type (cluster) as a SubVI output parameter.

The issue is like when my SubVI doesn't fill-in the output cluster with actual data, it's being filled-in implicitely by zeroes. Why that?

Please find a simple illustration project attached (LV2017)

My general target is to fill a big data cluster from SubVI. So how do I do it correctly? I thought that I could create my big cluster in a caller VI and then pass something like a reference to my SubVI, but I cannot find how to do that. I have to put my big data structure directly into SubVI. Is it correct? Does it mean that data is created in a SubVI and then copied to the caller VI?

So my general question is - how to correctly pass references to big data structures to SubVIs correctly.

 

Thank you. 

 

0 Kudos
Message 1 of 10
(3,570 Views)

For the most part, LabVIEW passes data by value, not by reference. One exception is the Data Value Reference (DVR). If you pass the DVR around, you can use the in place element structure to put a lock on it, edit it, and then release the lock. But, generally, if I have a cluster that I need to modify, then the SubVI has cluster input and output.

0 Kudos
Message 2 of 10
(3,550 Views)

A few more comments:

 

First of all, connected controls and indicators of subVI belong outside structures. (read this post and the entire thread).

 

Why would you even call the subVI if you don't want the output? What kind of data would you expect if the subVI does not touch the output? If you want it to return the last "valid" output, add a feedback node and read from it in the other case.

 

Easiest would be to replace the current cluster diagram constant with a control and wire it as input, then you would either return the input unchanged, or modified by the subVI. What is your worry about memory? Do you have noticeable memory problems? You can inline the subVI to lower the all overhead, but even without that the LabVIEW compiler manages memory well and limits data copies. What is a "big data cluster"? How big? How many elements? How many expensive data structures (e.g. very large arrays)?

0 Kudos
Message 3 of 10
(3,519 Views)

@altenbach

Dear altenbach, thanks for your comment


>>  What is your worry about memory? Do you have noticeable memory problems? 
Of course, not. It's not namely about the memory, it's rather about performance and convinience. You can also ask "what's my worry about performance", having probably in mind the overall PC performance, but I'm implementing a PC interface to a control system, so I do worry about a cyclical thread performance, which definitely matters. Firtst, in principle, I'd like to understand how are the parameters passed in/out of a function (SubVI) in LV. Second - my Q comes from my previous programming experience (e.g. C++), where it's essentially noted that one should pass "big" parameters in/out of function "by reference" (or "by pointer"), not "by value". Parameters, passed by value, are being re-copied back and force every time, while parameters passed by reference are just being addressed to the same (and the only) memory area. Again, if you don't worry about memory and performance you can pass by value, but the main point is that you have an opportunity to choose any method you like. How the parameters are passed in LV I have just realized thanks to the previous post from gregoryj because I haven't found it this info anywhere else.

My cluster is 200x float32 values. It's not an array. Of course, speaking of memory occupation, it's quite small data. 

The main trouble here for me passing the data by attaching the cluster to the in and out of a function is that it's pretty much inconvinient to put these two clusters onto FP of each of my SubVI. E.g. I have a number of different subvis dealing with only one of those 200 values and comprises a tiny piece of code. But for every if them I have to place 2 big clusters onto FP, so my FP becomes as big as several PC monitors.

 

Also I have found how to pass a reference to a cluster 

image.png

but I have made a very simple benchmarking program and sadly noted that LV "reference" seems to be quite another thing than C++ "reference", because in comparing with directly passing a local cluster variable the function execution time increases by several orders of magnitude ((

 

0 Kudos
Message 4 of 10
(3,493 Views)

@P.C. wrote:

but I have made a very simple benchmarking program and sadly noted that LV "reference" seems to be quite another thing than C++ "reference", because in comparing with directly passing a local cluster variable the function execution time increases by several orders of magnitude ((


More like THOUSANDS times slower.  The reason being that every time you use a property node to update a front panel item (value or any other property), it forces a thread swap to the UI thread and the front panel must redraw.  This is an extremely slow process relative to everything else you are trying to do.  It is best to pass the value out with a cluster indicator and let the main VI update however it needs to.

 

And at the size of that cluster, it would be much better to use either an array or Variant Attributes.


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
0 Kudos
Message 5 of 10
(3,485 Views)

That's not how you send around a reference to a cluster. It's a reference to the front panel object. If you really want the reference you should use Data Value Reference (DVR), but it sounds like unnecessary, just use the Cluster as input and output of the subvi.

/Y

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

Qestit Systems
Certified-LabVIEW-Developer
Message 6 of 10
(3,479 Views)

Note that since all elements in the cluster are the same type,

if you want to increment all of them, you don't have to unbundle & rebundle:

ic.png

"If you weren't supposed to push it, it wouldn't be a button."
Message 7 of 10
(3,463 Views)

A couple very general comments about passing clusters by value rather than by reference:

 

The LabVIEW compiler works differently than a C compiler.  (Caution: author's knowledge of C compilers predates Y2K.)   When you pass a large data structure by value in C, data must be copied to the stack as part of the standard compilation for a function call.  So in C, it's a good rule of thumb to follow to make sure you pass large data structures by pointer or by reference for the sake of execution efficiency.

 

The LabVIEW compiler looks deeper into the hierarchy of function calls to figure out for itself whether or not data copies need to be made.  You can have a cluster wire containing 100's of kbytes of data, feed it into a subvi as an input argument, do some operations that don't change the size of any cluster elements, then feed it back out as an output argument.  For reasonably well-structured code, LabVIEW's compiler will recognize that no data copying is needed at all.  Internally at the time of compilation, that big "by value" data structure gets handled about as efficiently as a "by reference" function call in C.

 

This part of the LabVIEW compiler's brain is referred to as the "in-placeness algorithm", and it's really quite good at generating code that runs efficiently while maintaining data integrity in a highly parallel execution environment.

 

 

-Kevin P

CAUTION! New LabVIEW adopters -- it's too late for me, but you *can* save yourself. The new subscription policy for LabVIEW puts NI's hand in your wallet for the rest of your working life. Are you sure you're *that* dedicated to LabVIEW? (Summary of my reasons in this post, part of a voluminous thread of mostly complaints starting here).
Message 8 of 10
(3,454 Views)

I have a LabVIEW Real-Time Project that does behavioral testing of human subjects to study aspects of sound localization.  The experiment is controlled from an Excel Workbook, with each trial having on the order of 140 parameters assembled from the Workbook.

 

The data are stored in a 140-element Cluster, and are maintained in a VIG.  At the beginning of a Trial, the specific set of values are updated from the Workbook and saved in the VIG, and passed to the main State Machine where they reside in a Shift Register, and are also passed (via a Network Stream) to the RT Target, again being saved in a Shift Register.  Most States need none of the values, but those States that need specific sets of values (for example, the parameters for playing a particular sound) just "unbundle" the required parameters from the wire running in the Shift Register.  Very little "passing of large clusters" takes place, and when it does, it happens at the beginning or end of a Trial (where a millisecond or two won't matter).

 

Bob Schor

0 Kudos
Message 9 of 10
(3,436 Views)

If you keep these large clusters on the subvi, make sure that the front panel is closed, else LabVIEW will update these controls and indicators at a cost. Even better, set the subvi to be inlined. 

Message 10 of 10
(3,427 Views)