GNU 並行連結參數與交替參數
我製作了一個基於使用者提供的參數執行的 Python 模擬器。為了使用該程序,我執行了多個隨機模擬(使用種子值控制)。我使用 GNU 並行以類似的方式執行帶有參數的模擬器,如下所示:
parallel 'run-sim --seed {1} --power {2}' ::: <seed args> ::: <power args>
現在,
--num
我想使用第三個參數,但想將該參數與種子值聯繫起來。因此,對於每個種子值,僅使用一個 num 值。但是,不應對每個冪值使用相同的 num 參數。簡而言之,這張表應該能讓你更好地理解:
| Power | Seed | num | |:-----------|------------:|:------------:| | 10 | 0 | 100 | | 10 | 1 | 150 | | 10 | 2 | 200 | | 10 | 3 | 250 | |:-----------|------------:|:------------:| | 20 | 0 | 300 | | 20 | 1 | 350 | | 20 | 2 | 400 | | 20 | 3 | 450 | ....
(表格格式可能不適合移動設備)
如果我要使用 for 循環編寫上述實現,我會執行以下操作:
for p in power: for s, n in (seed, num[p]) simulate(p, s, n)
其中 power 是一維數組,seed 是一維數組,num 是二維數組,其中一行描述了冪 p 的相應 num 值。
我的解決方案:
對每個冪值使用多個並行語句,並使用parallel 的
--link
參數來綁定seed 和num 參數。parallel --link 'run-sim --seed {1} --num {2} --power 10' ::: 0 1 2 3 ::: 100 150 200 250 parallel --link 'run-sim --seed {1} --num {2} --power 20' ::: 0 1 2 3 ::: 300 350 400 450 ...
這個解決方案的問題是我必鬚根據功率值的數量來限制每個語句的作業數量。在心臟驟停之前,我的電腦可以處理 50 個額外的程序,因此對於 3 個冪值,我必須將每個語句的作業限制為 12 個。
我在找什麼
一個班輪,這樣我就不必執行多個並行語句並將作業數固定為 50。
對於您想要的部分答案,對嗎?
$ parallel --link -k echo {1} {2} ::: {0..3} ::: {100..450..50} 0 100 1 150 2 200 3 250 0 300 1 350 2 400 3 450
如果是這樣,做我認為你想要的一種方法是
$ parallel -k echo {1} {2} ::: {10..20..10} ::: "$(parallel --link -k echo {1} {2} ::: {0..3} ::: {100..450..50})" 10 0 100 10 1 150 10 2 200 10 3 250 10 0 300 10 1 350 10 2 400 10 3 450 20 0 100 20 1 150 20 2 200 20 3 250 20 0 300 20 1 350 20 2 400 20 3 450
另一種方法是(加入排序以按照您想要的順序顯示它;在實際執行中沒有必要):
$ parallel --link -k echo {1} {2} ::: {0..3} ::: {100..450..50} | parallel -a- echo {2} {1} ::: {10..20..10} | sort -k 1,1 -k3,3 -k2,2 10 0 100 10 1 150 10 2 200 10 3 250 10 0 300 10 1 350 10 2 400 10 3 450 20 0 100 20 1 150 20 2 200 20 3 250 20 0 300 20 1 350 20 2 400 20 3 450
另一種方法是並行呼叫並行:
$ parallel parallel --link --arg-sep ,,, echo {1} ,,, {0..3} ,,, {100..450..50} ::: {10..20..10} 10 0 100 10 1 150 10 2 200 10 3 250 10 0 300 10 1 350 10 2 400 10 3 450 20 0 100 20 1 150 20 2 200 20 3 250 20 0 300 20 1 350 20 2 400 20 3 450
這是有效的,因為“內部”並行使用逗號而不是冒號作為參數分隔符,因此“外部”並行不會“看到”連結的參數。
雖然我正在研究一種更容易理解的方法(那裡有一個假定的“{}”),但我意識到最後一個範例並不完全適合您,因為第二個和第三個參數是一個字元串。因此,我添加了說明和(又一個!)並行,以展示如何執行 Python 模擬器。
$ parallel parallel --link --arg-sep ,,, -I [] echo {1} [] ,,, {0..3} ,,, {100..450..50} ::: {10..20..10} | parallel -C' ' echo foo {1} bar {2} blat {3} foo 10 bar 0 blat 100 foo 10 bar 1 blat 150 foo 10 bar 2 blat 200 foo 10 bar 3 blat 250 foo 10 bar 1 blat 350 foo 10 bar 0 blat 300 foo 10 bar 2 blat 400 foo 10 bar 3 blat 450 foo 20 bar 0 blat 100 foo 20 bar 1 blat 150 foo 20 bar 2 blat 200 foo 20 bar 3 blat 250 foo 20 bar 0 blat 300 foo 20 bar 1 blat 350 foo 20 bar 2 blat 400 foo 20 bar 3 blat 450
對於任何列舉值列表
$ parallel parallel --link --arg-sep ,,, -I [] echo {1} [] ,,, {0..3} ,,, v0.0 v0.1 v0.2 v0.3 v1.0 v1.1 v1.2 v1.3 ::: {10..20..10} | parallel -C' ' echo power {1} seed {2} num {3} power 20 seed 0 num v0.0 power 20 seed 1 num v0.1 power 20 seed 2 num v0.2 power 20 seed 3 num v0.3 power 20 seed 0 num v1.0 power 20 seed 1 num v1.1 power 20 seed 2 num v1.2 power 20 seed 3 num v1.3 power 10 seed 0 num v0.0 power 10 seed 1 num v0.1 power 10 seed 2 num v0.2 power 10 seed 3 num v0.3 power 10 seed 0 num v1.0 power 10 seed 1 num v1.1 power 10 seed 2 num v1.2 power 10 seed 3 num v1.3
這將是一個很長的答案。我想也許你想要更像這樣的東西,其中 1 到 12(冪數乘以種子數)是冪和種子的每個組合的唯一值,並且可能是值的列舉列表而不是 {1..12 }? 請注意,我將力量和種子聯繫起來,而不是 num 和種子。
$ parallel --link echo {1} {2} ::: "$(parallel echo {1} {2} ::: {10..30..10} ::: {0..3})" ::: {1..12} | parallel -C' ' echo run-sim --power {1} --seed {2} --num {3} run-sim --power 10 --seed 0 --num 1 run-sim --power 10 --seed 1 --num 2 run-sim --power 10 --seed 2 --num 3 run-sim --power 10 --seed 3 --num 4 run-sim --power 20 --seed 0 --num 5 run-sim --power 20 --seed 1 --num 6 run-sim --power 20 --seed 2 --num 7 run-sim --power 20 --seed 3 --num 8 run-sim --power 30 --seed 0 --num 9 run-sim --power 30 --seed 1 --num 10 run-sim --power 30 --seed 2 --num 11 run-sim --power 30 --seed 3 --num 12
目前尚不清楚您如何確定
num
. 您可以使用基於功率和種子的數組:$ declare -A num=([10,0]=100 [10,1]=150 [10,2]=200 [10,3]=250 [20,0]=300 [20,1]=350 [20,2]=400 [20,3]=450 [30,0]=133 [30,1]=166 [30,2]=200 [30,3]=233) $ env_parallel -j 50 echo power {1} seed {2} num '${num[{1},{2}]}' ::: 10 20 30 ::: 0 1 2 3
或者基於序列號的數組:
$ num=(dummy 100 150 200 250 300 350 400 450 133 166 200 233) $ env_parallel -j 50 echo power {1} seed {2} num '${num[{#}]}' ::: 10 20 30 ::: 0 1 2 3
或許:
parallel -j 50 echo power {1} seed '{=1 $_=(seq()-1)%4=}' num {2} ::: 10 10 10 10 20 20 20 20 30 30 30 30 :::+ 100 150 200 250 300 350 400 450 133 166 200 233