Jump to content

Aristos Queue

Members
  • Posts

    3,183
  • Joined

  • Last visited

  • Days Won

    204

Everything posted by Aristos Queue

  1. Please don't do this. The fact that LabVIEW allows "Use Default If Unwired" on conditional disable structures continues to cause all sorts of problems, problems of such complexity that various people are pushing to mutate that feature away in future versions. A block diagram constant of a reference type is ALWAYS "not a refnum". Just use that. If you're interested in the kinds of problems, here's just one for a sample: You have a disabled diagram structure with three frames, as shown below: You save the VI and close it. Later, you load this VI back into memory, but this time, someone has edited the subVI to have a different output type. When LV checks the types of terminals of this diagram, this time it decides that the output type needs to be the new type, which causes your diagram to break. That's a problem since the whole point of diag disable is supposed to isolate your code from the possibly broken code inside the structure. Similarly, if the subVI is missing, LabVIEW will use the third case to determine the tunnel's type, and the output would turn to double instead of string. This is one of the easy cases. They get much more bizzare and it is all the fault of "Use Default If Unwired".
  2. I went and asked. Here's the details:The Read Reference node of the IPE always has a buffer allocation standing by in case the data value reference coming in is invalid. So the code inside the structure is pointed either at the data brought in by the reference or the local allocation. The local allocation is initialized with the type's default value whenever it is needed. If we did an on-the-fly allocation, we'd have two problems: data allocations in RT (where, believe it or not, DVRs are actually safe to use as long as you guarantee there's no contention for them, so you can use them for the "guarantee no data copies use case") and complex logic for tracking when to deallocate an on-the-fly allocation. Top-level data size for the default value is generally small, so it really isn't worth worrying about most of the time -- you'd have to have a giant cluster of many many doubles to get significant top-level data size.
  3. Variants? I have no idea what you're talking about. But, yes, you have the behavior correct. Those two error terminals are the same error, just available at two different locations on the node -- where "node" in this case means the combined pair of the DVR read and DVR write.
  4. To add to DJed's post: In the particular example posted, you don't need the Merge Errors.vi at all because there's no reason to merge a guaranteed "no error" with the other error stream. Or, to phrase it another way: BOTH "ERROR OUT" TERMINALS RETURN THE SAME VALUE. So you never have to merge these two error streams. Automatic error handling is satisfied if you wire either one of these two error terminals.
  5. Yeah... I thought that too until our Chief Architect came to have a talk at my desk after I converted one batch of VIs to reentrant and caused LV's Getting Started Window to quintuple its memory allocation. Normal reentrancy solves concurrency issues at the cost of memory allocation. The vast majority of subVIs are never under parallel contention, so making those subVIs reentrant simply increases memory usage, which generally means a performance slowdown because things start paging in and out of memory, take longer to load from disk, and generally aren't cached because all the parallel copies keep knocking each other out of the caches. Only when you have parallel contention do you get a performance gain from use of normal reentrancy. Shared reentrancy is a different beast. Only one clone is in memory. If two subVI calls to that clone try to happen at the same time, a second clone is allocated. Once allocated, that clone stays allocated (I think as long as the VI stays in memory without being edited, but it might only be as long as the VI stays running... I'm not sure which). What this means is that you take a performance hit when that second clone gets allocated, but thereafter you get most of the benefits of parallel execution. There's slight thread friction each time the caller VI accesses the clone pool at the start of the subVI call, but that's minimal compared to the friction of being entirely serialized. Shared reentrancy appears in empiric tests to be a good compromise. There's a new feature on the horizon that will introduce yet another variant to consider, but you'll have to wait to August to hear about it (unless you join the beta program and help LV by doing a bit of testing in exchange for early enlightenment).
  6. This is just my theory... others with more practical experience may have other advice.
  7. If it works for VIs generally, then you should keep the same policy for methods of the class. Classes are just a system for organizing the VIs you'd write anyway. And being reentrant does mean all overrides have to be reentrant, but that shouldn't be a problem. For one thing, method overrides are generally adjustments to the parent's behavior, so if the parent didn't need synchronization, neither will the override. And if it really needs synchronization, the override can call a subVI.
  8. 10x slower? No benchmark I've seen shows that kind of slowdown. I won't rule it out (and I haven't looked at your VIs), but that would be... surprising. What version of LabVIEW are you using to do the benchmarking?
  9. Probably. It might be Trevor, might be me. [Trevor did the intro to OO presentation; he's another member of the LV language team who enjoys talking to customers.]
  10. This is now scheduled for April 7. For those who attended NI Week 2009, this will be mostly the same material that I presented in my advanced OO session at that point.
  11. and this are in conflict. You can't reserve all rights of copy and BSD license them simultaneously. I believe the correct notation is
  12. Those Xs also appear when the library is licensed and you don't have the license installed. ... but if you can drop them successfully, then that obviously isn't the problem. No idea what it could be.
  13. What is the best way to access the same array from parallel loops? Whatever answer you give here, use the same mechanism for objects.
  14. The author of those classes gave me a walk through of the system, oh, about two years ago I think. I think it's generally useful stuff, but overkill for small projects.
  15. Are you *sure* that the break is merely because the *path* to the parent has changed? The RTE generally doesn't care about that. Usually it requires that the substance of the dependency have changed to cause a break. Just a guess, but I suspect that the version numbers are being changed. That's what this *feels* like. It would help if you posted the exact text of the error you're seeing. (closing eyes, imagining setup... all of the following is speculative) Let's see... you have a parent class that is built into an EXE and a child class that is going to be dynamically loaded into that EXE but which is not built as part of the EXE. The child is actually produced through its own Source Distribution build (I presume that's what you mean by "when saving child classes with all dependencies"). A copy of the parent class ends up sitting next to the child because the child depends upon the parent class. See #4 for further thoughts about this copy. The EXE runs and tries to dynamically load the child. I assume you've worked out the path issues to successfully point to a file not inside the EXE (otherwise you wouldn't be getting the kind of error that you describe). The child was saved thinking its parent is at path XYZ. When it loads into the EXE, it finds that its parent is at path PDQ. That should be fine... as long as the parent classes are identical. Tangent: In fact, after the source distribution is built for the child, you should be able to safely delete the unneeded copy of the parent class. You only need that laying around if you are going to be loading the child someplace where the parent doesn't already exist. Now, back to the loading problem... The load should work if the two parents are identical. What could cause the two parent classes to not be identical? Well... how about if you built the EXE with "strip typedefs" but when you built the source distribution you did not "strip typedefs"? If the parent class had a typedef inside of it, it would now have different type (and thus a different version number). Hm... no, that shouldn't be the problem, because the parent in memory would have a future version number and a future version number should be fine... of course, that's assuming I've written the C++ code for loading in a run-time engine correctly, so this is worth checking. Ah, but if we reverse the equation, then there's a problem: If you did NOT strip typedefs when building the EXE but you DID strip typedefs when building the source distribution. Then the child class would be saved pointing to a parent whose version number had been bumped forward but the parent class in memory in the EXE would not be bumped, so the child class would complain about being unable to load with an old parent (because there is no way to unflatten data to older versions of the class, only newer ones). Ok, so this is worth testing: are the source distribution and the EXE both being built with the same "strip typedefs" settings? Assuming that isn't the problem, look through your EXE build specification for anything else that could cause a change to the parent class. Note, this isn't a change to the parent class' member VIs... for the version bump break, we're only looking for things that could change the .lvclass file itself (which includes the private data control, thus the typedef possibility). Having said that... does your parent class include any polymorphic VIs? Those get stripped by default when you build an EXE and are not stripped by default when you build a source distribution. I do not know enough about poly VI behaviors -- I pretty much never use that feature of LV -- so the following might be completely off base, but suppose that some member VI of the child class used the poly VI from the parent class. The parent in the EXE no longer has such a subVI. Does the polyVI node from the child's member VI cause the child's VI to break when the poly VI is missing? Or is LV smart enough in the RTE to ignore all references to polyVIs since those don't exist? I don't know. Perhaps someone on the forums knows? I can't think of anything else... That's all I can come up with from the data provided. Try the strip typedefs idea. If that doesn't work, post more details of the problem and maybe I'll think of something else.
  16. No. My team has been swamped with work and we all bowed out. We continue to get requests for it, so I suspect it'll happen sometime during the summer when the dev cycle is a bit lighter.
  17. Libraries have never loaded their VIs in the entire time since they were introduced in LV 8.0. Classes always have since they were introduced in LV 8.2. Open a .lvlib file. Yes, you'll see a list of VIs in the project tree but those VIs are not in memory, as you can see by looking at the VI Hierarchy window and choosing Show All VIs. Open a .lvclass file. Again, you'll see a list of VIs in the project tree, but this time, when you look at the VI Hierarchy window, you'll see all those VIs are actually in memory.
  18. I've never dug into it... it never bothered me. Might be easy to fix if someone tried to fix it. So, yeah, go ahead and report it.
  19. Yes, that does indeed help. Whatever the last directory you opened or saved a VI into, that's the directory LV holds locked. Open or save into any other directory to move the lock. Or close LV.
  20. Don't take that as a negative of LV Libraries. Libraries and classes serve different needs and so have different rules. :-)
  21. I have one of those errors... tracked it to a LV class that has in its private data control a strict VI Refnum that used the class itself as part of the conpane. Any chance that's your bug?
  22. Just classes. Libraries do not load all of their member VIs into memory just because the library loads into memory. Classes do.
  23. Is it specific to items in classes or is it any time you're building LLBs, regardless of content?
  24. I can see the problems you're having, but I am slightly unclear on exactly what your goal is, so I'll lay out a couple of options and hope one of them helps. You have some VIs that you want to invoke dynamically. 1) If you're trying to get those VIs to load into memory at the same time as your top-level VI, what you want is a "static VI reference". [Note: "static VI reference" and "strict VI reference" are not the same thing, and, yes, it is possible to have a "strict static VI reference".] It's in the Application palette. This creates a reference to a subVI but does not invoke the subVI. You can then use the reference that comes out of that node and wire it to either the Call By Reference node or the Run VI method. If you *know* that you're going to want to run these VIs as part of your app but you just need to choose among them dynamically as the app runs, you will find it is most efficient to make these static VI references be "strict" by popping up on them and choosing "Strictly Typed VI Reference". That causes the subVI to be reserved for run when the top level VI starts running, the same way all the usual subVIs get reserved. Not doing this means that the subVIs will be reserved before every run and unreserved when the run finishes. Being strict also means that you cannot use the "Run VI" method. Being strict means that the VIs are set up to run as subVIs of another app. The Run VI method executes a VI as a top-level VI. 2) The objection you might have to item #1 is that the subVIs will all load into memory. If you truly want to dynamically load these VIs into memory then you have to use Open VI Reference and supply a path. The easiest way is to put all of your dynamic subVIs in the same directory as the caller VI and then use "This VI's Path" node to get the path of the caller VI, then do "Strip Path" and "Build Path" to replace the file name of the caller VI with the file name of the desired dynamic subVI. From there you can again use Call By Reference or Run VI. Again, if you wire a conpane to the Open VI Reference node, the resulting reference is a strict VI reference which means you have to use Call By Reference to invoke it.
×
×
  • Create New...

Important Information

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