-
24-09-2019 - |
题
我的群集上学习的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)的结果是后的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).
我不知道为什么有进程中止?我怎样才能正确地qsub命令后台作业在PBS脚本?
解决方案
两件事情: 你需要告诉MPI在哪里发射过程, 假设你使用的MPICH,看看mpiexec的帮助部分,找到机文件或同等描述。除非提供机文件,它将一个主机上运行
PBS自动创建的节点文件中。它的名字被储存在PBS命令文件中提供PBS_NODEFILE环境变量。尝试以下方法:
mpiexec -machinefile $PBS_NODEFILE ...
如果您使用的MPICH2,你有两个引导使用mpdboot您的MPI运行。我不记得命令的详细信息,你必须阅读手册页。请记住,否则会造成机密文件mpdboot将失败。
我再次看了你的帖子,你会使用开放MPI,你还必须提供机文件mpiexec的命令,但你不必惹mpdboot
其他提示
默认情况下PBS(我假定转矩)以独占模式分配节点,以便每个节点只有一个工作。这是一个有点不同的,如果你有多个处理器,每个CPU最有可能的一个过程。 PBS是可以改变的,以分时方式分配点头,看看qmgr.long长话短说的man页面,则很可能不会有重叠的节点文件中的节点,因为节点文件时资源可用,而不是在创建时间提交。
PBS的目的是资源控制,最常见的时间,节点分配(自动)。
在PBS文件命令依次执行。你可以把过程中的背景,但可能是击败资源配置的目的,但我不知道您的具体工作流程。我用在PBS中的脚本的后台进程数据主程序运行之前并联使用和复制。 PBS脚本实际上只是一个外壳脚本。
您可以假设PBS不知道了你的脚本内部运行任何东西。您可以通过script.if你这样做肯定是运行在多进程/线程,这是给你和你的操作系统分配的核心/处理器,均衡的方式。如果你是在多线程程序中,最有可能的做法是运行一个MPI进程的节点,然后产卵OpenMP的线程。
让我知道你是否需要澄清
作为诊断,尝试呼叫到MPI_GET_PROCESSOR_NAME后立即插入这些语句。
printf("Hello, world. I am %d of %d on %s\n", myid, numprocs, name);
fflush(stdout);
如果所有进程返回相同的节点ID到,它会建议我说,你不太明白是怎么回事的作业管理系统和集群 - 也许是PBS(尽管你显然是告诉它,否则)将所有10个进程在一个节点上(你有10个核心中的节点?)。
如果这会产生不同的结果,这表明我的东西你的代码错误,虽然它看起来不错我。
有是在你的代码无关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循环意愿搞乱了。