2017-09-22 19 views
1

OpenMPIをC++で使用しようと思っていたので、数値積分を行う小さなコードを書いた。C++でMPIを実行しているときに関数を呼び出す

integral = trapezintegration(local_a, local_b, local_n); 

今私はMPIは、この行の横に正しく動作することをかなり確信している:私の問題は、それはそれがすべて正しく起こる行を実行していないようDEOSということです。 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 

私が期待したものexcactlyです。私がインテグラル、ランクワールドをプリントアウトするとき。私が取得:

17.5781 2 
17.5781 3 
17.5781 1 
17.5781 0  

これは私には奇妙に思える部分では、唯一のrank_world = = 0、整数= 17.5781の値を持つ必要があります。私の質問は、どのようにMPIで関数呼び出しを行うのですか?rank_world == 0の値を得ることはできません。

完全なコードは、以下に見られることができます。代わりに

integral = integral + f(i*h); 

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

答えて

2

それは代わりに

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

べきか?サイドノートとして

total_integralを計算する自然な方法は、働いていたMPI_Reduce()

+0

への単一の呼び出し、どのような恥ずかしい間違いを経由しています。 MPI_Reduce()についてのヒントをありがとう –

+0

あなたはようこそ!一度は誰もが余分な目を必要とします:-) –

関連する問題