web-dev-qa-db-ja.com

別のスクリプトによって呼び出されたスクリプトのforループをGNU並列コマンドに変換する

現在、作成した繰り返し可能な環境のUnixシステムでHaploTypeCallerプログラムを使用するための次のスクリプトがあります。

#!/bin/bash
#parallel call SNPs with chromosomes by GATK
for i in 1 2 3 4 5 6 7
do
  for o in A B D
  do
    for u in _part1 _part2
    do 
      (gatk HaplotypeCaller \
        -R /storage/ppl/wentao/GATK_R_index/genome.fa \
        -I GATK/MarkDuplicates/ApproachBsortedstettler.bam \
        -L chr$i$o$u \
        -O GATK/HaplotypeCaller/HaploSample.chr$i$o$u.raw.vcf &)
    done
  done
done

gatk HaplotypeCaller \
    -R /storage/ppl/wentao/GATK_R_index/genome.fa \
    -I GATK/MarkDuplicates/ApproachBsortedstettler.bam \
    -L chrUn \
    -O GATK/HaplotypeCaller/HaploSample.chrUn.raw.vcf&

このコードを少なくとも部分的に並列に変更するにはどうすればよいですか?このスクリプト全体を別の質問で見ることができる別のスクリプトに組み込むことを試みているのは価値があります ここ 私はすべきですか?パフォーマンスが大幅に向上しますか?

1
The69Er
parallel echo HaploSample.chr{1}{2}{3}.raw.vcf ::: 1 2 3 4 5 6 7 ::: A B D ::: _part1 _part2
1
Fedor Dikarev

parallelがなく、スクリプトの内臓が何をしているのかよくわからないため、これをテストすることはできません。しかし、これはうまくいくと私は信じており、あなたが探していたスタイルかもしれません。

スクリプトを書き直して、ループを削除し、引数を取ります。

#!/bin/bash
#parallel call SNPs with chromosomes by GATK
            (to be safe, verify that "$#" is 3)
i="$1"
o="$2"
u="$3"
            (if you want, verify that the arguments are valid)
gatk HaplotypeCaller \
          ︙       \
    -L "chr$i$o$u" \
    -O "GATK/HaplotypeCaller/HaploSample.chr$i$o$u.raw.vcf" &
 
gatk HaplotypeCaller \
          ︙       \
    -L chrUn -O GATK/HaplotypeCaller/HaploSample.chrUn.raw.vcf &
printf '%s\n' {1,2,3,4,5,6,7}' '{A,B,D}' '_part{1,2} | parallel -L1 (your_script)
  • {1,2,3}は3つの単語として展開されます:123
  • {1,2,3} {A,B}は5つの単語として展開されます:123A and B
  • {1,2,3}{A,B}は6つの単語として展開されます:1A1B2A2B3A3B
  • {1,2,3}' '{A,B}は6つの単語として展開されます:1 A1 B2 A2 B3 A3 B。これらの「単語」にはスペースが含まれていることに注意してください。
  • {1,2,3,4,5,6,7}' '{A,B,D}' '_part{1,2}は42(7×3×2)ワードとして展開され、各ワードには2つのスペースが含まれます。
  • printf '%s\n'各「単語」を別々の行に出力します。ただし、スペースを含む「単語」について話していることを忘れないでください。その効果は、1行に2つまたは3つの通常の(空白以外の)単語を出力することです。例えば、
    $ printf '%s\n' {1,2,3}' '{A,B}
    1 A
    1 B
    2 A
    2 B
    3 A
    3 B
    
    この時点では、これらは通常のスペースです。それらはもはや引用されていません。
  • -L1parallelに1行のデータでプログラムを実行するように指示します。スペースで行を分割し、3つの引数のセットを取得します。
#!/bin/bash
#parallel call SNPs with chromosomes by GATK

gatk_a_single() {
    i="$1"
    o="$2"
    u="$3"

    gatk HaplotypeCaller \
        -R /storage/ppl/wentao/GATK_R_index/genome.fa \
        -I GATK/MarkDuplicates/ApproachBsortedstettler.bam \
        -L chr$i$o$u \
        -O GATK/HaplotypeCaller/HaploSample.chr$i$o$u.raw.vcf
}
export -f gatk_a_single

# This call does not fit the pattern of the others, so just run that in the background
gatk_a_single Un "" "" &    

# Use 3 input sources: All combinations between all input sources will be generated and run
parallel gatk_a_single ::: 1 2 3 4 5 6 7 ::: A B D ::: _part1 _part2

# The parallel tasks are now complete
# Wait for the earlier backgrounded task to complete
wait
1
Ole Tange

最初の概算では、ジョブの数がコアの数未満の場合、並列化は理にかなっています。 42コアが利用可能ですか?そうでない場合は、すべてのジョブを一度に並列化しても意味がない可能性があります。

これがあなたの仕事を並行させる「素朴な」方法です:

1)コマンドを実行せず、書き込みます。

for i in 1 2 3 4 5 6 7
do
  for o in A B D
  do
    for u in _part1 _part2
    do 
      echo "gatk HaplotypeCaller \
        -R /storage/ppl/wentao/GATK_R_index/genome.fa \
        -I GATK/MarkDuplicates/ApproachBsortedstettler.bam \
        -L chr$i$o$u \
        -O GATK/HaplotypeCaller/HaploSample.chr$i$o$u.raw.vcf &"
    done
  done > file-$i.sh
done

これで、それぞれ6つのコマンドからなる7つのテキストファイルができました。これらの7つのスクリプトを次々に実行することにより、6つのバッチでジョブを並列化できます。十分なコア(16?)がある場合は、一度に6つのバッチを2つ実行できます。

泡立てて、すすぎ、繰り返します。

0
Jim L.