특정 노드에 병렬화된 작업 제출과 관련하여 다음 문제를 해결하고 싶습니다.
먼저 질문의 구조를 설명하겠습니다.
두 개의 매우 간단한 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.m
My_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.a
을g.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
)에 설치하고 스크립트에서 이를 사용하도록 하는 것이 좋습니다.