我只是想知道如何将以下openMP程序转换为MPI程序
#include <omp.h>
#define CHUNKSIZE 100
#define N 1000
int main (int argc, char *argv[])
{
int i, chunk;
float a[N], b[N], c[N];
/* Some initializations */
for (i=0; i < N; i++)
a[i] = b[i] = i * 1.0;
chunk = CHUNKSIZE;
#pragma omp parallel shared(a,b,c,chunk) private(i)
{
#pragma omp for schedule(dynamic,chunk) nowait
for (i=0; i < N; i++)
c[i] = a[i] + b[i];
} /* end of parallel section */
return 0;
}
我有一个类似的程序,我想在群集上运行,程序正在使用OpenMP。
谢谢!
更新:
在以下玩具代码中,我想限制函数f()中的并行部分:
#include "mpi.h"
#include <stdio.h>
#include <string.h>
void f();
int main(int argc, char **argv)
{
printf("%s\n", "Start running!");
f();
printf("%s\n", "End running!");
return 0;
}
void f()
{
char idstr[32]; char buff[128];
int numprocs; int myid; int i;
MPI_Status stat;
printf("Entering function f().\n");
MPI_Init(NULL, NULL);
MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
MPI_Comm_rank(MPI_COMM_WORLD,&myid);
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 ", myid);
strcat(buff, idstr);
strcat(buff, "reporting for duty\n");
MPI_Send(buff, 128, MPI_CHAR, 0, 0, MPI_COMM_WORLD);
}
MPI_Finalize();
printf("Leaving function f().\n");
}
但是,不期望运行输出。并行部件之前和之后的printf部件已经由每个过程执行,而不仅仅是主过程:
$ mpirun -np 3 ex2
Start running!
Entering function f().
Start running!
Entering function f().
Start running!
Entering function f().
WE have 3 processors
Hello 1 Processor 1 reporting for duty
Hello 2 Processor 2 reporting for duty
Leaving function f().
End running!
Leaving function f().
End running!
Leaving function f().
End running!
所以在我看来,并行部分不限于MPI_Init()和MPI_Finalize()。
答案 0 :(得分:4)
要回答您的更新:
使用MPI时,每个处理器都会运行相同的程序。为了限制并行部分,您需要使用如下语句:
if (rank == 0) { ...serial work... }
这将确保只有一个处理器在此块内完成工作。
您可以在f()
内部发布的示例程序中看到这是如何工作的,还有if(myid == 0)
语句。这个语句块将只由进程0执行,所有其他进程直接发送到else
并接收它们的消息,然后再发送回来。
关于MPI_Init
和MPI_Finalize
- MPI_Init
初始化MPI环境。调用此方法后,您可以使用其他MPI方法,例如Send
和Recv
。完成MPI方法的使用后,MPI_Finalize
将释放资源等,但程序将继续运行。例如,您可以在执行一些需要很长时间的I / O之前调用MPI_Finalize
。这些方法不会划分代码的并行部分,只是在您可以使用其他MPI调用的地方。
希望这有帮助。
答案 1 :(得分:1)
您只需要为每个进程分配一部分数组(a,b,c)。像这样:
#include <mpi.h>
#define N 1000
int main(int argc, char *argv[])
{
int i, myrank, myfirstindex, mylastindex, procnum;
float a[N], b[N], c[N];
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &procnum);
MPI_Comm_rank(comm, &myrank);
/* Dynamic assignment of chunks,
* depending on number of processes
*/
if (myrank == 0)
myfirstindex = 0;
else if (myrank < N % procnum)
myfirstindex = myrank * (N / procnum + 1);
else
myfirstindex = N % procnum + myrank * (N / procnum);
if (myrank == procnum - 1)
mylastindex = N - 1;
else if (myrank < N % procnum)
mylastindex = myfirstindex + N / procnum + 1;
else
mylastindex = myfirstindex + N / procnum;
// Initializations
for(i = myfirstindex; i < mylastindex; i++)
a[i] = b[i] = i * 1.0;
// Computations
for(i = myfirstindex; i < mylastindex; i++)
c[i] = a[i] + b[i];
MPI_Finalize();
}
答案 2 :(得分:1)
您可以尝试使用专有的Intel Cluster OpenMP。它将在群集上运行OpenMP程序。 是的,它使用“软件分布式共享内存”http://en.wikipedia.org/wiki/Distributed_shared_memory
模拟分布式内存集群上的共享内存计算机易于使用并包含在英特尔C ++编译器(9.1+)中。但它仅适用于64位处理器。