在C 中运行MPI时调用功能

Call function when running MPI in C++

本文关键字:调用 功能 MPI 运行      更新时间:2023-10-16

我想尝试将OpenMPI与C 一起使用,因此我编写了一个小型代码来进行数值集成。我的问题是,它似乎没有执行正确发生的行:

integral = trapezintegration(local_a, local_b, local_n);

现在,我非常有信心MPI在这条线旁边正确起作用。打印local_a,local_b,local_n和rank_world时,我得到:

0 3.75 2.5e+09 0  
3.75 7.5 2.5e+09 1   
7.5 11.25 2.5e+09 2  
11.25 15 2.5e+09 3 

这是我所期望的。当我打印积分时,rank_world。我得到:

17.5781 2  
17.5781 3  
17.5781 1  
17.5781 0    

这对我来说似乎很奇怪,只有rank_world = 0,应该具有积分= 17.5781的值。我的问题是,如何在MPI中进行函数调用,因此排名并非全部获得rank_world == 0的值?

完整的代码可以在下面看到:

#include <mpi.h>
#include <iostream>
double f(const double x){
    return x*x;
}
double trapezintegration(const double a, const double b, const double n){
    "a = start value of integration range";
    "b = end value of integration range";
    "n = number of integration slices";
    double integral=0.0, h=(b-a)/n;
    long loopbound = (long)n;
    "integral = the value of the numeric integral";
    "h        = width of the numeric integration";
    integral = -(f(a)+f(b))/2.0;
    for (long i=1;i<=loopbound;i++){
        integral = integral + f(i*h);
    }
    integral = integral*(b-a)/n;
    return integral;
}

int main(){
    // The MPI enviroment need to be initialized
    MPI_Init(NULL, NULL);
    // The program need to know how many processors that are avaible
    int world_size;
    MPI_Comm_size(MPI_COMM_WORLD, &world_size);
    // The processors index is also needed to be known
    int world_rank;
    MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
    // Now the execution of the program can be done
    // If no processor index (rank) is specfied the code will be 
    // executed for all the processes
    const double a=0.0, b=15.0, n=1e+10;
    double integral, total_integral;
    // Right now all of the processes have the same a and b
    // now different a and b will be assigned to the processes
    // The rank is the index of the processor going from
    // 0 to WORLD_SIZE-1, all of the processes will now get
    // different local_a and local_b
    double local_a = (b - a)/world_size*world_rank;
    double local_b = (b - a)/world_size*(world_rank+1);
    double local_n = n/world_size;
    std::cout << local_a << ' '<< local_b << ' ' << local_n << ' '  << world_rank << 'n'; 
    integral = trapezintegration(local_a, local_b, local_n);
    // All of the processes have now run the numerical integration
    // for their given interval. All of the integrated parts need
    // to be collected to get the total integration.
    // Lets collect the result in Rank 0
    std::cout << integral << ' ' << world_rank << 'n'; 
    if (world_rank != 0){
        MPI_Send(&integral,1,MPI_DOUBLE,0,555+world_rank,MPI_COMM_WORLD);
    }
    if (world_rank == 0){
        total_integral = integral;
        for (int i=1; i<world_size; i++){
                MPI_Recv(&integral,1,MPI_DOUBLE,i,555+i,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
                total_integral = total_integral + integral;
        }
    }
    // if rank is different from rank 0, the result need to be send
    if (world_rank == 0){
        std::cout << total_integral << 'n';
    }
    // The MPI enviroment need to be closed when the calculation is finished
    MPI_Finalize();
}

而不是

integral = integral + f(i*h);

应该是

integral = integral + f(a+i*h);

代替?

作为旁注,计算total_integral的自然方式是通过单个调用MPI_Reduce()