MPI获取与最小值处理器 [英] MPI Get Processor with Minimum value

查看:131
本文介绍了MPI获取与最小值处理器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在MPI,我做的值的降低运行(最小)。这工作得很好,但我怎么抢,最低是从哪里来的处理器数量,并征求有关详细信息,该处理器(或与降低运行发送更多的数据)?

In MPI, I am doing a reduce operation(minimum) on a value. This works fine, but how do I grab the processor number that the minimum came from and solicit that processor for more information(or send the additional data with the reduce operation)?

推荐答案

如果你不介意与一个整数值(填在这种情况下与当地的秩的值)本地配对每一个值,你可以使用< A HREF =htt​​p://www.mpi-forum.org/docs/mpi-1.1/mpi-11-html/node79.html> MPI_MINLOC或MPI_MAXLOC 以减少内建操作;或者这也很容易编写自己的MPI减少运营商包括像多个索引,ETCC

If you don't mind paring each value locally with an integer index (filled in this case with the value of the local rank), you can use the MPI_MINLOC or MPI_MAXLOC builtin operations for reduce; or it's fairly easy to write your own MPI reduction operator to include things like multiple indices, etcc

更新补充:
随着运营商内置或MINLOC MAXLOC,而不是传递一个值来找到最小的,您在通过加上一个整数索引。该索引可以有你想要的任何值,但它沿着跟随另一个值。 MPI已建成的配对的数据类型 - MPI_DOUBLE_INT了双+一个int,或MPI_2INT为两个整数,你可以使用

Updated to add: With the builtin operators MINLOC or MAXLOC, instead of passing in a single value to find the minimum of, you pass in that plus an integer index. That index can have any value you want it to, but it "follows" the other value along. MPI has built in "pair" data types - MPI_DOUBLE_INT for a double + an int, or MPI_2INT for two ints, that you can use.

所以说,你想找到的最小的整数数组,并在其上​​MPI任务它位于。作为正常的,你觉得对每一个任务,你的本地最低,并做减少;但这个时候,你也整数配对,在这种情况下,你的排名:

So say you want to find the minimum of an integer array, and on which MPI task it was located. As normal, you find your local minimum on each task, and do the reduce; but this time you also pair it with an integer, in this case your rank:

#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

如果你正在减少的值不是整数,(比如,双),则创建包含该减少值和整数索引的结构,并且使用适当的MPI对数据类型。 (例如,MPI_DOUBLE_INT)。

If the value you're reducing isn't an integer, (say, a double), you create a structure containing the reduction value and the integer index, and use the appropriate MPI pair data type. (eg, MPI_DOUBLE_INT).

更新进一步:好吧,只是为了好玩,用我们自己的归约操作和我们自己的类型做它来实现两个指标:

Updated further: Ok, just for fun, doing it with our own reduction operation and our own type to implement two indices:

#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.

这篇关于MPI获取与最小值处理器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆