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;
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章