在MPI中,我正在对值执行减少操作(最小值)。这工作正常,但我如何获取最小来自的处理器编号并请求该处理器以获取更多信息(或通过reduce操作发送附加数据)?MPI以最小值获取处理器
15
A
回答
24
如果您不介意在本地使用整数索引(在本例中使用本地排名的值填充每个值),则可以使用MPI_MINLOC or MPI_MAXLOC内置操作来减少;或者这也很容易编写自己的MPI减少运营商包括像多个索引,ETCC
更新补充: 随着内置运营商MINLOC或MAXLOC,而不是通过在一个单一的价值发现的最小的,你传入一个整数索引。该索引可以具有任何您想要的值,但它会“跟随”其他值。 MPI内置了“pair”数据类型 - MPI_DOUBLE_INT用于double + int,或者MPI_2INT用于两个int,您可以使用它们。
所以说你想找到一个整数数组的最小值以及它所在的MPI任务。正常情况下,你会在每项任务中找到你本地的最小值,然后进行减少;但这个时候你还用一个整数配对,在这种情况下,你的排名:
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
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<locn; i++)
localarr[i] = rand() % 100;
for (int proc=0; proc<size; proc++) {
if (rank == proc) {
printf("Rank %2d has values: ",rank);
for (int i=0; i<locn; i++)
printf(" %d ", localarr[i]);
printf("\n");
}
MPI_Barrier(MPI_COMM_WORLD);
}
int localres[2];
int globalres[2];
localres[0] = localarr[0];
for (int i=1; i<locn; i++)
if (localarr[i] < localres[0]) localres[0] = localarr[i];
localres[1] = rank;
MPI_Allreduce(localres, globalres, 1, MPI_2INT, MPI_MINLOC, MPI_COMM_WORLD);
if (rank == 0) {
printf("Rank %d has lowest value of %d\n", globalres[1], globalres[0]);
}
MPI_Finalize();
return 0;
}
并运行你:
$ 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
如果你减少的值不是一个整数,(比如double),您创建一个包含缩减值和整数索引的结构,并使用适当的MPI配对数据类型。 (例如,MPI_DOUBLE_INT)。
更新进一步:好吧,只是为了好玩,我们自己减少操作和我们自己的类型做它来实现两个指标:
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
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<locn; i++)
localarr[i] = 1.*rand()/RAND_MAX;
for (int proc=0; proc<size; proc++) {
if (rank == proc) {
printf("Rank %2d has values: ",rank);
for (int i=0; i<locn; i++)
printf(" %8.4lf ", localarr[i]);
printf("\n");
}
MPI_Barrier(MPI_COMM_WORLD);
}
local.val = localarr[0];
local.posn = 0;
for (int i=1; i<locn; i++)
if (localarr[i] < local.val) {
local.val = localarr[i];
local.posn = i;
}
local.rank = rank;
MPI_Allreduce(&local, &global, 1, mpi_dbl_twoindex, mpi_minloc_dbl_twoindex, MPI_COMM_WORLD);
if (rank == 0) {
printf("Rank %d has lowest value of %8.4lf in position %d.\n", global.rank, global.val, global.posn);
}
MPI_Op_free(&mpi_minloc_dbl_twoindex);
MPI_Type_free(&mpi_dbl_twoindex);
MPI_Finalize();
return 0;
}
运行提供了
$ 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.
相关问题
- 1. 我可以获得最小(最大)处理器状态的值
- 2. MPI处理器数量?
- 3. 获取最小值
- 4. MySQL:以最小值获取满行
- 5. 获取最小值和最大值
- 6. cypher子查询:获取具有最大/最小值的节点并处理它
- 7. MPI信号处理
- 8. MySQL声明以最大值获取最小值ID
- 9. MPI双环,最大值,最小值和平均值
- 10. 获取最小值,非空
- 11. 获取最小值php
- 12. Android - 获取接近传感器的最小值和最大值
- 13. 获取处理指令值
- 14. mpi内的Python多处理器
- 15. 错误的mpi处理器数量
- 16. MPI处理器中MPI_Request是否全局?
- 17. MPI:内核还是处理器?
- 18. MPI是否提供预处理器宏?
- 19. 在矩阵MPI中查找最小值和最大值
- 20. JSpinner获取最大最小值
- 21. 获取预处理器宏
- 22. C++获取处理器ID
- 23. 使用默认值获取最小值
- 24. MPI大数据处理
- 25. PHP读取文件并获取最大值和最小值
- 26. 如何从页面获取值以便jQuery可以处理它?
- 27. 获取参数的最大值或最小值到行值postgres
- 28. 获取最小值和最大值值从多行事件
- 29. JavaScript获取数组的最大值最小值平均值
- 30. 获取列和其他列值的最小值和最大值
你能否详细说明或举例说明这一点? – 2012-02-14 23:07:01
谢谢,这非常有帮助!是否可以定义类似MPI_DOUBLE_2INT的内容,以便每双可以发送多个密钥? – 2012-02-14 23:22:36
我认为除了内建类型以外的任何东西,你都必须编写自己的操作,但它不会那么难。 – 2012-02-15 01:46:49