toil
toilを実行する環境を構築する方法として、公式サイトではvirtualenvを利用することを推奨しているが、ここではtoilの環境を、anacondaで構築することにしてみた。 toilは、python2.7環境を要求する。今回はcwlで書かれたワークフローをtoilを利用して、Singularity 2.5.2上で動作させることを試してみた。
環境
$ singularity --version
2.5.2-dist
$ toil --version
3.16.0
$ toil-cwl-runner --version
DEBUG:rdflib:RDFLib Version: 4.2.2
3.16.0
手順
ここでは、サンプルとして実行するcwlのワークフローとして、https://github.com/hacchy1983/CWL-workflows を実行してみることにしたい。
$ conda create -n toil python=2.7 anaconda
$ source activate toil
$ pip install toil[cwl]
$ git clone https://github.com/hacchy1983/CWL-workflows
$ toil-cwl-runner Workflows/test-workflow.cwl Jobs/small.ERR034597.test-workflow.yml
陥った落とし穴
-
pip install toil[cwl]
とせずに、pip install toil
としてしまうと、cwltoolというpython libraryが入っていないのでエラーメッセージが出力される。従って、pip install toil[cwl]
としないといけない。 - toilはデフォルトでの実行時に、そのコア数に応じてpythonのスレッドをたくさん生成する仕様になっていて、メニーコアのマシンではかなり多くのスレッドが立つ。しかしながら、pythonでスレッドをたくさん作るとメモリ使用量が増えるので、使えるメモリが足りなくなると
thread.error: can't start new thread
というエラーメッセージが出力されて、キー入力を受け付けなくなってしまう。この場合、toilを実行するときに--debugWorker
という引数を付けるか、そもそもメモリをたくさん詰んだマシンで実行する。
まずは、サンプルのコマンドを実行してみる。
=========> Failed job 'file:///~/cache/CWL-workflows/Tools/fastqc.cwl' fastqc C/j/jobSOsgEt
INFO:toil.worker:---TOIL WORKER OUTPUT LOG---
INFO:toil:Running Toil version 3.16.0-5988d51822310572dee1aa1e3cb8c81e39ba376c.
Traceback (most recent call last):
File "~/anaconda3/envs/toil/lib/python2.7/site-packages/toil/worker.py", line 313, in workerScript
job._runner(jobGraph=jobGraph, jobStore=jobStore, fileStore=fileStore)
File "~/anaconda3/envs/toil/lib/python2.7/site-packages/toil/job.py", line 1337, in _runner
returnValues = self._run(jobGraph, fileStore)
File "~/anaconda3/envs/toil/lib/python2.7/site-packages/toil/job.py", line 1282, in _run
return self.run(fileStore)
File "~/anaconda3/envs/toil/lib/python2.7/site-packages/toil/cwl/cwltoil.py", line 470, in run
(output, status) = cwltool.main.single_job_executor(**opts)
File "~/anaconda3/envs/toil/lib/python2.7/site-packages/cwltool/main.py", line 58, in single_job_executor
return executor(t, job_order_object, **kwargs)
File "~/anaconda3/envs/toil/lib/python2.7/site-packages/cwltool/executors.py", line 31, in __call__
return self.execute(*args, **kwargs)
File "~/anaconda3/envs/toil/lib/python2.7/site-packages/cwltool/executors.py", line 71, in execute
self.run_jobs(t, job_order_object, logger, **kwargs)
File "~/anaconda3/envs/toil/lib/python2.7/site-packages/cwltool/executors.py", line 107, in run_jobs
r.run(**kwargs)
File "~/anaconda3/envs/toil/lib/python2.7/site-packages/cwltool/job.py", line 412, in run
"--user-space-docker-cmd.: {1}".format(container, e))
WorkflowException: Docker is not available for this tool, try --no-container to disable Docker, or install a user space Docker replacement like uDocker with --user-space-docker-cmd.: 'docker' executable not found: [Errno 2] No such file or directory: 'docker'
ERROR:toil.worker:Exiting the worker because of a failed job on host
WARNING:toil.jobGraph:Due to failure we are reducing the remaining retry count of job 'file:///~/cache/CWL-workflows/Tools/fastqc.cwl' fastqc C/j/jobSOsgEt with ID C/j/jobSOsgEt to 0
<=========
dockerがないマシンで実行したので、dockerがないといって怒られる。今回はdockerで動かすのではなくSingularityでコンテナを動かすことを考える。このとき、変更したいパラメータは、以下のものである。
$ toil-cwl-runner -h
--singularity [experimental] Use Singularity runtime for running containers. Requires Singularity v2.3.2+ and Linux with kernel version v3.18+ or with overlayfs support backported.
experimental であるが、--singularityのフラグを立てて実行してみた。すると、以下のエラーに見舞われた。
WARNING: Skipping user bind, non existent bind point (directory) in container: '/var/spool/cwl'
WARNING: Skipping user bind, non existent bind point (file) in container: '/var/lib/cwl/stg6bf16740-f33a-496b-9ec9-ebe8da26636c/small.ERR034597_1.fastq'
ERROR : Could not change directory to: /var/spool/cwl
ABORT : Retval = 255
[job fastqc.cwl] Job error:
エラーが吐かれてしまった。この直接の原因は、/var/spool/cwl
というコンテナ内に存在しないフォルダを --pwd
として指定しているため、そこにchange directoryできずにエラーを吐いたと考えられる。
この問題は、こちらのissueに書いてあった。 https://github.com/sylabs/singularity/issues/1607
ここで期待したい挙動はおそらく、Singularityのコンテナに、適当に作ったout_tmpdirをvar/spool/cwl/
のディレクトリでbindし、更にそのディレクトリをpwdとして指定したいというように見える。dockerでは類似の操作ができるが、issueによれば、どうやらsingularityではそんなことはできない(?)らしい。
toilのコードを見てみると、Singularityに投げる部分は、cwltoolのライブラリを実質的にラップしているということがわかった。つまり、cwltoolがうまく動かない限り、toil-cwl-runnerは動かないと考えられる。
ここで、 Singularityの --pwd
という引数を --workDir
という引数に変更すると、とりあえずエラーを回避して次に進むことはできた。果たしてこれで問題が解決されたのかはわからない。
しかし、またしても次に以下のようなエラーに見舞われた。
Skipping '/var/lib/cwl/stg8c52f05c-6887-4236-a266-f8f0a8a4cd47/small.ERR034597_2.fastq' which didn't exist, or couldn't be read
[job fastqc.cwl] Job error:
これに関連するものとして、以下のwarningが表示されている。
WARNING: Skipping user bind, non existent bind point (directory) in container: '/var/spool/cwl'
WARNING: Skipping user bind, non existent bind point (file) in container: '/var/lib/cwl/stg8c52f05c-6887-4236-a266-f8f0a8a4cd47/small.ERR034597_2.fastq'
この問題は以下に書いてある。
Singularity 2系列のツールでは、bindする先のディレクトリにスタブ(空ファイル)がないと、bindできないということらしい。そのため、入力として使いたいfastqファイルがSingularityのコンテナにbindできず、ファイルがないというエラーを吐いているのではないかと考えられる。
現在はここまでで、toil with cwl on Singularityの試みは止まっているが、Singularityのバージョンを上げればうまく動くかもしれない。他にもし、うまくいく方法をご存じの方がいらっしゃれば、コメントいただけると助かります!