Bashファイルのforループの並列化

Bashファイルのforループの並列化

私の考えでは並列化以下のbashスクリプトのforループです。


2つのMatlabスクリプトがあります

1) メイン.M

clear
rng default
P=2;
grid=randn(2,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を2回やりたいです。平行に

  • すべてがノードで実行する必要があります。


これは私のバージョンです並列化なし

1)Main.mとfmをMy_folderというフォルダに保存しました。

2)次のようにbashファイルtd.shを作成し、My_folderフォルダに保存しました。

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


    #$ -N try

    date
    hostname

    export SGE_TASK_ID

    for SGE_TASK_ID in {1..2}
do
    #Output the Task ID
    echo "Task ID is $SGE_TASK_ID"

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

三)ターミナルに行きssh username@A、、、cd /.../My_folder次のように入力します。bash td.sh


並列化のために、このフォーラムの多くの回答では使用をお勧めしますparallel。私はbashファイルが以下のようだと思います。

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


#$ -N try

date
hostname

export SGE_TASK_ID

SGE_TASK_ID={1..2}

echo "$SGE_TASK_ID" | parallel -P 2 /share/.../matlab -nodisplay -nodesktop -nojvm -nosplash -r "main; ID=$SGE_TASK_ID; f; exit"

ただし、これは端末で受信されるエラーです。

A.local
td.sh: line 16: parallel: command not found

parallel私が理解したのは、マシンに「ソフトウェア」がないことです。インストールできますか?それでは、どのようにインストールしますか?それともシステム管理者がインストールする必要がありますか?それとも他の提案がありますかparallel


更新:以下の2番目の答えのスクリプトを実装しようとしています。

#!/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

export SGE_TASK_ID

SGE_TASK_ID={1..2}

echo -e SGE_TASK_ID | xargs -I {} -P 4 /share/.../matlab -nodisplay -nodesktop -nojvm -nosplash  -r "main; ID={}; f; exit"

これは私が受け取ったエラーメッセージです。

Undefined function or variable 'SGE_TASK_ID'.

ベストアンサー1

ループ内でバックグラウンドでMatlab操作を開始し、ループ後に完了するまで待ちます。

for SGE_TASK_ID in 1 2; do
    printf 'Task ID is %d\n' "$SGE_TASK_ID"

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

wait

Matlab ジョブは高速で同時に開始して実行されます。 afterwaitループは、すべてのバックグラウンドジョブが完了する前にスクリプトが終了しないようにします。

ジョブを並列にJ実行できるジョブの場合:N

SGE_TASK_ID=1
n=0
while [ "$SGE_TASK_ID" -le "$J" ]; do
    if [ "$n" -eq "$N" ]; then
        wait  # waits for the N started jobs to finish
        n=0
    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

もう一つのバリエーションは待つことです一つバックグラウンド操作はループのステートメント内で実行され、if0に設定するのではなくwait -n1つだけ減少します。n

おすすめ記事