Jump to content


Photo
- - - - -

Suggestions for OpenG LVOOP Data Tools

closed review openg lvdata lvoop

  • This topic is locked This topic is locked
44 replies to this topic

#1 drjdpowell

drjdpowell

    The 500 club

  • Premium Member
  • 765 posts
  • Location:Oxford, UK
  • Version:LabVIEW 2011
  • Since:1999

Posted 17 January 2012 - 12:10 PM

*
POPULAR

This OpenG Review is closed. See Summary Post here. Please start a new thread to discuss new changes to this VI.
Read this post for start of review.

I’d like to suggest these three VIs (or similar) as possible LVOOP-object additions to the OpenG Toolkit:

OpenG suggestions.png

“Get Class Name” is a modification of “Get Name of Class of Object” posted by AQ. Here it just returns the basic class name (which I use often in custom probes and the like).

"Get Default Object” is inspired by this discussion and uses AQ’s zero-iteration loop method. This is a very simple VI, but using it instead of the raw code is much clearer to the reader.

“Same or child class” just uses “Preserve Runtime Class” as a tester. Again, the advantage here is code readability (or it will be, as soon as someone comes up with a good icon for it).

Thoughts?
— James

Attached Files


  • Antoine Châlons, jgcode and François Normandin like this

#2 mike5

mike5

    Very Active

  • Members
  • PipPipPip
  • 161 posts
  • Location:Slovenia
  • Version:LabVIEW 2010
  • Since:2009

Posted 17 January 2012 - 01:54 PM

How does "Get class name" work through inheritance? Does it return the correct class name at each level? Even whan called from dynakic dispatch method? (I don't have the time to test it right now...)

Br, Mike

Edited by mike5, 17 January 2012 - 01:54 PM.

Close the world, txEn eht nepO.

#3 jgcode

jgcode

    LabVIEW Renegade

  • OpenG
  • PipPipPipPipPipPip
  • 2,407 posts
  • Location:Australia
  • Version:LabVIEW 2009
  • Since:2005

Posted 17 January 2012 - 02:56 PM

I’d like to suggest these three VIs (or similar) as possible LVOOP-object additions to the OpenG Toolkit:

OpenG suggestions.png

“Get Class Name” is a modification of “Get Name of Class of Object” posted by AQ. Here it just returns the basic class name (which I use often in custom probes and the like).

"Get Default Object” is inspired by this discussion and uses AQ’s zero-iteration loop method. This is a very simple VI, but using it instead of the raw code is much clearer to the reader.

“Same or child class” just uses “Preserve Runtime Class” as a tester. Again, the advantage here is code readability (or it will be, as soon as someone comes up with a good icon for it).

Thoughts?


I like the suggestions to add functions like these to OpenG.

Get Class Name would make a splendid function IHMO.
OpenG does contain 'simple' functions where people sometimes argue that it is easier to just code the nodes each time.
I am feeling the same with the proposed Get Default Object function as any time you are not using the LabVIEW Object you would have to drop the VI and cast back to the Object (to e.g. use method VIs).
Therefore I believe it may be easier just to drop the For Loop and N=0 each time?
Maybe we could do this with a Merge VI instead?

Unsure if I feel the same as above about Same or Child Class.
Also thinking whether mje's Same Class test would be useful too?

How does "Get class name" work through inheritance? Does it return the correct class name at each level? Even whan called from dynakic dispatch method? (I don't have the time to test it right now...)


Yes, it flattens the Object which is on the wire - so the name of whatever you pass in will be returned.

#4 drjdpowell

drjdpowell

    The 500 club

  • Premium Member
  • 765 posts
  • Location:Oxford, UK
  • Version:LabVIEW 2011
  • Since:1999

Posted 17 January 2012 - 03:00 PM

Mike,

It returns the name of the class of the child object on the wire (in contrast to the “GetLVClassInfo.vi” that comes in vi.lib\Utility\VariantDataType, which returns the name of the class of the wire datatype, rather than the actual object on the wire).

Edited by drjdpowell, 17 January 2012 - 03:01 PM.


#5 drjdpowell

drjdpowell

    The 500 club

  • Premium Member
  • 765 posts
  • Location:Oxford, UK
  • Version:LabVIEW 2011
  • Since:1999

Posted 17 January 2012 - 03:16 PM

OpenG does contain 'simple' functions where people sometimes argue that it is easier to just code the nodes each time.
I am feeling the same with the proposed Get Default Object function as any time you are not using the LabVIEW Object you would have to drop the VI and cast back to the Object (to e.g. use method VIs).

No, it preserves the wire type, so no need to "cast back”:

Different objects.png

Unsure if I feel the same as above about Same or Child Class.
Also thinking whether mje's Same Class test would be useful too?

There are stronger arguments against “Same Class” than “Same or Child”. Also, with the above suggested OpenG VIs, one can build “Same Class” functionality in a clearer way (Is the default type of each object the same? —> Same class, for example).

— James

BTW, what do people think about error terminals on any of these VIs? I’ve left them off.
  • jgcode likes this

#6 jgcode

jgcode

    LabVIEW Renegade

  • OpenG
  • PipPipPipPipPipPip
  • 2,407 posts
  • Location:Australia
  • Version:LabVIEW 2009
  • Since:2005

Posted 17 January 2012 - 03:41 PM

No, it preserves the wire type, so no need to "cast back”:


Ha! I didn't know LabVIEW had that functionality (and it is all the way back to 8.2). :)
Just need to have a thralled(?) connection between the input and output for it to work.

Man, I wished this worked for an array of LabVIEW objects....

Anyways, I just commented on the image and just downloaded the VIs then - this function would be better than a Merge VI.

#7 drjdpowell

drjdpowell

    The 500 club

  • Premium Member
  • 765 posts
  • Location:Oxford, UK
  • Version:LabVIEW 2011
  • Since:1999

Posted 17 January 2012 - 03:45 PM

Another possibility; seeing if the object is the default value for it’s class:

Is Default.png

Maybe that’s too trivial. But the issue is code clarity; whether the icon is an advantage.

#8 drjdpowell

drjdpowell

    The 500 club

  • Premium Member
  • 765 posts
  • Location:Oxford, UK
  • Version:LabVIEW 2011
  • Since:1999

Posted 20 January 2012 - 02:32 PM

*
POPULAR

Here are the VIs after some work on icons and adding an additional function to return the fully-qualified class name. I’ve made the smaller VIs “inline”. I also changed “Get Default Object” to being based on “Preserve Runtime Class” as I found that the zero-iteration method sometimes didn’t work when in an inline VI (some detail of the complier that I don’t understand).

Get Default.png Is Default.png
Class Name.png Fully Quallified Name.png
Same or Descendant Class.png

PS to jgcode> what is the next step in possibly getting these into OpenG?

Attached Files


  • jgcode and JackDunaway like this

#9 jgcode

jgcode

    LabVIEW Renegade

  • OpenG
  • PipPipPipPipPipPip
  • 2,407 posts
  • Location:Australia
  • Version:LabVIEW 2009
  • Since:2005

Posted 24 January 2012 - 01:57 PM

Ok, this is now an official OpenG Review. :cool:
And therefore, I have moved this thread to OpenG Developers.

I have resaved the VIs in 2009 as the OP couldn't.
Please add comments regarding any of the VIs to this thread.
Upload any mods, tweaks, etc...

Attached File  OpenG LVOOP Suggestions Folder 2009.zip   33.65KB   116 downloads
[Code in LabVIEW 2009] Additionally please comment on where these VIs would go in the OpenG Library:LabVIEW has a Cluster, Class & Variant palette therefore, the LabVIEW Data Library package could be used to house these VIs - as it is where OpenG Variant VIs are (as well as an old GOOP VI).

LVOOP.png


Or we could create a new LVOOP Package - although I've always had in the back of my mind, that an OpenG Class package would look similar to this :)

#10 Ton Plomp

Ton Plomp

    How many lines per hour? Zero!

  • Premium Member
  • 2,005 posts
  • Location:New Zealand
  • Version:LabVIEW 2012
  • Since:2000

Posted 25 January 2012 - 08:50 AM

These tools look good (the location in the Data palette is good.)
One small glitch: One of the functions has a 'LabVIEW Object' input while the others have 'Object'

Ton

#11 drjdpowell

drjdpowell

    The 500 club

  • Premium Member
  • 765 posts
  • Location:Oxford, UK
  • Version:LabVIEW 2011
  • Since:1999

Posted 25 January 2012 - 10:25 AM

Thanks Ton, we should change everything to “Object”.

Regarding “Same or descendant class”, I forgot to make the inputs “required”, and the capitalization of the VI name is inconsistent with the other VIs; should be “Same or Descendant Class”.

Putting these VIs in LabVIEW Data would be fine, though that library is quite large already. It might be better to have a new “LVOOP” library, especially if there is a chance of adding more tools in future, such as the Class manipulation tools jgcode linked to.

#12 jgcode

jgcode

    LabVIEW Renegade

  • OpenG
  • PipPipPipPipPipPip
  • 2,407 posts
  • Location:Australia
  • Version:LabVIEW 2009
  • Since:2005

Posted 25 January 2012 - 10:49 AM

Putting these VIs in LabVIEW Data would be fine, though that library is quite large already. It might be better to have a new “LVOOP” library, especially if there is a chance of adding more tools in future, such as the Class manipulation tools jgcode linked to.


I (personally) think the Class Library Refnum API should be separate - to the VIs you have provided that work on Object Data.
However, yes the OpenG LabVIEW Data Library is quite full...

#13 drjdpowell

drjdpowell

    The 500 club

  • Premium Member
  • 765 posts
  • Location:Oxford, UK
  • Version:LabVIEW 2011
  • Since:1999

Posted 25 January 2012 - 11:04 AM

I (personally) think the Class Library Refnum API should be separate - to the VIs you have provided that work on Object Data.

I was imagining separate sub-palettes of a overall “LVOOP” palette, but perhaps they should be completely separate.

Actually, a few days ago I was looking at the Class Library Refnum API to see if it could help me with another idea I have for a useful Object VI. One could do some interesting stuff, but unfortunately Class Refnums don't work on RunTime so one can’t put anything built on it in an exe.

— James

#14 jgcode

jgcode

    LabVIEW Renegade

  • OpenG
  • PipPipPipPipPipPip
  • 2,407 posts
  • Location:Australia
  • Version:LabVIEW 2009
  • Since:2005

Posted 25 January 2012 - 11:15 AM

but unfortunately Class Refnums don't work on RunTime so one can’t put anything built on it in an exe.


(I wouldn't recommend doing it of course) but that's not 100% true - I have gotten some stuff to work.

#15 Aristos Queue

Aristos Queue

    LV R&D: I write C++/# so you don't have to.

  • Members
  • PipPipPipPipPipPip
  • 2,786 posts
  • Location:Austin, TX
  • Version:LabVIEW 2011
  • Since:2000

Posted 25 January 2012 - 05:24 PM

I would oppose the general disemination of the "Get Name of Class.vi" without a lot of caveats. Specifically, I'd be tempted to name the VI "Get Name of Class in a highly inefficient but generic manner good for probes but inappropriate if you are really writing a by-name-lookup object hierarchy.vi" ;-)

Here's the deal: This VI flattens your entire object data to a string. That's not cheap and it gets even more expensive as the object carries more data.

If I am really writing a hierarchy where I expect to do name lookups -- like for database storage type systems -- as part of my actual runtime code, I'm going to add a dynamic dispatch method to the root class called "Get Class Name.vi" and override that at every level of the hierarchy to return a string constant. This avoids the memory allocation and performance hit of the flattening to the string (indeed, if all goes as planned, in 2013's compiler, it will avoid any memory alloc entirely as long as the returned strings really are constants). This solution is what is used in C++.

Using any sort of reflection API to get this information in C# is less efficient than adding the "get class name" method. As far as I know, nothing beats adding this to your class definition. We don't do it for all classes generally because it extends the dispatch table with a feature that most classes do not need.

The class-to-path function that is in the palettes today is mostly to support scripting and debugging type work.

Can you find a way to address these concerns in the VI's icon, name and documentation?

Actually, a few days ago I was looking at the Class Library Refnum API to see if it could help me with another idea I have for a useful Object VI. One could do some interesting stuff, but unfortunately Class Refnums don't work on RunTime so one can’t put anything built on it in an exe.

You must be using an old version of LabVIEW. They started working in RunTime in LV 2010. I would NOT recommend using them -- they are VERY slow, because they aren't meant to be used in production code (they instantiate entire projects behind the scenes because they assume you're getting one of these references in order to do manipulation of VIs into or out of libraries or to query about project layout stuff). They should be used for scripting and tools work, not for the actual work of your application. The only reason that they're in the runtime engine is someone wanted to be able to do reflection of projects from TestStand without needing the full development environment.

A couple of renaming suggestions:

"Is Default.vi" ---> "Is Default Value.vi" (just seems clearer to me and leaves namespace open for other "Is Default..." type VIs in the future)

"Same or descendant class.vi" ---> "Is Same or Descendant Class.vi" (use of Is to be consistent with other VIs that primarily return a Boolean; also fixing capitalization to match others)

"Fully Qualified Class Name.vi" ---> "Qualified Class Name.vi" (the Fully is redundant and the shorter name gets more useful info into the palette display)

"Class Name.vi" ---> "Class File Name Without Extension.vi" (the class name is defined throughout LV as either the file name or the qualified name. This makes it clear what is being returned. Again, I wouldn't ship this VI myself, but if you do include it...)

> Putting these VIs in LabVIEW Data would be fine, though that library is quite large already

Can you add them to a subpalette of the "Cluster, Class & Variant" palette? I don't know what ability you have to add to the built-in palettes of LV, but that would seem to me to be the right place for them.
  • drjdpowell likes this

#16 drjdpowell

drjdpowell

    The 500 club

  • Premium Member
  • 765 posts
  • Location:Oxford, UK
  • Version:LabVIEW 2011
  • Since:1999

Posted 25 January 2012 - 11:22 PM


Here's the deal: This VI flattens your entire object data to a string. That's not cheap and it gets even more expensive as the object carries more data.

If only we had some VI that returns the default value of object class so we don’t need to flatten the data. Someone should make one of those.

I would oppose the general disemination of the "Get Name of Class.vi" without a lot of caveats. Specifically, I'd be tempted to name the VI "Get Name of Class in a highly inefficient but generic manner good for probes but inappropriate if you are really writing a by-name-lookup object hierarchy.vi" ;-)

Wouldn’t by-name-lookup code use the Qualified Name, for uniqueness? Getting just the name is really for human readability, i.e. probes and the like. Also, anyone with more than a tiny bit of LabVIEW ability will take less than five minutes to identify “Get LV Class Path” as a way to get the name of a class. Now THAT is a inefficient method!

I did a quick speed test of getting a name string for objects with internal data of 10kB (and 1000kB), with time in microseconds:
Class Name: 7 (160)
Fully Qualified Class Name: 9 (170)
Get LV Class Path: 129 (630)

“Get LV Class Path” is on the standard palettes, so if people are doing by-name-lookups I suspect some of them are taking the shortcut of not having a “Get Class Name” override at every level.

And, hey, some of us just want to write some probes!

If I am really writing a hierarchy where I expect to do name lookups -- like for database storage type systems -- as part of my actual runtime code, I'm going to add a dynamic dispatch method to the root class called "Get Class Name.vi" and override that at every level of the hierarchy to return a string constant. This avoids the memory allocation and performance hit of the flattening to the string (indeed, if all goes as planned, in 2013's compiler, it will avoid any memory alloc entirely as long as the returned strings really are constants). This solution is what is used in C++.

Using any sort of reflection API to get this information in C# is less efficient than adding the "get class name" method. As far as I know, nothing beats adding this to your class definition. We don't do it for all classes generally because it extends the dispatch table with a feature that most classes do not need.

Sounds great, but do you really want to add a method to every single command message class you write in the Actor Framework just to support the ability for someone to write a custom message probe?

— James

PS> Like all your VI renaming suggestions.

#17 PaulL

PaulL

    The 500 club

  • Members
  • PipPipPipPipPip
  • 530 posts
  • Location:Tucson AZ
  • Version:LabVIEW 2013
  • Since:1997

Posted 25 January 2012 - 11:46 PM

If only we had some VI that returns the default value of object class so we don’t need to flatten the data. Someone should make one of those.

Yes, we need this in order to make a generic XML parser. Currently (as of LabVIEW 2010) this is only accessible to the NI folks, as I understand it.

#18 Aristos Queue

Aristos Queue

    LV R&D: I write C++/# so you don't have to.

  • Members
  • PipPipPipPipPipPip
  • 2,786 posts
  • Location:Austin, TX
  • Version:LabVIEW 2011
  • Since:2000

Posted 26 January 2012 - 12:25 AM

Wouldn’t by-name-lookup code use the Qualified Name, for uniqueness? Getting just the name is really for human readability, i.e. probes and the like. Also, anyone with more than a tiny bit of LabVIEW ability will take less than five minutes to identify “Get LV Class Path” as a way to get the name of a class. Now THAT is a inefficient method!

Misunderstanding between you and I: when I say "name of class", I *always* mean the qualified name unless I specify otherwise.

In any case, the VI that I wrote for jgcode gets the qualified name. And it is an inefficient way to do so that I would not recommend using for most lookup type applications. It works fine for probes/scripting/reflection type utilities, but not production code, which is what anything in the palettes should be intended for.

And, hey, some of us just want to write some probes!

That's why I asked if there were any suggestions for addressing my concerns in the name and iconography, to make sure that this is used only for the probes use case.

Sounds great, but do you really want to add a method to every single command message class you write in the Actor Framework just to support the ability for someone to write a custom message probe?

No. That's my point. This is a fine mechanism *for* *probes*. But it doesn't really belong in the palettes where it might be mistaken for other purposes if you give it the nice friendly name that it has at the moment.


If only we had some VI that returns the default value of object class so we don’t need to flatten the data. Someone should make one of those.

Yes, we need this in order to make a generic XML parser. Currently (as of LabVIEW 2010) this is only accessible to the NI folks, as I understand it.

Isn't the VI up above one that, given an object, returns the default value of that object? And Get LV Class Default Value.vi returns the default value if all you know is the class. What are you looking for?

#19 drjdpowell

drjdpowell

    The 500 club

  • Premium Member
  • 765 posts
  • Location:Oxford, UK
  • Version:LabVIEW 2011
  • Since:1999

Posted 26 January 2012 - 03:40 PM

Isn't the VI up above one that, given an object, returns the default value of that object? And Get LV Class Default Value.vi returns the default value if all you know is the class. What are you looking for?

I was joking (should have used a smilie). Of course I’m already using “Get Default Object.vi” inside “Class Name.vi” so that I’m not flattening the data of the input object (which was your initial criticism).

Actually, this is why I was confused be my later time tests where “Class Name” is slower for large objects. Must be a copy going on somewhere. So I experimented and found that I could make it faster by passing the input object through to an output terminal:

With Object out.png

I modified “Qualified Class Name” in the same way. Now they give execution tines of around 4-5 microseconds, independent of object data size (up to 1 Meg, at least).

In any case, the VI that I wrote for jgcode gets the qualified name. And it is an inefficient way to do so that I would not recommend using for most lookup type applications. It works fine for probes/scripting/reflection type utilities, but not production code, which is what anything in the palettes should be intended for.

That's why I asked if there were any suggestions for addressing my concerns in the name and iconography, to make sure that this is used only for the probes use case. … This is a fine mechanism *for* *probes*. But it doesn't really belong in the palettes where it might be mistaken for other purposes if you give it the nice friendly name that it has at the moment.

Should the standard for the OpenG palette the same as for the LabVIEW palette? The current OpenG Data palette is full of VIs for doing non-standard things with variants by using the inefficient method of parsing flattened data. These new object VIs don’t look out of place. What if we call the VI “Class Display Name” to try and make the point that this is really a name for human readability rather than look-up?

#20 Aristos Queue

Aristos Queue

    LV R&D: I write C++/# so you don't have to.

  • Members
  • PipPipPipPipPipPip
  • 2,786 posts
  • Location:Austin, TX
  • Version:LabVIEW 2011
  • Since:2000

Posted 26 January 2012 - 04:54 PM

That performance optimization makes sense to me given what I know of the compiler. It's a bit weird, but I know why it is being done. I'll talk to the compiler guys and see if they can clean things up without the need for that oputput (LV2013 or later, so keep your optimization for now).

Should the standard for the OpenG palette the same as for the LabVIEW palette?

To me, they're all the same palettes unless there's a palette with an explicitly different palette with a "for debugging" name.

The current OpenG Data palette is full of VIs for doing non-standard things with variants by using the inefficient method of parsing flattened data. These new object VIs don’t look out of place. What if we call the VI “Class Display Name” to try and make the point that this is really a name for human readability rather than look-up?

That helps. I'd also like the CH to point people toward more info on the topic, perhaps somewhere in the LAVA Wiki.

[Later] Perhaps make it "Class Display File Name" or "Class Display Qualified Name".

[Later again] There actually is a Display Name property on the class itself (see the properties page for classes). This isn't that display name, so there could be a problem calling it "display". I keep coming back to "debug file name" and "debug qualified name", but maybe you've got something better?

Edited by Aristos Queue, 26 January 2012 - 04:56 PM.






Also tagged with one or more of these keywords: closed review, openg, lvdata, lvoop