1

Pythonスクリプトを使用して、研究所のクラスターにジョブを送信しようとしています。

 compile_cmd = 'ifort -openmp ran_numbers.f90 ' + fname \
                  + ' ompscmf.f90 -o scmf.o'
 subprocess.Popen(compile_cmd, shell=True)

 Popen('qsub launcher',shell=True)

問題は、システムがこの時点でハングしていることです。上記のスクリプトに明らかな誤りはありますか? コードで言及されているすべてのファイルは、そのディレクトリで利用できます(クロスチェックしました)。qsubは、ジョブをクラスターに送信するために使用されるコマンドです。fnameは、その過程で作成したファイルの名前です。

4

2 に答える 2

6

qsub を使用してクラスターに複数のジョブを送信するために使用したスクリプトがあります。qsub は通常、ジョブの送信を次の形式で受け取ります。

qsub [qsub options] job

私の仕事では、ジョブは通常、各ノードで実行されるプログラムまたはコードを実際に呼び出す bash (.sh) または python スクリプト (.py) です。「test_job.sh」というジョブを最大ウォールタイムで送信したい場合は、

qsub -l walltime=72:00:00 test_job.sh

これは、次の python コードになります。

from subprocess import call

qsub_call = "qsub -l walltime=72:00:00 %s"
call(qsub_call % "test_job.sh", shell=True)

あるいは、次のような bash スクリプトがあるとしたらどうでしょうか。

#!/bin/bash

filename="your_filename_here"
ifort -openmp ran_numbers.f90 $filename ompscmf.f90 -o scmf.o

その後、これを送信しましたqsub job.shか?


編集:正直なところ、最適なジョブ キューイング スキームはクラスターごとに異なります。ジョブ送信スクリプトを簡素化する簡単な方法の 1 つは、各ノードで使用可能な CPU の数を調べることです。最近のキューイング システムの中には、多数の単一 CPU ジョブを送信できるものもあり、それらはできるだけ少ないノードでこれらをまとめて送信します。ただし、一部の古いクラスターではそれができず、多くの個別のジョブを送信することは嫌われています。

クラスター内の各ノードに 8 個の CPU があるとします。次のようなスクリプトを書くことができます

#!/bin/bash
#PBS -l nodes=1;ppn=8

for ((i=0; i<8; i++))
do
    ./myjob.sh filename_${i} &
done
wait

これが行うことは、1 つのノードで 8 つのジョブを一度に送信し (&バックグラウンドで実行することを意味します)、8 つのジョブすべてが完了するまで待機することです。これは、ノードごとに多数の CPU を持つクラスターに最適な場合があります (たとえば、私が使用した 1 つのクラスターにはノードごとに 48 個の CPU があります)。

または、多くの単一コア ジョブを送信することが最適であり、上記の送信コードが機能しない場合は、python を使用して bash スクリプトを生成し、qsub に渡すことができます。

#!/usr/bin/env python
import os
from subprocess import call

bash_lines = ['#!/bin/bash\n', '#PBS -l nodes=1;ppn=1\n']
bash_name = 'myjob_%i.sh'
job_call = 'ifort -openmp ran_numbers.f90 %s ompscmf.f90 -o scmf.o &\n'
qsub_call = 'qsub myjob_%i.sh'

filenames = [os.path.join(root, f) for root, _, files in os.walk(directory)
                                   for f in files if f.endswith('.txt')]
for i, filename in enumerate(filenames):
    with open(bash_name%i, 'w') as bash_file:
        bash_file.writelines(bash_lines + [job_call%filename, 'wait\n'])
    call(qsub_call%i, shell=True)
于 2013-10-17T16:28:25.503 に答える