В приведенном ниже коде при проверке правильное количество поступлений не получается. Эта же функциональность также протестирована со стандартными функциями MPI и получен правильный ответ. Почему Boost-версия не дает правильного результата?
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)>();
возвращает пустой необязательный.
Теперь документация немного вводит в заблуждение:
Тип T должен иметь связанный тип данных, т.е.
is_mpi_datatype<T>
должен вывестиmpl::true_
, В случаях, когда типT
не соответствует передаваемому типу, эта подпрограмма вернет пустойoptional<int>
,
Мне кажется, что вместо этого в случаях, когда T
не соответствует переданному типу, вы получите либо фиктивный результат, либо пустой optional<int>
, Если это не тип данных MPI, вы получите пустой optional<int>
,
Причина, по которой вы получаете именно 2, заключается в том, что Boost.MPI отправляет два сообщения для каждого сообщения типа данных не MPI. Один, содержащий размер сериализованного буфера и фактическое сообщение. Ваш зонд сопоставляет сообщение размера, содержащее одно size_t
, который имеет тот же размер, что и 2 int
,
К сожалению, Boost.MPI полон тонких проблем и ошибок такого рода, касающихся различных способов передачи сообщений.
Других решений пока нет …