Houdini 18.0 タスクを実行する方法

カスタムスケジューラ

Pythonでカスタムスケジューラを記述することで、サードパーティ製または内製のスケジューラソフトウェアを使用することができます。

On this page

概要

カスタムスケジューラノードを作成すれば、ビルトインのスケジューラノードで対応していないスケジューラソフトウェアにワークを送信することができます。 カスタムノードであれば、独自にワークのスケジュールを組んだり(例えば、独自のスケジューリングアルゴリズムを使用したい)、サードパーティ製または内製のスケジューラのAPIにアクセスすることができます。

Warning

カスタムスケジューラを作成するには、Pythonプログラミングの経験とインテグレートしたいスケジューラソフトウェアの知識が必要になります 。 Pythonコードで何を実装するべきなのか、何が効率的で効率的でないのかは、スケジューラソフトウェアに完全に依存するので、ここでは手順の説明をすることはできません。 インテグレーションのスニペットを記述するには、スレッドプログラミング、サーバーの実行、他にも初心者向けでないプログラミングが必要になります。

また、現在の実装はあくまで 原案 と思ってください。今後のバージョンで修正/変更される予定です。 カスタムスケジューラの実装を試してみた結果を私たちにフィードバックしていただくことを歓迎しております。 この領域では、それが今後の励みになります。

カスタムスケジューラの作り方

カスタムスケジューラを実装するには、以下の手順を踏みます:

  1. TOPネットワーク内にPython Schedulerノードを作成します。

    このノードには、スケジューラの挙動を定義するコールバック関数用のフィールドが備わっています。 このノードは、他のスケジューラと同様に動作し、コールバック関数フィールドに入力されたPythonコードを評価して実行します。 これは、作業ネットワーク内でスケジューラコードを試行することができて非常に便利です。

  2. このノードのタブで色々なPythonスニペットを記入する方法に関しては、以下のコールバックの実装方法を参照してください。

  3. ユーザ側でノードの挙動を制御できるようにするためにSpareパラメータを追加します。

    このようにした方が、Pythonコード内で値をハードコーディングするよりも非常に柔軟性があり便利です。 コードを記述しつつインターフェースを改良し、コードが記述し終わったらパラメータを追加/削除することができます。

    以下のカスタムスケジューラにパラメータインターフェースを追加する方法を参照してください。

  4. スケジューラが正しく動作すれば、他のユーザや他のネットワークで使用できるように、そのスケジューラをデジタルアセットに変換することができます。また、これによって個々のTOPノードがスケジューラのパラメータをオーバーライドすることができます(Python Schedulerインスタンスをオーバーライドすることはできません)。

スケジューラの実装方法

オーバーライドできるコールバックに関しては、スケジューラノードのコールバックを参照してください。

Initialization and Cleanup > Start and Stop

Initialization and Cleanup タブのPythonスニペットを使って、最初にスケジューラを起動した時に実行させるコード、TOPネットワークがクックを開始した時に実行させるコード、ネットワークがクックを停止した時に実行させるコード、スケジューラがもはや不要になった時に実行させるコードを記述します。

この作業ディレクトリは、TOP Networkのコードが実行されるディレクトリで、通常では生成ファイルが保存される場所です。 ファームセットアップでは、この作業ディレクトリを共有ネットワークファイルシステム上にしてください。 PDGは、作業ディレクトリのlocalパス、さらに、remoteパスも知っている必要があります。 localパスは、ユーザのファイルシステム上の有効なパス(ネットワークがクックする場所)で、remoteパスはリモートレンダーファームホスト上で有効なパスである必要があります。PDGで指定されたパスを使って、localremote間のファイルパス変換が行なわれます(それぞれlocalizedelocalizeと呼びます)。

localremoteのパスを生成/変換するコードは、スケジューラによって異なります。 例えば、スケジューラソフトウェアには、共有ディレクトリを検索するための独自の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を返すことができます。 SchedulerBusySchedulerReadyは、onScheduleコールバックを制御できる準備が整っているかどうかをPDGに知らせることができます。 これを利用することで、サーバーや他のリソースの負荷を制御しながらフェームへのワークアイテムの投入を制限することができます。

tickPeriodmaxItemsのスケジューラ系ノードのパラメータを使用することで、onTickonScheduleのコールの頻度を設定することができます。

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)

ジョブが成功したら、このメソッドがコールされます。 nameindexの引数に加えて、cook_duration引数を渡します(ジョブが実行された浮動小数点の秒数の期間)。

self.onWorkItemFailed(name, index)

ジョブが成功したら、このメソッドがコールされます。オリジナルのワークアイテムのnameindexを渡します。

self.onWorkItemCanceled(name, index)

ユーザが手動でジョブをキャンセルしたら、このメソッドがコールされます。 オリジナルのワークアイテムのnameindexを渡します。

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

file_pathのファイルディペンデンシーをローカルマシンからリモート先(例えば、共有ネットワークドライブ)にコピーする時にコールされます。 これは、ワークスクリプトで必要となるファイルを作業ディレクトリにコピーするために使用します。 このスニペットは、ファイルのコピーに成功するとTrueを返します。

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フォルダの追加セクションを参照してください。

Scheduler Propertiesフォルダの追加

すべてのビルトインスケジューラでオーバーライド可能なスケジューラプロパティはScheduler Propertiesフォルダに入っています。 スケジューラプロパティの使い方に関する詳細は、スケジューラオーバーライドドキュメントを参照してください。

ユーザーがカスタムスケジューラのスケジューラパラメータをもっと簡単にオーバーライドできるようにしたいのであれば、 オーバーライド可能なスケジューラプロパティをScheduler Propertiesフォルダ構造に追加してください。 これをするには、それらのスケジューラプロパティをtopscheduler.user.dsという名前のファイルに追加してください。 このtopscheduler.user.dsファイルは、ユーザーのHOUDINI_PATHのどこにでも配置することができます。

topscheduler.user.dsファイルは、スケジューラのオーバーライド可能なプロパティの定義を含んだダイアログスクリプトファイルです。

Tip

カスタムスケジューラ用のダイアログスクリプトを作成するには、以下の手順に従ってください:

  1. Houdiniを起動し、/tasks/topnet1にカスタムスケジューラノードを配置します。

  2. 以下のHythonコードを実行します:

    open("topscheduler.user.ds", "w").write(hou.node("/tasks/topnet1/foo").parmTemplateGroup().asDialogScript(full_info=True))
    
  3. そのファイルから、スケジューラプロパティでない且つ個々のノードでオーバーライド不可なパラメータを削除します。

  4. 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

タスクを実行する方法

基本

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

次のステップ

リファレンス