MPI 加农算法

加农算法计算矩阵相乘 为了实现方便 只实现了矩阵自乘 而且 实际上各线程都可读取整个矩阵(略去输入和分配中的通信过程)

在各线程相互交换数据的过程中 一定要注意避免死锁

#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define TAG 0

static inline void rtoij(int r,int w,int *i,int *j) {
	//rank to i,j
	*i=r/w;
	*j=r-(*i)*w;
}
static inline void ijtor(int i,int j,int *r,int w) {
	//i,j to rank
	*r=i*w+j;
}
static inline int aj(int i,int j,int w) {
	return (j+i)%w;
}
static inline int bi(int i,int j,int w) {
	//initial b distribute
	return aj(i,j,w);
}
int main(int argc,char *argv[]) {
	float m[][2]={{1,2},
			 {3,4}};//the matrix 
	//multiply by itself
	int self,size;
	MPI_Init(&argc,&argv);
	MPI_Comm_rank(MPI_COMM_WORLD,&self);
	MPI_Comm_size(MPI_COMM_WORLD,&size);
	MPI_Request r;
	MPI_Status s;
	int w=sqrt(size);
	int i,j,an,bn,ap,bp;
	rtoij(self,w,&i,&j);
	ijtor(i,(j+w-1)%w,&an,w);//next a process
	ijtor((i+w-1)%w,j,&bn,w);//next b process
	ijtor(i,(j+1)%w,&ap,w);//previous a process
	ijtor((i+1)%w,j,&bp,w);

	float res,a,b,tmp;
	//initialize data distribution
	a=m[i][aj(i,j,w)];
	b=m[bi(i,j,w)][j];
	res=a*b;

	for(int i=0;i<w-1;++i) {
		MPI_Issend(&a,1,MPI_FLOAT,an,TAG,MPI_COMM_WORLD,&r);//avoid dead lock
		MPI_Recv(&tmp,1,MPI_FLOAT,ap,TAG,MPI_COMM_WORLD,&s);
		a=tmp;
		MPI_Wait(&r,&s);

		MPI_Issend(&b,1,MPI_FLOAT,bn,TAG,MPI_COMM_WORLD,&r);//avoid dead lock
		MPI_Recv(&tmp,1,MPI_FLOAT,bp,TAG,MPI_COMM_WORLD,&s);
		b=tmp;
		MPI_Wait(&r,&s);

		res+=a*b;
	}
	if(0==self) {
		printf("%f",res);
		for(int i=1;i<size;++i) {
			MPI_Recv(&res,1,MPI_FLOAT,i,TAG,MPI_COMM_WORLD,&s);
			printf(" %f",res);
		}
		printf("\n");
	} else {
		MPI_Ssend(&res,1,MPI_FLOAT,0,TAG,MPI_COMM_WORLD);
	}
	MPI_Finalize();
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值