首页 > 解决方案 > MPI_Reduce() 到特定的数组元素

问题描述

我在并行代码中遇到问题,我需要将所有进程的值减少到根进程,将它们求和,然后将总和分配给数组元素。我想在循环中执行此操作,以便每个 MPI_Reduce() 调用都减少为数组中的连续元素。我想知道如何指向数组中的特定位置。部分 for 循环代码如下所示。

for(int i = 1; i < N_t; i++) {
 ....

        loc_EK = valEK * (cblas_ddot(loc_N, loc_vx, 1, loc_vx, 1) + 
        cblas_ddot(loc_N, loc_vy, 1, loc_vy, 1));
        loc_EP = valEP * cblas_dasum(loc_N, loc_y, 1);
        loc_ET = loc_EP + loc_EK;

        // Gather and sum loc_E components in root process
        MPI_Reduce(&loc_EK, (EK + 1 + i), 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
        MPI_Reduce(&loc_EP, (EP + 1 + i), 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
        MPI_Reduce(&loc_ET, (ET + 1 + i), 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
    }
}

我当前使用 (EK+i+1) 指向数组位置,其中 EK 是指向动态数组的指针。我曾尝试使用 EK[i+1],但正如预期的那样,这不起作用。我应该如何解决这个问题,以便我可以将每个减少的总和分配给 EK 指向的数组元素?请注意,显示的所有变量和指针之前都已初始化,我只是排除了代码中不必要的部分,以便更切中要害。

标签: c++arraysparallel-processingmpidynamic-arrays

解决方案


您需要指定为:

   MPI_Reduce(loc_EK, &EK[1], N_t, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); 

一个完整的运行示例:

#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>

int main(int argc,char *argv[]){
    MPI_Init(NULL,NULL); // Initialize the MPI environment
    int world_rank; 
    int world_size;
    MPI_Comm_rank(MPI_COMM_WORLD,&world_rank);
    MPI_Comm_size(MPI_COMM_WORLD,&world_size);
    int size = 10;
    double *number = new double[size];
    for(int i = 0; i < size; i++)
         number[i] = world_rank + 1;

    double *sum = new double[size + 1];
    for(int i = 0; i < size + 1 ; i++) 
        sum[i] = 0;
        
    MPI_Reduce(number, &sum[1], size, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);            
    
    if(world_rank == 0){
      for(int i = 0; i < size; i++)
         printf("%f\n",sum[i]);
    }

    MPI_Finalize();
    return 0;
 }

输出(两个过程):

3.000000
3.000000
3.000000
3.000000
3.000000
3.000000
3.000000
3.000000
3.000000
3.000000

推荐阅读