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
AristosQueue (NI)
NI Employee (retired)

Grr... I hit submit on that last post before I finished typing... I'll have more to add later.

AristosQueue (NI)
NI Employee (retired)

> The current inline offering probably resembles preallocated reentrant VIs the most, in that we incur such an instruction jump.

 

No, it doesn't. As I explained before, the current inlining is copying the almost-assembly code into the caller. It is not copying G code into the caller. So, to provide a trivial example, if the G code called a polyVI, the inlined code would be just a call to the specific instance VI, without any reference to the polyVI. There's a lot more to it than that. But it is actually inlined into the caller, but not at the G code layer.

SteveChandler
Trusted Enthusiast

> No, it doesn't. As I explained before, the current inlining is copying the almost-assembly code into the caller. It is not copying G code into the caller.

 

Ah hah! That clears up a lot in my mind. I guess that the way I was thinking of "Hard Inlining", my idea would pretty much be a duplicate of this.

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


SteenSchmidt
Trusted Enthusiast

Ok, then I misunderstood you Stephen - sorry about that. In that case the synchronization structure really isn't that big of a deal. It'll always be possible to segregate completely independent execution paths into two or more subVIs to inline independently. Of course, you could inherit a VI that you can't (or won't) edit...

 

Then remains only my suggestion of an Inline Code Node instead of the VI setting of inlining it or not. With such a node it wouldn't be critical to lose the synchro barrier, but the question is if that barrier shouldn't remain in place - no need to promote weird dataflow behavior if it can be avoided. But the node has its advantages I'd say...

CLA, CTA, CLED & LabVIEW Champion
SynchronizationOverhead
NI Employee (retired)

My apologies for being a little slow in finding this topic (thanks, AQ!) and responding to it. Below are my many thoughts on the various proposals mentioned in this thread.

 

Synchronization-free Inlining
One of the goals of the (2010) Inlining feature was to easily be able to inline compatible subVIs such that the inlining causes no change in behavior other than improved runtime performance. Thus, inlining a subVI with independent parallel sections of code should behave the same as if it was executed as a normal subVI, including the synchronization barrier. This is why we chose to keep the synchronization by default.

 

Synchronization-free Inlining has been requested by other internal groups (eg. Simulation). I'm fine with that, so long as its not the default and the user has to specify it. Also, since this would probably be specified on the callee, I (like Altenbach) would expect some kind of different visualization in the caller to show that the subVI-looking thing doesn't act quite like a subVI. I wouldn't mind seeing a visualization for normal Inline subVIs too while we're at it.

 

Sync-free Inlining would certainly enable additional optimizations on the inlined code with respect to its surrounding code. As it is, we already do some interprocedural-style optimizations on VIs including their inlined code, but the sequence frame we wrap around the inlined code restricts some further optimizations, especially those involving nodes with side-effects. The synchronization barrier (i.e. sequence frame) we wrap around the inlined VI doesn't actually need to block execution of purely functional nodes (no side effects). It only needs to enforce execution order of nodes with side-effects.

 

Implementation of this feature should actually be pretty simple (don't wrap the inlined code in a sequence frame). The UI changes (fitting the checkbox into the dialog, considering localization, visualization, etc.) are probably more complicated than implementing the compiler changes.

 

@DFGray: I would also prefer a more descriptive title for the option, like "remove data synchronization" or "remove synchronization barriers".

 

Type Coercion
@Altenbach: I agree that the type coercion at the inlined subVI's boundaries is an additional bit of overhead when the datatypes don't match. As AQ mentions, this need could be fulfilled by the generics feature (in combination with inlining), which still needs some elaboration before it can be released. Removing the datatype coercion on inlined subVIs using the official inlining feature alone would be rather difficult using the current implementation, since we do our inlining on the DataFlow Intermediate Representation (DFIR) not the actual source objects, and the type-propagation algorithm runs on the source objects, and does not currently work on DFIR graphs. If, however, you used the "Inline SubVI VI server method" that DFGray links to, it will actually copy the the subVI's source objects into the caller's diagram and re-typeprop the graph before compiling. Using this method, you can let LabVIEW's typeprop algorithm remove the unnecessary datatype coercions. Hopefully we can have a more supported official means of providing this behavior in a future release.

 

FPItem Updates
@SteveChandler: "What do you think about the possibility of updating indicators on the caller with a wire rather than a reference?" Currently, Inline SubVIs don't allow property/invoke nodes (whose updates can be rather slow), so updating the caller's indicator with a reference in the inline subVI is not currently possible. On the other hand, since inlining essentially removes the inlined controls/indicators and wires them directly to the connected terminals on the caller, just wiring your value out of the inline subVI into the caller's indicator/local will give you an immediate update like you want (although not within inlined loops, etc.).

 

@Steen: The inline subVI's FP controls/indicators do behave like the "sockets" you describe, as they are eliminated and directly wired up to the connecting terminals on the caller's diagram. I also like your idea for optimizing references to a caller's FPItems into static property nodes (or even locals), but due to the state of the code right now, there's still a decent amount of cleanup necessary before we could enable that. Right now we disallow any/all Property and Invoke nodes for a few different reasons.

 

If you want inlined code fragments (which could be broken code on their own), you should check out the VI Macro ideas.
 http://forums.ni.com/t5/LabVIEW-Idea-Exchange/Macro-in-LabVIEW/idi-p/1095676
 http://forums.ni.com/t5/LabVIEW-Idea-Exchange/Macro-VIs-and-Code-Fragments/idi-p/1436538

 

Spatial Locality
@Steen: The current inlining implementation is very similar to what you describe for Inline expansion, in that we do in fact copy the subVI's IR into the caller's IR at the very beginning of compilation, before any other optimizations are applied. We generate all the code as one contiguous code block, as if the code was all together in the same VI, thus achieving the spacial locality of reference that you desire. We do not need to jump to a completely different place in memory, unless the synchronization barrier or parallelism in the inlined code causes the operations to be split into separate clumps (exactly as hand-inlined code would behave if copied into the caller and wrapped in a sequence frame). The no-synchronization and no-coercion options could be additional options on top of the default behavior, but the default behavior maintains the generally expected subVI behavior. On the other hand, removing the sync barrier could allow independent sections of an inlined subVI to split up and join separate clumps in the caller, actually separating the instructions in memory.

 

Per-Callsite Configuration
@Altenbach: Re: Configuring sync in Call Setup, there have been discussions about specifying inlining itself on a per-callsite basis, eg. in the call setup menu. If so, configuring sync-free in the same dialog makes sense. However, I think users might get lost or confused if they have to go to two differently scoped dialogs to configure inlining and sync-free inlining separately.

 

@Steen: I am also in favor of your Inline Code Node, or any form of per-callsite inlining configuration. During the initial brainstorming/design, we realized that we could have the configuration in the caller (per-callsite) or the callee (per subVI). We elected to set it in the callee (similar to the C inline keyword) since the developer of the inline VI would be best suited to know if the subVI is safe to inline and small enough to be generally beneficial to inline. Plus it would mean fewer places to have to set the option. On the other hand, callers may know better that a particular callsite has constant inputs or unwired outputs or executes inside a loop, any of which could enable additional optimizations when the subVI is inlined into that particular callsite. I think either place has its valid use cases. Feel free to suggest it as a new Idea Exchange idea. I'll vote for it.

SteveChandler
Trusted Enthusiast

@SynchronizationOverhead: "On the other hand, since inlining essentially removes the inlined controls/indicators and wires them directly to the connected terminals on the caller, just wiring your value out of the inline subVI into the caller's indicator/local will give you an immediate update like you want (although not within inlined loops, etc.)."

 

That makes a lot of sense for probably a couple of reasons. The obvious reason is that aside from references nothing in the loop is available outside the loop until the loop completes. I suppose that subconsciously I was thinking that if the loop were in a hard inlined VI then I could wire a terminal inside the loop to the connector pane and cheat my way inside from the caller. That would be against the rules but it seems like an interesting exception for sharing data between loops. Black holes are interesting too but you likely wouldn't want to be near one.

 

I, like Altenbach and yourself, would definately want this to be the non-default option. Adding a visual indication that the VI is set to "No Sync" is a very good idea.

 

That was one of the best posts that I have seen anywhere. A much deserved virtual kudos since I can not give idea exchange replies a real one.

 

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


SteenSchmidt
Trusted Enthusiast

I've posted a suggestion for an Inline Code Node here:

 

http://forums.ni.com/t5/LabVIEW-Idea-Exchange/New-Inline-Code-Node/idi-p/1645822

 

I see the current location for defining inline capability fits somewhat with C, but then again the LV feature itself differs somewhat from C. In C the inline keyword is a suggestion for the compiler, not a guarentee that inlining will occur. You can also use the inline keyword in C at the declaration site, but there are several opaque implementation specific features - when using the extern keyword in the declaration for instance. You can have two declarations of the same function in C, one function ending up being inlined and the other ending up being a function call. That can have some weird consequences if you compare function call addresses to see if you are calling the same function or not (you might be even if the addresses differ). This opacity I'd like to go away from C, but that will not happen. LabVIEW seems to fix this Smiley Happy.

 

Cheers,

Steen

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

OK, I'm leaning WAY OVER the fence!!! BUT, I am thinking along the lines of the FPless Sub diagram "new construct".  The analogy of the BDless things (global.vi and .ctl) and FPless things (*.visd?) can be derived from the existing "Laws of LabVIEW" and IMHO would promote adoption of a "new construct." 

 

@ Steve Chandler-  Please rebrand the idea!

 

@S.O. thank you! but you have some homework to do- Post a new KB derived for that essay PLEASE


"Should be" isn't "Is" -Jay
InfiniteNothing
Active Participant

Don't we already violate the "all terminals of a subVI" and the "all nodes of a structure" paradigm for single cycle loops on FPGA? I think having this behavior explicitly defined and consistent would make FPGA coding a bit more clear and share some of the FPGA magic with the other G code.

CLED (2016)
AristosQueue (NI)
NI Employee (retired)

InfiniteNothing: To the best of my knowledge, no. Is there some place that NI documented that we broke either of those paradigms for the single-cycle timed loop that you could link me to? I checked with the FPGA team to be sure. They said that you may have uninitialized values for some inputs on the early iterations, but that's not the same as the inputs being not yet computed -- valid values just haven't propagated through the pipeline yet. That may be what you're thinking of when you suggest that the "all terminals of a subVI" paradigm is violated. None of us could come up with anything that even resembles violating the "all nodes of a structure" paradigm being violated.