在 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()
我想尝试将 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()