nextflowで暗黙的な変数cpusを設定するやり方について

## はじめに

たとえば、ここにpiyo.nfというファイルがあったとします。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144608/2e52fb2d-ef19-8572-12ad-6922c68f0fd2.png" width=120 height=120>


```groovy:piyo.nf
process PIYO {
  """
  echo $task.cpus > cpus.txt
  """
}
```

piyo(ﾋﾟﾖ) これはnextflowスクリプトなので、次のように実行することができます。

```
nextflow run piyo.nf
```

## 何もしないと task.cpus は１にされてしまうでねえか

このスクリプトは、`task.cpus` の結果をcpus.txtに保存するものです。
実行結果を見てみましょう。（どこに保存されているのかわからないのでfindで検索）

```
find -name cpus.txt | xargs cat
```

どうでしょうか？おそらく1になっているはずです。Nextflowで書かれたスクリプトは何も考えずに実行すると自動的にいくつCPUを使えるか捕捉してくれるのかな？と思ったんですが、必ずしもそうじゃないみたいなんです。

たとえば次のような[STAR](https://github.com/alexdobin/STAR)を実行するスクリプトを書いたとき、


```
  STAR --genomeDir $genomeDir \
       --readFilesIn $reads \
       --runThreadN $task.cpus \　←ココ
```

何も考えずに実行すると、--runThreadN 1 で実行されてしまいますよね。
いくつCPUのコアがあっても、1つしか使ってくれない。これでは悲しすぎますね。そうならないためにはどうすればいいのでしょうか？

## task.cpusってそもそも何よ？

すみません。僕も正直よくわかっていません。NextflowはGroovy言語のDSLだと思われ、Groovy言語をある程度しっかり理解しないと本当のところはわからないと思うんですよ。

https://twitter.com/nomad421/status/1364411907365560326

https://twitter.com/PaoloDiTommaso/status/1364489472558170117

なんで、本当のところはわかっていないんですが、Nextflowのリファレンスをみると、ディレクティブという項目があって、次のように書けばよいことがわかります。


## 方法1 ディレクティブとして直接プロセス定義に書き込む

```groovy:piyo2.nf
process PIYO2 {
  cpus 2

  """
  echo $task.cpus > cpus.txt
  """
}
```

実行します。

```
nxtflow run piyo2.nf
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144608/2e52fb2d-ef19-8572-12ad-6922c68f0fd2.png" width=120 height=120> ﾋﾟﾖ

結果を確認してみましょう。

```
find -name cpus.txt | xargs cat
```

さきほどの1に加えて、今度は2という結果も表示されるはずです。

公式リファレンス参照： https://www.nextflow.io/docs/latest/process.html#cpus

## 方法2 configurationファイルに記述する

しかし、process内に直接CPUのコア数を定義したくないですよね。別の環境で実行することを考えられると、process内でコア数を定義するのは避けた方が良さそうな気がします。なので設定ファイルを作成して、そこに記録しておくというのが良さそうです。ファイル名は `nextflow.config` として、ワークフローと同じディレクトリに配置します。


```groovy:nextflow.config
process {
    cpus = 3
}
```

実行します

```
nextflow run piyo.nf
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144608/2e52fb2d-ef19-8572-12ad-6922c68f0fd2.png" width=120 height=120>ﾋﾟﾖ

結果確認

```
find -name cpus.txt | xargs cat
```

先程の1,2だけでなく、3も表示されているはずです。
うまくいかない場合は、ディレクティブで指定したcpusが残っていないか確認してください。

下記のようにすると特定の名前のプロセスだけ設定することもできるようです。

```groovy
process {
    withName: PIYO {
        cpus = 3
    }
}
```

公式リファレンス参照：https://www.nextflow.io/docs/latest/config.html#process-selectors

## 方法3 コマンドライン引数で指定する

でも、結局さっさとためしにコマンドを実行する時に、わざわざ構成ファイルを編集していたら面倒くさいと思います。そこで、１番手軽な方法は、コマンドライン引数でなんとかする方法だと思います。

実行します。

```
nextflow run piyo.nf -process.cpus=4
```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144608/2e52fb2d-ef19-8572-12ad-6922c68f0fd2.png" width=120 height=120>ﾋﾟﾖ

結果を確認します。

```
find -name cpus.txt | xargs cat
```

1,2,3 だけでなく4も表示されていると思います。コマンドラインオプションは最優先されるので、nextfflow.config を書き換える必要はありません。

`--process` ではなく `-process` なのは、これがnextflow runコマンド一般に対するオプションであって、ワークフロー piyo.nf に関するオプションではないからですね。より詳しくは `nextflow run -help` とするとヘルプが表示されます。ここでも`--help` ではなく `-help` であることにご注意ください。


この記事は以上です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144608/a3f5c197-c37c-7b30-1194-11175588c3eb.png)