Thanks for the post. We were able to make everything much simpler by adjusting Grasshopper to call SolveInstance in two passes when your component implements the new IGH_TaskCapableComponent interface (and the option is enabled for your component).
The first pass is used to build a calculation task for every iteration. Each iteration could launch further sub-tasks if it makes sense.
The second pass gets results from these tasks and sets IGH_DataAccess output
This makes every iteration potentially computed in a separate task and the output data structure is exactly the same without any extra effort.
That sounds amazing, really looking forward, this will be a great improvement for larger computations and general UX of gh. I will start migration from v5 to v6 asap just for this
Please hold off on migrating based on the document I provided. I think there are a few changes I want to make in the base class that will simplify the code a little more. I’ve updated a few more components this week and there is a bit of unnecessary repetition that I think I can remove.
It would be nice, but I won’t be able to make that change for the “Boundary Surfaces” component. This component works on a single large collection of curves and tries to figure what to do for all of these curves at once. Consider the case of a small circle inside of a larger circle. The interdependencies of these curves in the calculation makes multi-threading at the lower level difficult.
Fortunately, the story will be different for others components.
The Sept 5, 2017 WIP now includes an additional 10 components that use multiple threads to solve. Here are the additional components that could use some “kicking of the tires” for multi-threaded solving.
This was actually available in last week’s WIP, but I forgot to mention it. David and I added converted another set of components to be able to use multiple threads for solving. The current list is:
I’m having some problems trying to use the Parallel option for the BREP | Line and BREP | Curve components … basically Rhino ‘stops working’ using either of them, but running single-threaded works. Calculation is ~6.4M lines intersecting a BREP … although i’d like to actually check the 16 individual faces of the BREP, but first things first …
Related - is there any chance Mesh | Ray could be next on the list of threaded components? In the same script I’m currently testing 2818 rays from 4771 points for intersection with a (rather large) mesh - the ~13.4m tests take ~4 minutes so i’d like to get this multi-threaded
@DavidRutten would it be possible to parallelize the Surface Geodesic component? This is a computationally heavy component which I suspect could be easily parallelized. While you’re at it, I’m wondering if you can expose the tolerance value in the component?
Surface Split is another component which could be parallelized and is often computationally expensive.
hi … sorry my email notifications are still not working
I don’t have the case in front of me, but i suspect there are parallel faces and even if not, it is likely that other models would include parallel faces
(it is building envelope analysis, so pretty good chance they are ‘box-like’)
Have you considered an “Auto” mode for multithreading? I have found that when dealing with a small number of geometries, many of the MT operations are considerably slower than their single-threaded counterparts (e.g., 254ms vs 15ms) because of the set-up time for the threads themselves (as outlined in previous discussions/posts w/ @stevebaer).
In an ideal world, a scalable definition would use Single threading with a small number of input objects and Multithreading with a large number, and there is likely a set of thresholds that represents the breakeven point between the two. I understand that this breakeven point may differ considerably between components and may even be complicated by the fact that some multithreading components can accept different kinds of input types, and therefore further complicate the breakeven threshold.
That said, I could see some sort of one-time regression analysis done on this problem in a sandbox scenario that could determine of a set of thresholds based on an accounting of the input geometry/data, which would be prebaked by McNeel after a set of tests. Those thresholds would simply apply ST vs MT based on those thresholds, and therefore scale appropriately as the amount of input data increases/decreases.
Right now I am considering implementing a hack that essentially routes data into a ST version of the component or a MT version based on my own realworld tests… but boy, it would be nice if GH could handle that.