Houdini 19.5 PDG/TOPsを使ってタスクを実行する方法

スケジューラ系ノードコールバック

スケジューラ系ノードはワークアイテムを実行します。

On this page

概要

スケジューラは、PDGグラフで主なタイプのノードの1つです。 スケジューラ系ノードの目的は、PDGによってスケジューラ系ノードに投入された準備ワークアイテムを実行することです。

さらに、スケジューラは、ステータスの変化を報告し、必要に応じてジョブがPDGと通信可能であることを確認しなければなりません。 デフォルトでは、ジョブは、それに対応したpdgjsonPythonモジュールを使用してXMLRPCによる通信を行ない、 スケジューラは、XMLRPCサーバーが起動していることを確認する役割を担っています。

Note

この仕組は、必要に応じてカスタムスケジューラに置き換えることができます。

スケジューラコールバック

各スケジューラ系ノードには、その挙動を制御するために実装可能なコールバックがいくつか備わっています。 スケジューラ系ノードでコールバックを記述する時に実装で必須となる唯一のコールバックがonScheduleです。 このフックが実際に準備ワークアイテムを実行する役割を担っています。 ワークアイテムが初めから In Process としてマークされている場合、それらのワークアイテムはスケジューラに届かなくなり、代わりにPDGの内部スケジューラで制御されます。 他のコールバックは任意であり、そのノードの挙動をさらにカスタマイズしたい場合にのみ使用します。

Warning

ワークアイテムアトリビュートを安全に書き込める唯一のコールバックがonScheduleです。 onTickコールバック内でワークアイテムにアトリビュートを追加したいのであれば、そのワークアイテムを安全に修正できるようにするために、pdg.WorkItem.lockAttributesを使用する必要があります。

さらに、スケジューラ系ノードは、アクティブに実行されているワークアイテムの参照のみを維持しなければなりません。 そのスケジューラは、ワークアイテムが成功したのか失敗したのかをPDGに通知したら、そのワークアイテムの参照をもはや維持しないでください。

スケジューラ系ノードAPIの全リストはpdg.Schedulerに載っています。

applicationBin(self, name, work_item)str

このコールバックは、ノードがスケジューラによってパラメータ化できるアプリケーションを使用するコマンドを作成している時に使用されます。 例えば、Pythonベースのジョブで使用したいpythonアプリケーションを制御するUIが存在した場合です。

カスタムスケジューラのバインディングは、自身のアプリケーションの名前を使ってカスタムノードを扱うことができます。

最低でもhythonpythonに対応している必要があります。

onSchedule(self, work_item)pdg.scheduleResult

このコールバックは、指定したpdg.WorkItemを実行する準備が整った時に評価されます。 スケジューラは、ファームスケジューラに必要なジョブ仕様を作成し、可能であればジョブを投入します。 ワークアイテムを実行するのに十分なリソースがファームになかった場合、DeferredまたはFullDeferredが返されます。これは、スケジューラがそのワークアイテムを受け入れることができない理由で後でチェックするようにPDGに伝えます。

そうでない場合、そのワークアイテムが受け入れられたことを示すSucceededを返します。

他の戻り値は、何かしらの理由でワークアイテムを即座に制御したい時に使用します。 これは、ワークアイテムが連続で実行されるようになるので、通常では推奨しません。

例えば、Local Schedulerは、ローカルマシン上で利用可能なすべての'スロット'が使用中であると判断するとFullDeferredを返します。 その一方で、利用可能なスロットがあるものの、特定のワークアイテムには十分なほどのスロットがなければDeferredを返します。 十分なスロットがあれば、必要になるスロットを確保し、そのワークアイテム用のサブプロセスを生成してから、そのワークアイテムを実行中ワークアイテムのプライベートキューに追加して追跡します。

Note

このコールバックがコールされる頻度は、PDGノードパラメータのpdg_maxitemspdg_tickperiodで制御します(以下のonTickを参照)。

onTick(self)pdg.tickResult

このコールバックは、PDGグラフがクック中に周期的にコールされます。 通常では、このコールバックは実行中ワーキングアイテムのステートをチェックする時に使用します。 これは、途中のクックをキャンセルするための唯一の安全場所でもあります。

このコールバックの周期は、PDGノードパラメータのpdg_tickperiodで制御され、 ティック間のonScheduleコールバックによる準備ワークアイテムの最大数は、PDGノードパラメータのpdg_maxitemsで制御されます。 デフォルトでは、ティック周期が0.5秒、ティックあたりの最大準備ワークアイテム数は30です。 つまり、onScheduleは1秒あたり最大60回コールされることになります。 これらの値の調整は、ファームスケジューラの負荷を制御するのに役立ちます。

このコールバックは、スケジューラが新しいワークアイテムを受け入れる準備が整っているとSchedulerReadyを返し、 その時にフル稼働であればSchedulerBusyを返します。 スケジューラに深刻な問題があった場合(例えば、ファームへの接続が切れた場合)、SchedulerCancelCookを返します。

onAcceptWorkItem(self, work_item)pdg.acceptResult

デフォルトでは、カスタムスケジューラは、プロセス外のワークアイテムのみを受け入れます。 Invoke TOPまたはPython Script TOP内のワークアイテムのようなIn-Processのワークアイテムは、PDG自体で内部的に制御されます。 オプションのonAcceptWorkItemコールバックを使用することで、その挙動を上書きすることができます。

このコールバックは、指定したワークアイテムをスケジューラが処理可能かどうかを判断するためにコールされます。 このコールバックがpdg.acceptResult.Acceptを返した場合、そのワークアイテムはスケジューラによってキューに登録され、後でonScheduleコールに渡されます。 pdg.acceptResult.Rejectは、指定したワークアイテムをスケジューラが処理不可であることを示し、pdg.acceptResult.Defaultは、代わりにデフォルトの挙動が使用されることを示します。

Note

このコールバック内でワークアイテムを実際にクックまたはスケジュールを組もうとはしないでください。 このコールバックは、ワークアイテムがカスタムスケジューラと互換性があるかどうかを判断する場合にのみ使用してください。

onConfigureCook(self, cook_options)

このコールバックは、グラフがクックを開始する前、そのクックのスケジューラのリストが選択された後でコールされます。 このコールバックを使用することで、クック開始前にそのクックオプションを変更することができます。

cook_optionsは、現行クックで使用されているpdg.CookOptionsの書込み可能な参照です。

Note

すべてのクックオプションがこのコールバックで変更できるわけではありません。 例えば、pdg.CookOptions.nodeNamesオプションを変更しても、PDGは既にそれを処理済みで、このコールバックの前にクックすべきノード/スケジューラのリストが決まっているので何の効果もありません。

onStartCook(self, static, cook_set)bool

このコールバックは、PDGクックが開始されて静的ワークアイテムが生成された後にコールされます。

フルクックではなく静的クックを実行する時はstaticTrueを指定します。 詳細はonScheduleStaticを参照してください。

cook_setには、クックされるPDG pdg.Nodesetを指定します。

これを使用することで、任意のリソースを初期化したり、クック全体に適用する任意の値をキャッシュ化することができます。 Falseを返したり、例外が引き起こされると、クックは中止されます。 以下のコードをコールすることで、ユーザの作業ディレクトリがPDGに伝わります:

self.setWorkingDir(local_path, remote_path)

onStopCook(self, cancel)bool

クックが完了またはキャンセルされた時にコールされます。 cancelTrueを指定しても、実行中のジョブが即座にキャンセルさせるわけではありません。 その場合、スケジューラは、実行中のジョブをキャンセルして、実際にキャンセルされるまでそのジョブをブロックします。 これは、onStartCookでセットアップされた任意のリソースを外す時にも使用します。 戻り値は無視されます。

onStart(self)bool

最初にスケジューラが作成された時にPDGでコールされます。 これを使用することで、クック間で持続させるリソースを確保することができます。 戻り値は無視されます。

onStop(self)bool

スケジューラがクリーンアップされた時にPDGでコールされます。 これを使用することで、リソースを開放することができます。 戻り値は無視されます。

Note

このメソッドは、Houdiniをシャットダウンした時に場合によってはキャンセルすることができません。

onCancelWorkItems(self, work_items, node)

現行クック中にスケジュールに組まれたワークアイテムのサブセットをスケジューラがキャンセルする時にコールされます。 nodeNone以外の値を設定すると、work_itemsリストのすべてのワークアイテムはそれと同じPDGノードのものに絞られ、スケジューラはそのノード関連のすべてのタスクをキャンセルします。 nodeNoneの場合、スケジューラはwork_itemsリスト内のワークアイテムをキャンセルします。

例えば、nodeNone以外の値を設定すると、HQueueスケジューラはそのnode関連のトップレベルノードジョブをキャンセルします。 nodeNoneの場合、HQueueスケジューラはwork_itemsリストの内容に基づいて個々のワークアイテムをキャンセルします。

endSharedServer(self, sharedserver_name)bool

共有サーバーが強制終了された時にコールされます。 例えば、Houdini Command Chainは、コマンドチェーンが終了した時にこのコールバックを評価し、それに関連したHoudiniサーバーを閉じるendserverワークアイテムを生成します。 通常では、スケジューラはpdgjob.sharedserverモジュールのshutdownServer関数を使用することで、XMLRPC経由でシャットダウンコマンドを送信することができます。 コマンドチェーンの使用方法に関する詳細は、コマンドサーバーを参照してください。

getStatusURI(self, work_item)str

指定したワークアイテムのステータスURIを返します。 このURLは、ワークアイテムのMMB詳細ウィンドウに表示されるものです。 file://でローカルファイルを、http://でウェブページを指した書式の文字列になっています。

getLogURI(self, work_item)str

指定したワークアイテムのログURIを返します。 このURLは、ワークアイテムのMMB詳細ウィンドウに表示されるもので、特別な@pdg_logアトリビュートを使って利用することもできます。 file://でローカルファイルを、http://でウェブページを指した書式の文字列になっています。

workItemResultServerAddr(self)str

ワークアイテムのResult Serverのネットワークエンドポイントを<HOST>:<PORT>の形式で返します。 これは、__PDG_RESULT_SERVER__コマンドトークンや$PDG_RESULT_SERVERジョブ環境変数と等価です。 通常では、これはXMLRPC APIサーバーが返されます。

onScheduleStatic(self, dependency_map, dependent_map, ready_items)None

PDGグラフの静的クック(クックモードがStaticDepsFullまたはStaticDepsNode)を実行する時にコールされます。 通常では、この関数は、完全なジョブ仕様を構築し、それをファームスケジューラに投入します。 この挙動は、ファームスケジューラAPIに依存します。 例えば、ワークアイテム間の依存関係は、正しい順番で処理が実行されるようにするために、その依存関係をそのジョブ仕様の親/子関係に変換する必要があります。

Note

この機能性は、完全な静的クックが必須の場合にのみ必要になります。 /tops/custom_scheduler.html#staticcookを参照してください。

dependency_mapは、pdg.WorkItemとその依存関係ワークアイテムのsetのマップです。

dependent_mapは、pdg.WorkItemとその依存関係ワークアイテムのsetのマップです。

ready_itemsは、実行準備が整ったpdg.WorkItemのリストです。

Note

この情報は、pdg.Graph.dependencyGraphを介して取得することができます。

import pdg
n = hou.node("/obj/topnet1/out")
# 必ずPDGコンテキストが作成されるようにするためにcookWorkItemsをコールします。
n.cookWorkItems(tops_only=True)
# PDGクックの生成フェーズを実行します。
n.getPDGGraphContext().cook(True, pdg.cookType.StaticDepsFull)
# 生成されたタスクグラフワークアイテムとトポロジーを取得します。
(dependencies, dependents, ready) = n.getPDGGraphContext().graph.dependencyGraph(True)

Note

このクックモードは、TOP UIには表示されておらず、ストックスケジューラでは対応していません。 ただし、Local Schedulerにはデモ用に基本的な実装が備わっています。 このクックモードを発動させるには、modeStaticDepsFullまたはStaticDepsNodeを指定してpdg.GraphContext.cookをコールします。

この実装は、必須データを保存し、この関数から即座に戻ります。 そして、PDGグラフの実行を非同期で管理し、スケジューラノード関数のonWorkItemSucceededonWorkItemFailedonWorkItemCanceledを介してすべてのステージの変化を報告します。 さらに、例えばonWorkItemAddOutputをコールすることで、ジョブで行なわれたすべてのアトリビュート変更と追加されたファイルがPDGに報告されます。

すべてのワークアイテムが終了時にPDGに報告されると、静的クックが終了します。

See also

PDG/TOPsを使ってタスクを実行する方法

基本

初心者向けチュートリアル

次のステップ

リファレンス

  • すべてのTOPsノード

    TOPノードは、データをネットワークに送り込んでワークアイテムに変換し、色々なノードでそれを制御するワークフローを定義します。たいていのノードは、ローカルマシンまたはサーバーファーム上で実行可能な外部プロセスを表現しています。

  • プロセッサ系ノードコールバック

    プロセッサ系ノードはスケジューラで実行可能なワークアイテムを生成します。

  • パーティショナー系ノードコールバック

    パーティショナー系ノードは複数の上流ワークアイテムを単一パーティションにグループ化します。

  • スケジューラ系ノードコールバック

    スケジューラ系ノードはワークアイテムを実行します。

  • 独自のファイルタグとハンドラー

    PDGはファイルタグを使用して出力ファイルのタイプを決めます。

  • Python API

    ディペンデンシーグラフを扱うためのPython PDGパッケージのクラスと関数。

  • Job API

    ジョブスクリプトで使用するPython API

  • ユーティリティAPI

    Python pdgutilsパッケージのクラスと関数は、PDGノードでの使用だけでなく、スクリプトやプロセス外のジョブスクリプトでの使用も想定されています。