LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

VI Template instanciation and Set Control Value method

I've been trying to create a set of VIs where I can repeatedly call a VI which has a wait function in it without having to wait for it to finish AND where I can pass a different value to each instance of that VI. Each instance is supposed to wait, and when it's finished doing its thing spit out its results to a LV2 global array.
From the searching I did I found the option of using a *.vit to create a new VI for each instance and using Set Control Value to pass the value.

I built a small demo to test this, where each instance replaces its corresponding element in the global array, and it seems my problem is two-fold:
1. The creation seems to take a lot of time (50-100 ms for each instance). I'm not sure this will be a problem, but I may have to do this creating quite a lot, so it might pose a problem.
2. Some of the instances in my demo don't seem to be receiving the value I'm passing, so the array has a 0 in its place.
This seems to happen at random, but it happens quite a lot - I only need to run the VI a few times in a row and it happens. If I set the array to have 20 or 30 elements it usually happens every time.
Stranger still, if I place a wait between opening the reference and passing the value none of the instances seem to get the value and if I place a wait before the Run method only a small number seem to get it.

In the demo I attached (backsaved to 6.1), the vit is reentant. I have noticed that when I set it to be non-reentant it seems to cause this problem less. Either way, I don't understand why it does it at all - the VIs are definitely being created and getting a unique reference each, so the Set method should work. As a side question, is there any meaning to a *.vit being reentrant?

So, finally, the question - is this a bug, or am I misunderstanding something about the way this is supposed to work?
And, if it is a bug, or if I can't use it, is there any other option for running concurrent versions of a VI, with each of them recieveing a seperate value?

Message Edited by tst on 05-18-2005 03:04 PM


___________________
Try to take over the world!
Message 1 of 7
(2,853 Views)
Update:

I just ran it in 7.1, where it seems to run to fine, so I'm guessing this is a 7.0 bug.
Can anyone confirm this (I couldn't find it in LAVA's buglist)?
Also, any suggestions for another solution to the original problem (other than using 7.1)?

___________________
Try to take over the world!
0 Kudos
Message 2 of 7
(2,842 Views)
Correction:
It only seems not to appear in 7.1 if the vit isn't reentrant. If it is the problem exists and it also exists if a delay is placed.
So the thoery of a 7.0 bug can be abandoned - either this is a consistent bug or I'm misunderstanding.

___________________
Try to take over the world!
0 Kudos
Message 3 of 7
(2,836 Views)
tst

Some background information first.

An instance of a reentrant VI has a separate dataspace every time it is called (but all instance share the same front panel).
An instance of a vit template is a complete copy of the template that does exist only in memory.

Typically reentrant VI are used when:
1) you want to call a piece of code in parallel
2) you want to do recursion using a call by reference

Vit template are typically used when you want to create reusable user interface

In regard to your example, I remove the reentrancy of the Vit (which does not really make sens in here).
The problem that your are having has actually nothing to do with instantiation of vit or the set control value method.
You basically have a race condition in your vit. You wait 800 ms in parallel you set the numeric value in your lv2 gbl.
You have no way of knowing which will happen first. So in your launcher, when you exit the for loop, you get the array from your lv2 gbl, but you get it too soon. Some of the instances of the Vit are still running and waiting (and they have not set the array value yet in the lv2 gbl). To check this, open the hierachy window and look at it while you are running your example.

Without changing your vit, you need to add a delay of 800ms after the end of the for loop to make sure that ALL the instances of the template have all written to the lv2 glbl BEFORE you try to query the lv2 gbl.

See the modified attached example.

I hope it help

PJM

Note: check out this very good presentation by Michael Availiotis on LAVA about asynchronous process (http://lavausergroup.org/niweek2004/meeting/lava_niweek_2004.zip). He is using named queue to pass data to the asynchronous process


  


vipm.io | jki.net

Message 4 of 7
(2,825 Views)
Ah.
A race condition.
That's a classic.
I do actually have an excuse for why I didn't see that one. Like I said, this was a test I did to learn how this work, and since my plan called for a wait, I put it in. What I failed to realize is that my simulation was flawed, because I only ran it once. I don't believe this will actually matter in the real system, because there I probably won't mind reading data which is one or two iterations old.

1. Thanks for the line about reentrancy in a vit. That's what I thought (although I'm still wondering as to why this seemed to happen more when the vit was reenrant, but that doesn't really matter).

2. I see that removing the Close VI Ref has taken care of my first problem (execution time). I take it that Auto Dispose Ref takes care of that for me?
I still wonder why this made such a big difference. I see that for some reason using the Close VI was also the cause for many of the instances not succeeding when I put a delay after the Open. I don't understand that either.

3. Thanks for the presentation. I think I actually looked at it in the past, but I'll be sure to check it again now.

___________________
Try to take over the world!
0 Kudos
Message 5 of 7
(2,821 Views)
OK, I solved my problem, but there is still something I don't understand.
Placing a 50 ms wait after opening the ref and before setting the value causes almost all the elements not to be replaced. This only happens if the close VI is used.
The way I understood it from the presentation, and from looking at the hirerchy window, it seems that using Close VI Ref actually shuts down the VI, even if it hasn't finished executing.
This is not the way I would think this would work, although it does explain why this happens only when using the close VI, but I still don't see why placing a wait before running the VI matters. I guess the real question here is what is the meaning and significance of using the close VI and why does it cause that effect?

___________________
Try to take over the world!
0 Kudos
Message 6 of 7
(2,793 Views)
tst,

some time ago there was a thread named "Is this roughly how LabVIEW works" (in this sense don't know if this are the exact words). In this thread which was mainly answered by Greg McKaskle I remember the following:

A VI is hold in memory as long as a reference to the VI is open. I'm not sure if Greg stated, that a VI which is runing and all references are closed will be aborted. It seems it is so.

I often use dynamically loaded VIs and keep the reference to the VI open. When the app ends all references will be closed. This will not work if the VIs will be loaded and unloaded while the app is running. In this case I do it this way:

Open the reference to the VI, set the control values, run VI and wait and then close the reference. In the loaded VI make sure that Open VI Reference with the path to the current VI will be called as the first action. This creates a reference to the VI (in this case to itself). Make a Close Reference when the VI ends. This should keep the VI in memory. I have tested this with either LV 5.1 or 6.0.2 which haven't the "Auto dispose Ref". Maybe setting "Auto dispose Ref" and not closing the reference in the loading VI will do the same without leaving unclosed references in memory.
Waldemar

Using 7.1.1, 8.5.1, 8.6.1, 2009 on XP and RT
Don't forget to give Kudos to good answers and/or questions
Message 7 of 7
(2,776 Views)