2017-02-17 3 views
0

В приведенном ниже коде при проверке правильное количество прибытий не получено. Те же функции также тестируются со стандартными функциями MPI, и получается правильный ответ. Почему версия Boost не дает правильного результата? версияboost :: iprobe не возвращает правильный счет

форсиро-

#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; 
} 

Edit: Использование isend(dest, tag, values, n) вместо isend(dest, tag, values) дал правильный ответ, где n является количество элементов в массив.

ответ

1

Ваша Boost версия на самом деле не отправляет 70 int, но один int [70]. Для Boost этот тип не является типом MPI, поэтому правильный (*stat).count<decltype(a)>(); возвращает пустую опцию.

documentation Теперь немного вводит в заблуждение:

тип Т должен иметь тип данных, связанный, т.е. 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 полон тонких проблем и ошибок такого рода, связанных с тем, что сообщения на самом деле переданы.

Смежные вопросы