CWL の requirements 一巡り: LoadListingRequirement

公開:2020/12/07
更新:2020/12/12
5 min読了の目安(約4800字TECH技術記事

この記事は CWL Advent Calendar 2020 の8日目の記事です。

Common Workflow Language (CWL) では、ワークフロー実行処理系が満たさなければならない機能以外にも、Process requirements と呼ばれる optional features についても標準化が行われています[1]

今回は CWL v1.2 で定義されている LoadListingRequirement について簡単な解説を行います。また、各サンプルは可能な限り公式の準拠度テストで用いられているファイルを引用します。

対象読者

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

LoadListingRequirementCWL v1.1 から導入された process requirement で、loadListing フィールドを用いて Expression (Parameter references および JavaScript Expression) 内での Directory 型オブジェクトの listing フィールドの読み込み方法を制御することができます。

loadListing フィールドでは以下の値を指定できます (詳細は LoadListingEnum 参照)。

  • no_listing (例: tests/listing_none2.cwl)
    • 処理系はディレクトリの中身を一切調べません(dir.listingundefined として評価される[2])。
  • shallow_listing (例: tests/listing_shallow1.cwl)
    • 処理系はディレクトリ内のファイルおよびディレクトリを listing フィールドから取得できるようにしますが、例えば listing フィールド内の Directory オブジェクトに対しては、no_listing と同様の動作をします。
  • deep_listing (例: tests/listing_deep1.cwl)
    • CWL v1.0 と同様の動作をします。つまり、処理系はディレクトリに含まれるファイルおよびディレクトリを再帰的に調べ、対応するディレクトリの listing フィールドから取得できるようにします。

今回の例では 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 型のオブジェクトには、&$ などを含む文字をパス名に使えないという制限があるため、そのような文字を含むファイルを決め打ちで出力するようなツールをワークフローに組み込むことができませんでした。LoadListingRequirementno_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 からアップデートする方は注意しましょう。

脚注
  1. つまり、Process requiremens を含むワークフローやツール定義は、全ての CWL 準拠のワークフロー実行処理系で動かせるわけではありません。詳細は別記事を参照してください。 ↩︎

  2. CWL 的に undefined ってなんなのさって話を Issue #75 で始めたので、もしかしたら undefined ではなく null が返ってくるようになるかもしれません。どちらが返ってくるとしても、listing が "ない" ことを(読み込まれないことによる性能向上以外に)期待したツール定義やワークフロー定義は書かないほうがいいでしょう。 ↩︎ ↩︎

  3. Directory の仕様を見ると、v1.0, v1.1, v1.2listing に関する記述が変わってませんね…。loadListing の値で挙動が変わるのなら Directory の項で言及されるべきでは?と思ったので Issue を立てました。 ↩︎