2015-10-20 72 views
0

我正在嘗試在所有處理器上查找我正在處理的排序中的全局最小值和最大值。我試圖用MPI_ReduceallMPI_Allreduce加倍

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

如果有人知道爲什麼這個seg錯誤,請告訴我。我真的很想快速簡單地獲得全局最大值和最小值。

回答

0

我做了一些閱讀,MINLOC和MAXLOC操作要求您使用一個大小大於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; 
+0

你可能會更好用不同的對類型,例如int + double。 – Jeff

+1

'MPI_2DOUBLE_PRECISION'是Fortran MPI類型,不是C++類型。你不應該在C++代碼中使用它。 – Gilles

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;