LabVIEW Idea Exchange

cancel
Showing results for 
Search instead for 
Did you mean: 
SteveChandler

Hard Inline VI

Status: New

 

When you inline a subVI it is not the same thing as placing the contents of the VI on the callers block diagram. Almost but not quite.

 

The difference is that all outputs of a VI (inlined or not) become available at the same time when the VI completes execution.

 

 

inlined VI Settings.PNG

 

Set the VI above to inlined and use it in another VI

 

using inlined VI.png

 

The idea is an additional inline setting as follows.

 

inlined VI Settings.PNG

 

Now the VI will truely be inlined as if it were not a sub VI at all.

 

hard inlined VI.png

 

The name "hard inline" is just a suggestion and could be called something else.

 

 

=====================
LabVIEW 2012


35 Comments
DFGray
NI Employee (retired)

After some thought, and reading through the previous comments, I find myself agreeing with the original idea.  Yes, it will change the fundamental way the program executes.  But I can think of valid use cases for this type of behavior.  For example, I have a library of code fragments which are synchronized quite well by normal data flow.  I want them to be optimized into the rest of my code, so I want no added synchronization barrier.  This is an advanced use case, and should not be the default.  But I don't see a valid argument for not including it as an option.  I do think the option should be called something a bit more descriptive, such as "remove data synchronization" or something similar.  Default should be safe - include the sync barrier.

 

Note that the Inline SubVI VI server method does include this option.  In defense of the other side, I have never used it without including the barrier.  However, I have never used it on a per VI basis either.  I have always used it in build processes as a batch operation.

altenbach
Knight of NI

There are not just the synchronization barriers of the inputs and output, there is also coercion to the datatype of all inputs. If we were to truly allow hard inlined code, the coercions should also be eliminated.

 

Imagine an inlined subVI that only contains a multiply primitive. If the VI were truly inlined, we should be able to wire a mix of scalars and arrays to the inputs and things would not break, but adapt correctly, because the inlined code would be able to correctly handle it. (we could even end up with a subVI as discussed here and in the directly following post). Basically a skeleton of operations, that, if manually inlined, would not break the code, should equally work.

 

I actually think that removing the coercion barrier is more useful than removing the sync barrier.

 

Maybe the snchronization could be configured in the call setup, which would default to the current behavior. If the synchronization is removed, the subVI should get a special glyph or halo to alert the programmer.

SteveChandler
Trusted Enthusiast

@Jeff, Removing the call overhead is probably the main reasoning behind inlining subVIs. But the term implies that the code is transparently sucked into the callers block diagram. If I select some section of code and do an edit/create subVI from selection then that actually changes my code by wrapping the selection in a sequence frame. It adheres to the dataflow paradigm because of the sequence structure but I am only asking for the option to not place the sequence structure.

@ Norbert, This would likely be considered an advanced feature. There are many advanced features available that I am quite comfortable with although they were very confusing to me when I was a new user. I am glad that just because as a new user I would not take advantage of them (or even misuse as as I was experimenting/learning) that they were there because I use some of them today. If the only things available in G were things that are "rock simple" that new users will take advantage of then I would have moved on long ago. After years I am still learning new things about G. New users will always misuse everything. It will not be the end of the world if G never supports this. I can not even think of a good reason that I would need it other than updating indicators on the caller without using a reference. I think there are performance issues involved using value property nodes. But even beyond this it does seem like a very interesting and potentially useful behavior. I am hoping that if the time comes that I really want this it is available.

=====================
LabVIEW 2012


AristosQueue (NI)
NI Employee (retired)

Altenbach: What you're talking about is generics/templates/dynamic polymorphism/some other name users sugest in this thread. We really don't want to inline in G code for all sorts of performance reasons. Generics is an approach that would let us generate, for any given set of type inputs, the specific code for that type, which could itself then be inlined. At the moment, we strongly believe that that's a better approach to solving the "same VI but with a different type" problem.

 

SteveChandler: I've flip-flopped on the idea of subVIs directly writing to caller VIs on several occassions. "Hard Inlining" could iimply one of two behaviors:

  1. "hard inlining" a subVI would actually put the subVI's controls on the caller VI's front panel so that the subVI has its own controls to update.
  2. "hard inlining" a subVI would cause any write to an FPTerminal on the subVI to write to the control of the same label name on the caller VI.

#2 has a lot of problems. My biggest concern is that FPTerminals have very different semantics from Local Variables, but you would essentially be substituting one for the other when compiling the subVI. That introduces state into a caller VI in a very subtle way, and not a good way. And you need rules about what if the caller VI doesn't have a control of that name -- do you ignore that FPTerminal or do you fall over to Option 1? Have to break the VI if the label names matched but the types did not.

 

#1 is better, possibly a nice way to do "static subpanel" type of operations, but it doesn't really achieve the magic of two separate subVIs updating the same caller panel.

 

My current position is "nice idea, but pipedream." I'm definitely open to further thoughts.

 

My favorite approach to "subVIs updating callers" is the reverse of inlining. Instead, put a static reference to a caller control on the subVI. Yes, that means that you couldn't reuse the subVI for any other VI, but if you want a subVI to be able to dynamically choose what control to write to, that's what control refnums are for. The interesting case -- to me -- is where I just want to create a subVI from some complex algorithm and I want it to still update the same panel without converting over to control refnums.

 

DFGray et al: From a UI standpoint, I think I could support "hard inlining", as described here, if it truly, visually, inlined the subVI onto the caller diagram. That way anyone reading the diagram would actually see the inner nodes as independent. Now, here's the rub... we would still need to keep the coercion dots. Inlining the actual G code is expensive. But changing the subVI node to be a really big single node with a graphic of the subVI's diagram is easy, as long as we didn't go actually propagating types across that subVI. Now, down the line, we could couple this with generics and get the full package, but I think inliniing itself would want to avoid actually copying in the G code.

 

I think.

AristosQueue (NI)
NI Employee (retired)

Something like this perhaps?

HardInline.png

SteenSchmidt
Trusted Enthusiast

> AQ: ...but I think inliniing itself would want to avoid actually copying in the G code.

 

But that is the actual premise for inlining? Else we're talking about macros, which exist somehwere between a reentrant code module and true inline expansion. The question is what NI is offering here, and if the feature is properly named?

 

Inline expansion (aka "Hard inlining" in this idea):

The code from the inlined subVI should actually be copied into each place that subVI is called, before compilation, optimization etc. The inlined subVIs FP controls and indicators are "virtual", in the sense that they are merely "sockets" for the wires that go into the inlined code, they will be eliminated by the compiler. They have no correlation with the caller's FP either, but if you wire a caller's control refnum into an inlined subVI, and in the inlined subVI access a control of the caller by reference, the compiler would be able to optimize this code by replacing the referenced property node with the static property node from the caller (since the inlined code ends up on the same BD as the caller's FP terminals). That's an optimization possibility, not reflecting what is possible today. Inline expansion like this doesn't involve any coercion, synchronization barriers and the like - the code is simply copied into place, and that's what the compiler sees.

 

I maintain my suspicion that there could be a huge performance difference between what is offered now as inlining, and what true inline expansion would offer. If the code is in fact copied into the caller's BD the instructions of the caller and that instance of the inlined subVI would reside very close together in memory at runtime (spatial locality of reference). The instruction pointer must on the other hand jump to a completely different place in memory when we encounter a reentrant VI (spatial non-locality of reference). The current inline offering probably resembles preallocated reentrant VIs the most, in that we incur such an instruction jump. I can't see how spatial locality of reference can be ensured if the inlined code isn't in fact inlined into the caller's BD?

 

But I agree that there is a big discrepancy between seeing a subVI on the BD, and this unsynchronized behavior. Therefore I suggest an Inline Code Node instead of the per VI setting of today:

 

InlineCodeNode.png or InlineCodeNode2.png or InlineCodeNode3.png or InlineCodeNode4.png

 

In my opinion VI Properties/Execution is the wrong place to decide if a VI should be inlined or not. It should be on an individual instance basis, hence the Inline Code Node. You should be able to either drop a subVI, or you can drop it into an Inline Code Node. You have no VI setting for recursion either (if that could ever make sense). The Inline Code Node doesn't have VI refnum inputs, as the definition must always be static (to allow for the compiler to inline the code at edit time). With an Inline Code Node you can inline existing code, instead of globally deciding if a VI should always inline or never inline.

 

When you debug with execution highlighting enabled, it should no longer be surprising if the Inline Code Node runs before any inputs are ready, nor should the asynchronous behaviour of IO surprise (since that's the defined behavior, and has to do with the Inline Code Node and not the subVI you've embedded in it). If you can step into such an Inline Code Node or not when debugging, would be up to the debugging capabilities of the version of LabVIEW you use. Maybe you can't do that now, but it might be possible in LV 2015 (just as it maybe would be possible to step into a Call by Reference Node at that time?).

 

Cheers,

Steen

CLA, CTA, CLED & LabVIEW Champion
JÞB
Knight of NI

Steve C, I'm still on the fence but, leaning.....If I understand correctly, (clairification would be nice for what I get wrong here) there are af few use cases.

 

1) selecting a group of functions and wires on the BD enables a "Create > Sub diagram"  Click new sub-diagram and select >"Remove sync barrier" (alternately Create> "new construct" would do this in one step) .  What this accomplishes is to essentially create a construct free to execute as if it were on the callers BD without any structure around it.  The construct would be a seperate file and have:  a "connector pane-like component", an Icon  and a Block Diagram but essentially no front panel.  By "connector pane-like component" I mean this is where the callers wires attach but are not "terminals" and would virtuallize the source/sink nodes they enter/leave Something like Steve M's illustration with the border shrunk right down to the functions nodes.

 

2) Selecting code containing a terminal and removing the sync barrier would require the "new constructs" terminals' controls/indicators to reside on a existing FP in memory (or show broken).  [note probably need a load caller FP method].  Changes to the callers FP object would break the new construct simillar to re-linking afer changing a connector pane.

 

3) drop a copy of the new construct would add appropriate controls/indicators on the callers FP or IF ALREADY found link to the existing  controls/indicators (possibly with a pop-up ?)  

 

Now the magic- since the new construct has no FP what limits the developer to linking new construct terminals to only the callers controls/indicators?  I see no reason not to allow link to > select any FP object in the application space!  KINDA BLOWS my mind!Smiley Surprised  

 

IMPLEMENTATION: would need some real work since the new constructs icon would need to be distinctive (halo effect) AND the "linked to" controlls and indicators would need some special treatment to set them off on the targeted BDs.

 

I can think of a use or two for this behavior- but, its a loaded gun in the hands of novices!  Smiley Wink

 

Did I sum this up correctly?


"Should be" isn't "Is" -Jay
SteenSchmidt
Trusted Enthusiast

Jeff: This stuff about linking an inlined VI's terminals to a caller's FP controls/indicators is just a corner case. I think it's too specialized, and too far away from the current LabVIEW paradigm. It either means you must have access to the entire application in which you'll use your inlined subVI when you develop that subVI (to be able to select among controls), or that you must setup alot of stuff for each inlined subVI when you drop it into place.

 

The Inline Code Node I mention in my latest post is much more subtle and simple to understand. With that you can use any existing subVI for inlining, and any optimizations regarding caller FP terminal access is done by the compiler transparently. You don't have to select any FP controls to link to, but you're of course free to wire a control reference to your inlined subVI, if such a control exist on its totally ordinary conpane, and let the compiler optimize on that. You can also use the same VI as an ordinary subVI and have the usual behavior.

 

/Steen

CLA, CTA, CLED & LabVIEW Champion
SteveChandler
Trusted Enthusiast

Jeff, leaning which way? You and others have pointed out a lot of issues that need to be taken into account.

 

The idea is really to just remove the sync barrier. An indicator on the inlined VI wired to a terminal would be just as if the code were not in a subVI at all.

 

Steen, I like the Inline Code Node. Feel free to use the basis of this idea to propose a new one. Also feel free to rewrite this idea.

 

Moderators, if Steen does rewrite this idea then mark this one as the duplicate even though it came first since it only has two votes at this time.

=====================
LabVIEW 2012


AristosQueue (NI)
NI Employee (retired)

> The code from the inlined subVI should actually be copied into

> each place that subVI is called, before compilation, optimization etc.

 

I would not define "Inlining" as the same as macros/templates. To me, if you allow type prop to re-run so that polymorphic VIs actually change which function they call, you're no longer inlining, you're running a code generation macro. Inlining takes the exact code of the function and inlines it, which is what happens with the feature today.

 

> I maintain my suspicion that there could be a huge performance

> difference between what is offered now as inlining, and what true

> inline expansion would offer

 

No need for suspicions. It *will* be a huge performance gain for some functions. But it isn't necessarily inlining. It's macro/template processing.