2010-01-31 92 views
4

我正在学习集群上的OpenMPI。这是我的第一个例子。我期望输出将显示来自不同节点的响应,但它们都从同一节点node062响应。我只是想知道为什么以及如何从不同的节点获得报告来显示MPI实际上是将流程分发到不同的节点?感谢致敬!在集群上测试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 

编译和运行:

[[email protected] examples]$ mpicc ./ex1.c -o ex1 
[[email protected] examples]$ qsub ex1.pbs 
35540.mgt 
[[email protected] 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 
---------------------------------------- 

UPDATE:

我想在一个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)的结果是这个脚本的qsub后细与先前编译的可执行EX1背景。

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的运行时间太快,可能这两个后台作业没有太多的运行时间重叠,当我以同样的方式适用于我的实际是不是这样的项目。于是我将睡眠(30)添加到ex1.c中,以延长ex1的运行时间,这样两个在后台运行ex1的作业几乎可以同时运行。

/* 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脚本中正确地背景作业?

回答

3

几件事情: 您需要告诉mpi在哪里启动进程, 假设您使用的是mpich,查看mpiexec的帮助部分并查找机器文件或等效描述。除非提供机器文件,否则它将在一台主机上运行

PBS自动创建节点文件。其名称存储在PBS命令文件中可用的PBS_NODEFILE环境变量中。请尝试以下操作:

mpiexec -machinefile $PBS_NODEFILE ... 

如果你正在使用MPICH2,你使用mpdboot有两个启动你的MPI运行。我不记得命令的细节,你将不得不阅读手册页。请记住创建秘密文件,否则mpdboot将失败。

我再次看了你的帖子,你会使用开放MPI,你还必须提供机文件mpiexec的命令,但你不必惹mpdboot

+0

非常感谢!这解决了我的问题。如果其他人为自己保留了一些节点,或者某些节点正在运行其他作业,那么mpiexec会提供$ PBS_NODEFILE作为机器文件通知?你也可以尝试回答我在http://superuser.com/questions/102812/torch-in-cluster上发布的关于在集群上使用PBS的问题吗?提前致谢! – Tim 2010-01-31 03:46:52

1

作诊断,请尝试将这些语句后立即您致电MPI_GET_PROCESSOR_NAME。

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

如果所有进程返回相同的节点ID到,它会建议我说,你不太明白是怎么回事的作业管理系统和集群 - 也许是PBS(尽管你显然告诉它否则)将所有10个进程放在一个节点上(节点中是否有10个内核?)。

如果这样做会产生不同的结果,那就表明我的代码有问题,尽管对我来说看起来没问题。

+0

谢谢马克。我对PBS也不熟悉,现在也在学习它。如果可能,你可以尝试在http://superuser.com/questions/102812/torch-in-cluster上回答关于PBS/Torch的问题吗? – Tim 2010-01-31 03:49:06

+0

对不起蒂姆,我是一个Grid Engine用户,只有PBS的知识。 – 2010-01-31 03:52:32

2

默认情况下,PBS(我假设扭矩)以独占模式分配节点,以便每个节点只有一个作业。如果你有多个处理器,最有可能每个CPU有一个进程,这有点不同。可以改变PBS以分时方式分配点头,查看qmgr.long故事的手册页,很可能在节点文件中不会有重叠节点,因为节点文件是在资源可用时创建的,而不是在提交。

PBS的用途是资源控制,最常见的是时间节点分配(自动)。

PBS文件中的命令按顺序执行。您可以将流程置于后台,但这可能会破坏资源分配的目的,但我不知道您的确切工作流程。我使用PBS脚本中的后台进程在主程序并行运行之前复制数据,使用&。 PBS脚本实际上只是一个shell脚本。

你可以假设PBS不知道你的脚本内部工作情况。您当然可以在通过脚本中运行多个进程/线程。如果您这样做了,那么由您和您的操作系统来平衡分配核心/处理器就足够了。如果您使用多线程程序,最可能的方法是运行一个mpi进程,然后产生OpenMP线程。

让我知道你是否需要澄清

+0

再次感谢!在我的真实项目中,我想在一个PBS脚本中多次运行可执行文件,并且全部都在后台运行。但是,当我在上面给出的简单示例中尝试这种方法时,有一些进程被中止。请参阅我对原文的更新。如何在PBS脚本中运行后台作业?提前致谢! – Tim 2010-01-31 05:58:56

+0

@Tim 很难说,看起来像mpi工作正在被外部终止。您在PBS脚本中分配了多少时间,这是我的第一个猜测 – Anycorn 2010-01-31 06:22:30

+0

walltime设置为1:10:00。我认为这足以让人睡觉(30)。你看到在PBS脚本中指定背景作业有什么错误吗? – Tim 2010-01-31 06:36:10

0

有一个在你的代码无关MPICH的错误,您重复我在你的两个循环。

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++) 

第二个for循环会搞砸了。