-
Posts
3,183 -
Joined
-
Last visited
-
Days Won
204
Content Type
Profiles
Forums
Downloads
Gallery
Everything posted by Aristos Queue
-
This topic is incredibly timely for me, as I've been building my own tool to do this recently. On this topic, I have some bad news. But before that... Ravi, I liked your UI, so I integrated a few features I had in my app into yours. I hope you don't mind. Added: Tracking of execution highlight and ability toggle it on all selected VIs Tracking of paused VIs and ability to toggle pause on all selected VIs Selection of project/target Filtering of vi.lib Filtering of global VIs Filtering of control templates (.ctt) Sorting by library name Compressed the column text for some entries so more columns fit on the screen Here's the modified VI: LabVIEW Task Manager AQ Revision.zip Just a bit of tweaking and it can be added directly to the Project directory and launched from the Tools menu. Sorry... it's 2am and I'm not doing that extra bit of tweaking right now. Now, on to the bad news... I've spent the last week working on exactly this sort of tool, and I've had a series of problems that I could not solve. I looked at the Task Manager uploaded by Ravi Beniwal, thinking he might have overcome the issues somehow. His tool has the same bugs, though he may not realize it. After consultation with other LV R&D folks today, I can now say that these bugs cannot be fixed in LV 2011 or earlier. And I'm doubtful we can do anything about them in the time remaining for LV 2012 features. Two insurmountable problems I found... ----------------------------- First: Affects reentrant VIs. There is no effective way to get a list of the clone VIs... you know, the ones that are named "XYZ.vi:1" or higher numbers. These are the VIs that you often most need to abort, since one of the more common patterns in LV is to kick off reentrant clones running independently and then, when something goes wrong, you need to kill them. But you cannot get a list of all the reentrant clones that a VI has. You can open a VI ref to the clones by using Open VI Reference and passing a name in like "XYZ.vi:1". I tried checking each value sequentially until I got an error, only to discover that the numbers are not sequential. They can be any number up to MAX_Int32 (roughly 2 billion), so the "guess and check" method is out. ----------------------------- Second: Affects both remote VI Server calls and local Asynch Call By Ref calls. You can't abort subVIs. The Abort VI method will return error 1000 unless the VI is the top-level VI. So what's the problem? When you launch a VI using the Asynch Call By Reference using "Fire & Forget" mode, it launches as a subVI, even though it will keep running if its caller quits. That means that even if the VI is not reentrant, so you can get a reference to it, you still can't tell it to abort. And there is no way to get the caller VI because the caller VI is a fake proxy (you can see it in the VI Hierarchy window). When you launch a VI remotely using the Run VI method or ACBR, you also have a proxy caller that isn't abortable. ----------------------------- I've talked to multiple R&D staff with really deep knowledge of this issue, and there is no solution, and when I raised the topic was basically the first time that those involved collectively realized just how problematic this is to solve. I'd like to say something will be better in 2012, but that seems unlikely at this late date (yes, a month after 2011 released is late in our dev cycle; we do have to finish development pretty far in advance to get the testing solid). The best workaround solution is to build a mechanism into your reentrant and dynamically launched VIs that allows them to be messaged by some tool to stop them -- like if they use a queue, register that queue with a central data store somewhere that you could run to kill all those queues, which would make those VIs exit on their own. Unfortunately, that lead me to discover the third issue. There's no solution in LV to have code that is conditionally compiled in only when debugging is enabled on the VI. Code that registers the VI with the central system is useful while debugging, but probably shouldn't be there when you release -- it's only going to create performance overhead and take up memory. But you'll have to remove it manually before you build your application OR create a custom conditional disable symbol in every project you write. I find this solution distasteful at best. Anyway, that's my sucky news on the LV Task Manager front. I hope the edits I did add are useful.
-
Debug mode doesn't change what code is compiled, only how it is compiled. Disabled code is left out either way.
-
Simultaneous breakpoint custom probes?
Aristos Queue posted a topic in Development Environment (IDE)
At some point, a debug problem becomes so thorny that a programmer must declare that the current debug tools are insufficient and spend time writing new tools before proceeding. In my current hobby-at-home project, I've hit that point. I spent this entire weekend writing a couple of tools for tackling parallel debugging. One tool that I haven't written (yet) is a custom probe to simultaneously pause parallel VIs, and I want to know if anyone has already written such a beast and would share it so I don't have to build it. What I'm imagining is this: A custom probe that has on its panel an array of paths to other VIs. When the custom probe trips, it passes True for its boolean output (to pause the running VI) and it also calls Pause VI method on all the VIs listed in the array. There would be an option for each path to pause all the reentrant clones of the path or a particular subset of reentrant clones. I need this to debug an event handler and to keep the parallel VIs from continuing to generate events. A couple of times, I have gotten very close to the source of a bug only to have LV run out of memory because the background VIs continued to generate events and queue stuff up. It's really annoying. Basically, I need this probe to do what a breakpoint typically does when there are parallel loops on the VI's diagram -- it pauses both loops. But put both of those loops into subVIs and now you have my problem. PS: Bonus points if the custom probe registers the pause with some central debug tool that has a list of all the paused VIs so that all of them can be told to unpause as a group rather than finding and hitting the Pause button on every diagram (which in my case could be 10 to 20 VIs). -
Handling Parallel Execution Sub-VI's in an OO sense?
Aristos Queue replied to AlexA's topic in Object-Oriented Programming
For OO in general, no it's not a problem. In C# and JAVA, the *only* way to pass objects around is by reference. In LV specifically, tt's not a no-no for classes any more than it is for any other LV data type. Passing around references is generally bad in a parellel environment like LabVIEW -- they tend to cause a lot of overhead and are the source of the single hardest-to-solve class of bugs. Data flow is preferred for all LV activities, regardless of the data type. -
Handling Parallel Execution Sub-VI's in an OO sense?
Aristos Queue replied to AlexA's topic in Object-Oriented Programming
Short answer: How would you create an integer in LabVIEW that you could access from two different VIs? Whatever answer you choose for that question, the same answer would apply to you object question. Longer answer: In LabVIEW, parallel access to the same block of data is a separate topic from classes. You can use a global VI, a single-element queue, a data value reference, or many other strategies for sharing any piece of data between two parallel parts of your code. For straight up "I want to modify this object from two parallel VIs", a Data Value Reference is going to be the correct answer for sharing an object. For a more sophisticated approach that prevents some of the pitfalls of simultaneous access to the same shared data, check out this approach from NI Week 2011. There are multiple variations on that theme posted online (see Lapdog and JAMA) -- the tradeoff is both are more complicated, but at the same time, more powerful/flexible. Ok... that's the desktop/RT system. I presume that the host target is where your FPGA communications VIs will be living. If you're actually on the FPGA target, none of the above works. Go back to my "short answer". How would you share a single integer? The answer, to the best of my knowledge about FPGA, is that isn't really possible. FPGA has no concept of pointers or shared data. Instead, you write your VIs such that only one section of the code needs the integer at any given moment, and you pass the integer into that function. But for your host target needs, I think that should be enough info to get you started. -
Best Practices for LVOOP Probes?
Aristos Queue replied to lvb's topic in Object-Oriented Programming
The reason that we don't just use the private data control typedef is that there are several types -- mostly refnums -- where the display for probing is not the same as the control on the FP. The most common is an integer to display, but some of them, like the queue refnums, display as strings, populated with details about the queue. We decided that the generic probe for classes should follow the exact same behavior as the generic probe for all other types and let users build custom probes as needed for particular cases. At the time, it seemed the best way to handle it. Probes don't automatically inherit. Honestly, I can't remember why... it was almost 8 years ago that we made that decision, and in all these years, I don't think anyone has asked me about it. Can anyone think of a good reason we would have done that? Given the way classes are constructed in LV, it probably took effort to keep that property from inheriting, which means there was probably a reason --- not necessarily a good reason, just a reason. You can use the same VI that is in your parent as the probe for your child, you just can't set it as the default probe for the class. You can even select and use it if the VI is private in the parent class. Probes are debug, not part of your actual application, and as such, they just ignore the access scope rules. That way if your parent has defined something to explore the private parts of the parent, you can use that probe to explore the private parts defined by the parent on the child. -
NI forum post asking about LVOOP design pattern
Aristos Queue replied to jcarmody's topic in Object-Oriented Programming
> I always figured there was some magical subtlety I was missing that made the pattern worthy of a special name. Nope. Patterns are patterns, even the very common ones. Having said that, it is amazing how often in software design that people go to great lengths to solve problem XYZ, and someone else pipes up with, "Why don't you just do MNO?" where MNO is some common action. That's often the case with the facade pattern... rather than trying to call an api directly, create a facade that you call through. -
proposal Should OpenG Move to vi.lib?
Aristos Queue replied to jgcode's topic in OpenG General Discussions
You're going to be forcing a relink of any existing VIs that expect to find their subVIs in user.lib but now find them in vi.lib. That's going to be a source-code level change for caller VIs (updating their saved subVI paths). It also means anyone loading any of these VIs dynamically needs to update their code. This is, in many ways, a change that breaks backward compatibility. Does VIPM give you any way to give feedback to users about the effects of a particular upgrade at the time that they choose to upgrade? If so, you probably want to employ that mechanism. Given that, I can imagine some people wanting to have both the user.lib and the vi.lib versions installed on the same LabVIEW. You could choose to not call this an upgrade but instead issue brand new packages, deprecating the ones in user.lib. That way people don't see these new versions as "upgrades" but actual new tools, which they would only adopt for new projects, and might continue to use the existing user.lib packages for existing projects. -
Jim Kring wrote: > which is (I believe) much less efficient I can confirm your belief. The native recursion is better performance. Greg Sands wrote: > Perhaps it would be a good opportunity to evaluate > whether a non-recursive implementation would be better All recursive algorithms can be re-written iteratively. You would be evaluating this trade-off on a case-by-case basis. As far as readability is concerned, in general, the more parameters that the recursive function has, the more the recursive solution is better than the iterative. For something with very few input parameters, the iterative is often easier to understand. The performance tradeoff is more clear cut in LabVIEW -- the iterative solution will generally out perform the recursive one. The LabVIEW compiler's dataspace call structure is different from the stack-based approach of most compilers. Our structure allows for better cooperative multitasking, but it does mean a relatively high overhead for recursive calls since we have to actually allocate heap space instead of just moving a stack pointer. However, I'm sure there is a level of complexity where the recursive solution wins, but it is probably fairly high up.
-
The best way I can suggest is to contact NI tech support and arrange for us to look at your code under secure conditions (possibly even rising to the level of signing an NDA). The sorts of problems you're describing are the deepest dread of compiler writers -- they might be user error, they might be our fault, neither you nor we can tell at the moment, and the longer it goes on, the more it will undercut your confidence in our language. That's bad for both of us -- you eventually will rewrite using some other tool and we lose a customer. Please take the effort to contact NI (though this being Labor Day Weekend, I'm honestly not sure what our staffing is like at the moment). If you're using Source Code Control, commit your changes regularly so we can see the different evolutions of the code. If you're not using SCC, zip your VIs up regularly and name the files with timestamps.
-
I can't think of a time since school that I've had to do something like that. There's some lookup optimizations for hash tables, but that's it. Usually, if I'm worried about string length its with respect to graphics space or string parsing, not comparison.
-
proposal Should OpenG Move to vi.lib?
Aristos Queue replied to jgcode's topic in OpenG General Discussions
The following is NOT my area of expertise. I am raising something that is possibly FUD -- it's something I've heard about that you should research further before deciding the "move to vi.lib" question. I would be concerned about future versions of Windows. Vista and Winy both ratcheted up security for applications, and they encourage app authors to go well beyond the requirements. You can find Microsoft's current recommendations here: http://msdn.microsoft.com/en-us/library/aa368769%28v=vs.85%29.aspx But they keep moving up, and finding that these are requirements one day soon isn't unreasonable. I can easily imagine Windows requiring that any app that modifies a directory created by an installer must itself be signed by the same original authority. That would mean OpenG's installer wouldn't be able to write to vi.lib unless NI signed the installer. Probably not desirable. Now, on the flip side, NI might decide to move vi.lib out of Program Files under such a scenario. There's lots of possibilities here. So, it's not necessarily a showstopper, but I'd suggest you investigate MS' Windows 8 plans before deciding this issue. -
That's the same size as previous versions. Hasn't changed since 7.1, I believe.
-
If you contact NI tech support, we often have to investigate bugs in proprietary code. The Application Engineers (AEs) have various ways of handling this, from simple verbal agreement that we'll delete your code after we're done investigating and guarantee that the bare number of people actually look at it all the way up to full NDA agreements and AEs coming out to look at your code on site. If you can't figure out which function on your diagram is causing the "quick exit", that approach may help you.
-
Ok, when you put it that way, it sounds perfectly reasonable, but I have never needed that functionality in any other programming language, despite having written several systems of similar nature. I haven't needed it in LabVIEW either, but I haven't tried in LabVIEW to write the kind of dynamic registration system that you are attempting. I couldn't come up with a quick reason why I haven't needed it. I thought, "Well, maybe *I* haven't needed it, but it'll turn up in code by others," but in a brief search this morning I can't find any examples of typical programs that do this in other languages.Curiouser and curiouser, thought Alice. In any case, the Preserve Run-Time Class would (if you had a later LV version) do what you're looking for, and the only disadvantage I can see is that the other process has to register for a subtree of message types (as opposed to some more arbitrary filter mechanism). It will be faster than anything you can do involving Library refnums (most things are faster if you can do them without Library refnums). I can't really come up with a way to do this in LV 8.6 short of you adding a new method to your class hierarchy for "Is X a child of me?" and a second method for "get class name", which each class overrides correctly.
-
This is actually something that you should pretty much never have to do. Although the Preserve Run-Time Class function will do what you're asking, the PRTC was put in so you could reasonably make *assertions* that two objects are the exact same class, not for runtime testing. What code are you writing where you need this type of functionality? It's a highly unusual request.
-
Hey, asbo, since you reported that TestStand crashes, would you mind reposting this onto ni.com/forums so that an AE can investigate and CAR the crash? (unless upgrading to 4.2.1 fixes the crash, of course)
-
You're not going to like my solution... it's icky, and I wish there was a better solution, but I've used this and it works: In your class, store a NON-strict VI reference. When you want to use the reference, use a property node to get the VI Name property and wire that to an Open VI Reference node, then take the output of that and use it for your Asynch Call By Ref and your subpanel. You can make this a bit more performant by storing a string alongside the VI reference that is the fully qualified name of the referenced VI so you don't have to use the property node every time.
-
Can I override private data?
Aristos Queue replied to Jason H's topic in Object-Oriented Programming
Daklu: Your opinion is probably shared by most LV users who haven't worked in other languages because LV doesn't have constructors with parameters. If it did, you would probably find yourself wanting to reuse your parent's constructors about as often as you want to use the Call Parent Node in any other method. -
Glad I could help. :-)
-
OK... so at the end of all this... is the behavior now what everyone would call "correct"? If yes, does it match the documentation? If no, what still needs tweaking?
-
Can I override private data?
Aristos Queue replied to Jason H's topic in Object-Oriented Programming
Because it wouldn't solve anything.Instead of a constant, a user might drop a control. The data may come from an Unflatten From String instantiating the default value of the class. There's not really a good way to bottleneck and say "always call this constructor here". Worse, LV data is live from the moment a control is dropped to be copied/pasted around to controls and constants, which means any constructor function would need to be invoked as soon as the control drops on a panel. But the problem is that you might be editing the class right then... there's no guarantee that such a constructor is runnable at any given moment. Originally, I had this idea that we could run the "default value constructor.vi" when the class gets reserved for running, since there's only one copy of the default value and we could update it once. That idea fell apart because RT needs an independent copy of the default value for every allocation. That left me with the idea of flagging every memory allocation that hasn't yet been properly constructed yet and run it on those memory locations whenever the class gets reserved. That option seems viable, although I am worried about the "I just edited the default value constructor VI, now LV needs to update all the memory locations to the new value" problem. Probably not an issue, but I haven't spent any time working on the default constructor issue in the last couple years... the times when someone has asked for this feature has been very rare compared to other requests. It's really not been a priority to find a solution. -
Don't bother learning about "friends" yet. It's not hard to understand, but you shouldn't need it in most applications. Because it's a very rarely needed feature, while you're still learning, I'd push that topic off for a while. Here... start with this 1 hour presentation that will get you all the basics: http://zone.ni.com/wv/app/doc/p/id/wv-1766 Then you can look at the "Additional Resources" section of the LVOOP FAQ for more tutorials, white papers, Powerpoint walkthroughs and other learning materials to fit your learning style: http://zone.ni.com/devzone/cda/tut/p/id/3573