参考书籍: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.结果:

0
Posted in 算法设计与分析

Leave a Comment:

电子邮件地址不会被公开。