MPI_Allreduce加倍

时间:2015-10-20 00:43:54

标签: c++ mpi openmpi

我正试图找到所有处理器的全局最小值和最大值,以便进行我正在进行的排序。我正在尝试使用MPI_Reduceall

int rank, nproc;
MPI_Comm_size(MPI_COMM_WORLD,&nproc);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);

vector< vector<double> > buckets(nproc);
double local_min = *std::min_element(values_to_sort.begin(), values_to_sort.end());
double local_max = *std::max_element(values_to_sort.begin(), values_to_sort.end());

int min = 0;
int max = 0;

double global_min;
double global_max;

MPI_Allreduce(&local_min, &global_min, 1, MPI_2DOUBLE_PRECISION, MPI_MINLOC, MPI_COMM_WORLD);
MPI_Allreduce(&local_max, &global_max, 1, MPI_2DOUBLE_PRECISION, MPI_MAXLOC, MPI_COMM_WORLD);

cout << "local_min " << local_min << " local_max " << local_max << endl;
cout << "global_min " << global_min << " global_max " << global_max << endl;

我的代码会显示,并且每次都会出现段错误。这是一个简单的函数,使用:

生成随机双精度调用
int min = 0;
    int max = 100;

    vector<double> values_to_sort;
    vector<double> sorted_values;
    for(int i=0; i< 1000; i++)
    {
      values_to_sort.push_back( ((double) rand()*(max-min)/(double)RAND_MAX-min) );
    }

如果有人知道为什么这个段出现故障,请告诉我。我真的希望以一种快速简单的方式获得全局最大值和最小值。

2 个答案:

答案 0 :(得分:2)

您真的需要在这里使用MPI_MINLOCMPI_MAXLOC吗?由于您陈述问题的方式以及您使用解决方案的方式,MPI_MINMPI_MAX会很好:

double local_min = *std::min_element(values_to_sort.begin(), values_to_sort.end());
double local_max = *std::max_element(values_to_sort.begin(), values_to_sort.end());

double global_min;
double global_max;

MPI_Allreduce(&local_min, &global_min, 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD);
MPI_Allreduce(&local_max, &global_max, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);

cout << "local_min " << local_min << " local_max " << local_max << endl;
cout << "global_min " << global_min << " global_max " << global_max << endl;

现在,如果您确实需要拥有全局最小值和全局最大值的流程等级,那么您确实需要MPI_MINLOCMPI_MAXLOC。但是,您应该像这样使用它:

struct double_int {
    double val;
    int rank;
} local_min, local_max, global_min, global_max;

local_min.val = *std::min_element(values_to_sort.begin(), values_to_sort.end());
local_max.val = *std::max_element(values_to_sort.begin(), values_to_sort.end());
local_min.rank = local_max.rank = rank;

MPI_Allreduce(&local_min, &global_min, 1, MPI_DOUBLE_INT, MPI_MINLOC, MPI_COMM_WORLD);
MPI_Allreduce(&local_max, &global_max, 1, MPI_DOUBLE_INT, MPI_MAXLOC, MPI_COMM_WORLD);

cout << "on process " << rank << " local_min " << local_min.val
     << " local_max " << local_max.val << endl;
cout << "global_min " << global_min.val << " owned by process " << global_min.rank << endl;
cout << "global_max " << global_max.val << " owned by process " << global_max.rank << endl;

答案 1 :(得分:0)

我做了一些阅读,MINLOC和MAXLOC操作要求你使用一些大小的数组&gt; 1将值和等级存储为一对。

我的更新代码

 int rank, nproc;
    MPI_Comm_size(MPI_COMM_WORLD,&nproc);
    MPI_Comm_rank(MPI_COMM_WORLD,&rank);

    vector< vector<double> > buckets(nproc);
    double local_min[2];
    local_min[1] = rank;
    local_min[0] = *std::min_element(values_to_sort.begin(), values_to_sort.end());

    double local_max[2];
    local_max[1] = rank;
    local_max[0] = *std::max_element(values_to_sort.begin(), values_to_sort.end());

    double global_min[2];
    double global_max[2];

    MPI_Allreduce(&local_min, &global_min, 1, MPI_2DOUBLE_PRECISION, MPI_MINLOC, MPI_COMM_WORLD);
    MPI_Allreduce(&local_max, &global_max, 1, MPI_2DOUBLE_PRECISION, MPI_MAXLOC, MPI_COMM_WORLD);

    cout << "local_min " << local_min[0] << " local_max " << local_max[0] << endl;
    cout << "global_min " << global_min[0] << " global_max " << global_max[0] << endl;