使用集合通信实现向量的加法

本文介绍了如何使用MPI的Scatter和Gather操作实现分布式环境下向量的加法。首先,0号进程读取向量并分散给其他进程,每个进程进行局部求和,最后通过Gather操作将结果汇聚到0号进程并输出。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目的:对向量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];
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值