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;
}