As we know, starting from Maya 2016, Maya introduces a new evaluation model that enabled better utilization of computer resources by distributing computation over all available cores and taking advantage of GPU compute power. Unlike previous versions of Maya, which was limited to node-level parallelisms, Maya now includes a mechanism for scene-level analysis and parallelization. For example, if your scene contains different characters that are unconstrained to one another, Maya can evaluates each character at the same time.
At the heart of Maya’s new evaluation architecture is an Evaluation Manager (EM), responsible for creating a parallel-friendly description of your scene, called the Evaluation Graph (EG). The EM schedules EG nodes across available compute resources. If you are not familiar with Maya EM/EG, and want to have a deep idea about the background, I suggest you can check the in-depth technical doc at Using Parallel Maya.
Here, I just want to bring up some best practice and suggestions to avoid some issues while migrating or make use of the Maya Parallel Evaluation in your plugin.
In general, if your plug-in plays by the DG rules, there is not much you need to change in your plug-in to make it work in Parallel mode. Porting your plug-in so it works in Parallel may be as simple as recompiling it against the latest version of OpenMaya. But, if the EM generates different results than DG-based evaluation, you need to check these items to make sure that your plug-in follow best practices:
- Be careful with MPxNode::setDependentsDirty().
If your scene uses custom plug-ins that rely on the
MPxNode::setDependentsDirtyfunction to manage attribute dirtying, this may cause some problems. Plug-in developer sometimes use
MPxNode::setDependentsDirtyto avoid expensive calculations in
MPxNode::computeby monitoring and/or altering dependencies and storing computed results for later re-use.
Since the EM relies on dirty propagation to create the EG, any custom plug-in logic that alters dependencies may interfere with the construction of a correct EG. Furthermore, since the EM evaluation does not propagate dirty messages, any custom caching or computation in
MPxNode::setDependentsDirtyis not called while the EM is evaluating. I will talk detail about the solution in next blog post.
- Handles requests for evaluation at all levels of the plug tree.
While the DG can request plug values at any level, the EM always requests the root plug. This mostly happen when you have a compound attribute, for example, for plug N.gp.p, your compute() method must handle requests for evaluation of N.gp, N.gp, N.gp.p, and N.gp.p. Recently we happen to see an issue which is caused by not including the root plug in compute() method.
- Overrides MPxNode::compute().
Besides the above suggestions, there are some other recommended best practices include:
This is especially true of classes extending MPxTransform which previously relied on asMatrix(). See the rockingTransform SDK sample. For classes deriving from MPxDeformerNode and MPxGeometryFilter, override the deform() method.
- Avoid storing state in static variables. Store node state/settings in attributes. This has the additional benefit of automatically saving/restoring the plug-in state when Maya files are written/read.
- Node computation should not have any dependencies beyond input values. Maya nodes should be like functions. Output values should be computed from input state and node-specific internal logic. Your node should never walk the graph or try to circumvent the DG.