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