On this page |
概要
カスタムスケジューラノードを作成すれば、ビルトインのスケジューラノードで対応していないスケジューラソフトウェアにワークを送信することができます。 カスタムノードであれば、独自にワークのスケジュールを組んだり(例えば、独自のスケジューリングアルゴリズムを使用したい)、サードパーティ製または内製のスケジューラのAPIにアクセスすることができます。
Warning
カスタムスケジューラを作成するには、Pythonプログラミングの経験とインテグレートしたいスケジューラソフトウェアの知識が必要になります 。 Pythonコードで何を実装するべきなのか、何が効率的で効率的でないのかは、スケジューラソフトウェアに完全に依存するので、ここでは手順の説明をすることはできません。 インテグレーションのスニペットを記述するには、スレッドプログラミング、サーバーの実行、他にも初心者向けでないプログラミングが必要になります。
また、現在の実装はあくまで 原案 と思ってください。今後のバージョンで修正/変更される予定です。 カスタムスケジューラの実装を試してみた結果を私たちにフィードバックしていただくことを歓迎しております。 この領域では、それが今後の励みになります。
カスタムスケジューラの作り方
カスタムスケジューラを実装するには、以下の手順を踏みます:
-
TOPネットワーク内に
Python Schedulerノードを作成します。
このノードには、スケジューラの挙動を定義するコールバック関数用のフィールドが備わっています。 このノードは、他のスケジューラと同様に動作し、コールバック関数フィールドに入力されたPythonコードを評価して実行します。 これは、作業ネットワーク内でスケジューラコードを試行することができて非常に便利です。
-
このノードのタブで色々なPythonスニペットを記入する方法に関しては、以下のコールバックの実装方法を参照してください。
-
ユーザ側でノードの挙動を制御できるようにするためにSpareパラメータを追加します。
このようにした方が、Pythonコード内で値をハードコーディングするよりも非常に柔軟性があり便利です。 コードを記述しつつインターフェースを改良し、コードが記述し終わったらパラメータを追加/削除することができます。
以下のカスタムスケジューラにパラメータインターフェースを追加する方法を参照してください。
-
スケジューラが正しく動作すれば、他のユーザや他のネットワークで使用できるように、そのスケジューラをデジタルアセットに変換することができます。また、これによって個々のTOPノードがスケジューラのパラメータをオーバーライドすることができます(Python Schedulerインスタンスをオーバーライドすることはできません)。
スケジューラの実装方法
オーバーライドできるコールバックに関しては、スケジューラノードのコールバックを参照してください。
Initialization and Cleanup > Start and Stop
Initialization and Cleanup タブのPythonスニペットを使って、最初にスケジューラを起動した時に実行させるコード、TOPネットワークがクックを開始した時に実行させるコード、ネットワークがクックを停止した時に実行させるコード、スケジューラがもはや不要になった時に実行させるコードを記述します。
この作業ディレクトリは、TOP Networkのコードが実行されるディレクトリで、通常では生成ファイルが保存される場所です。
ファームセットアップでは、この作業ディレクトリを共有ネットワークファイルシステム上にしてください。
PDGは、作業ディレクトリのlocal
パス、さらに、remote
パスも知っている必要があります。
local
パスは、ユーザのファイルシステム上の有効なパス(ネットワークがクックする場所)で、remote
パスはリモートレンダーファームホスト上で有効なパスである必要があります。PDGで指定されたパスを使って、local
とremote
間のファイルパス変換が行なわれます(それぞれlocalize
、delocalize
と呼びます)。
local
とremote
のパスを生成/変換するコードは、スケジューラによって異なります。
例えば、スケジューラソフトウェアには、共有ディレクトリを検索するための独自のAPIが用意されていたり、システム環境変数(例えば、$REPO_DIR
)を設定する必要があることもあります。
Python Schedulerノードには Working Directory パラメータが備わっており、コード内でself["pdg_workingdir"].evaluateString()
を使用することで、そのパラメータにアクセスすることができます。
慣例として、このパラメータには、local
のフルパス、または、ファームファイルシステムのマウントポイントを基準とした相対パスのどちらかを指定します。
Scheduling > Schedule
これは、ジョブのスケジューリングを行なう"実際のワーク"を実行する重要なメソッドです。
このメソッドは、ノードがワークアイテムを処理してスケジュールを組む際にコールされます。
このメソッドは、pdg.WorkItemオブジェクトをwork_item
として受け取ります。
WorkItem
データを受け取って、それを使ってインテグレートしたい独自システム内でスケジュールが組まれたジョブを作成できるように、ここには スケジューラ特有の ロジックを実装しなければなりません。
そのロジックには、特定の変数が定義された環境でコマンドラインを走らせたり、依存ファイルをコピーしたり、スケジューラAPIをコールするといった処理が必要になります。
-
command
文字列アトリビュートには、ジョブを実行するコマンドラインを格納します。 -
スケジューラが後でジョブを照会できるようにジョブ毎の固有なキーを必要/受け取る場合には、
WorkItem.name
を使用してください。 -
ジョブがスケジュールに組まれたら(または、エラーに遭遇したら)、このスニペットはpdg.scheduleResult値を返すようにしてください。
Scheduling > Ticking
ファームスケジューラのAPIのポーリング(問い合わせ)を使ってジョブの進捗を監視したいことが多いです。 これは、onTickコールバックの実装によって行なうことができます。 このonTick関数の戻り値のpdg.tickResultは、PDGにバインドの状態を知らせます。
例えば、ファームスケジューラの接続が切れて復旧できなくなった場合にSchedulerCancelCook
を返すことができます。
SchedulerBusy
とSchedulerReady
は、onSchedule
コールバックを制御できる準備が整っているかどうかをPDGに知らせることができます。
これを利用することで、サーバーや他のリソースの負荷を制御しながらフェームへのワークアイテムの投入を制限することができます。
tickPeriod
とmaxItems
のスケジューラ系ノードのパラメータを使用することで、onTickとonScheduleのコールの頻度を設定することができます。
Scheduling > Schedule static
onScheduleStaticを参照してください。 これは、静的クックモードでのみ利用し、現在のところTOP UIには露出されていません。
Job Status Notification
ジョブのステータスが変更されたことをTOPネットワークに伝えるためのメソッドを必ず実装しなければなりません。
スケジューラソフトウェアから通知を受け取る方法は、実装によって異なります。
しかし、Houdiniには、再利用できそうなコードをバインドしたいくつかのスケジューラのPython実装が同梱されています。
$HFS/houdini/pdg/types/schedulers
と$HFS/houdini/python2.7libs/pdg
のソースコードを調べることを強く推奨します。
スケジューラがジョブのステータスの変更があったかどうかをポーリング(問い合わせ)する必要がある場合、onTickメソッドでポーリングする必要があることに注意してください。
あなたが使用しているスレッドまたはコールバックで、常にself
(Scheduler
オブジェクト)を参照しなければならないことを忘れないでください。
Note
pdg.Scheduler
通知メソッドには、ジョブを作成したオリジナルのワークアイテムのname
文字列とindex
整数を渡す必要があります。
この場合のindex
のことをバッチサブインデックスと呼ぶことに注意してください。
非バッチジョブでは、index
に-1
を渡してください。
あなたのスケジューラソフトウェアが、それらの引数をジョブにデータとして追加することができる場合、あなた自身でそれらの引数を何かしらの方法(例えば、スケジューラソフトウェアの内部ジョブIDを(name, index)
タプルにマッピングしたPython辞書
をメモリ内に保持することができます)で保存する必要があります。
しかし、スケジューラソフトウェアがジョブのステータスの変更を検知したら、pdg.Scheduler (self
)の以下のメソッドのどれかがコールされます:
self.onWorkItemStartCook(item_name, index)
以前にキューに登録したジョブが実行を開始した時に、このメソッドがコールされます。
self.onWorkItemSucceeded(name, index, cook_duration)
ジョブが成功したら、このメソッドがコールされます。
name
とindex
の引数に加えて、cook_duration
引数を渡します(ジョブが実行された浮動小数点の秒数の期間)。
self.onWorkItemFailed(name, index)
ジョブが成功したら、このメソッドがコールされます。オリジナルのワークアイテムのname
とindex
を渡します。
self.onWorkItemCanceled(name, index)
ユーザが手動でジョブをキャンセルしたら、このメソッドがコールされます。
オリジナルのワークアイテムのname
とindex
を渡します。
onWorkItemFileResult(name, index, result, tag, checksum)
ワークアイテムにファイル結果がある時にコールされます。
result
はそのファイルパスの文字列で、tag
はファイルタグの文字列(例えば、file/geo
)、checksum
が整数値です。
Scheduling > Submit as job
これは、ユーザがTOPネットワーク全体を単一ジョブとして投入した時にコールされます。 これは、あなたが実装するかどうか選択自由なオプションの機能です。 例えば、HQueue Schedulerには Submit Graph as Job ボタンがあります。
-
graph_file
変数には、クックするTOPネットワークを含んだHIPファイルのパスが格納されます。このパスは、そのTOPネットワークをクックするマシンの作業ディレクトリを基準としたパスです。 -
node_path
変数には、HIPファイル内のクックするTOPネットワークノードのノードパスが格納されます。
もし あなたがこの機能に対応したい場合、あなたのコード次第では、Houdiniを実行するスクリプトジョブを作成して、それをスケジュールに組んで、指定したHIPファイルを読み込んで、指定したネットワークをクックすることができます。
Tip
HOMを使ってHoudiniにTOPネットワークをクックさせるには、まず親ネットワークを検索し、そのネットワーク内からディスプレイフラグが有効になっているTOPノードを検索し、そのTOPノードのhou.TopNode.executeGraph()メソッドをコールします。
hou.hipFile.load(graph_file) network = hou.node(node_path) to_cook = network.displayNode() if not disp_node: to_cook = network # ネットワークを初期化します。 to_cook.executeGraph(True, True, False, True) # PDGグラフのクックをブロックします to_cook.executeGraph(True, True, False, False)
Note
$HFS/houdini/python2.7libs/pdg/job/top.py
のスクリプトを利用することもできます。
このスクリプトは、ストックスケジューラが使用しているものです。
Shared servers > Transfer file
Logging
これらのスニペットは、work_item
変数にpdg.WorkItemオブジェクトを格納します。
ワークアイテムのデータ(必要に応じてスケジューラのAPIも一緒に)を使用して、それに該当するジョブのログ/ステータスのページの場所を特定することができれば、TOPインターフェース上にそのログ/ステータスをワークアイテムの情報の一部として表示することができます。
Log URI
getLogURIを参照してください。
ワークアイテムに関しては、システムがそれに該当するジョブの出力/エラーのログを表示する時に取得可能なURLを返します。
共有ネットワークファイルシステム上のファイルを参照している場合には、file:
URLが返されます。例えば、file:///myfarm/tasklogs/jobid20.log
です。
スケジューラがfile:
URLに対応していない場合は、空っぽの文字列を返します。
Status URI
getStatusURIを参照してください。
ワークアイテムに関しては、システムがそれに該当するジョブのステータスを表示する時に開くことが可能なURLを返します。
通常では、スケジューラのウェブインターフェース内のジョブのステータスのページへのhttp:
リンクが返されます。
スケジューラがhttp:
URLに対応していない場合は、空っぽの文字列を返します。
ユーザインターフェースの作り方
Spareパラメータ とは、既存ノードのパラメータインターフェースに追加する"ユーザ"パラメータのことです。 このパラメータを追加することで、スケジューラにユーザ側で設定可能なオプションを追加することができます。 このノードを後でアセットに変換すれば、それらのSpareパラメータがアセットのインターフェースの一部として自動的に使用できるようになります。
-
Spareパラメータを追加する方法に関しては、Spareパラメータを参照してください。
-
このノードのPythonコードスニペットの中に
self
を使用すれば、このスケジューラを表現したpdg.Schedulerインスタンス(これは、Houdiniネットワークノードオブジェクト ではありません )を参照することができます。Python Processorノード/アセット上のすべてのSpareパラメータは、このオブジェクト内にpdg.Portオブジェクトとしてコピーされます。
self["parm_name"]
を使用することで、それらのパラメータにアクセスすることができ、Port.evaluateFloat()
,Port.evaluateInt()
などを使用することで、それらの値を読み込むことができます。# このノードの"url"パラメータからコピーされた値を取得します。 url = self["url"].evaluateString()
-
スクリプトからそれらのパラメータを簡単に参照できるようにするために、それらのパラメータ名を短く、且つ、意味のわかる内部名を付けるように心がけてください。
-
個々のノードがパラメータをオーバーライドできるようにするには: Spareパラメータ編集インターフェース内で、そのパラメータに
pdg::scheduler
タグを付けます。 このタグは、パラメータがスケジューラジョブパラメータであり、個々のノードでオーバーライドできる事をPDGに示します。 これらのパラメータは、 Node Properties メニューにも追加されているはずなので、ユーザーは簡単にどのパラメータがオーバーライド可能なのか知ることができ、それらの値をオーバーライドすることができます。 詳細は、Schedulers Propertiesフォルダの追加セクションを参照してください。-
スケジューラのオーバーライドの使い方の詳細は、スケジューラのオーバーライドを参照してください。
-
現在のところ、このタグの値は使用しません。システムは、
pdg::scheduler
という名前のタグが存在するかどうかのみをチェックします。 -
これは、ノードをアセットに変換した場合にのみ動作することに注意してください。Python Schedulerインスタンスのパラメータをオーバーライドすることはできません。
Note
個々のノードでオーバーライド可能なパラメータを評価する時、必ず以下のメソッドを使用してください:
-
Scheduler Propertiesフォルダの追加
すべてのビルトインスケジューラでオーバーライド可能なスケジューラプロパティはScheduler Properties
フォルダに入っています。
スケジューラプロパティの使い方に関する詳細は、スケジューラオーバーライドドキュメントを参照してください。
ユーザーがカスタムスケジューラのスケジューラパラメータをもっと簡単にオーバーライドできるようにしたいのであれば、
オーバーライド可能なスケジューラプロパティをScheduler Properties
フォルダ構造に追加してください。
これをするには、それらのスケジューラプロパティをtopscheduler.user.ds
という名前のファイルに追加してください。
このtopscheduler.user.ds
ファイルは、ユーザーのHOUDINI_PATH
のどこにでも配置することができます。
topscheduler.user.ds
ファイルは、スケジューラのオーバーライド可能なプロパティの定義を含んだダイアログスクリプトファイルです。
Tip
カスタムスケジューラ用のダイアログスクリプトを作成するには、以下の手順に従ってください:
-
Houdiniを起動し、
/tasks/topnet1
にカスタムスケジューラノードを配置します。 -
以下のHythonコードを実行します:
open("topscheduler.user.ds", "w").write(hou.node("/tasks/topnet1/foo").parmTemplateGroup().asDialogScript(full_info=True))
-
そのファイルから、スケジューラプロパティでない且つ個々のノードでオーバーライド不可なパラメータを削除します。
-
Commonフォルダ下にすべてのプロパティを配置したいのであれば、
parmtag { spare_category "foo" }
をすべてのパラメータ定義に追加してください。foo
はカスタムスケジューラのカテゴリに置換してください。そのカテゴリがpdg.TypeRegistry.registerSchedulerに渡された引数に合致します。
カスタムスケジューラの使い方
Python Schedulerインスタンスまたはカスタムスケジューラアセットを、TOPグラフ全体(つまり、すべてのワークアイテム)または特定のノードから生成されたワークアイテムのみに対して、デフォルトのTOPスケジューラとして設定することができます。
-
デフォルトのTOPスケジューラとして設定するには、TOP Networkノードを選択して、 Default TOP Scheduler をカスタムスケジューラノードに変更します。
-
特定のTOPノードに対して設定するには、そのTOPノードを選択して、 Override TOP Scheduler をカスタムスケジューラノードに設定します。
これによって、TOP NetworkノードまたはTOPノードをクックすると、カスタムスケジューラを使ってワークアイテムが処理されるようになります。
See also |