MPI收集/减少操作混乱
MPI gather/reduce operation confusion?
在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;
}
reduce的例子如下:
#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;
}
在这两个例子中,我们都有一个if/else条件,如下所示:
if(world.rank() == 0){
//gather or reduce operation
//Output
}else{
//gather or reduce operation
}
我在这里不明白的是,如果中的集体操作和其他中的什么之间的区别?参数的数量有所不同,但我不太明白逻辑是如何实现的。
感谢
MPI_SCATTER(sendbuf, sendcount, sendtype,
recvbuf, recvcount, recvtype, root, comm)
此MPI调用同时具有输入和输出参数,必须在所有进程中使用,包括根进程,但输入参数(sendbuf
、sendcount
、sendtype
)仅在秩等于root
的进程中有效,在所有其他进程中都被忽略。
MPI是为可移植性而设计的,因此MPI调用的设计使它们可以在C和Fortran 77中以相同的方式实现——在设计MPI标准时,这两种语言都不支持函数重载或可选参数。(Un-)幸运的是,像boost::mpi
这样的C++库通过提供有效隐藏未使用参数的调用版本,获得了C++在重载函数时提供的自由。现在很明显,对gather(world, my_number, 0)
的调用没有输出参数,因此它有要在不是操作根的进程中使用,而gather(world, my_number, all_numbers, 0)
有输出参数,所以只有才能在根中使用。这在编写代码时造成了一些不对称性——您必须执行if (world.rank() == root) { ... } else { ... }
之类的操作。
作为MPI的铁杆用户,我认为这很丑陋,但也有其他人不同意我的观点。我想。。。这取决于情况。
查看:
boost/mpi/collectives/gather.hpp
您将看到gather_impl的不同实现,一个在参数列表中有"out"值,另一个没有。没有"out"值的进程将其数据发送到根进程。因此,在收集示例中:
gather(world, my_number, 0)
实现mpi发送和
gather(world, my_number, all_numbers, 0)
为根处理器实现本地拷贝,为其他处理器实现mpi接收。
- 为什么在popback()操作之后,它仍然打印完整的矢量
- 重载操作程序时出错>>用于类中的字符串 memebr
- 如何克服提升精神AST混乱
- 对字符串进行位操作
- 我可以在 C++ 中的函数体之外进行操作吗?
- MPI突然停止了对多个核心的操作
- 如何在信号处理程序和普通函数中对全局变量进行互斥读写操作
- 对字符数组中的元素执行逐位操作
- 如何在directx/c++中进行平移/缩放操作
- 逐位操作的隐式类型转换
- 为什么一个向量上的多线程操作很慢
- 排序时无法执行交换操作.我做的时候它会崩溃.为什么
- 位移操作和位掩码未检测到重复字符
- 如何进行特定的位操作?
- 当我们进行一些操作时,应该使用什么'std::string'或'std::stringstream'?
- 字符串操作 - 字符计数
- 此代码中的操作流程是什么?C/C++.
- 复制和交换习惯用法与移动操作之间的交互
- 像union_这样的 Boost.Geometry 操作如何处理浮点类型的基本不精确性?
- MPI收集/减少操作混乱