Parallel.For Crash

Hi,
I would like to use Parallel.For for this simple loop:

private void RunScript(List guid, List plane, Box box)
{
for(int i = 0; i < plane.Count; i++){
Rhino.Render.TextureMapping textureMapping = Rhino.Render.TextureMapping.CreateBoxMapping(plane[i], box.X, box.Y, box.Z, true);
Rhino.RhinoDoc.ActiveDoc.Objects.ModifyTextureMapping(guid[i], 1, textureMapping);
}
}

I tried this one, but it crashes rhino immediately.
Honestly I am new to multi-threading, can somebody tell why crash occurs and how to properly use Parallel.For in this case? Thank you :slight_smile:

private void RunScript(List guid, List plane, Box box)
{
System.Threading.Tasks.Parallel.For(0, plane.Count, i => {
Rhino.Render.TextureMapping textureMapping = Rhino.Render.TextureMapping.CreateBoxMapping(plane[i], box.X, box.Y, box.Z, true);
Rhino.RhinoDoc.ActiveDoc.Objects.ModifyTextureMapping(guid[i], 1, textureMapping);
});
}

I don’t think you can modify the document in a multi threaded way. Many geometry operations can be parallelyzed, but not the rhino doc.

Yes I tried line by line and rhinodoc is crashing rhino and grasshopper.

Why it is not possible to parallelyze rhinodoc?

Because there would be no point to it. Changes to a document need to happen in a pretty unambiguous order because objects need to be moved to a chronologically linear undo buffer and some operations require the document to be in a valid state. If multiple threads are all making changes to the same document at the same time there will be racing conditions.

I got this from gh forum, but it is faster just a very small amount:

var numbers = Enumerable.Range(0, plane.Count);
var result = numbers.AsParallel().AsOrdered();
foreach (var i in result)
{
  Rhino.Render.TextureMapping textureMapping = Rhino.Render.TextureMapping.CreateBoxMapping(plane[i], box.X, box.Y, box.Z, true);
  Rhino.RhinoDoc.ActiveDoc.Objects.ModifyTextureMapping(guid[i], 1, textureMapping);
}

I am wondering why ModifyTextureMapping operation becomes so slow when number of guids increases to let say 500 hundread?

It could be because of undo records. You can try disabling the Grasshopper undo setting to see if it speeds up, but you typically don’t want to disable that for long.

Sorry but no result tried tick untick

First one no parallel C#
Other parallel C#
Last compiled component

I’m not terribly shocked it takes a second to update 500 objects in the Rhino document though. The document wasn’t designed to handle a huge throughput of changes because Rhino was never meant as an animation package. The assumption until very recently has always been that the document is modified by commands that people run by pressing buttons on a keyboard or a mouse. It’s only when you start to do this sort of stuff from sliders that the delay becomes really noticeable.

Don’t get me wrong, I’d love for it to be faster. But the times you’re getting tell me there’s nothing wrong with your code, it’s just the way Rhino is.

Roger that:)

One more question.

Baking objects to rhino is also not possible to speed up?

I believe if we could make this process faster, we’d have done so…

I haven’t tried this, but would it be a possibility to let multiple instances of Rhino do the baking (with the baker acting as a round robin), and then collect (import) the resulting object? Too complex to set up?

perhaps. Anyway, depending on what kind of baking to be done I imagine that one could split the job up and let for example two Rhino instances do half of the job each, where one bakes odd number of instances and the other bakes even numbers (or divide the job even more if need be).

Would that work? Does GrassHopper have anything inbuilt that would simplify this kind of thing? Perhaps the Elefront plug-in had something. I recall they performed massive computations in parallel with multiple instances of Rhino. In the following video (about the Morpheus Hotel project) they talk about their experiences from such massive computations.

Fig.1. One of the most interesting videos I’ve seen on what you can do with Rhino. Worth every minute:

// Rolf

I think elefront just split the process into sub grasshopper files.

I am wondering if that 5 hours baking process is actual script calculation time