Python作成したツールを使用していくつかのシミュレーションを実行したいのですが、問題は、異なるパラメーター/引数などをすべて指定して複数回呼び出す必要があることです。
ここでは、次のように、タスクに複数のfor
ループを使用しています。
for simSeed in 1 2 3 4 5
do
for launchPower in 17.76 20.01 21.510 23.76
do
python sim -a $simSeed -p $launchPower
done
done
シミュレーションを同時に実行するために、シミュレータを呼び出す行の最後に&
を追加します。
python sim -a $simSeed -p $launchPower &
この方法を使用すると、そのようなシードを複数実行できます。ただし、コンピューターのメモリが限られているため、上記のスクリプトを書き直して、内側のfor
ループを並列に起動し、外側のfor
ループを順次起動するようにします。
例として、simSeed = 1
の場合、launchPower
が17.76 20.01 21.510 23.76
と等しい状態で5つの異なるプロセスを実行する必要があります。この部分が完了したらすぐに、simSeed = 2
に対してスクリプトを実行し、launchPower
が17.76 20.01 21.510 23.76
と等しい5つの異なる並列プロセスをもう一度実行します。
どうすればこのタスクを達成できますか?
TLDR:
外部ループを順次実行し、内部ループを並列に実行して、内部ループの最後の並列プロセスが終了すると、外部ループが次の反復に移動するようにします。
GNU Parallelには、ジョブを並行して開始するときにリソースの使用を制限するいくつかのオプションがあります。
2つのネストされたループの基本的な使用法は次のとおりです。
parallel python sim -a {1} -p {2} ::: 1 2 3 4 5 ::: 17.76 20.01 21.510 23.76
たとえば、最大5つのジョブを同時に起動する場合は、次のように指定できます。
parallel -j5 python <etc.>
または、--memfree
オプション。十分なメモリが空いている場合にのみ新しいジョブを開始します。少なくとも256 MByte
parallel --memfree 256M python <etc.>
最後のオプションは、メモリが指定された「予約」値の50%を下回ると、最後に開始されたジョブを強制終了することに注意してください(ただし、キャッチアップのために自動的に再キューイングされます)。
コメントで述べたように、これはまさにGNU parallel
の用途です。
for simSeed in 1 2 3 4 5
do
## Launch 5 instances in parallel
parallel -j5 python sim -a $simSeed -p {} ::: 17.76 20.01 21.510 23.76
done
それぞれのプロセスIDとwait
を保存して、それらを完了することができます。
for simSeed in {1..5}; do
pids=()
for launchPower in 17.76 20.01 21.510 23.76; do
python sim -a $simSeed -p $launchPower &
pids+=($!)
done
wait ${pids[@]}
done
pids
は、内部ループのバックグラウンドジョブのプロセスIDの配列です。とともに ${pids[@]}
配列のすべての要素が待機コマンドに渡されます。