Using Fabric for Maya with Maya 2016¶
Maya 2016のサポートはFabric Engine バージョン 2.0.0 で最初に追加されました。Maya 2016の新しい重要な機能のひとつに、Mayaノードグラフの並列評価のサポートがあります。Fabric for Mayaでは、Maya 2016の並列評価機能が有効になっているときは、(ユーザーが設定すれば)特定のノードを並列に実行することができるようになりました。
デフォルトでは、CanvasとSpliceノードはたとえ、Mayaの並列評価が有効になっていたとしても、互いに並列に動作することはありません。なぜかというと、Fabric for Mayaはあらゆる互いのノードが同時に実行されることが安全であるか、確証を持てないためです。例えば、ある2つのノードはスレッドセーフでないKLエクステンションを使っているかもしれません。
Fabric for Mayaでは、ノードごとの並列評価動作を設定できます。2つの異なる動作があります。
- 共有実行(または評価):Fabricノードは、共有実行が有効になっている他のあらゆる全てのFabricノードと、潜在的に並列に実行されます。
注釈
共有実行が有効になっているCanvasノードとSpliceノードは、潜在的に互いに並列実行されます。 - 排他実行(または評価)(これがデフォルトです):Fabricノードは他のFabricノードとは並列に実行されません。しかしながら、Fabricノードでない、他のノードとは並列に実行される可能性があります(この並列動作はMaya 2016によってコントロールされます)。
注釈
CanvasノードとSpliceノードの共有実行は、Canvasノード、Spliceノードの内部の並列評価とは異なります。たとえFabricノードが共有実行を有効にされていなくても、PEXコールのような内部的な並列操作は実行できるのです。現在のところ、共有実行はスクリプティングを通してのみ、有効にすることができます。共有実行を有効にするためのスクリプトコマンドが、各Fabric CanvasとFabric Spliceにあります。
Follow these steps to see an example showing the difference between shared and unshared execution of Canvas nodes:
- The samples folder “Maya/Canvas/ParallelEvaluation” contains a scene called “four_outlines_with_parallel_evaluation”. It comes in two versions, with the suffix “_OFF” (no shared execution) and with “_ON” (shared execution).
- Load the “four_outlines_with_parallel_evaluation_OFF” sample and press playback. After one hundred frames stop playback and take a look at the script log. You will see the time, in milliseconds, it took to evaluate all the Canvas nodes. Keep that number in mind.
- Now load the “four_outlines_with_parallel_evaluation_ON” sample and press playback. Depending on your CPU you will probably already notice that it plays back faster. Stop playback and take a look at the script log again. This time the evaluation time should be noticeable smaller.
Canvasノードの並列評価の有効化¶
Canvasノードの並列評価を有効にするMELコマンドは:
FabricCanvasSetExecuteShared -mayaNode canvasMayaNodeName
-enable true;
このコマンドは即座に効果をもたらします。
The MEL command to get the current parallel evaluation mode of a Canvas node is:
FabricCanvasGetExecuteShared -mayaNode canvasMayaNodeName
;
It returns 1 (true) if parallel evaluation is enabled for the node and 0 (false) if it is disabled.
Canvasノードの並列計算を行うサンプルのMELスクリプトです:
$count = 16;
loadPlugin "FabricMaya";
file -f -new;
spaceLocator -n "inputLocator1" -p 0 0 0;
spaceLocator -n "inputLocator2" -p 0 0 0;
createNode -n "combiningCanvasNode" "canvasNode";
for ($i = 0; $i < $count; ++$i)
{
$nodeName = `format -s $i "slowCanvasNode^1s"`;
print `format -s $nodeName "** Building node ^1s\n"`;
createNode -n $nodeName "canvasNode";
FabricCanvasSetExecuteShared -m $nodeName -e false;
FabricCanvasAddFunc -m $nodeName -e "" -t "func" -c "dfgEntry {}\n";
FabricCanvasAddPort -m $nodeName -e "func" -d "i1" -p "In" -t "Vec3";
FabricCanvasAddPort -m $nodeName -e "func" -d "i2" -p "In" -t "Vec3";
FabricCanvasAddPort -m $nodeName -e "func" -d "o" -p "Out" -t "Vec3";
FabricCanvasSetCode -m $nodeName -e "func" -c `format -s $i "dfgEntry {\n UInt64 ticks = getCurrentTicks();\n o = Vec3();\n for ( Index n = 0; n < (1<<20); ++n )\n o += +2e-8 * (i1 + i2);\n //report(\"op:slow^1s:tid=\" + getHardwareThreadID() + \":\" + getSecondsBetweenTicks(ticks, getCurrentTicks()) + \"ms\");\n}\n"`;
FabricCanvasAddPort -m $nodeName -e "" -d "i1" -p "In" -t "Vec3";
FabricCanvasConnect -m $nodeName -e "" -s "i1" -d "func.i1";
connectAttr -f "inputLocator1.translate" `format -s $nodeName "^1s.i1"`;
FabricCanvasAddPort -m $nodeName -e "" -d "i2" -p "In" -t "Vec3";
FabricCanvasConnect -m $nodeName -e "" -s "i2" -d "func.i2";
connectAttr -f "inputLocator2.translate" `format -s $nodeName "^1s.i2"`;
FabricCanvasAddPort -m $nodeName -e "" -d "o" -p "Out" -t "Vec3";
FabricCanvasConnect -m $nodeName -e "" -s "func.o" -d "o";
$iName = `format -s $i "i^1s"`;
FabricCanvasAddPort -m "combiningCanvasNode" -e "" -d $iName -p "In" -t "Vec3";
connectAttr -f `format -s $nodeName "^1s.o"` `format -s $iName "combiningCanvasNode.^1s"`;
}
print "** Building node combiningCanvasNode\n";
FabricCanvasAddPort -m "combiningCanvasNode" -e "" -d "o" -p "Out" -t "Vec3";
spaceLocator -n "outputLocator" -p 0 0 0;
connectAttr -f "combiningCanvasNode.o" "outputLocator.translate";
$combinedKL = "dfgEntry {\n UInt64 ticks = getCurrentTicks();\n o = Vec3();";
for ($i = 0; $i < $count; ++$i)
{
$combinedKL = `format -s $combinedKL -s $i "^1s\n o += i^2s;"`;
}
$combinedKL = `format -s $combinedKL "^1s\n //report(\"op:combined:tid=\" + getHardwareThreadID() + \":\" + getSecondsBetweenTicks(ticks, getCurrentTicks()) + \"ms\");\n}"`;
FabricCanvasAddFunc -m "combiningCanvasNode" -e "" -t "func" -c "dfgEntry {}";
FabricCanvasSetCode -m "combiningCanvasNode" -e "func" -c $combinedKL;
for ($i = 0; $i < $count; ++$i)
{
$iName = `format -s $i "i^1s"`;
FabricCanvasAddPort -m "combiningCanvasNode" -e "func" -d $iName -p "In" -t "Vec3";
FabricCanvasConnect -m "combiningCanvasNode" -e "" -s $iName -d `format -s $iName "func.^1s"`;
}
FabricCanvasAddPort -m "combiningCanvasNode" -e "func" -d "o" -p "Out" -t "Vec3";
FabricCanvasConnect -m "combiningCanvasNode" -e "" -s "func.o" -d "o";
currentTime 1;
select -r "inputLocator1";
move -r -10 0 -10;
setKeyframe "inputLocator1.translate";
select -r "inputLocator2";
move -r 3 0 -3;
setKeyframe "inputLocator2.translate";
currentTime 120;
select -r "inputLocator1";
move -r -10 0 10;
setKeyframe "inputLocator1.translate";
select -r "inputLocator2";
move -r -7 0 7;
setKeyframe "inputLocator2.translate";
currentTime 1;
select -r "inputLocator1";
Spliceノードの並列評価の有効化¶
Spliceノードの並列評価を有効にするMELコマンドは:
fabricSplice "setEvaluateShared" spliceMayaNodeName
"{\"enabled\": true}";
このコマンドは即座に効果をもたらします。
Spliceノードの並列計算を行うサンプルのMELスクリプトです:
$count = 16;
loadPlugin "FabricMaya";
file -f -new;
spaceLocator -n "inputLocator1" -p 0 0 0;
spaceLocator -n "inputLocator2" -p 0 0 0;
createNode -n "combiningSpliceNode" "spliceMayaNode";
for ($i = 0; $i < $count; ++$i)
{
$nodeName = `format -stringArg $i "slowSpliceNode^1s"`;
print `format -stringArg $nodeName "Building node ^1s"`;
createNode -n $nodeName "spliceMayaNode";
fabricSplice "setEvaluateShared" $nodeName "{\"enabled\": true}";
fabricSplice "addInputPort" $nodeName "{\"portName\": \"i1\", \"dataType\" : \"Vec3\", \"arrayType\": \"Single Value\", \"addMayaAttr\": true}";
connectAttr -f "inputLocator1.translate" `format -stringArg $nodeName "^1s.i1"`;
fabricSplice "addInputPort" $nodeName "{\"portName\": \"i2\", \"dataType\" : \"Vec3\", \"arrayType\": \"Single Value\", \"addMayaAttr\": true}";
connectAttr -f "inputLocator2.translate" `format -stringArg $nodeName "^1s.i2"`;
fabricSplice "addOutputPort" $nodeName "{\"portName\": \"o\", \"dataType\" : \"Vec3\", \"arrayType\": \"Single Value\", \"addMayaAttr\": true}";
$iName = `format -stringArg $i "i^1s"`;
fabricSplice "addInputPort" "combiningSpliceNode" `format -stringArg $iName "{\"portName\": \"^1s\", \"dataType\" : \"Vec3\", \"arrayType\": \"Single Value\", \"addMayaAttr\": true}"`;
connectAttr -f `format -stringArg $nodeName "^1s.o"` `format -stringArg $iName "combiningSpliceNode.^1s"`;
fabricSplice "addKLOperator" $nodeName `format -stringArg $i "{\"opName\": \"slow^1s\"}"` `format -stringArg $i "require Math;\noperator slow^1s(\n in Vec3 i1,\n in Vec3 i2,\n io Vec3 o\n )\n{\n UInt64 ticks = getCurrentTicks();\n o = Vec3();\n for ( Index n = 0; n < (1<<20); ++n )\n o += +2e-8 * (i1 + i2);\n report(\"op:slow^1s:tid=\" + getHardwareThreadID() + \":\" + getSecondsBetweenTicks(ticks, getCurrentTicks()) + \"ms\");\n}"`;
}
print `format -stringArg "combiningSpliceNode" "Building node ^1s"`;
fabricSplice "addOutputPort" "combiningSpliceNode" "{\"portName\": \"o\", \"dataType\" : \"Vec3\", \"arrayType\": \"Single Value\", \"addMayaAttr\": true}";
spaceLocator -n "outputLocator" -p 0 0 0;
connectAttr -f "combiningSpliceNode.o" "outputLocator.translate";
$combinedKL = "require Math;\noperator combined(";
for ($i = 0; $i < $count; ++$i)
{
$combinedKL = `format -stringArg $combinedKL -stringArg $i "^1s\n in Vec3 i^2s,"`;
}
$combinedKL = `format -stringArg $combinedKL "^1s\n io Vec3 o\n )\n{\n UInt64 ticks = getCurrentTicks();\n o = Vec3();"`;
for ($i = 0; $i < $count; ++$i)
{
$combinedKL = `format -stringArg $combinedKL -stringArg $i "^1s\n o += i^2s;"`;
}
$combinedKL = `format -stringArg $combinedKL "^1s\n report(\"op:combined:tid=\" + getHardwareThreadID() + \":\" + getSecondsBetweenTicks(ticks, getCurrentTicks()) + \"ms\");\n}"`;
fabricSplice "addKLOperator" "combiningSpliceNode" "{\"opName\": \"combined\"}" $combinedKL;
currentTime 1;
select -r "inputLocator1";
move -r -10 0 -10;
setKeyframe "inputLocator1.translate";
select -r "inputLocator2";
move -r 3 0 -3;
setKeyframe "inputLocator2.translate";
currentTime 120;
select -r "inputLocator1";
move -r -10 0 10;
setKeyframe "inputLocator1.translate";
select -r "inputLocator2";
move -r -7 0 7;
setKeyframe "inputLocator2.translate";
currentTime 1;
select -r "inputLocator1";