sc_*_*ray 5 c++ boost mpi boost-mpi
在boost教程中,有一些收集和减少操作的例子.收集代码如下:
#include <boost/mpi.hpp>
#include <iostream>
#include <vector>
#include <cstdlib>
namespace mpi = boost::mpi;
int main(int argc, char* argv[])
{
mpi::environment env(argc, argv);
mpi::communicator world;
std::srand(time(0) + world.rank());
int my_number = std::rand();
if (world.rank() == 0) {
std::vector<int> all_numbers;
gather(world, my_number, all_numbers, 0);
for (int proc = 0; proc < world.size(); ++proc)
std::cout << "Process #" << proc << " thought of "
<< all_numbers[proc] << std::endl;
} else {
gather(world, my_number, 0);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
减少的例子如下:
#include <boost/mpi.hpp>
#include <iostream>
#include <cstdlib>
namespace mpi = boost::mpi;
int main(int argc, char* argv[])
{
mpi::environment env(argc, argv);
mpi::communicator world;
std::srand(time(0) + world.rank());
int my_number = std::rand();
if (world.rank() == 0) {
int minimum;
reduce(world, my_number, minimum, mpi::minimum<int>(), 0);
std::cout << "The minimum value is " << minimum << std::endl;
} else {
reduce(world, my_number, mpi::minimum<int>(), 0);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在这两个示例中,我们都有if/else条件,如下所示:
if(world.rank() == 0){
//gather or reduce operation
//Output
}else{
//gather or reduce operation
}
Run Code Online (Sandbox Code Playgroud)
我在这里无法理解的是if中的集体操作与其他中的什么不同?参数数量有所不同,但我不太清楚逻辑是如何工作的.
谢谢
MPI有两种类型的集体操作 - 一种具有指定的"根"过程,另一些则没有.广播指定根的操作(根进程将相同的数据发送到所有进程),分散(根进程将其数据分散到所有进程),收集(根进程从所有进程收集数据)和减少(根进程从所有进程收集数据)同时减少它).在MPI标准中,这些操作通常具有类似于以下的形式:
MPI_SCATTER(sendbuf, sendcount, sendtype,
recvbuf, recvcount, recvtype, root, comm)
Run Code Online (Sandbox Code Playgroud)
该MPI调用有两个输入和输出参数以及它在所有进程,包括根一个被使用,但输入参数(sendbuf
,sendcount
,sendtype
)只在其秩等于过程显著root
和所有其他进程都将被忽略.
MPI是为可移植性而设计的,因此MPI调用的设计使得它们可以在C和Fortran 77中以相同的方式实现 - 两种语言在设计MPI标准时都不支持函数重载或可选参数.(不)幸运的是,C++库boost::mpi
通过提供有效隐藏未使用参数的那些调用的版本,承担了C++在重载函数中提供的自由.现在很明显,调用gather(world, my_number, 0)
没有输出参数,因此它必须在不gather(world, my_number, all_numbers, 0)
具有操作根的进程中使用,同时具有输出参数,因此必须仅在根中使用.这在编写代码时会产生一些不对称性 - 你必须这样做if (world.rank() == root) { ... } else { ... }
.
我作为一个铁杆MPI用户认为这个丑陋,但还有其他人不同意我的看法.我想......这取决于.