CWL の requirements 一巡り: LoadListingRequirement
この記事は CWL Advent Calendar 2020 の8日目の記事です。
Common Workflow Language (CWL) では、ワークフロー実行処理系が満たさなければならない機能以外にも、Process requirements と呼ばれる optional features についても標準化が行われています[1]。
今回は CWL v1.2 で定義されている LoadListingRequirement について簡単な解説を行います。また、各サンプルは可能な限り公式の準拠度テストで用いられているファイルを引用します。
対象読者
- CWL をかじったことがあるけど
requirementsはよくわからない人- つまり中級者以上が対象です。
- 初心者は CWL Advent Calendar 2020 の初日の記事へ Go!
例
Conformance test #245: tests/listing_shallow1.cwl:
#!/usr/bin/env cwl-runner
class: CommandLineTool
cwlVersion: v1.2
requirements:
LoadListingRequirement:
loadListing: shallow_listing
InlineJavascriptRequirement: {}
inputs:
d: Directory
outputs:
out:
type: boolean
outputBinding:
outputEval: '$(inputs.d.listing.length === 1 && inputs.d.listing[0].listing === undefined)'
baseCommand: "true"
今回は入力パラメータも説明に必要なため掲載します。tests/listing-job.yml (tmp1 の中身はこちら):
d:
class: Directory
location: tmp1
LoadListingRequirement は CWL v1.1 から導入された process requirement で、loadListing フィールドを用いて Expression (Parameter references および JavaScript Expression) 内での Directory 型オブジェクトの listing フィールドの読み込み方法を制御することができます。
loadListing フィールドでは以下の値を指定できます (詳細は LoadListingEnum 参照)。
-
no_listing(例: tests/listing_none2.cwl)- 処理系はディレクトリの中身を一切調べません(
dir.listingがundefinedとして評価される[2])。
- 処理系はディレクトリの中身を一切調べません(
-
shallow_listing(例: tests/listing_shallow1.cwl)- 処理系はディレクトリ内のファイルおよびディレクトリを
listingフィールドから取得できるようにしますが、例えばlistingフィールド内のDirectoryオブジェクトに対しては、no_listingと同様の動作をします。
- 処理系はディレクトリ内のファイルおよびディレクトリを
-
deep_listing(例: tests/listing_deep1.cwl)- CWL v1.0 と同様の動作をします。つまり、処理系はディレクトリに含まれるファイルおよびディレクトリを再帰的に調べ、対応するディレクトリの
listingフィールドから取得できるようにします。
- CWL v1.0 と同様の動作をします。つまり、処理系はディレクトリに含まれるファイルおよびディレクトリを再帰的に調べ、対応するディレクトリの
今回の例では shallow_listing が指定されているため、tmp1 に入っている tmp2 ディレクトリを tmp1.listing フィールドから取得できますが、tmp2.listing (例中の inputs.d.listing[0].listing)はロードされないため undefined になります[2:1]。
何に使うの?
CWL v1.0 では LoadListingRequirement は仕様として存在しなかったため、listing フィールドにはディレクトリに含まれる File および Directory オブジェクトの内容が再帰的に展開されていました。この挙動は大量のファイルを含むディレクトリを扱う場合に性能劣化を起こす可能性がありますが、CWL v1.1 以降では LoadListingRequirement.loadListing を適切に指定することで、それを抑制することができます。
また、CWL の File 型や Directory 型のオブジェクトには、& や $ などを含む文字をパス名に使えないという制限があるため、そのような文字を含むファイルを決め打ちで出力するようなツールをワークフローに組み込むことができませんでした。LoadListingRequirement で no_listing を指定することで、$ などを含むファイルをディレクトリでくるんで渡す、という workaround が可能になります。
注意
WorkflowInputParameter などにある loadListing の説明には以下の記述があります。
By default:
no_listing
一方で、上で説明したように、CWL v1.0 では deep_listing 相当の動作をしていました[3]。そのため、CWL v1.0 から v1.1 (および v1.2) への変更には listing に関する破壊的変更が含まれています。自分のツール定義やワークフロー定義を CWL v1.0 からアップデートする方は注意しましょう。
-
つまり、Process requiremens を含むワークフローやツール定義は、全ての CWL 準拠のワークフロー実行処理系で動かせるわけではありません。詳細は別記事を参照してください。 ↩︎
-
CWL 的に
undefinedってなんなのさって話を Issue #75 で始めたので、もしかしたらundefinedではなくnullが返ってくるようになるかもしれません。どちらが返ってくるとしても、listingが "ない" ことを(読み込まれないことによる性能向上以外に)期待したツール定義やワークフロー定義は書かないほうがいいでしょう。 ↩︎ ↩︎ -
Directoryの仕様を見ると、v1.0, v1.1, v1.2 でlistingに関する記述が変わってませんね…。loadListingの値で挙動が変わるのならDirectoryの項で言及されるべきでは?と思ったので Issue を立てました。 ↩︎
Discussion