02-07-2024 11:52 AM
I have a large project. I'm trying to replace a core .lvlib with an .lvlibp for development performance reasons.
It took some work to get the .lvlib into a state where it could be built into a PPL -- mainly dealing with VIMs. But now the project is able to happily work with my .lvlib, and I'm able to build a PPL from it (using a standalone project).
However...if I try to replace the .lvlib with the .lvlibp in my top-level project (using right-click "Replace with..."), LabVIEW will spin its wheels for...seemingly ever. After 18 hours of running (LabVIEW was using 20+GB of RAM and 20-50% of my CPU), I ended up giving up and killing the process.
Is there another reasonable approach that could work here? Should I let it run for longer? Do I need a machine with more than 32 GB of RAM? Are there other things I should be looking for that might be causing it to spin its wheels indefinitely?
02-07-2024 12:42 PM
It could be that replacing such a core part of your project all at once triggers some sort of race condition or infinite loop that LabVIEW just can't handle.
How are you with LabVIEW VI scripting? What if you did it one by one? Something like this (after ensuring you have a complete backup):
1. Open each VI in the project in turn.
2. If it's a member of the lvlib or lvlibp, skip it.
3. Otherwise, traverse the VI for any subVIs, constants, or controls belonging to the lvlib.
4. One at a time, call the "Replace" method, using the "Path" input to point it to the matching file in the lvlibp.
5. For any VI that breaks or "Replace" method that fails, log it and add it to a secondary list. For any success, log it in a different list and skip that VI if it ever runs again (on this run or on another one if you get a lock-up or crash)
6. Save the VI.
7. Move to the next VI in the list and repeat.
8. If there were no errors or broken VIs made when replacing, stop here.
9. Feed back the list of VIs that broke and/or failed their replace methods back into the sequence at the start.
10. Check the list of VIs that need to be fed back in, and if the list is the same twice in a row, exit the script loop with the output of the error list to allow you to attempt to manually track down anything that didn't replace itself properly with the script.
02-09-2024 09:09 AM - edited 02-09-2024 09:11 AM
When I hear the term "core component" and LabVIEW Spins. I think circular dependencies. Obviously, I can't see your code but, you really need to look into the lvlib and ensure that project members do not call library members that call project members with library dependencies. Show a screenshot of the VI Hierarchy view. What does the API for the library look like?
02-09-2024 10:11 AM
What happens if you change your lvlib to lvlibp in the lvproj file (it's just a text file) when LV is shut down?
02-09-2024 10:20 AM - edited 02-09-2024 10:21 AM
@JÞB wrote:
When I hear the term "core component" and LabVIEW Spins. I think circular dependencies.
I do suspect this is what the problem is.
There are some cyclical dependencies in the callers of the lvlib/lvlibp... and I'm currently working on removing those before I try the lvlibp replacement again. Will update if that turns out to be the issue!
02-09-2024 10:24 AM
@Yamaeda wrote:
What happens if you change your lvlib to lvlibp in the lvproj file (it's just a text file) when LV is shut down?
That was one of the first things I tried too -- while it added the lvlibp to my project, it didn't relink anything, so everything else was still dependent on the original lvlib.
02-16-2024 10:54 AM - edited 02-16-2024 11:07 AM
Thought I'd update with more info... at the moment I've found a few strategies have been helpful. That said I'm still not there yet.
1. Systematically breaking circular dependencies, library by library, going up the dependency chain has been pretty effective. I've been doing this in a project, adding just the lowest-level library, and ensuring that no unexpected dependencies are found. However, I've also found issues where cycles within libraries have been problematic, and those are more tedious to remove (and involve breaking up the library temporarily to track down cycles). I've also had to either mark VIMs as private or move them to separate libraries, which means not being able to both use a VIM in my library AND expose it publicly, because of the cyclical dependency that would cause...
2. When replacing a lvlib with a lvlibp, if LabVIEW CPU usage drops to 0% or RAM stays stable for 10 seconds, then LabVIEW will never finish the "replace..." process. It will need to be killed. Don't waste time waiting on it once this happens.
3. When replacing libraries, LabVIEW can only handle one replacement at a time before it has internal conflicts. So...the process that I've found works is to only have the library I want to update in my project (other things will show up in dependencies), save it, close LabVIEW, clear compiled object cache, open project, replace one lvlib with a lvlibp, save, close, repeat with next lvlib dependency. I've also found that sometimes wiping mutation history has been necessary.
4. Building multiple dependent PPLs. The only reasonable solution I've found to building multiple dependent PPLs is to have a separate build project for each one, to configure every build spec to build to a folder in user.lib (or equivalent), and to exclude packed dependencies from each. All other approaches I tried led to issues (PPLs not finding expected dependencies, LabVIEW attempting to load from conflicting places, etc, etc.)
5. Classes in vi.lib. This is the issue I haven't resolve yet --- my code relies on some classes in vi.lib, classes that aren't in PPLs. If one of my PPLs references one of these classes, the PPL will make it's own copy of that class internally. That then means that I can't have code that uses the vi.lib class and passes it into a method exposed by the PPL. I suspect I'll have to do some sort of major refactor to just avoid this situation (or to migrate the vi.lib library to a PPL), both of which I'd prefer not to do.
02-16-2024 11:03 AM
(Created a new issue for the last bullet above, since it's pretty specific and a bit of an offshoot from the initial problem.)