GNU 병렬 작업 큐 스크립트

GNU 병렬 작업 큐 스크립트

대기열에서 실행하려는 프로그램의 요구 사항에 맞게 약간 수정한 스크립트를 GitHub에서 찾았습니다.

하지만 작동하지 않으며 이유를 모르겠습니다. 실제로 작업을 대기열 파일에 반영하지 않습니다.

GitHub 페이지 링크는 다음과 같습니다.

https://gist.github.com/tubaterry/c6ef393a39cfbc82e13b8716c60f7824

이것은 내 수정된 버전입니다.

#!/bin/sh

END="END"
true > queue

tail -n+0 -f queue | parallel -j 16 -E "$END"

while read i; do
    echo "command [args] > ${i%.inp}.log 2> ${i%.inp}.err" > queue
done < "jobs.txt"

echo "$END" >> queue
echo "Waiting for jobs to complete"

while [ "$(pgrep 'perl /usr/local/bin/parallel' | grep -evc 'grep' | tr -d " ")" -gt "0" ]; do
    sleep 1
done

touch killtail
mv killtail queue
rm queue

내가 생각할 수 있는 유일한 것은 OpenBSD에서 단계 중 하나가 예상대로 작동하지 않는다는 것입니다. 그러나 단계를 다시 예약하고 모든 것이 오류 없이 실행되었지만 하나의 작업만 제출되었습니다. 변경 사항은 tail -n+0 -f queue | parallel -j 16 -E "$END"첫 번째 while 루프 이후로 이동하고 이것이 무엇을 의미하는지 잘 모르기 때문에 true > queue으로 변경하는 것입니다 .touch queuetrue > queue

어떤 도움이라도 대단히 감사하겠습니다.

편집하다:

실행하려는 명령에 대한 입력 파일 경로로 채워진 jobs.txt 파일이 있습니다. jobs.txt의 파일은 명령에 대한 인수 중 하나가 되며 계산 결과를 로그 파일에 출력하고 오류는 오류 파일에 출력합니다.

내 기대는 각 작업이 대기열에 추가되고 최대 16개의 작업이 코어당 하나씩 병렬로 실행되는 것입니다. 명령의 매개변수 중 하나가 한 번에 하나의 코어 사용률을 계산하는 것이기 때문입니다. 이는 병렬 -E 매개변수로 표시되는 "END"에 도달할 때까지 계속됩니다.

작성된 대로 jobs.txt에는 대기열에 에코되는 내용이 없습니다. 다시 시도해보겠습니다 >>

원작에서 질문을 많이 했어요. 확실히 알고 있던 부분을 변경했는데, 정말 헷갈려서 그대로 유지하기로 결정한 기능도 있었습니다.

내가 확실하지 않은 것 중 하나는 tail -n+0입니다.

그게 무슨 일인지 모르겠어요

편집 2:

${PROGRAM} ${JOB}.inp ${NCPU} > ${JOB}.log 2> ${JOB}.err

${JOB}은 주어진 시간에 수행해야 하는 작업 수에 따라 1~무한계산 사이의 임의의 위치에 대한 참조입니다. 현재 jobs.txt에는 실행해야 하는 374개의 개별 테스트가 있습니다. ${PROGRAM}은 ${JOB}.inp에서 매개변수를 가져와 해당 계산을 수행하는 소프트웨어입니다. ${NCPU}는 각 작업에 사용할 코어 수입니다. 현재 16코어 프로세서에서 각 작업을 직렬로 실행하려고 합니다.

목표는 전체 명령을 입력하지 않고도 필요한 만큼 많은 계산을 대기열에 추가하는 것입니다. 목록 생성을 사용한 find calculations -name '*.inp' -print > jobs.txt다음 스크립트(예: SerialRun.sh 또는 ParallelRun.sh)를 실행하고 결과를 생성하고 싶습니다. 이러한 작업은 다양한 사용자가 작업을 구성하기 위해 선택하는 방식에 따라 다양한 디렉토리에 중첩될 수 있으며, find를 사용하는 이 접근 방식을 통해 작업을 매우 빠르게 제출하고 결과를 올바른 경로에 생성할 수 있습니다. 각 계산이 완료된 후 시스템이 계속 테스트를 실행하는 동안 데이터를 분석할 수 있습니다.

스크립트가 너무 복잡할 수 있습니다. 저는 작업 대기열 시스템을 찾다가 GNU Parallel 프로젝트가 된 nqs를 발견했습니다. 병렬 대기열 작업의 예를 많이 찾을 수 없었지만 GitHub에서 이 스크립트를 발견하고 시도해 보기로 결정했습니다. 나는 그것이 쓰여진 방식에 대해 많은 질문을 가지고 있지만, 나는 그것에 의문을 제기할 만큼 평행성을 잘 이해하지 못합니다.

대기열을 설정하는 것이 이보다 더 간단할 것이라고 생각합니다.

편집 3:

아마도 올바른 방법은 다음과 같습니다.

while read i; do
    command "$i" > "${i%.inp}".log 2> "${i%.inp}".err | parallel -j 16
done < "jobs.txt"

그게 효과가 있을까요?

답변1

이런 복잡한 스크립트가 필요 없고 parallel원하는 것을 스스로 할 수 있습니다. 원하는 .inp다른 도구를 사용하여 파일 목록에서 확장자를 제거 sed하고 다음과 같이 기본 이름을 입력하세요 parallel.

sed 's/\.inp//' jobs.txt | parallel -j 16 "${PROGRAM} {}.inp > {}.log 2> {}.err"

{}기호는 병렬 기본 기능의 일부이며 man parallel아래에 설명되어 있습니다.

{} 입력 줄.

대체 문자열은 입력 소스에서 읽은 전체 줄로 대체됩니다. 입력 소스는 일반적으로 stdin(표준 입력)이지만 , 또는 를 사용하여 지정할 --arg-file수도 :::있습니다 ::::.

따라서 병렬로 전달한 항목으로 대체됩니다. 이 경우 확장자가 sed.

{.}또는 다음을 사용할 수 있습니다 .

{.} 확장자가 없는 입력 라인입니다.

이 대체 문자열은 확장명이 제거된 입력으로 대체됩니다. 입력 줄에 마지막 / 뒤에 .가 포함되어 있으면 문자열 끝까지의 마지막 .가 제거되고 {.}가 나머지 부분으로 대체됩니다. 예를 들어, foo.jpg는 foo가 되고, subdir/foo.jpg는 subdir/foo가 되고, sub.dir/foo.jpg는 sub.dir/foo가 되고, sub.dir/bar는 sub.dir/bar로 유지됩니다. 입력 행에 가 포함되어 있지 않으면 변경되지 않습니다.

교체 문자열 {.}은 --extensionreplace를 사용하여 변경할 수 있습니다.

이를 사용하면 파일이 필요하지 않습니다 jobs.txt. 모든 파일이 동일한 디렉터리에 있으면 다음을 수행할 수 있습니다.

parallel -j 16 "${PROGRAM} {.}.inp > {.}.log 2> {.}.err" ::: *.inp

또는 다음을 사용한다고 가정하여 하위 디렉터리로 재귀적으로 내려오도록 만들 수 있습니다 bash.

shopt -s globstar
parallel -j 16 "${PROGRAM} {.}.inp > {.}.log 2> {.}.err" ::: **/*.inp

관련 정보