Threading within ThreadSafe?
I'm getting yelled at by Igor that certain threading things are not available within ThreadSafe functions. I have code that I'd like to make available to a function that's already ThreadSafe, but it seems I can't do that.
For instance: I wrote earlier about the ellipse fitting code (do a search) I had ported from Matlab, then optimized a bit for Igor. Part of that optimization is threading loops that go over each datum since those are slow and one doesn't care about the result of the other. For N=1000 points on my ellipse, it sped the code up from 2 seconds to under half a second, since that was the major time-sink.
What I want to do is insert this into an impact crater analysis suite I have. I trace crater rims, and I have an "EasyRead" function that takes all my rims, splits them up into individual craters (since lat/lon are just in two giant waves), and then farms the analysis out to one crater per thread. The analysis function has to be ThreadSafe because it's being called from a function via ThreadStart. The analysis function then calls a circle fit and ellipse fit. The circle fit is insanely fast and isn't threaded, but per the paragraph above, the ellipse fit is.
Except, because of this apparent limitation, I can't easily call the ellipse code because it, itself, has threading within it. While I'm using Igor 7, this limitation appears to not have been lifted in Igor 8.
I can understand the basic reason for this: If you're already using a bunch of threads for one thing, as one processor finishes a task it should go to the next main thing and so, effectively, you're avoiding having two threads from different functions or "sub-"functions run simultaneously and thus get less benefit from threading. But, not having this ability limits the "genericability" (to make up a word) of certain worker functions. I could also imagine a situation where the above issue isn't the case: Say I have 3 craters with 100,000 points each, farmed out to 1 thread each, and I'm on a cluster with 1003 CPUs. Since matrix manipulation does not scale linearly with N, each crater on one thread would take a long time, but if I could use 1000 CPUs (333/4 for each), it would go much faster. But I wouldn't be able to do that.
Is there any way around this?
Which function/operation exactly do you want to be treadsafe?
August 6, 2018 at 11:58 am - Permalink
Any of the threading ones. :) Basically, if a function is ThreadSafe, Igor throws an error if I have anything within that function that could be used to spawn a new thread. It even yells if it would never encounter them (e.g., if I say if(nthreads>1): do threading stuff; else: do normal function).
August 6, 2018 at 12:00 pm - Permalink
Igor's concept of threadsafe is checked at compile time not at runtime.
Have you looked into the input/output queues for threading? With them you can start all threads you need from the main thread and push your data from one thread to the other.
August 9, 2018 at 04:48 am - Permalink
Spawning new threadgroups from a thread is a Bad Idea. There is a reason the threading calls are not marked threadsafe.
As Thomas suggests, use the techniques provided to monitor your threads and push data to them when called for.
August 9, 2018 at 09:21 am - Permalink