Jump to content

DereferenceByName Xnode ( -> operator in C)


Recommended Posts

Property nodes already do this? Granted it requires implementing the property, but I'm generally not a fan of pulling data from class wires via the cluster primitives as it makes it hard to track where data is consumed. 

Link to post
Share on other sites

The above bit is what gets tedious to setup for all of those property VIs, this would get used inside those VIs for outside access but for a lot of stuff I do I try to avoid the overhead of an additional VI call just to pull out a data value. Here's a clarification of the boilerplate I'm eliminating:

 

DerefBoilerplate.png

Link to post
Share on other sites

Oh right. I jumped to objects by analogy to the c languages, completely forgetting the hard boundary between clusters and objects in LV

Link to post
Share on other sites

Well the nice thing about his is that you dont have to copy the entire data structure, just the portions you care about. Note that he unbundles inside the IPE structure. For known names that you want to support (like always unbundle the thing called "waveform") the VIM would work, but its not arbitrary like the xnode could be.

Edited by smithd
Link to post
Share on other sites

I think it's extremely useful. I added DVR support to the latest version of LV-Signals which does something very similar:

LV-Signals.png

It only works with DVRs of clusters, and it looks like yours works with DVRs in general. Check out LV-Signals if you get a chance, the original use was to use it with LV-Create-Signals.xnode, which creates a DVR and a value change event for each element in the cluster.

https://github.com/erdosmiller/lv-signals

Edited by DTaylor
  • Like 1
Link to post
Share on other sites
On 7/15/2017 at 0:25 PM, UnlikelyNomad said:

Then I get the daunting task of scripting up the GenerateCode ability >_>

When you do this give LV-Scripting a chance: https://github.com/erdosmiller/lv-scripting

It has similar functionality to the LAVA Scripting Library: https://lavag.org/files/file/54-scripting-tools/ , but with a heavy emphasis on ease of use for code generation. The package has a dozen or so examples which likely cover everything you need for your XNode.

Link to post
Share on other sites

So cool, I would definitely use an XNode that does this.  Yes the VIM could work with the issues already mentioned, with copying the whole cluster in memory just to grab one element.  Props for the idea, and DTaylor's suggestion.

Link to post
Share on other sites

Oh sorry it was renamed Maleable VI, official feature in 2017 but was implemented as a custom XNode shipped with LabVIEW since around 8.2.

http://zone.ni.com/reference/en-XX/help/371361P-01/lvupgrade/labview_features/

VI Macro discussion before 2017 made VIMs official.

https://lavag.org/topic/19163-vi-macros/

It has some shared functionality with XNodes (type propagation for inputs and outputs) but other custom things like right click, adding removing terminals, and changing node size and icon at edit time can only be done as an XNode, not a VIM.

Link to post
Share on other sites
18 hours ago, infinitenothing said:

Maybe VIM could help?

 

Read DVR example.png

Read DVR.png

I use a lot of reference applications for things like buffers, etc. where pulling out everything everytime would become prohibitive. (As others have stated about my unbundle being inside the IPE). Perhaps the compiler would see the other items aren't pulled out and not copy everything, but if it copied my two gigs of full rate 50khz data when all I wanted was the current data size: boom. Memory fault.

Ultimately this XNode is going to become part of a palette of functionality that aids in development of by-reference designs that go beyond just type matching and maybe even someday others start using these and I never have to inherit code where a class instance stores state data in a FG, especially when that FG isn't part of the class. Preview of other coming attractions: Generics in LabVIEW. (With type restrictions!) All of these features will build on what I learn getting this "simple" introduction to XNodes working.

Link to post
Share on other sites

Was debugging enabled on the VI when it was ran?  I assume probing the cluster wire would force the string to be copied into another memory location.  Anyway that does sound good since one VIM that takes a few minutes to write could perform some of the same functionality as the XNode.  Still would require an unbundle by name, but a Read-Only DVR function could be pretty useful.  I think I made one during the 2017 beta replacing the icon now that I think about it.

Link to post
Share on other sites

Interesting, the same holds even if you do the following:

  • Pull out the string and read array size
  • pull out string and use split string (at char 0xFF) but only read offset
  • Inside of top (writing loop) in-place manipulate data of string (convert to byte array, replace element 0, byte array to string, rebundle)

To force labview to do an allocation, I had to go so far as to pull the data out of the DVR and manipulate it and use the manipulated data (I used the same byte array replace index + split string) . They really did a solid job with the optimization here.

1 hour ago, UnlikelyNomad said:

Was the compiler smart enough that it never put the string into the cluster in the first place? /snicker

Yes it actually did. And in typical labview fashion there are two copies (one for the data after the for loop, one to bundle it). You can get rid of the unnecessary copy through this embarrassing scheme:

sad.PNG

As impressive as the DVR optimization is, this is far more common and far more sad :(

Edited by smithd
Link to post
Share on other sites

I was testing a buffer I wrote for an application some months ago and pushed nearly 2 gigs of data into it 200 rows at a time and then read back the row count. LabVIEW's memory never went above 350megs. Definitely tricky to benchmark in LabVIEW sometimes. LabVIEW is great because it does a lot of stuff for you. LabVIEW sucks because it does a lot of stuff for you.

Edited by UnlikelyNomad
Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Similar Content

    • By Axelwlt
      Hi
      I am reading big TDMS files (~1GB) and I try to minimize memory usage.
      I read a signal once and I want to keep it for later usage, so I tried to write it to a DVR in the hope that I have only one instance of the data in memory.

      However the task manager tells me that uses 2 times more memory than it should.
      I think the problem is that the array is not deallocated although I don't need it after writing it to the DVR.
      Is there a solution to make sure I don't have copies of data?
    • By Ram Prakash
      Can anyone please tell what a DVR [ Data value reference ] is ? I want to know at what situation it will be used and what are the advantages we get by using DVR. I am really confused in this topic . If someone has any code in which they have worked with DVRs. kindly share it to me.
       
      Thank you.
    • By Zyl
      Hi everybody,
       
      I'm running into something I don't really understand. Maybe you can help me here !
      I've got a LVLIB that is used as an 'Interface': it exposes public VIs which wrap around public functions of a private class (see code attached) . The class is private because I want to force the users to use the 'interface' functions.
      In one of my interface VI, I create a DVR on the private class (Interface_init). The DVR is stored into a typedef (FClass_DVR.ctl) and this typedef is the 'reference' that link all the interface public functions.
      In TestCode.vi (which is not part of the lvlib and illustrates the standard code that a user can create to use my driver), I can call my public interface functions and link them without any problem.

      But as soon as I create an indicator on that reference (to create a state-machine-context-cluster for example), my TestCode VI breaks !

      The error returned is : This VI cannot use the LabVIEW class control because of library access scope. The LabVIEW class is a private library item and can only be accessed from inside the same library or libraries contained in that library.
      I understand that the class is private. But the DVR is contained into a public control. Using an In Place structure on that DVR into TestCode would not work, since the class is private. So why is the DVR control problematic at that point ? Creating it do not breaks any access protection...
      Am I missing something ?
      DVR Private POC.zip
    • By Brains
      Hi,
      Does anybody know the best way to make a copy of a byref object (open gds v4) at runtime and pass all the attributes values (including inherited attributes) to the new object?
      Thank you!
      Craig
    • By IpsoFacto
      I've got some weird stuff going on with a cRIO project I'm working on wanted to get some opinions on it. The basic architecture is a set of classes that do some process. That process registers with a server. The internal data of the process is held in a DVR and the server get's access to that DVR. Clients use TCP to ask the server to do something, the server makes a call against the classes DVR and returns a response to the client.
      To simplify the issues I'm seeing I created a class that internally just increments an integer every 500ms. The client asks the server what's the current count, the server asks the Counter class and returns the answer to the client. This works perfectly fine when running the VI in the IDE. When built it connects, will get the JSON message back, but always gets a default value from the DVR call (zero, in this case). As soon as I open a remote debug panel to the cRIO, everything is working. The count is correct, the client calls work, just like normal. As soon as I right-click, close debug, it goes back to zero. Open debug works, close debug, back to zero. I know the DVR isn't getting dropped because the count continues to increment while not in debug, the process is still running happily with no issues.
      Here's a few screenshots of the code;
      Count Class process (get the count, increment, write it back to the DVR) - Counter Class process
      You can see the DVR vi's are actually vim's using a cast. I can't imagine that's the issue.
      Server Side call - Server Side calls
      All this does is get the count from the DVR (same as above) and wraps it in JSON and passes it back to the client as a JSON string.
      I also implemented an Echo class that ignores the process and DVR's, it just takes whatever string you sent form the client to the server and passes it back with a prepended "@echo". This works when running as an executable with the debug turned off so I know the client, server, and the server/class calls are all working as expected.
      Any thoughts here would be welcome, thanks.
      edit: I added the any possible errors coming from the variant cast to the JSON reply. When the debug is open there are no errors, when the debugger is closed it throws error 91, but the in-place element structure reading the DVR does not throw any errors. How can a variant not exist until a debugger is opened and than it magically exists?
      edit: the internal data dictionary is a wrapper around a variant attribute, I wired out the "found?" terminal all the way out to the JSON reply and if the debugger is open the attribute is found, but not if the debugger is closed. Anyone have issues with Variant Attributes in Real-Time?
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.