简体   繁体   中英

MPI_Reduce() to specific array elements

I have an problem in a parallelised code where I need to reduce values from all processes to the root process, summing them and then assigning the sum to an array element. I would like to do this in a loop such that each MPI_Reduce() call reduces to consecutive elements along an array. I would like to know how to point to the specific location in the array. Part of the for loop code is shown below.

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

I am currectly pointing the the array positions using (EK+i+1), where EK is the pointer to a dynamic array. I have tried using EK[i+1] but as expected this did not work. How should I fix this so that I can assign each reduced sum to elements of the array pointed to by EK? Note that all variables and pointers shown have been previously initialised, I've just excluded unnecessary parts of the code to be more to the point.

You need to specified as:

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

A full running example:

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

Output (two processes):

3.000000
3.000000
3.000000
3.000000
3.000000
3.000000
3.000000
3.000000
3.000000
3.000000

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM