使用MPI 计算积分

我们现在使用MPI 来对一个SIN 函数进行定积分求面积的计算。

简单说下定积分,定积分根据将X划分为一个一个的小梯形,将面积球和之后近似于目标面积。

2017-01-22 22-49-57 的屏幕截图

 

如上图所示,我们需要的是使用MPI 将整个图形分解成N 个梯形,其中每一个梯形的面积开一个进程来计算,然后使用MPI 的规约求和函数来计算最终的结果。
#include<stdio.h>
#include<stdlib.h>
#include<mpi.h>
#include<math.h>

const double a = 0.0;
const double b = 3.14;

int n  = 100;

/*计算梯形面积的函数*/
double sum_quer(double a,double b,int n,double h){
    
    double *x = (double *)malloc(sizeof(double) * (n + 1));
    double *f = (double *)malloc(sizeof(double) * (n + 1));
    double inte = (sin(a) + sin(b)) /2;
    for(int i = 0;i < (n+1);i++){
        x[i] = x[i-1] + h;
        f[i] = sin(x[i]);
        inte += f[i];
    }
    inte = inte*h;
    return 0;
}

int main(int argc,char **argv){

    int myid,nprocs;
    int local_n;
    double local_a;
    double local_b;
    double total_inte;

    MPI_Init(&argc,&argv);      /*初始化MPI 系统*/
    MPI_Comm_rank(MPI_COMM_WORLD,&myid); /*设置当前通信子*/
    MPI_Comm_size(MPI_COMM_WORLD,&nprocs);/*设置工作进程个数*/

    local_n = n / nprocs;
    int h = (b - a)/n;
    local_a = a + myid *local_n*h;
    local_b = local_a + local_n * h;

    double local_inte = sum_quer(local_a,local_b,local_n,h);

    MPI_Reduce(&local_inte,&total_inte,1,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD);  /*规约各个计算结果*/

    if(myid == 0){
        
        printf("integral out put is %d",total_inte);
    }
    
    MPI_Finalize();

    return 0;



}
这里还有几个小点需要注意。 关于IO处理。 我们的程序是SPMD 类型的,程序只需要编写一次然后多进程执行罢了,但是如果我们需要输入数据呢?比如使用scanf 来输入数据? 解决方法:给0号进程编写scanf 函数,其他的进程使用 MPI_Send 来接受变量。
#include<stdio.h>
#include<mpi.h>


void get_data(){

    int my_rank;
    int comm_zz;
    double *a;
    double *b;
    int    *n;
    int  dest;

    if(my_rank == 0){   /*如果是0号进程就接受并发送数据*/
        scanf("%lf %lf %d",a,b,n);
        for(dest = 0;dest < comm_zz;dest++){
            MPI_Send(a,1,MPI_DOUBLE,dest,0,MPI_COMM_WORLD);
            MPI_Send(b,1,MPI_DOUBLE,dest,0,MPI_COMM_WORLD);
            MPI_Send(n,1,MPI_INT,dest,0,MPI_COMM_WORLD);
        }
    }else{            /*其他进程接受参数*/
        MPI_Recv(a,1,MPI_DOUBLE,0,0,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
        MPI_Recv(b,1,MPI_DOUBLE,0,0,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
        MPI_Recv(n,1,MPI_INT,0,0,MPI_COMM_WORLD,MPI_STATUS_IGNORE);

    }


}
MPI_Reduce 2017-01-24 14-07-33 的屏幕截图 全局规约函数,很简单,最核心的是第五个参数操作符参数,根据不同的参数我们可以实现不同的功能。 MPI 中定义的规约操作符 MPI_MAX               最大值 MPI_MIN                最小值 MPI_SUM               累加和 MPI_PROD            累乘积 MPI_LAND            逻辑与 MPI_BAND            按位于 MPI_LOR               逻辑或 MPI_BOR               按位或 MPI_LXOR            逻辑异或 MPI_BXOR            按位异或 MPI_MAXLOC      求最大值和位置 MPI_MINLOC       求最小值和位置   集和通信与点对点通信 1.在通信子中的所有进程都必须调用相同的集和通信函数 2.每个进程传递给MPI集合通信函数的参数必须是相融的 3.参数output_data_p 只用在dest_process 上。 4.点对点通信函数是通过标签和通信子来匹配的。集合通信函数不使用标签,只通过通信子和调用顺序来进行匹配。

查看原文:http://zmrlinux.com/2017/01/24/%e4%bd%bf%e7%94%a8mpi-%e8%ae%a1%e7%ae%97%e7%a7%af%e5%88%86/
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值