如何使用 MPI 发送整数数组并计算它们的阶乘?
How to send an integer array Using MPI and calculate factorial of them?
考虑进程 0 有一个整数数组,我们应该在其中计算所有的阶乘
数组中的元素。修改程序以将数组发送到计算所有的进程 1
阶乘和 return 要处理 0 的结果。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <mpi.h>
int main (int argc, char ** argv)
{
int rank, size,code,tag=100;
int a[10]={1,2,3,4,5,6,7,8,9,10};
int count,fact = 1,i,j,k;
MPI_Init (&argc, &argv); /* starts MPI */
MPI_Comm_rank (MPI_COMM_WORLD, &rank); /* get current process id */
if (rank == 0) {
for ( i = 0; i < 9; ++i)
{
code=MPI_Send(&a[i],1, MPI_INTEGER,1,tag, MPI_COMM_WORLD);
code=MPI_Recv(&fact,1, MPI_INTEGER,1,tag, MPI_COMM_WORLD,MPI_STATUSES_IGNORE);
printf("Process %d,Result=%d\n",rank,fact);
}
}
else if (rank == 1)
{
for (int j = 0; j < 9; ++j)
{
code=MPI_Recv(&a[j],1, MPI_INTEGER,0,tag, MPI_COMM_WORLD,MPI_STATUSES_IGNORE);
count = j;
for ( k = 0; k < count; ++k)
{
fact = fact*(j+1);
code=MPI_Send(&fact,1, MPI_INTEGER,0,tag, MPI_COMM_WORLD);
}
}
}
MPI_Comm_size (MPI_COMM_WORLD, &size); /* get number of processes */
MPI_Finalize();
return 0;
}
您的代码存在一些问题,即 MPI_INTEGER
不是有效的 MPI C data type(尽管它在 MPI fortran 中有效),MPI_INT
是。此外,您计算阶乘的方式是假设来自 process 0
的元素始终是来自 1 to N
的连续自然数。您不应该这样假设,也不需要单独发送每个元素,而是执行以下操作:
进程 0:
- 用值创建数组以计算它的阶乘;
- 创建一个数组来存储将由
process 1
发送的阶乘;
- 将整个数组(在 1. 中创建)发送到
process 1
;
- 等待(即调用
MPI_recv
)等待来自进程1的结果。
进程 1:
- 创建一个数组来存储将由
process 0
; 发送的值
- 等待(即调用
MPI_recv
)来自process 0
的值;
- 创建一个数组来存储阶乘;
- 计算阶乘;
- 将它们存储在为此目的创建的数组中;
- 将包含阶乘的数组发送到
process 0
。
代码如下所示:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <mpi.h>
int main (int argc, char ** argv){
int rank, size,tag=100;
MPI_Init (&argc, &argv); /* starts MPI */
MPI_Comm_rank (MPI_COMM_WORLD, &rank); /* get current process id */
if (rank == 0)
{
int a[10]={1,2,3,4,5,6,7,8,9,10}; // the array with the values to calculate the factorial
int fact[10] = {0}; // the array to store the results
MPI_Send(a, 10, MPI_INT,1,tag, MPI_COMM_WORLD); // the values
MPI_Recv(fact, 10, MPI_INT,1,tag, MPI_COMM_WORLD,MPI_STATUSES_IGNORE); // wait for the result
for(int i = 0; i < 10; i++) // print the results;
printf("Process %d,Result=%d\n",rank, fact[i]);
}
else if (rank == 1)
{
int a[10] = {0};
int fact[10] = {0};
MPI_Recv(a, 10, MPI_INT,0,tag, MPI_COMM_WORLD,MPI_STATUSES_IGNORE);
for(int i = 0; i < 10; i++){
int f = 1;
for (int k = 1; k <= a[i]; ++k) // Calculate the factorials
f *= k;
fact[i] = f;
}
MPI_Send(fact,10, MPI_INT,0,tag, MPI_COMM_WORLD); // send the factorials to process 0
}
MPI_Comm_size (MPI_COMM_WORLD, &size); /* get number of processes */
MPI_Finalize();
return 0;
}
输入: {1,2,3,4,5,6,7,8,9,10}
输出
Process 0,Result=1
Process 0,Result=2
Process 0,Result=6
Process 0,Result=24
Process 0,Result=120
Process 0,Result=720
Process 0,Result=5040
Process 0,Result=40320
Process 0,Result=362880
Process 0,Result=3628800
考虑进程 0 有一个整数数组,我们应该在其中计算所有的阶乘 数组中的元素。修改程序以将数组发送到计算所有的进程 1 阶乘和 return 要处理 0 的结果。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <mpi.h>
int main (int argc, char ** argv)
{
int rank, size,code,tag=100;
int a[10]={1,2,3,4,5,6,7,8,9,10};
int count,fact = 1,i,j,k;
MPI_Init (&argc, &argv); /* starts MPI */
MPI_Comm_rank (MPI_COMM_WORLD, &rank); /* get current process id */
if (rank == 0) {
for ( i = 0; i < 9; ++i)
{
code=MPI_Send(&a[i],1, MPI_INTEGER,1,tag, MPI_COMM_WORLD);
code=MPI_Recv(&fact,1, MPI_INTEGER,1,tag, MPI_COMM_WORLD,MPI_STATUSES_IGNORE);
printf("Process %d,Result=%d\n",rank,fact);
}
}
else if (rank == 1)
{
for (int j = 0; j < 9; ++j)
{
code=MPI_Recv(&a[j],1, MPI_INTEGER,0,tag, MPI_COMM_WORLD,MPI_STATUSES_IGNORE);
count = j;
for ( k = 0; k < count; ++k)
{
fact = fact*(j+1);
code=MPI_Send(&fact,1, MPI_INTEGER,0,tag, MPI_COMM_WORLD);
}
}
}
MPI_Comm_size (MPI_COMM_WORLD, &size); /* get number of processes */
MPI_Finalize();
return 0;
}
您的代码存在一些问题,即 MPI_INTEGER
不是有效的 MPI C data type(尽管它在 MPI fortran 中有效),MPI_INT
是。此外,您计算阶乘的方式是假设来自 process 0
的元素始终是来自 1 to N
的连续自然数。您不应该这样假设,也不需要单独发送每个元素,而是执行以下操作:
进程 0:
- 用值创建数组以计算它的阶乘;
- 创建一个数组来存储将由
process 1
发送的阶乘; - 将整个数组(在 1. 中创建)发送到
process 1
; - 等待(即调用
MPI_recv
)等待来自进程1的结果。
进程 1:
- 创建一个数组来存储将由
process 0
; 发送的值
- 等待(即调用
MPI_recv
)来自process 0
的值; - 创建一个数组来存储阶乘;
- 计算阶乘;
- 将它们存储在为此目的创建的数组中;
- 将包含阶乘的数组发送到
process 0
。
代码如下所示:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <mpi.h>
int main (int argc, char ** argv){
int rank, size,tag=100;
MPI_Init (&argc, &argv); /* starts MPI */
MPI_Comm_rank (MPI_COMM_WORLD, &rank); /* get current process id */
if (rank == 0)
{
int a[10]={1,2,3,4,5,6,7,8,9,10}; // the array with the values to calculate the factorial
int fact[10] = {0}; // the array to store the results
MPI_Send(a, 10, MPI_INT,1,tag, MPI_COMM_WORLD); // the values
MPI_Recv(fact, 10, MPI_INT,1,tag, MPI_COMM_WORLD,MPI_STATUSES_IGNORE); // wait for the result
for(int i = 0; i < 10; i++) // print the results;
printf("Process %d,Result=%d\n",rank, fact[i]);
}
else if (rank == 1)
{
int a[10] = {0};
int fact[10] = {0};
MPI_Recv(a, 10, MPI_INT,0,tag, MPI_COMM_WORLD,MPI_STATUSES_IGNORE);
for(int i = 0; i < 10; i++){
int f = 1;
for (int k = 1; k <= a[i]; ++k) // Calculate the factorials
f *= k;
fact[i] = f;
}
MPI_Send(fact,10, MPI_INT,0,tag, MPI_COMM_WORLD); // send the factorials to process 0
}
MPI_Comm_size (MPI_COMM_WORLD, &size); /* get number of processes */
MPI_Finalize();
return 0;
}
输入: {1,2,3,4,5,6,7,8,9,10}
输出
Process 0,Result=1
Process 0,Result=2
Process 0,Result=6
Process 0,Result=24
Process 0,Result=120
Process 0,Result=720
Process 0,Result=5040
Process 0,Result=40320
Process 0,Result=362880
Process 0,Result=3628800