目的:对向量x,y求和得到z并输出
x,y的分量个数为n
comm_sz:进程数目
my_rank:进程编号
MPI_Comm:表示通信子,所有的操作必须同一个通信子中完成
local_n:每个进程操作的分量数目
基本步骤
先利用 Read_vector()读取数据并从0号进程发送给其他进程。MPI提供了MPI_Scatter()函数,可以实现0号进程读入整个向量,将分量按照块划分的方式发送给其他进程。
然后每个进程使用mpi_Vector_sum()对接收到的local_x,local_y求和得到local_z
最后使用 Print_vector()将结果输出。MPI提供了MPI_Gather()函数,将向量的所有分量收集到0号进程上,然后0号进程将所有分量都打印出来
具体代码
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#读取
void Read_vector(double local_a[],int local_n,int n,char vec_name[],int my_rank,MPI_Comm comm);
#输出
void Print_vector(double local_b[],int local_n,int n,char title[],int my_rank,MPI_Comm comm);
#求和
void mpi_Vector_sum(double local_x[],double local_y[],double local_z[],int local_n);
#主函数
int main(void){
int n,local_n;
double *local_x,*local_y,*local_z;
int comm_sz,my_rank;
n=6;
#开启并行环境
MPI_Init(NULL,NULL);
MPI_Comm_size(MPI_COMM_WORLD,&comm_sz);
MPI_Comm_rank(MPI_COMM_WORLD,&my_rank);
local_n=n/comm_sz; #必须整除。
#给每个进程执行的数据开辟空间
local_x=malloc(local_n*sizeof(double));
local_y=malloc(local_n*sizeof(double));
local_z=malloc(local_n*sizeof(double));
#读取x,y
Read_vector(local_x,local_n,n,"x",my_rank,MPI_COMM_WORLD);
Read_vector(local_y,local_n,n,"y",my_rank,MPI_COMM_WORLD);
#对x,y求和
mpi_Vector_sum(local_x,local_y,local_z,local_n);
#打印向量
Print_vector(local_z,local_n,n,"The sum is",my_rank,MPI_COMM_WORLD);
#释放空间
free(local_x);
free(local_y);
free(local_z);
MPI_Finalize();
return 0;
}
0号进程读取数据保存到a中,然后通过MPI_Scatter()散射给其他进程
void Read_vector(
double local_a[],
int local_n,
int n,
char vec_name[],
int my_rank,
MPI_Comm comm){
int i;
double *a=NULL;
if(my_rank==0){
a=malloc(n*sizeof(double));
printf("Enter the vector %s\n",vec_name);
for (i=0;i<n;i++)
scanf("%lf",&a[i]);
#前3个参数表示发送缓存区的信息,第3-6参数表示接收缓存区的信息,0表示发送消息源进程为0,comm表示通信字
MPI_Scatter(a,local_n,MPI_DOUBLE,local_a,local_n,MPI_DOUBLE,0,comm);
free(a);
}else{
MPI_Scatter(a,local_n,MPI_DOUBLE,local_a,local_n,MPI_DOUBLE,0,comm);
}
}
0号进程利用 MPI_Gathe()负责接收,一共接受local_n个,存到b里边,然后打印
void Print_vector(double local_b[],int local_n,int n,char title[],int my_rank,MPI_Comm comm){
int i;
double *b=NULL;
if(my_rank==0){
b=malloc(n*sizeof(double));
MPI_Gather(local_b,local_n,MPI_DOUBLE,b,local_n,MPI_DOUBLE,0,comm);
printf("%s\n",title);
for(i=0;i<n;i++)
printf("%f ",b[i]);
printf("\n");
free(b);
}else{
MPI_Gather(local_b,local_n,MPI_DOUBLE,b,local_n,MPI_DOUBLE,0,comm);
}
}
求和函数
void mpi_Vector_sum(double local_x[],double local_y[],double local_z[],int local_n){
int i;
for (i=0;i<local_n;i++)
local_z[i]=local_x[i]+local_y[i];
}