《并行程序设计导论》06mpi思维改变

下面的程序不能执行,我只是在编译器里面写的笔记,但是思路是对的

#include<mpi.h>
#include<stdio.h>
double f(double x)
{
   return 2*x+2.3;
}
double trap(double left_endpt,double right_endpt,int trap_count,double base_len)
{
   double estimate,x;
   int i;
   estimate=(f(left_endpt)+f(right_endpt))/2.0;
   for(i=1;i<=trap_count-1;i++)
   {
      x=left_endpt+i*base_len;
      estimate+=f(x);
   }
   estimate*=base_len;
   return estimate;
}
/*大部分MPI实现只允许0号进程访问标准输入,
所以这里我们用0号进程来实现数据的输入,(优化)使用集合通信
首先是最直接的,然后再用集合通信里的广播函数MPI_Bcast函数
*/
void get_input1(int my_rank,int comm_sz,double* a,double* b,int* n)
{
   int dest;
   if(my_rank==0)
   {
      printf("please input a,b,n");
      scanf("%f%f%d",a,b,n);
      for(dest=1;dest<comm_sz;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_Recv(b,1,MPI_DOUBLE,0,0,MPI_COMM_WORLD);
      MPI_Recv(n,1,MPI_INT,0,0,MPI_COMM_WORLD);
   }
   
}

void get_input2(int my_rank,int comm_sz,double* a,double* b,int* n)
{
   int dest;
   if(my_rank==0)
   {
      printf("please input a,b,n");
      scanf("%f%f%n",a,b,n);
   }
   MPI_Bcast(a,1,MPI_DOUBLE,0,MPI_COMM_WORLD);
      MPI_Bcast(b,1,MPI_DOUBLE,0,MPI_COMM_WORLD);
      MPI_Bcast(n,1,MPI_INT,0,MPI_COMM_WORLD);
}
void build_mpi_type(double* a,double* b,int* n,MPI_Datatype* input_mpi_t_p)
{
   int array_of_blocklength[3]={1,1,1};
   MPI_Datatype array_of_types[3]={MPI_DOUBLE,MPI_DOUBLE,MPI_INT};
   MPI_Aint array_of_displacements[3]={0};
   MPI_Aint a_addr,b_addr,n_addr;
   MPI_Get_address(&a,&a_addr);
   MPI_Get_address(&b,&b_addr);
   array_of_displacements[1]=b_addr-a_addr;
   MPI_Get_address(&n,&n_addr);
   array_of_displacements[2]=n_addr-a_addr;
   MPI_Type_create_struct(3,array_of_blocklength,array_of_displacements,array_of_types,input_mpi_t_p);
   MPI_Type_commit(input_mpi_t_p);//在使用通信函数input_mpi_t之前,必须先用一个函数调用去指定他
   //上述函数允许MPI实现为了在通信函数内使用这一数据类型,优化数据类型的内部表达
}
void get_input3(int my_rank,int comm_sz,double* a,double* b,int* n)
{
   MPI_Datatype input_mpi_t;
   build_mpi_type(a,b,n,,&input_mpi_t);
   if(my_rank==0)
   {
      printf("please input a,b,n");
      scanf("%f%f%d",a,b,n);
   }
   MPI_Bcast(a,1,input_mpi_t,0,MPI_COMM_WORLD);
   MPI_Type_free(&input_mpi_t);
   //在构造新的数据类型时,mpi可能要再内部分配额外的空间,因此当我们使用新的数据类型时可以调用一个函数去释放额外的存储空间
}



int main(void)
{
   int my_rank,comm_sz,n=1024,local_n;
   
	double a=0.0,b=3.0,h,local_a,local_b;
	double local_int,total_int;
	int source;
	MPI_Init(NULL,NULL);//通信子初始化
	MPI_Comm_rank(MPI_COMM_WORLD,&my_rank);
	MPI_Comm_size(MPI_COMM_WORLD,&comm_sz);
   get_input1(my_rank,comm_sz,&a,&b,&n);
   //输入函数有三种写法
	h=(b-a)/n;
	local_n=n/comm_sz;
	local_a=a+my_rank*local_n*h;
	local_b=local_a+local_n*h;
	local_int=trap(local_a,local_b,local_n,h);
   /*if(my_rank!=0)
   {
      MPI_Send(&local_int,1,MPI_DOUBLE,0,0,MPI_COMM_WORLD);

   }
   else
   {
      total_int=local_int;//0号进程自身的面积
      for(source=1;source<comm_sz;source++)
      {
         MPI_Recv(&local_int,1,MPI_DOUBLE,sorce,0,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
         total+=local_int;
      }
   }*/
   //使用集合函数可以写成
   MPI_Reduce(&local_int,&total_int,1,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD);
   if(my_rank==0)
   {
      printf("在划分%d个小梯形,边界为%lf和%lf,我们预测的面积为%f",n,a,b,total_int);

   }
   MPI_Finalize();
   return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值