Why do some shape-related nodes have their scheduling type set to serial?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
To give a bit of context, I am working on a custom node that takes an array of matrices as an input and exports a curve where the cvs are driven by those matrices (I'm aware you can do this with vanilla nodes). Most of the time the node works fine but it will occasionally randomly cause as crash. Using a debugger shows this error
Exception thrown at 0x00007FF8AFC6792F (NurbsEngine.dll) in maya.exe: 0xC0000005: Access violation reading location 0x0000000000000000.The error does not occur during the compute function of my custom node.
I was able to prevent the crash by changing the scheduling type to serial, but I don't fully understand why that fixes the issue. Below is all the information I was able to find in trying to understand the issue.
What is serial scheduling?
To clarify, I'm talking about serial not globallySerial.
Depending on where you look in the documentation, the details can be a bit unclear. Here is the information provided from several Autodesk sources:
All nodes of this type should be chained and executed sequentially
Maya Help | Evaluation Toolkit | Autodesk
Asserts it is safe to run this node along with instances of other nodes. However, all nodes of this scheduling type are executed sequentially within the same evaluation chain.
Maya Help: MPxNode Class Reference
Groups are formed for nodes having this ShedulingType when they are directly connected to each other.
Within a same group nodes are guaranteed to not to be concurrently evaluated. However nodes in distinct groups can still be concurrently be evaluated.
You are able to see these groups by using:
Evaluation Tookit > Debugging > Evaluation Graph Inspection > Graphical Output > Visual Scheduling Graph
Here you see the definition from the MPxNode documentation in action. When the rebuildCurve node and pointOnCurveInfo nodes are directly connected, they get flagged as a serial group for the purpose of scheduling. I was not able to locate a list of serial nodes, and there doesn't seem to be a command we can use the query that information, so I did some testing with various nodes and the scheduling graph to find out.
Which nodes are serial?
I mainly limited my testing to nurbs-curve related nodes since that was most related to my issue.
This is not a comprehensive list, just the ones I was able to find during my testing:
- Curve-Related
- rebuildCurve
- pointOnCurveInfo
- curveInfo
- motionPath
- fitBSpline
- reverseCurve
- nearestPointOnCurve
- The nurbsCurve shape node itself is NOT serial
- Others
- polySmoothFace
- transformGeometry
It might be possible that these nodes are not always serial, since at least on MPxNode the schedulingType for a node is returned by a function (see here) which could contain some logic, but I wasn't able to find an example of this from Autodesk.
Why are they serial?
I understand vaguely that nodes are serial if them accessing the same data would cause problems. In the past I've noticed that pointOnCurveInfo nodes (and some others) sometimes appear suspiciously long in the profiler. Below you can see the scheduling graph and the profiler graph for the same scene, and you can see that the pointOnCurveInfo nodes that are not in the serial group take a long time to evaluate, while the ones in the serial group take less time individually.
My guess is that this has something to do with the fact that Maya does not cache shape data in the same way it caches basic numerical data. You can observe this by creating a mesh, applying a skinCluster, then a lattice, and then profiling the scene while moving the lattice.
You'll be able to see the skinCluster does get recomputed even though none of its inputs were dirty.
But with a simple scene like this if I update locator4, the blendColors node does not get re-update because the output is clean and we can use the cached output from the last time it evaluated.
I think that Maya does this because caching the mesh output after each deformer would cost too much memory.
So my best explanation for the difference in evaluation time is that even though the pointOnCurveInfo nodes are in parallel, they all need to access the same curve data, which requires them to either copy it, or take turns accessing it (there's probably a technical term for this), either of which would add overhead. That same overhead does not exist if they are scheduled in serial.
But when you connect a nurbs curve shape node to several pointOnCurveInfo nodes it can schedule them in parallel, so there is clearly some safe guards that allow for parallel scheduling even if they are bottlenecked by being unable to access memory in parallel. Then why if you replace the nurbs curve shape node with a rebuildCurve node does Maya require the nodes to be scheduled serially?