在 C++ 中 运行 MPI 时调用函数

Call function when running MPI in C++

我想尝试将 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,应该有integral = 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()