【问题标题】:Force gnu-parallel to treat replacement string as command强制 gnu-parallel 将替换字符串视为命令
【发布时间】:2019-01-18 20:10:34
【问题描述】:

我想在使用替换字符串时将包含命令列表的文件传递给 gnu-parallel(例如:{%})。

不幸的是,如果使用替换字符串,gnu-parallel 会将文件中的命令解释为/bin/bash 的参数。

这是我想做的:

parallel -j 8 'CUDA_VISIBLE_DEVICES=$(({%} - 1)) {}' < commands.txt

commands.txt的内容在哪里:

/path/to/binary -arg1 a -arg2 1.0
/path/to/binary -arg1 a -arg2 1.1
...
/path/to/binary -arg1 z -arg2 9.9

但是,这会引发以下错误:

/bin/bash: /path/to/binary -arg1 a -arg2 1.0: command not found

我希望 GNU Parallel 能够运行:

CUDA_VISIBLE_DEVICES=0 /path/to/binary -arg1 a -arg2 1.0

环境变量CUDA_VISIBLE_DEVICES的目的是让每个进程运行在不同的GPU上(默认情况下所有进程都运行在同一个GPU上)。如果我不需要CUDA_VISIBLE_DEVICES,下面的代码就可以完美运行:

parallel -j 8 < commands.txt

我怎样才能解决这个问题?

【问题讨论】:

  • 您希望 GNU Parallel 运行什么命令?
  • 那么 CUDA_VISIBLE_DEVICES 是干什么用的?
  • 如果我没有为每个进程指定不同的 CUDA_VISIBLE_DEVICES 值,所有进程都在同一个 GPU 上运行。
  • 哦,我明白了。您希望为每个实例设置不同的环境变量。我没有从你的问题中得知这一点。
  • 我想如果我使用 --colsep ' ' 它会起作用,我马上就会发现。

标签: gpu gnu-parallel


【解决方案1】:

虽然--colsep 有时可能会起作用,但它并不总是正确的选择。这将创建文件abcdef

echo 'touch abc\ def' | parallel -v --colsep ' ' A=B {}

通常最好使用 eval 取消引用表达式:

echo 'touch abc\ def' | parallel -v eval A=B {}

所以:

parallel -j 8 'eval CUDA_VISIBLE_DEVICES=$(({%} - 1)) {}' < commands.txt

如果您经常使用$(({%} - 1)),请考虑制作自己的替换字符串:

echo '--rpl {%-1}\ $_=slot()-1' >> ~/.parallel/config
parallel -j 8 'eval CUDA_VISIBLE_DEVICES={%-1} {}' < commands.txt

甚至:

echo '--rpl '"'"'{CUDA} $_="CUDA_VISIBLE_DEVICES=".(slot()-1)'"'" >> .parallel/config
parallel -j 8 'eval {CUDA} {}' < commands.txt

【讨论】:

    【解决方案2】:

    使用--colsep ' ' 可以解决问题:

    parallel -j 8 --colsep ' ' 'CUDA_VISIBLE_DEVICES=$(({%} - 1)) {}' < commands.txt
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-09-15
      • 1970-01-01
      • 2020-10-07
      • 1970-01-01
      • 2016-11-12
      • 1970-01-01
      • 1970-01-01
      • 2023-04-11
      相关资源
      最近更新 更多