4

私はクラスター上でOpenMPIを学んでいます。これが私の最初の例です。出力には異なるノードからの応答が表示されると思いますが、それらはすべて同じノードnode062から応答します。MPIが実際にプロセスをさまざまなノードに分散していることを示すために、さまざまなノードから実際にレポートを取得する理由と方法を知りたいのですが。ありがとう、よろしく!

ex1.c

/* test of MPI */  
#include "mpi.h"  
#include <stdio.h>  
#include <string.h>  

int main(int argc, char **argv)  
{  
char idstr[2232]; char buff[22128];  
char processor_name[MPI_MAX_PROCESSOR_NAME];  
int numprocs; int myid; int i; int namelen;  
MPI_Status stat;  

MPI_Init(&argc,&argv);  
MPI_Comm_size(MPI_COMM_WORLD,&numprocs);  
MPI_Comm_rank(MPI_COMM_WORLD,&myid);  
MPI_Get_processor_name(processor_name, &namelen);  

if(myid == 0)  
{  
  printf("WE have %d processors\n", numprocs);  
  for(i=1;i<numprocs;i++)  
  {  
    sprintf(buff, "Hello %d", i);  
    MPI_Send(buff, 128, MPI_CHAR, i, 0, MPI_COMM_WORLD); }  
    for(i=1;i<numprocs;i++)  
    {  
      MPI_Recv(buff, 128, MPI_CHAR, i, 0, MPI_COMM_WORLD, &stat);  
      printf("%s\n", buff);  
    }  
}  
else  
{   
  MPI_Recv(buff, 128, MPI_CHAR, 0, 0, MPI_COMM_WORLD, &stat);  
  sprintf(idstr, " Processor %d at node %s ", myid, processor_name);  
  strcat(buff, idstr);  
  strcat(buff, "reporting for duty\n");  
  MPI_Send(buff, 128, MPI_CHAR, 0, 0, MPI_COMM_WORLD);  
}  
MPI_Finalize();  

}  

ex1.pbs

#!/bin/sh  
#  
#This is an example script example.sh  
#  
#These commands set up the Grid Environment for your job:  
#PBS -N ex1  
#PBS -l nodes=10:ppn=1,walltime=1:10:00  
#PBS -q dque    

# export OMP_NUM_THREADS=4  

 mpirun -np 10 /home/tim/courses/MPI/examples/ex1  

コンパイルして実行します。

[tim@user1 examples]$ mpicc ./ex1.c -o ex1   
[tim@user1 examples]$ qsub ex1.pbs  
35540.mgt  
[tim@user1 examples]$ nano ex1.o35540  
----------------------------------------  
Begin PBS Prologue Sat Jan 30 21:28:03 EST 2010 1264904883  
Job ID:         35540.mgt  
Username:       tim  
Group:          Brown  
Nodes:          node062 node063 node169 node170 node171 node172 node174 node175  
node176 node177  
End PBS Prologue Sat Jan 30 21:28:03 EST 2010 1264904883  
----------------------------------------  
WE have 10 processors  
Hello 1 Processor 1 at node node062 reporting for duty  
Hello 2 Processor 2 at node node062 reporting for duty        
Hello 3 Processor 3 at node node062 reporting for duty        
Hello 4 Processor 4 at node node062 reporting for duty        
Hello 5 Processor 5 at node node062 reporting for duty        
Hello 6 Processor 6 at node node062 reporting for duty        
Hello 7 Processor 7 at node node062 reporting for duty        
Hello 8 Processor 8 at node node062 reporting for duty        
Hello 9 Processor 9 at node node062 reporting for duty  

----------------------------------------  
Begin PBS Epilogue Sat Jan 30 21:28:11 EST 2010 1264904891  
Job ID:         35540.mgt  
Username:       tim  
Group:          Brown  
Job Name:       ex1  
Session:        15533  
Limits:         neednodes=10:ppn=1,nodes=10:ppn=1,walltime=01:10:00  
Resources:      cput=00:00:00,mem=420kb,vmem=8216kb,walltime=00:00:03  
Queue:          dque  
Account:  
Nodes:  node062 node063 node169 node170 node171 node172 node174 node175 node176  
node177  
Killing leftovers...  

End PBS Epilogue Sat Jan 30 21:28:11 EST 2010 1264904891  
----------------------------------------

アップデート:

単一のPBSスクリプトで複数のバックグラウンドジョブを実行して、ジョブを同時に実行できるようにしたいと思います。たとえば、上記の例では、ex1を実行するための別の呼び出しを追加し、両方の実行をex1.pbsのバックグラウンドに変更しました。

#!/bin/sh  
#  
#This is an example script example.sh  
#  
#These commands set up the Grid Environment for your job:  
#PBS -N ex1  
#PBS -l nodes=10:ppn=1,walltime=1:10:00  
#PBS -q dque 

echo "The first job starts!"  
mpirun -np 5 --machinefile /home/tim/courses/MPI/examples/machinefile /home/tim/courses/MPI/examples/ex1 &  
echo "The first job ends!"  
echo "The second job starts!"  
mpirun -np 5 --machinefile /home/tim/courses/MPI/examples/machinefile /home/tim/courses/MPI/examples/ex1 &  
echo "The second job ends!" 

(1)以前にコンパイルされた実行可能ファイルex1でこのスクリプトをqsubした後、結果は良好です。

The first job starts!  
The first job ends!  
The second job starts!  
The second job ends!  
WE have 5 processors  
WE have 5 processors  
Hello 1 Processor 1 at node node063 reporting for duty        
Hello 2 Processor 2 at node node169 reporting for duty        
Hello 3 Processor 3 at node node170 reporting for duty        
Hello 1 Processor 1 at node node063 reporting for duty        
Hello 4 Processor 4 at node node171 reporting for duty        
Hello 2 Processor 2 at node node169 reporting for duty        
Hello 3 Processor 3 at node node170 reporting for duty        
Hello 4 Processor 4 at node node171 reporting for duty  

(2)ただし、ex1の実行時間は速すぎると思います。おそらく、2つのバックグラウンドジョブの実行時間はあまり重なっていないと思います。これは、実際のプロジェクトに同じ方法を適用した場合には当てはまりません。そこで、ex1.cにsleep(30)を追加して、ex1の実行時間を延長し、ex1をバックグラウンドで実行している2つのジョブがほぼ常に同時に実行されるようにしました。

/* test of MPI */  
#include "mpi.h"  
#include <stdio.h>  
#include <string.h>  
#include <unistd.h>

int main(int argc, char **argv)  
{  
char idstr[2232]; char buff[22128];  
char processor_name[MPI_MAX_PROCESSOR_NAME];  
int numprocs; int myid; int i; int namelen;  
MPI_Status stat;  

MPI_Init(&argc,&argv);  
MPI_Comm_size(MPI_COMM_WORLD,&numprocs);  
MPI_Comm_rank(MPI_COMM_WORLD,&myid);  
MPI_Get_processor_name(processor_name, &namelen);  

if(myid == 0)  
{  
  printf("WE have %d processors\n", numprocs);  
  for(i=1;i<numprocs;i++)  
  {  
    sprintf(buff, "Hello %d", i);  
    MPI_Send(buff, 128, MPI_CHAR, i, 0, MPI_COMM_WORLD); }  
    for(i=1;i<numprocs;i++)  
    {  
      MPI_Recv(buff, 128, MPI_CHAR, i, 0, MPI_COMM_WORLD, &stat);  
      printf("%s\n", buff);  
    }  
}  
else  
{   
  MPI_Recv(buff, 128, MPI_CHAR, 0, 0, MPI_COMM_WORLD, &stat);  
  sprintf(idstr, " Processor %d at node %s ", myid, processor_name);  
  strcat(buff, idstr);  
  strcat(buff, "reporting for duty\n");  
  MPI_Send(buff, 128, MPI_CHAR, 0, 0, MPI_COMM_WORLD);  
}  

sleep(30); // new added to extend the running time
MPI_Finalize();  

}  

しかし、再コンパイルとqsubを再度実行した後、結果は正しくないようです。中止されたプロセスがあります。ex1.o35571:

The first job starts!  
The first job ends!  
The second job starts!  
The second job ends!  
WE have 5 processors  
WE have 5 processors  
Hello 1 Processor 1 at node node063 reporting for duty  
Hello 2 Processor 2 at node node169 reporting for duty  
Hello 3 Processor 3 at node node170 reporting for duty  
Hello 4 Processor 4 at node node171 reporting for duty  
Hello 1 Processor 1 at node node063 reporting for duty  
Hello 2 Processor 2 at node node169 reporting for duty  
Hello 3 Processor 3 at node node170 reporting for duty  
Hello 4 Processor 4 at node node171 reporting for duty  
4 additional processes aborted (not shown)  
4 additional processes aborted (not shown)  

ex1.e35571:

mpirun: killing job...  
mpirun noticed that job rank 0 with PID 25376 on node node062 exited on signal 15 (Terminated).  
mpirun: killing job...  
mpirun noticed that job rank 0 with PID 25377 on node node062 exited on signal 15 (Terminated).  

なぜプロセスが中止されるのだろうか?PBSスクリプトでバックグラウンドジョブを正しくqsubするにはどうすればよいですか?

4

4 に答える 4

3

いくつかのこと:mpichを使用していると仮定して、プロセスを起動する場所をmpiに指示する必要があります。mpiexecヘルプセクションを見て、マシンファイルまたは同等の説明を見つけてください。マシンファイルが提供されていない限り、1つのホストで実行されます

PBSはノードファイルを自動的に作成します。その名前は、PBSコマンドファイルで使用可能なPBS_NODEFILE環境変数に保存されます。次のことを試してください。

mpiexec -machinefile $PBS_NODEFILE ...

mpich2を使用している場合は、mpdbootを使用してmpiランタイムを2回起動します。コマンドの詳細は覚えていません。manページを読む必要があります。シークレットファイルを作成することを忘れないでください。そうしないと、mpdbootが失敗します。

私はあなたの投稿をもう一度読みました、あなたはオープンmpiを使用します、あなたはまだmpiexecコマンドにマシンファイルを提供する必要があります、しかしあなたはmpdbootを台無しにする必要はありません

于 2010-01-31T02:49:50.110 に答える
2

デフォルトでは、PBS(私はトルクを想定しています)はノードを排他モードで割り当てるため、ノードごとに1つのジョブのみが割り当てられます。複数のプロセッサがある場合は少し異なります。CPUごとに1つのプロセスである可能性があります。PBSを変更して、タイムシェアリングモードでnodを割り当てることができます。qmgr.longのマニュアルページをご覧ください。ノードファイルは、リソースが利用可能なときに作成されるため、ノードファイルに重複するノードがない可能性があります。提出。

PBSの目的は、リソース制御、最も一般的には時間、ノード割り当て(自動)です。

PBSファイルのコマンドは順番に実行されます。プロセスをバックグラウンドで配置することはできますが、それはリソース割り当ての目的を損なう可能性がありますが、正確なワークフローはわかりません。PBSスクリプトのバックグラウンドプロセスを使用して、メインプログラムが並行して実行される前に、&を使用してデータをコピーしました。PBSスクリプトは、実際には単なるシェルスクリプトです。

PBSは、スクリプトの内部動作について何も知らないと想定できます。確かに、viaスクリプトで複数のプロセス/スレッドを実行できます。そうする場合、コア/プロセッサをバランスの取れた方法で割り当てるのは、ユーザーとオペレーティングシステムの責任です。マルチスレッドプログラムを使用している場合、最も可能性の高いアプローチは、ノードに対して1つのmpiプロセスを実行してから、OpenMPスレッドを生成することです。

説明が必要な場合はお知らせください

于 2010-01-31T04:36:45.440 に答える
1

診断として、MPI_GET_PROCESSOR_NAMEを呼び出した直後にこれらのステートメントを挿入してみてください。

printf("Hello, world.  I am %d of %d on %s\n", myid, numprocs, name);
fflush(stdout); 

すべてのプロセスが同じノードIDを返す場合は、ジョブ管理システムとクラスターで何が起こっているのかを完全に理解していないことを示唆します-おそらくPBSは(明らかにそうではないと言っているにもかかわらず)10個すべてを入れています1つのノードでプロセスを実行します(ノードに10個のコアがありますか?)。

これによって異なる結果が生成される場合は、コードに問題があることを示唆していますが、私には問題ないように見えます。

于 2010-01-31T03:20:17.960 に答える
0

mpichとは関係のないコードにバグがあり、2つのループでiを再利用しました。

for(i=1;i<numprocs;i++)  
  {  
    sprintf(buff, "Hello %d", i);  
    MPI_Send(buff, 128, MPI_CHAR, i, 0, MPI_COMM_WORLD); }  
    for(i=1;i<numprocs;i++)  

2番目のforループは物事を台無しにします。

于 2011-03-13T10:07:52.570 に答える