使用MPI程序来计算杨辉三角

♥,.*,.♥,.*,.♥,.*,.♥,.*♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥♥,.*,.♥,.*,.♥,.*,.♥,.*♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥

参考书籍:mpi并行程序设计(都志辉)

MPI程序设计题目:使用MPI程序编写计算杨辉三角

1.设计思路:对于杨辉三角的每一行,采用并行计算的方式计算每个数据。

在杨辉三角中,有如下规律:nums[i][j]=nums[i-1][j-1]+nums[i-1][j](i,j>0)

因此,对于打印N行杨辉三角,可以使用1个主机和N-1个从机(第1列都为1可以不使用从机进行计算)。主机负责将nums[i-1][j-1],nums[i-1][j]这两个数据发给进程号为j的从机。从机将数据进行运算后发给主机。主机对发送的数据和接收的数据进行统计。对于主机,当一行数据接收完毕时,如果需要继续计算,则继续给从机发送数据;若不需要再进行计算,则将一个特定的标识符发给每个从机,从机接收到标识符后进程结束。

2.代码:

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

// 8 行 杨辉三角
#define N 8
int main(int argc,char **argv){
	int nums[N][N]={0};       //杨辉三角的存储数组  
	MPI_Comm comm=MPI_COMM_WORLD;   
	MPI_Status status;
	int send_buff[2]={0};       //主机(进程0)发送数据给从机
	int recv_buff[2]={0};       //从机接收主机的数据

	int ans=0;                 //主机接收从机处理过的数据
	int send,recv;              //统计主机发送了send个数据,接收了recv个数据
	int rank;  //进程号
	int tag;   //标识符  
	MPI_Init(&argc,&argv);
	MPI_Comm_rank(comm,&rank);

	int i,j;
	if(rank==0)
	{
		//printf("rank=0\n");
		//初始化
		for(i=0;i<N;i++) nums[i][0]=1;
		send=0;
		recv=0;
		printf("1\n");         
       for(i=1;i<N;i++)
		{
			//printf("i=%d",i);
			for(j=1;j<N;j++)
			{
				//printf("j=%d\n",j);
				send_buff[0]=nums[i-1][j-1];
				send_buff[1]=nums[i-1][j];
				MPI_Send(send_buff,2,MPI_INT,j,0,comm);          //发送数据给从机(进程j)
				send=send+1;
				//printf("send=%d\n",send);
			}
			for(j=1;j<N;j++)
			{
				MPI_Recv(&ans,1,MPI_INT,j,2,comm,&status);       //接收从机处理的数据
				recv=recv+1;
				//printf("recv=%d\n",recv);
				//printf("ans=%d\n",ans);
				nums[i][j]=ans;	
			}
			for(j=0;j<=i;j++)
			{
				//打印杨辉三角
				printf("%d ",nums[i][j]);
				//MPI_Send(send_buff,2,MPI_INT,j,3,comm);

			}
			printf("\n");

		}

		if(i==N)
		{
			for(j=0;j<N;j++)
			{
              //从机停止运行
				MPI_Send(send_buff,2,MPI_INT,j,3,comm);
			}
		}
	}
	else
	{

		while(1)
		{
			//printf("rank=1\n");
			MPI_Recv(recv_buff,2,MPI_INT,0,MPI_ANY_TAG,comm,&status);//接收主机的数据
			tag=status.MPI_TAG;
			//printf("tag=%d\n",tag);
           //接收到标识符为3时,停止运行
			if(tag==3) break;
			ans=recv_buff[0]+recv_buff[1];
			//printf("recv: ans=%d\n",ans);
			MPI_Send(&ans,1,MPI_INT,0,2,comm);                      //发送数据给主机
		}

	}
	MPI_Finalize();
	return 0;
}

3.结果:


♥,.*,.♥,.*,.♥,.*,.♥,.*♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥♥,.*,.♥,.*,.♥,.*,.♥,.*♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥

广告时间:

本宝宝开通了一个公众号,记录日常的深度学习和强化学习笔记。

希望大家可以共同进步,嘻嘻嘻!求关注,爱你呦!

KeepYourAims

发布了125 篇原创文章 · 获赞 126 · 访问量 19万+

猜你喜欢

转载自blog.csdn.net/Valieli/article/details/103530933