GNU 병렬 연결 인수와 교대 인수

GNU 병렬 연결 인수와 교대 인수

사용자가 제공한 인수를 기반으로 실행되는 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

관련 정보