MPI以最小值获得处理器

在MPI中,我正在对值进行reduce操作(最小值)。 这样可以正常工作,但是如何获取最小值的处理器编号并请求该处理器获取更多信息(或使用reduce操作发送附加数据)?

如果您不介意在本地使用整数索引(在本例中使用本地排名的值填充)来削减每个值,则可以使用MPI_MINLOC或MPI_MAXLOC内置操作进行reduce; 或者编写自己的MPI减少运算符以包含多个索引等信息是相当容易的

更新以添加:使用内置运算符MINLOC或MAXLOC,而不是传入单个值来查找最小值,而是传入加上整数索引。 该索引可以具有您想要的任何值,但它“跟随”另一个值。 MPI内置了“对”数据类型 – 用于double + int的MPI_DOUBLE_INT或用于两个int的MPI_2INT,您可以使用它们。

所以说你想找到一个整数数组的最小值,以及它所在的MPI任务。 正常情况下,您会在每项任务中找到当地最低要求,并执行减少; 但是这次你还要把它与一个整数配对,在这种情况下你的等级:

#include  #include  #include  int main(int argc, char **argv) { int rank, size; const int locn=5; int localarr[locn]; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); srand(rank); for (int i=0; i 

跑步你得到:

 $ mpirun -np 5 ./minloc Rank 0 has values: 83 86 77 15 93 Rank 1 has values: 83 86 77 15 93 Rank 2 has values: 90 19 88 75 61 Rank 3 has values: 46 85 68 40 25 Rank 4 has values: 1 83 74 26 63 Rank 4 has lowest value of 1 

如果要减少的值不是整数(例如,双精度),则创建包含缩减值和整数索引的结构,并使用适当的MPI对数据类型。 (例如,MPI_DOUBLE_INT)。

进一步更新 :好的,只是为了好玩,使用我们自己的缩减操作和我们自己的类型来实现两个索引:

 #include  #include  #include  typedef struct dbl_twoindex_struct { double val; int rank; int posn; } dbl_twoindex; void minloc_dbl_twoindex(void *in, void *inout, int *len, MPI_Datatype *type){ /* ignore type, just trust that it's our dbl_twoindex type */ dbl_twoindex *invals = in; dbl_twoindex *inoutvals = inout; for (int i=0; i<*len; i++) { if (invals[i].val < inoutvals[i].val) { inoutvals[i].val = invals[i].val; inoutvals[i].rank = invals[i].rank; inoutvals[i].posn = invals[i].posn; } } return; } int main(int argc, char **argv) { int rank, size; const int locn=5; double localarr[locn]; dbl_twoindex local, global; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); /* create our new data type */ MPI_Datatype mpi_dbl_twoindex; MPI_Datatype types[3] = { MPI_DOUBLE, MPI_INT, MPI_INT }; MPI_Aint disps[3] = { offsetof(dbl_twoindex, val), offsetof(dbl_twoindex, rank), offsetof(dbl_twoindex, posn), }; int lens[3] = {1,1,1}; MPI_Type_create_struct(3, lens, disps, types, &mpi_dbl_twoindex); MPI_Type_commit(&mpi_dbl_twoindex); /* create our operator */ MPI_Op mpi_minloc_dbl_twoindex; MPI_Op_create(minloc_dbl_twoindex, 1, &mpi_minloc_dbl_twoindex); srand(rank); for (int i=0; i 

跑步给

 $ mpirun -np 5 ./minloc2 Rank 0 has values: 0.8402 0.3944 0.7831 0.7984 0.9116 Rank 1 has values: 0.8402 0.3944 0.7831 0.7984 0.9116 Rank 2 has values: 0.7010 0.8097 0.0888 0.1215 0.3483 Rank 3 has values: 0.5614 0.2250 0.3931 0.4439 0.2850 Rank 4 has values: 0.9165 0.1340 0.1912 0.2601 0.2143 Rank 2 has lowest value of 0.0888 in position 2.