wait -n의 대안(서버에 이전 버전의 bash가 있기 때문에)

wait -n의 대안(서버에 이전 버전의 bash가 있기 때문에)

특정 노드에 병렬화된 작업 제출과 관련하여 다음 문제를 해결하고 싶습니다.


먼저 질문의 구조를 설명하겠습니다.

두 개의 매우 간단한 Matlab 스크립트가 있습니다

1) 메인.엠

clear
rng default
P=2;
grid=randn(4,3);
jobs=1;

2) FM

sgetasknum_grid=grid(jobs*(str2double(getenv('SGE_TASK_ID'))-1)+1: str2double(getenv('SGE_TASK_ID'))*jobs,:); %jobsx3

result=sgetasknum_grid+1; 

filename = sprintf('result.%d.mat', ID);
save(filename, 'result')

exit

내가 하고 싶은 일은:

  • main.m을 실행하세요.

  • 그럼 FM을 실행해 보세요4 번, 병렬 실행 가능매번 2개의 작업

  • 모든 것이 노드에서 실행되어야 합니다.


위의 단계를 구현한 방법은 다음과 같습니다.

1)저는 이라는 폴더에 main.m저장했어요f.mMy_folder

2)td.sh아래와 같이 스크립트를 작성하여 폴더에 저장했습니다.My_folder

#!/bin/bash -l
#$ -S /bin/bash
#$ -l h_vmem=5G
#$ -l tmem=5G
#$ -l h_rt=480:0:0
#$ -cwd
#$ -j y


#$ -N try

date
hostname

J=4 #number tasks

N=2 #number tasks executed in parallel

export SGE_TASK_ID


SGE_TASK_ID=1
n=0
while [ "$SGE_TASK_ID" -le "$J" ]; do
    if [ "$n" -eq "$N" ]; then
        wait -n  # as soon as one task is done, refill it with another
        n=$(( n - 1 ))
    fi

    printf 'Task ID is %d\n' "$SGE_TASK_ID"

    /share/.../matlab -nodisplay -nodesktop -nojvm -nosplash -r "main; ID=$SGE_TASK_ID; f; exit" &

    SGE_TASK_ID=$(( SGE_TASK_ID + 1 ))
    n=$(( n + 1 ))
done

wait

삼)터미널에 가서 ssh username@A, cd /.../My_folder, 다음을 입력합니다.bash td.sh


질문:다음 오류가 발생합니다.

td.sh: line 26: wait: -n: invalid option
wait: usage: wait [id]

아래 설명에서 알 수 있듯이 문제는 @A의 bash 버전이 오래되었고(4.3의 wait 내장에 -n 옵션이 추가됨) 시스템 관리자가 이를 업데이트할 수 없다는 것입니다. 최신 버전은 아마도 bash 4.1일 것입니다.

그렇다면 대안을 제안해주실 수 있나요 wait -n?

답변1

작성한 스크립트는 gnu 병렬을 사용하거나 -j 옵션을 사용하여 수행하는 것이 더 나을 수 있습니다. 또는 Python(또는 다른 언어)으로 다시 작성할 수 있습니다.

보고 있다

  • parallel: bash에서 사용하기 위한 도구입니다(세 가지 중 가장 배우기 쉽고 한 가지 작업만 수행합니다).
  • make: 좀 더 발전해서 자신만의 언어가 있습니다. 파일을 생성하는데 사용됩니다. 예를 들어, A.b필요한 것을 얻으려면 A.ag.f(를) 수행하십시오 z;y;z. A.a합계를 계산하는 방법에 대한 규칙을 추가할 수도 있습니다 g.f. 무엇이 무엇에 의존하는지 파악하고 올바른 순서로 구축합니다. 가능하다면 (요청하는 경우) 작업을 병렬로 수행합니다.
  • python: 스크립트가 원하는 작업을 수행하는 프로그래밍 언어로, MATLAB이 수행하는 작업을 수행합니다.

또한 무엇이 설치되어 있거나 설치될 수 있는지 고려해야 합니다. 이렇게 하면 다음 사항을 알 수 있습니다.

type parallel
type make
type python

참고: type이것은 타이핑 지침이 아닙니다. 입력하신 명령어입니다. 각 명령의 유형(위치)을 알려줍니다.

답변2

while 루프에서 wait를 전혀 사용하지 않는 것은 어떻습니까?

while [ "$SGE_TASK_ID" -le "$J" ]; do

    # grep count of matlab processes out of list of user processes
    n = $(ps ux | grep -c "matlab")

    ##  if [ "$n" -le "$N" ]; then
    if [ "$n" -eq "$N" ]; then
        # sleep 1 sec if already max processes started
        sleep 1
        ##  wait -n  # as soon as one task is done, refill it with another
        ##  n=$(( n - 1 ))
    else
        # start another process
        printf 'Task ID is %d\n' "$SGE_TASK_ID"

        /share/.../matlab -nodisplay -nodesktop -nojvm -nosplash -r "main; ID=$SGE_TASK_ID; f; exit" &

        SGE_TASK_ID=$(( SGE_TASK_ID + 1 ))

    fi
    ##  n=$(( n + 1 ))
done

물론, grep의 문자열은 실행 중인 항목에 따라 다를 수 있습니다(예: f.m좀 더 특별한 이름을 지정하고 grep을 지정합니다.)

답변3

귀하의 셸 스크립트는 셸 스크립트 없이도 즉시 여러 작업을 병렬로 실행하도록 지원하는 분산 리소스 관리자(아마도 그리드 엔진)용으로 작성된 것처럼 의심스럽습니다. 이러한 기능을 사용하지 않는 이유는 무엇입니까?

qsub -t 1-4 ./script.sh

그런 다음 SGE_TASK_ID 값을 수정하는 모든 행을 삭제하십시오. GridEngine이 이를 설정합니다.

#$-t 1-4( 물론 원하는 경우 한 줄을 사용하여 스크립트에서 옵션을 설정할 수도 있습니다 ...)

답변4

직접 설치할 수 있습니다.

대부분의 소프트웨어의 경우 루트 권한이 필요한 설치 프로세스의 유일한 부분은 파일을 표준 위치에 복사하는 것입니다. (장치 드라이버, 커널, 가상 머신 등의 경우에는 그렇지 않습니다.)

Bash를 홈 디렉터리( ~/bin)에 설치하고 스크립트에서 이를 사용하도록 하는 것이 좋습니다.

관련 정보