사용자가 제공한 인수를 기반으로 실행되는 Python 시뮬레이터를 만들었습니다. 프로그램을 사용하기 위해 여러 무작위 시뮬레이션을 실행합니다(시드 값으로 제어됨). 저는 GNU 병렬을 사용하여 아래와 비슷한 방식으로 인수를 사용하여 시뮬레이터를 실행합니다.
parallel 'run-sim --seed {1} --power {2}' ::: <seed args> ::: <power args>
--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가 1D 배열인 경우, Seed는 1D 배열이고 num은 2D 배열입니다. 여기서 행은 거듭제곱 p에 해당하는 num 값을 나타냅니다.
내 솔루션:
각 검정력 값에 대해 여러 병렬 문을 사용하고--link
매개변수시드 및 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개로 고정할 필요가 없는 단일 라이너입니다.
답변1
어떻게 결정하는지는 불분명합니다 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
답변2
을 위한부분당신이 원하는 대답이 맞죠?
$ 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(제곱의 수 x 시드의 수)는 각 거듭제곱과 시드의 조합에 대한 고유한 값이고 {1..12가 아닌 열거된 값 목록이 될 수 있습니다. }? 참고로 저는 숫자와 시드보다는 전력과 시드를 연결하고 있습니다.
$ 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