увеличить MPI коллективных операций с вектором - PullRequest
0 голосов
/ 02 февраля 2020

В библиотеке boost::mpi коллективные операции имеют перегрузки для обработки массива значений входа / выхода в стиле c, где операция повторяется для каждого элемента массива. Например, boost :: mpi :: redu имеет следующую перегрузку

template<typename T, typename Op> 
  void reduce(const communicator & comm, const T * in_values, int n, 
              T * out_values, Op op, int root);
template<typename T, typename Op> 
  void reduce(const communicator & comm, const T * in_values, int n, Op op, 
              int root);

Здесь in_values и out_values являются указателями на массивы C, а Операция сокращения выполняется для каждого элемента таких массивов.

Можно ли использовать std::vector вместо массива C -тиля?

Согласно справке c ++ для ' std::vector:

Элементы хранятся непрерывно, что означает, что к элементам можно обращаться не только через итераторы, но и с помощью смещений для обычных указателей на элементы. Это означает, что указатель на элемент вектора может быть передан любой функции, которая ожидает указатель на элемент массива.

Поэтому я считаю, что это действительно возможно используйте std::vector. Согласно здесь , портативное решение будет использовать std::vector::front. Следующая минимальная программа реализует эту идею:

#include <iostream>
#include <vector>
#include <boost/mpi/environment.hpp>
#include <boost/mpi/communicator.hpp>
#include <boost/mpi/collectives.hpp>
#include <boost/mpi/operations.hpp>

int main()
{
  boost::mpi::environment env;
  boost::mpi::communicator world;

  std::vector<int> v = { world.rank() + 1, 2 * (world.rank() + 1), 3 * (world.rank() + 1) };
  if (world.rank() == 0)
    {
      std::vector<int> v_reduced(v.size());
      boost::mpi::reduce(world, &v.front(), 3, &v_reduced.front(), std::plus<int>{}, 0);
      std::cout << "reduced vector:";
      for (auto const& x : v_reduced)
    std::cout << ' ' << x;
      std::cout << std::endl;
    }
  else
    {
      boost::mpi::reduce(world, &v.front(), 3, std::plus<int>{}, 0);
    }

  return 0;
}

Тестируя программу, она, кажется, дает ожидаемое поведение.

Вопрос: используется &x.front(), как в приведенном выше примере на Коллективная операция надбавки MPI хорошо определена, или одна в UB?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...