LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Reentrancy with a subVI inside itself

Solved!
Go to solution

I'm trying to create a utility that will read any kind of variant, automatically unpack it and create some sort of string output. I am using some VIs from VariantType.lvlib to help with this.

 

It got confusing when I started trying to unpack clusters. GetClusterInfo.vi creates an array of variants which then need to be run back through the same vi that unpacked the cluster. I was hoping to be able to do this by making the vi reentrant but this is somehow causing the data inside the original variant to disappear.

 

I don't want them to run in parallel as much as I want them to run nested. Is this possible?

 

DebugWriteToFile.vi is the main vi. which calls DebugVarDecode.vi.

0 Kudos
Message 1 of 15
(3,323 Views)

Recursion (where a sub-VI calls itself) is certainly possible in LabVIEW (I use it fairly frequently).  All you need to do is to open the VI's Properties, go to Execution, and select "Shared clone reentrant execution".

 

Bob Schor

0 Kudos
Message 2 of 15
(3,316 Views)

Works for me as written, but you can make recursion happen a little easier by dropping the sub.vi on its own block diagram like this:Recursion.PNG

0 Kudos
Message 3 of 15
(3,310 Views)
Solution
Accepted by topic author B_Strange

It's a Variant TYPE library, so many functions just give you the type, not the data values.

 

But you can convert a cluster to any array of variants (values included) using the "Variant to Data" primative.

Message 4 of 15
(3,306 Views)

For situations like this, I prefer to build an array of elements to process (or put them in a queue) instead of using recursion. I haven't checked the relative performance but I suspect it's better, and the code is easier to debug (you can monitor the array or queue to see how elements are added and processed). Each time you go a level deeper, you add that list of elements to the array or queue. On each loop iteration, you take the top item and process it. When the queue/array is empty, you're done.

0 Kudos
Message 5 of 15
(3,297 Views)

@fairlyFunctional wrote:

Works for me as written, but you can make recursion happen a little easier by dropping the sub.vi on its own block diagram like this:


Well it sort of works in that it's able to parse the information about the error cluster container itself. However, when the contents of this cluster are fed back through the vi, the information disappears. The output is the default of the separate data types (boolean=false, numeric=0, string="").

 

My output reads: 20150916T1721_Cluster_error in (no error)__Boolean_status_False_I32_code_0_String_source_

while it should read: 20150916T1721_Cluster_error in (no error)__Boolean_status_True_I32_code_2_String_source_test

 

I don't know why but the reentrant instances of the subvi are either not getting the data or not outputting it.

 

Also, thanks for the tip. I tried dropping the subvi in like you showed and it behaved the same. Still getting bad output but the wiring is much simpler so I'll stick with that.

0 Kudos
Message 6 of 15
(3,272 Views)

 


@nathand wrote:

For situations like this, I prefer to build an array of elements to process (or put them in a queue) instead of using recursion.


 I think I may have to go this route. I'd rather figure out this recursion business because it seems like it could be pretty powerful if implemented correctly.

0 Kudos
Message 7 of 15
(3,264 Views)
Solution
Accepted by topic author B_Strange

drjdpowell had the right plan. Here's a corrected .vi that should get you there.

0 Kudos
Message 8 of 15
(3,249 Views)

@B_Strange wrote:

 I think I may have to go this route. I'd rather figure out this recursion business because it seems like it could be pretty powerful if implemented correctly.


For whatever it's worth - in over a decade of writing LabVIEW code, I don't think I've used a recursive VI more than once. (OK, maybe that's not an entirely fair statement - recursion only became available in LabVIEW fairly recently). The last time I had a reason to benchmark it (http://forums.ni.com/t5/LabVIEW/Numbers-bigger-then-10-to-a-array-of-integers/td-p/1584814) a recursive solution was 5 times slower than a non-recursive solution.

 

Recursion is a powerful concept, but not so much the LabVIEW implementation. There are languages (functional languages such as F# and Haskell) that make extensive use of recursion, to the point of replacing most loops with recursive calls, and they also support tail-recursion where a properly-written recursive function doesn't need to allocate a new copy of itself on the stack for each call. LabVIEW does not do this, so recursive calls will use more memory and incur a performance penalty versus a loop.

 

Of course, if you're just curious about how recursion works, go for it - but I wouldn't recommend writing a lot of recursive LabVIEW code.

0 Kudos
Message 9 of 15
(3,245 Views)

@fairlyFunctional wrote:

drjdpowell had the right plan. Here's a corrected .vi that should get you there.


Y'know... I read that and just glossed over it thinking I'd already covered it. Shame on me. Thanks for putting it so bluntly!

0 Kudos
Message 10 of 15
(3,239 Views)