MPI Collective Communications

int MPI_Address(void * location, MPI_Aint * address)
  得到给定位置在内存中的地址,将被废弃的函数,建议用MPI_Get_address取代

int MPI_Allgather(void * sendbuff, int sendcount, MPI_Datatype sendtype, void * recvbuf, int * recvcounts, int * displs, MPI_Datatype recvtype, MPI_Comm comm)
  每一进程都从所有其它进程收集数据,相当于所有进程都执行了一个MPI_Gather调用。

int MPI_Allgatherv(void * sendbuff, int sendcount, MPI_Datatype sendtype, void * recvbuf, int recvcounts, int * displs, MPI_Datatype recvtype, MPI_Comm comm)
  所有进程都收集数据到指定的位置,就如同每一个进程都执行了一个MPI_Gatherv调用

int MPI_Allreduce(void * sendbuf, void * recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
  归约所有进程的计算结果,并将最终的结果传递给所有其它的进程,相当于每一个进程都执行了一次MPI_Reduce调用。

int MPI_Alltoall(void * sendbuf, void * recvbuf, int count, MPI_Datatype datatype, void * recvbuf, int * recvcounts, int * rdispls, MPI_Datatype recvtype, MPI_Comm comm)
  所有进程相互交换数据

int MPI_Alltoallv(void * sendbuf, int * sendcount, int * sdispls, MPI_Datatype sendtype, void * recvbuf, int * recvcounts, int * rdispls, MPI_Datatype recvtype, MPI_Comm comm)
  所有进程相互交换数据, 但数据有一个偏移量。
  
int MPI_Gather(void * sendbuf, int sendcount, MPI_Datatype sendtype, void * recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)
  从进程组中收集消息

int MPI_Gatherv(void * sendbuf, int sendcount, MPI_Datatype sendtype, void * recvbuf, int * recvcounts, int * displs, MPI_Datatype recvtype, int root, MPI_Comm comm)
  从进程组中收集消息到指定的位置

int MPI_Op_create(MPI_User_function function, int commute, MPI_Op * op)
  创建一个用户定义的通信函数句柄

int MPI_Op_free(MPI_Op * op)
  释放一个用户定义的通信函数句柄

int MPI_Scan(void * sendbuf, void * recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
  在给定的进程集合上进行扫描操作

int MPI_Scatter(void * sendbuf, int sendcount, MPI_Datatype sendtype, void * recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)
  将数据从一个进程发送到组中其它进程

int MPI_Scatterv(void * sendbuf, int * sendcounts, int * displs, MPI_Datatype sendtype, void * recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)
  将缓冲区中指定部分的数据从一个进程发送到组中其它进程

系统定义的Reduce Operations:
MPI_MAX
MPI_MIN
MPI_SUM
MPI_PROD product
MPI_LAND logical and
MPI_BAND bit-wise and(按位与)
MPI_LOR logical or
MPI_BOR bit-wise or
MPI_LXOR logical xor
MPI_BXOR bit-wise xor
MPI_MAXLOC max value and location
MPI_MINLOC min value and location

自定义Reduce Operations:

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

typedef struct{
    double val;
    int log;
}SegScanPair;

void segscan(SegScanPair *in,SegScanPair *inout,int *len,MPI_Datatype *dptr){
    int i;
    SegScanPair c;
    for(i=0;i<*len;i++){
       if(in->log==inout->log)c.val=in->val+inout->val; 
       else c.val=inout->val;
      c.log=inout->log;
      *inout=c;
      in++;inout++;
    }

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

    int myid,i,base,p;  
    SegScanPair a,answer;
    MPI_Op myop;
    MPI_Datatype type[2]={MPI_DOUBLE,MPI_INT},sspair;
    MPI_Aint disp[2]={0,sizeof(double)};
    //MPI_Aint disp[2];
    //disp[0]=0;disp[1]=8;
    int namelen=10,max=0;  
    int blocklen[2]={1,1};
    MPI_Init (&argc, &argv);  
    MPI_Comm_rank (MPI_COMM_WORLD, &myid);  
    MPI_Comm  comm=MPI_COMM_WORLD;
    //MPI_Get_address(&a,disp);
    //MPI_Get_address(&a.log,disp+1);
    //base=disp[0];
    //for(i=0;i<2;i++){
    //  disp[i]-=base;  
    //  p=disp[i];
    //  printf("%d \n",p);
    //}
    MPI_Type_struct(2,blocklen,disp,type,&sspair);
    MPI_Type_commit(&sspair);
    MPI_Op_create((MPI_User_function *)segscan,0,&myop);

    a.val=1.0;a.log=myid%2;
    //MPI_Reduce_scatter(&a,&b,namelen,MPI_INT,MPI_MAX,comm);
    MPI_Scan(&a,&answer,1,sspair,myop,comm);
        //for(i=0;i<namelen;i++)
        //printf("%d ",b[i]);
        printf("%f-%d\n",answer.val,answer.log);    

//MPI_Reduce(&myid,&max,1,MPI_INT,MPI_PROD,0,comm);
//  if(myid==0){
//      printf("the max value is %d \n",max);   
//  }
        MPI_Finalize ();  
    return 0;
} 
调用MPI_Op_create((MPI_User_function *)segscan,0,&myop)方法构造一个operation,segscan是一个自定义的方法,0表示不可交换。

MPI_UB:当定义一个结构体,并且需要发送或接受多个该结构体的项时,为了对齐与填充需要,需要显示指定MPI_UB的项作为该结构体的最后一个成员。

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

int main (int argc, char **argv)  
{  
    int myid,i,j,*ra,*displs,*rcount,num=0,*sptr;  
    int namelen=10,gsize=3,stride,blocklen[2];  
    int a[namelen][15];
    MPI_Aint disp[2];
    MPI_Init (&argc, &argv);  
    MPI_Comm_rank (MPI_COMM_WORLD, &myid);  
    MPI_Comm  comm=MPI_COMM_WORLD;
    MPI_Datatype rtype,type[2];
    for(i=0;i<namelen;i++)
        for(j=0;j<15;j++)
            {a[i][j]=num;num++;}
    //MPI_Type_contiguous(100,MPI_INT,&rtype);


    displs=(int *)malloc(gsize*sizeof(int));
    rcount=(int *)malloc(gsize*sizeof(int));
    ra=(int *)malloc(gsize*namelen*sizeof(int));
        for(i=0;i<gsize;i++){
        displs[i]=i* namelen;
        rcount[i]=10-i;
    }
    disp[0]=0;disp[1]=15*sizeof(int);
    type[0]=MPI_INT;type[1]=MPI_UB;
//当定义一个结构体,并且需要发送或接受多个该结构体的项时,为了对齐与填充需要,需要显示指定MPI_UB的项作为该结构体的最后一个成员。
    blocklen[0]=1;blocklen[1]=1;

    MPI_Type_struct(2,blocklen,disp,type,&rtype);
    MPI_Type_commit(&rtype);
    sptr=&a[0][myid];
    MPI_Gatherv(sptr,10-        myid,rtype,ra,rcount,displs,MPI_INT,0,comm);
    if(myid==0){
        for(i=0;i<3*namelen;i++)
        printf("ra is---%d ",ra[i]);
        printf("\n");
        }
    /*  if(myid==0){

        MPI_Bcast(a,100,MPI_INT,0,comm);
        }else{
        printf("current thread is---%d \n",myid);
        MPI_Bcast(a,100,MPI_INT,0,comm);
        for(i=0;i<namelen;i++){printf("ra[%d]=%d ",i,a[i]);}
        printf("\n");
    }*/
        MPI_Finalize ();  
    return 0;
} 
  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值