boost::iprobe return 不正确计数
boost::iprobe does not return correct count
在下面的代码中,在探测时,没有获得正确的到达数量。还使用标准 MPI 函数测试了相同的功能并获得了正确答案。为什么 Boost 版本没有产生正确的结果?
提升版本:
#include <iostream>
#include <boost/mpi.hpp>
using namespace boost;
using namespace boost::mpi;
int main()
{
environment env;
communicator world;
if (world.rank() == 0)
{
int a[70];
auto req = world.isend(0, 0, a);
//req.wait(); // does not make any difference on the result.
optional<status> stat;
while (!stat)
{
stat = world.iprobe(0, 0);
if (stat)
{
optional<int> count = (*stat).count<int>();
if (count)
{
std::cout << *count << std::endl; // output: 2, expected: 70.
}
}
}
}
return 0;
}
标准版:
#include <iostream>
#include <mpi.h>
int main()
{
MPI_Init(NULL, NULL);
int rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if (rank == 0)
{
int a[70];
MPI_Request req;
MPI_Status stat;
MPI_Isend(a, 70, MPI_INT, 0, 0, MPI_COMM_WORLD, &req);
//MPI_Wait(&req, &stat);
int flag;
MPI_Iprobe(0, 0, MPI_COMM_WORLD, &flag, &stat);
if (flag)
{
int count;
MPI_Get_count(&stat, MPI_INT, &count);
std::cout << count << std::endl; // output: 70.
}
}
MPI_Finalize();
return 0;
}
编辑: 使用 isend(dest, tag, values, n)
而不是 isend(dest, tag, values)
给出了正确答案,其中 n
是数组中元素的数量。
您的 Boost 版本实际上并没有发送 70 int
,而是发送了一个 int [70]
。对于 Boost,此类型不是 MPI 数据类型,因此正确的 (*stat).count<decltype(a)>();
returns 是一个空的可选值。
现在 documentation 有点误导:
The type T must have an associated data type, i.e., is_mpi_datatype<T>
must derive mpl::true_
. In cases where the type T
does not match the transmitted type, this routine will return an empty optional<int>
.
我似乎相反,在 T
与传输类型不匹配的情况下,您将得到虚假结果或空 optional<int>
。如果它不是 mpi 数据类型,你会得到一个空的 optional<int>
.
之所以得到 2,是因为 Boost.MPI 为每个 non-MPI 数据类型消息发送了两条消息。一个包含序列化缓冲区的大小和实际消息。您的探针处理 size-message,其中包含一个 size_t
,其大小与 2 int
.
相同
不幸的是,Boost.MPI 充满了与实际传输消息的不同方式相关的微妙问题和错误。
在下面的代码中,在探测时,没有获得正确的到达数量。还使用标准 MPI 函数测试了相同的功能并获得了正确答案。为什么 Boost 版本没有产生正确的结果?
提升版本:
#include <iostream>
#include <boost/mpi.hpp>
using namespace boost;
using namespace boost::mpi;
int main()
{
environment env;
communicator world;
if (world.rank() == 0)
{
int a[70];
auto req = world.isend(0, 0, a);
//req.wait(); // does not make any difference on the result.
optional<status> stat;
while (!stat)
{
stat = world.iprobe(0, 0);
if (stat)
{
optional<int> count = (*stat).count<int>();
if (count)
{
std::cout << *count << std::endl; // output: 2, expected: 70.
}
}
}
}
return 0;
}
标准版:
#include <iostream>
#include <mpi.h>
int main()
{
MPI_Init(NULL, NULL);
int rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if (rank == 0)
{
int a[70];
MPI_Request req;
MPI_Status stat;
MPI_Isend(a, 70, MPI_INT, 0, 0, MPI_COMM_WORLD, &req);
//MPI_Wait(&req, &stat);
int flag;
MPI_Iprobe(0, 0, MPI_COMM_WORLD, &flag, &stat);
if (flag)
{
int count;
MPI_Get_count(&stat, MPI_INT, &count);
std::cout << count << std::endl; // output: 70.
}
}
MPI_Finalize();
return 0;
}
编辑: 使用 isend(dest, tag, values, n)
而不是 isend(dest, tag, values)
给出了正确答案,其中 n
是数组中元素的数量。
您的 Boost 版本实际上并没有发送 70 int
,而是发送了一个 int [70]
。对于 Boost,此类型不是 MPI 数据类型,因此正确的 (*stat).count<decltype(a)>();
returns 是一个空的可选值。
现在 documentation 有点误导:
The type T must have an associated data type, i.e.,
is_mpi_datatype<T>
must derivempl::true_
. In cases where the typeT
does not match the transmitted type, this routine will return an emptyoptional<int>
.
我似乎相反,在 T
与传输类型不匹配的情况下,您将得到虚假结果或空 optional<int>
。如果它不是 mpi 数据类型,你会得到一个空的 optional<int>
.
之所以得到 2,是因为 Boost.MPI 为每个 non-MPI 数据类型消息发送了两条消息。一个包含序列化缓冲区的大小和实际消息。您的探针处理 size-message,其中包含一个 size_t
,其大小与 2 int
.
不幸的是,Boost.MPI 充满了与实际传输消息的不同方式相关的微妙问题和错误。