Same for AnswerType.
*/
class DictionaryPayLoad
: public ConsensusAlgorithms::Process<
- std::pair<types::global_dof_index, types::global_dof_index>,
- unsigned int>
+ std::vector<
+ std::pair<types::global_dof_index, types::global_dof_index>>,
+ std::vector<unsigned int>>
{
public:
/**
*/
class ConsensusAlgorithmsPayload
: public ConsensusAlgorithms::Process<
- std::pair<types::global_dof_index, types::global_dof_index>,
- unsigned int>
+ std::vector<
+ std::pair<types::global_dof_index, types::global_dof_index>>,
+ std::vector<unsigned int>>
{
public:
/**
* @note The buffer is empty. Before using it, you have to set its size.
*/
virtual void
- create_request(const unsigned int other_rank,
- std::vector<RequestType> &send_buffer);
+ create_request(const unsigned int other_rank, RequestType &send_buffer);
/**
* Prepare the buffer where the payload of the answer of the request to
* its size.
*/
virtual void
- answer_request(const unsigned int other_rank,
- const std::vector<RequestType> &buffer_recv,
- std::vector<AnswerType> & request_buffer);
+ answer_request(const unsigned int other_rank,
+ const RequestType &buffer_recv,
+ AnswerType & request_buffer);
/**
* Process the payload of the answer of the request to the process with
* @param[in] recv_buffer data to be sent part of the request (optional)
*/
virtual void
- read_answer(const unsigned int other_rank,
- const std::vector<AnswerType> &recv_buffer);
+ read_answer(const unsigned int other_rank,
+ const AnswerType & recv_buffer);
};
* is to be performed.
*/
virtual std::vector<unsigned int>
- run(const std::vector<unsigned int> &targets,
- const std::function<std::vector<RequestType>(const unsigned int)>
- & create_request,
- const std::function<std::vector<AnswerType>(
- const unsigned int,
- const std::vector<RequestType> &)> &answer_request,
- const std::function<void(const unsigned int,
- const std::vector<AnswerType> &)>
- & process_answer,
- const MPI_Comm &comm) = 0;
+ run(
+ const std::vector<unsigned int> & targets,
+ const std::function<RequestType(const unsigned int)> &create_request,
+ const std::function<AnswerType(const unsigned int,
+ const RequestType &)> &answer_request,
+ const std::function<void(const unsigned int, const AnswerType &)>
+ & process_answer,
+ const MPI_Comm &comm) = 0;
private:
/**
* @copydoc Interface::run()
*/
virtual std::vector<unsigned int>
- run(const std::vector<unsigned int> &targets,
- const std::function<std::vector<RequestType>(const unsigned int)>
- & create_request,
- const std::function<std::vector<AnswerType>(
- const unsigned int,
- const std::vector<RequestType> &)> &answer_request,
- const std::function<void(const unsigned int,
- const std::vector<AnswerType> &)>
- & process_answer,
- const MPI_Comm &comm) override;
+ run(
+ const std::vector<unsigned int> & targets,
+ const std::function<RequestType(const unsigned int)> &create_request,
+ const std::function<AnswerType(const unsigned int,
+ const RequestType &)> &answer_request,
+ const std::function<void(const unsigned int, const AnswerType &)>
+ & process_answer,
+ const MPI_Comm &comm) override;
private:
#ifdef DEAL_II_WITH_MPI
/**
* Buffers for sending requests.
*/
- std::vector<std::vector<RequestType>> send_buffers;
+ std::vector<std::vector<char>> send_buffers;
/**
* Requests for sending requests.
* resized and consequently its elements (the pointers) are moved
* around.
*/
- std::vector<std::unique_ptr<std::vector<AnswerType>>> request_buffers;
+ std::vector<std::unique_ptr<std::vector<char>>> request_buffers;
/**
* Requests for sending answers to requests.
*/
bool
all_locally_originated_receives_are_completed(
- const std::function<void(const unsigned int,
- const std::vector<AnswerType> &)>
+ const std::function<void(const unsigned int, const AnswerType &)>
& process_answer,
const MPI_Comm &comm);
*/
void
maybe_answer_one_request(
- const std::function<std::vector<AnswerType>(
- const unsigned int,
- const std::vector<RequestType> &)> &answer_request,
- const MPI_Comm & comm);
+ const std::function<AnswerType(const unsigned int,
+ const RequestType &)> &answer_request,
+ const MPI_Comm & comm);
/**
* Start to send all requests via ISend and post IRecvs for the incoming
*/
void
start_communication(
- const std::vector<unsigned int> &targets,
- const std::function<std::vector<RequestType>(const unsigned int)>
- & create_request,
- const MPI_Comm &comm);
+ const std::vector<unsigned int> & targets,
+ const std::function<RequestType(const unsigned int)> &create_request,
+ const MPI_Comm & comm);
/**
* After all rank has received all answers, the MPI data structures can
*/
template <typename RequestType, typename AnswerType>
std::vector<unsigned int>
- nbx(const std::vector<unsigned int> &targets,
- const std::function<std::vector<RequestType>(const unsigned int)>
- & create_request,
- const std::function<std::vector<AnswerType>(
- const unsigned int,
- const std::vector<RequestType> &)> &answer_request,
- const std::function<void(const unsigned int,
- const std::vector<AnswerType> &)>
+ nbx(const std::vector<unsigned int> & targets,
+ const std::function<RequestType(const unsigned int)> &create_request,
+ const std::function<AnswerType(const unsigned int,
+ const RequestType &)> &answer_request,
+ const std::function<void(const unsigned int, const AnswerType &)>
& process_answer,
const MPI_Comm &comm);
* @copydoc Interface::run()
*/
virtual std::vector<unsigned int>
- run(const std::vector<unsigned int> &targets,
- const std::function<std::vector<RequestType>(const unsigned int)>
- & create_request,
- const std::function<std::vector<AnswerType>(
- const unsigned int,
- const std::vector<RequestType> &)> &answer_request,
- const std::function<void(const unsigned int,
- const std::vector<AnswerType> &)>
- & process_answer,
- const MPI_Comm &comm) override;
+ run(
+ const std::vector<unsigned int> & targets,
+ const std::function<RequestType(const unsigned int)> &create_request,
+ const std::function<AnswerType(const unsigned int,
+ const RequestType &)> &answer_request,
+ const std::function<void(const unsigned int, const AnswerType &)>
+ & process_answer,
+ const MPI_Comm &comm) override;
private:
#ifdef DEAL_II_WITH_MPI
/**
* Buffers for sending requests.
*/
- std::vector<std::vector<RequestType>> send_buffers;
+ std::vector<std::vector<char>> send_buffers;
/**
* Buffers for receiving answers to requests.
*/
- std::vector<std::vector<AnswerType>> recv_buffers;
+ std::vector<std::vector<char>> recv_buffers;
/**
* MPI request objects for sending request messages.
/**
* Buffers for sending answers to requests.
*/
- std::vector<std::vector<AnswerType>> requests_buffers;
+ std::vector<std::vector<char>> requests_buffers;
/**
* Requests for sending answers to requests.
*/
unsigned int
start_communication(
- const std::vector<unsigned int> &targets,
- const std::function<std::vector<RequestType>(const unsigned int)>
- & create_request,
- const MPI_Comm &comm);
+ const std::vector<unsigned int> & targets,
+ const std::function<RequestType(const unsigned int)> &create_request,
+ const MPI_Comm & comm);
/**
* The `index`th request message from another rank has been received:
* process the request and send an answer.
*/
void
- answer_one_request(const unsigned int index,
- const std::function<std::vector<AnswerType>(
- const unsigned int,
- const std::vector<RequestType> &)> &answer_request,
- const MPI_Comm & comm);
+ answer_one_request(
+ const unsigned int index,
+ const std::function<AnswerType(const unsigned int,
+ const RequestType &)> &answer_request,
+ const MPI_Comm & comm);
/**
* Receive and process all of the incoming responses to the
void
process_incoming_answers(
const unsigned int n_targets,
- const std::function<void(const unsigned int,
- const std::vector<AnswerType> &)>
+ const std::function<void(const unsigned int, const AnswerType &)>
& process_answer,
const MPI_Comm &comm);
*/
template <typename RequestType, typename AnswerType>
std::vector<unsigned int>
- pex(const std::vector<unsigned int> &targets,
- const std::function<std::vector<RequestType>(const unsigned int)>
- & create_request,
- const std::function<std::vector<AnswerType>(
- const unsigned int,
- const std::vector<RequestType> &)> &answer_request,
- const std::function<void(const unsigned int,
- const std::vector<AnswerType> &)>
+ pex(const std::vector<unsigned int> & targets,
+ const std::function<RequestType(const unsigned int)> &create_request,
+ const std::function<AnswerType(const unsigned int,
+ const RequestType &)> &answer_request,
+ const std::function<void(const unsigned int, const AnswerType &)>
& process_answer,
const MPI_Comm &comm);
* @copydoc Interface::run()
*/
virtual std::vector<unsigned int>
- run(const std::vector<unsigned int> &targets,
- const std::function<std::vector<RequestType>(const unsigned int)>
- & create_request,
- const std::function<std::vector<AnswerType>(
- const unsigned int,
- const std::vector<RequestType> &)> &answer_request,
- const std::function<void(const unsigned int,
- const std::vector<AnswerType> &)>
- & process_answer,
- const MPI_Comm &comm) override;
+ run(
+ const std::vector<unsigned int> & targets,
+ const std::function<RequestType(const unsigned int)> &create_request,
+ const std::function<AnswerType(const unsigned int,
+ const RequestType &)> &answer_request,
+ const std::function<void(const unsigned int, const AnswerType &)>
+ & process_answer,
+ const MPI_Comm &comm) override;
};
*/
template <typename RequestType, typename AnswerType>
std::vector<unsigned int>
- pex(const std::vector<unsigned int> &targets,
- const std::function<std::vector<RequestType>(const unsigned int)>
- & create_request,
- const std::function<std::vector<AnswerType>(
- const unsigned int,
- const std::vector<RequestType> &)> &answer_request,
- const std::function<void(const unsigned int,
- const std::vector<AnswerType> &)>
+ pex(const std::vector<unsigned int> & targets,
+ const std::function<RequestType(const unsigned int)> &create_request,
+ const std::function<AnswerType(const unsigned int,
+ const RequestType &)> &answer_request,
+ const std::function<void(const unsigned int, const AnswerType &)>
& process_answer,
const MPI_Comm &comm);
* @note The function call is delegated to another ConsensusAlgorithms::Interface implementation.
*/
virtual std::vector<unsigned int>
- run(const std::vector<unsigned int> &targets,
- const std::function<std::vector<RequestType>(const unsigned int)>
- & create_request,
- const std::function<std::vector<AnswerType>(
- const unsigned int,
- const std::vector<RequestType> &)> &answer_request,
- const std::function<void(const unsigned int,
- const std::vector<AnswerType> &)>
- & process_answer,
- const MPI_Comm &comm) override;
+ run(
+ const std::vector<unsigned int> & targets,
+ const std::function<RequestType(const unsigned int)> &create_request,
+ const std::function<AnswerType(const unsigned int,
+ const RequestType &)> &answer_request,
+ const std::function<void(const unsigned int, const AnswerType &)>
+ & process_answer,
+ const MPI_Comm &comm) override;
private:
// Pointer to the actual ConsensusAlgorithms::Interface implementation.
*/
template <typename RequestType, typename AnswerType>
std::vector<unsigned int>
- selector(const std::vector<unsigned int> &targets,
- const std::function<std::vector<RequestType>(const unsigned int)>
- & create_request,
- const std::function<std::vector<AnswerType>(
- const unsigned int,
- const std::vector<RequestType> &)> &answer_request,
- const std::function<void(const unsigned int,
- const std::vector<AnswerType> &)>
- & process_answer,
- const MPI_Comm &comm);
+ selector(
+ const std::vector<unsigned int> & targets,
+ const std::function<RequestType(const unsigned int)> &create_request,
+ const std::function<AnswerType(const unsigned int, const RequestType &)>
+ &answer_request,
+ const std::function<void(const unsigned int, const AnswerType &)>
+ & process_answer,
+ const MPI_Comm &comm);
AnonymousProcess(
const std::function<std::vector<unsigned int>()>
&function_compute_targets,
+ const std::function<void(const unsigned int, RequestType &)>
+ & function_create_request = {},
const std::function<void(const unsigned int,
- std::vector<RequestType> &)>
- &function_create_request = {},
- const std::function<void(const unsigned int,
- const std::vector<RequestType> &,
- std::vector<AnswerType> &)>
- &function_answer_request = {},
- const std::function<void(const unsigned int,
- const std::vector<AnswerType> &)>
+ const RequestType &,
+ AnswerType &)> &function_answer_request = {},
+ const std::function<void(const unsigned int, const AnswerType &)>
&function_read_answer = {});
/**
* @copydoc Process::create_request()
*/
void
- create_request(const unsigned int other_rank,
- std::vector<RequestType> &send_buffer) override;
+ create_request(const unsigned int other_rank,
+ RequestType & send_buffer) override;
/**
* @copydoc Process::answer_request()
*/
void
- answer_request(const unsigned int other_rank,
- const std::vector<RequestType> &buffer_recv,
- std::vector<AnswerType> & request_buffer) override;
+ answer_request(const unsigned int other_rank,
+ const RequestType &buffer_recv,
+ AnswerType & request_buffer) override;
/**
* @copydoc Process::read_answer()
*/
void
- read_answer(const unsigned int other_rank,
- const std::vector<AnswerType> &recv_buffer) override;
+ read_answer(const unsigned int other_rank,
+ const AnswerType & recv_buffer) override;
private:
const std::function<std::vector<unsigned int>()>
function_compute_targets;
- const std::function<void(const int, std::vector<RequestType> &)>
+ const std::function<void(const int, RequestType &)>
function_create_request;
- const std::function<void(const unsigned int,
- const std::vector<RequestType> &,
- std::vector<AnswerType> &)>
+ const std::function<
+ void(const unsigned int, const RequestType &, AnswerType &)>
function_answer_request;
- const std::function<void(const int, const std::vector<AnswerType> &)>
+ const std::function<void(const int, const AnswerType &)>
function_read_answer;
};
template <typename RequestType, typename AnswerType>
std::vector<unsigned int>
- nbx(const std::vector<unsigned int> &targets,
- const std::function<std::vector<RequestType>(const unsigned int)>
- & create_request,
- const std::function<std::vector<AnswerType>(
- const unsigned int,
- const std::vector<RequestType> &)> &answer_request,
- const std::function<void(const unsigned int,
- const std::vector<AnswerType> &)>
+ nbx(const std::vector<unsigned int> & targets,
+ const std::function<RequestType(const unsigned int)> &create_request,
+ const std::function<AnswerType(const unsigned int,
+ const RequestType &)> &answer_request,
+ const std::function<void(const unsigned int, const AnswerType &)>
& process_answer,
const MPI_Comm &comm)
{
template <typename RequestType, typename AnswerType>
std::vector<unsigned int>
- pex(const std::vector<unsigned int> &targets,
- const std::function<std::vector<RequestType>(const unsigned int)>
- & create_request,
- const std::function<std::vector<AnswerType>(
- const unsigned int,
- const std::vector<RequestType> &)> &answer_request,
- const std::function<void(const unsigned int,
- const std::vector<AnswerType> &)>
+ pex(const std::vector<unsigned int> & targets,
+ const std::function<RequestType(const unsigned int)> &create_request,
+ const std::function<AnswerType(const unsigned int,
+ const RequestType &)> &answer_request,
+ const std::function<void(const unsigned int, const AnswerType &)>
& process_answer,
const MPI_Comm &comm)
{
template <typename RequestType, typename AnswerType>
std::vector<unsigned int>
- serial(const std::vector<unsigned int> &targets,
- const std::function<std::vector<RequestType>(const unsigned int)>
- & create_request,
- const std::function<std::vector<AnswerType>(
- const unsigned int,
- const std::vector<RequestType> &)> &answer_request,
- const std::function<void(const unsigned int,
- const std::vector<AnswerType> &)>
- & process_answer,
- const MPI_Comm &comm)
+ serial(
+ const std::vector<unsigned int> & targets,
+ const std::function<RequestType(const unsigned int)> &create_request,
+ const std::function<AnswerType(const unsigned int, const RequestType &)>
+ &answer_request,
+ const std::function<void(const unsigned int, const AnswerType &)>
+ & process_answer,
+ const MPI_Comm &comm)
{
return Serial<RequestType, AnswerType>().run(
targets, create_request, answer_request, process_answer, comm);
template <typename RequestType, typename AnswerType>
std::vector<unsigned int>
- selector(const std::vector<unsigned int> &targets,
- const std::function<std::vector<RequestType>(const unsigned int)>
- & create_request,
- const std::function<std::vector<AnswerType>(
- const unsigned int,
- const std::vector<RequestType> &)> &answer_request,
- const std::function<void(const unsigned int,
- const std::vector<AnswerType> &)>
- & process_answer,
- const MPI_Comm &comm)
+ selector(
+ const std::vector<unsigned int> & targets,
+ const std::function<RequestType(const unsigned int)> &create_request,
+ const std::function<AnswerType(const unsigned int, const RequestType &)>
+ &answer_request,
+ const std::function<void(const unsigned int, const AnswerType &)>
+ & process_answer,
+ const MPI_Comm &comm)
{
return Selector<RequestType, AnswerType>().run(
targets, create_request, answer_request, process_answer, comm);
AnonymousProcess<RequestType, AnswerType>::AnonymousProcess(
const std::function<std::vector<unsigned int>()>
&function_compute_targets,
+ const std::function<void(const unsigned int, RequestType &)>
+ & function_create_request,
const std::function<void(const unsigned int,
- std::vector<RequestType> &)>
- &function_create_request,
- const std::function<void(const unsigned int,
- const std::vector<RequestType> &,
- std::vector<AnswerType> &)>
- &function_answer_request,
- const std::function<void(const unsigned int,
- const std::vector<AnswerType> &)>
+ const RequestType &,
+ AnswerType &)> &function_answer_request,
+ const std::function<void(const unsigned int, const AnswerType &)>
&function_read_answer)
: function_compute_targets(function_compute_targets)
, function_create_request(function_create_request)
template <typename RequestType, typename AnswerType>
void
AnonymousProcess<RequestType, AnswerType>::create_request(
- const unsigned int other_rank,
- std::vector<RequestType> &send_buffer)
+ const unsigned int other_rank,
+ RequestType & send_buffer)
{
if (function_create_request)
function_create_request(other_rank, send_buffer);
template <typename RequestType, typename AnswerType>
void
AnonymousProcess<RequestType, AnswerType>::answer_request(
- const unsigned int other_rank,
- const std::vector<RequestType> &buffer_recv,
- std::vector<AnswerType> & request_buffer)
+ const unsigned int other_rank,
+ const RequestType &buffer_recv,
+ AnswerType & request_buffer)
{
if (function_answer_request)
function_answer_request(other_rank, buffer_recv, request_buffer);
template <typename RequestType, typename AnswerType>
void
AnonymousProcess<RequestType, AnswerType>::read_answer(
- const unsigned int other_rank,
- const std::vector<AnswerType> &recv_buffer)
+ const unsigned int other_rank,
+ const AnswerType & recv_buffer)
{
if (function_read_answer)
function_read_answer(other_rank, recv_buffer);
template <typename RequestType, typename AnswerType>
void
- Process<RequestType, AnswerType>::answer_request(
- const unsigned int,
- const std::vector<RequestType> &,
- std::vector<AnswerType> &)
+ Process<RequestType, AnswerType>::answer_request(const unsigned int,
+ const RequestType &,
+ AnswerType &)
{
// nothing to do
}
template <typename RequestType, typename AnswerType>
void
- Process<RequestType, AnswerType>::create_request(
- const unsigned int,
- std::vector<RequestType> &)
+ Process<RequestType, AnswerType>::create_request(const unsigned int,
+ RequestType &)
{
// nothing to do
}
template <typename RequestType, typename AnswerType>
void
- Process<RequestType, AnswerType>::read_answer(
- const unsigned int,
- const std::vector<AnswerType> &)
+ Process<RequestType, AnswerType>::read_answer(const unsigned int,
+ const AnswerType &)
{
// nothing to do
}
process.compute_targets(),
/* create_request: */
[&process](const unsigned int target) {
- std::vector<RequestType> request;
+ RequestType request;
process.create_request(target, request);
return request;
},
/* answer_request: */
- [&process](const unsigned int source,
- const std::vector<RequestType> &request) {
- std::vector<AnswerType> answer;
+ [&process](const unsigned int source, const RequestType &request) {
+ AnswerType answer;
process.answer_request(source, request, answer);
return answer;
},
/* process_answer: */
- [&process](const unsigned int target,
- const std::vector<AnswerType> &answer) {
+ [&process](const unsigned int target, const AnswerType &answer) {
process.read_answer(target, answer);
},
comm);
template <typename RequestType, typename AnswerType>
std::vector<unsigned int>
NBX<RequestType, AnswerType>::run(
- const std::vector<unsigned int> &targets,
- const std::function<std::vector<RequestType>(const unsigned int)>
- & create_request,
- const std::function<std::vector<AnswerType>(
- const unsigned int,
- const std::vector<RequestType> &)> &answer_request,
- const std::function<void(const unsigned int,
- const std::vector<AnswerType> &)>
+ const std::vector<unsigned int> & targets,
+ const std::function<RequestType(const unsigned int)> &create_request,
+ const std::function<AnswerType(const unsigned int, const RequestType &)>
+ &answer_request,
+ const std::function<void(const unsigned int, const AnswerType &)>
& process_answer,
const MPI_Comm &comm)
{
template <typename RequestType, typename AnswerType>
void
NBX<RequestType, AnswerType>::start_communication(
- const std::vector<unsigned int> &targets,
- const std::function<std::vector<RequestType>(const unsigned int)>
- & create_request,
- const MPI_Comm &comm)
+ const std::vector<unsigned int> & targets,
+ const std::function<RequestType(const unsigned int)> &create_request,
+ const MPI_Comm & comm)
{
#ifdef DEAL_II_WITH_MPI
// 1)
AssertIndexRange(rank, Utilities::MPI::n_mpi_processes(comm));
auto &send_buffer = send_buffers[index];
- send_buffer = (create_request ? create_request(rank) :
- std::vector<RequestType>());
+ send_buffer =
+ (create_request ? Utilities::pack(create_request(rank)) :
+ std::vector<char>());
// Post a request to send data
auto ierr = MPI_Isend(send_buffer.data(),
- send_buffer.size() * sizeof(RequestType),
- MPI_BYTE,
+ send_buffer.size(),
+ MPI_CHAR,
rank,
tag_request,
comm,
bool
NBX<RequestType, AnswerType>::
all_locally_originated_receives_are_completed(
- const std::function<void(const unsigned int,
- const std::vector<AnswerType> &)>
+ const std::function<void(const unsigned int, const AnswerType &)>
& process_answer,
const MPI_Comm &comm)
{
int message_size;
{
const int ierr =
- MPI_Get_count(&status, MPI_BYTE, &message_size);
+ MPI_Get_count(&status, MPI_CHAR, &message_size);
AssertThrowMPI(ierr);
}
- Assert(message_size % sizeof(AnswerType) == 0,
- ExcInternalError());
- std::vector<AnswerType> recv_buffer(message_size /
- sizeof(AnswerType));
+ std::vector<char> recv_buffer(message_size);
{
const int tag_deliver = Utilities::MPI::internal::Tags::
consensus_algorithm_nbx_process_deliver;
- const int ierr =
- MPI_Recv(recv_buffer.data(),
- recv_buffer.size() * sizeof(AnswerType),
- MPI_BYTE,
- target,
- tag_deliver,
- comm,
- MPI_STATUS_IGNORE);
+ const int ierr = MPI_Recv(recv_buffer.data(),
+ recv_buffer.size(),
+ MPI_CHAR,
+ target,
+ tag_deliver,
+ comm,
+ MPI_STATUS_IGNORE);
AssertThrowMPI(ierr);
}
if (process_answer)
- process_answer(target, recv_buffer);
+ process_answer(target,
+ Utilities::unpack<AnswerType>(recv_buffer));
// Finally, remove this rank from the list of outstanding
// targets:
template <typename RequestType, typename AnswerType>
void
NBX<RequestType, AnswerType>::maybe_answer_one_request(
- const std::function<std::vector<AnswerType>(
- const unsigned int,
- const std::vector<RequestType> &)> &answer_request,
- const MPI_Comm & comm)
+ const std::function<AnswerType(const unsigned int, const RequestType &)>
+ & answer_request,
+ const MPI_Comm &comm)
{
#ifdef DEAL_II_WITH_MPI
// get size of incoming message
int number_amount;
- auto ierr = MPI_Get_count(&status, MPI_BYTE, &number_amount);
+ auto ierr = MPI_Get_count(&status, MPI_CHAR, &number_amount);
AssertThrowMPI(ierr);
// allocate memory for incoming message
- Assert(number_amount % sizeof(RequestType) == 0,
- ExcInternalError());
- std::vector<RequestType> buffer_recv(number_amount /
- sizeof(RequestType));
+ std::vector<char> buffer_recv(number_amount);
ierr = MPI_Recv(buffer_recv.data(),
number_amount,
- MPI_BYTE,
+ MPI_CHAR,
other_rank,
tag_request,
comm,
// Allocate memory for an answer message to the current request,
// and ask the 'process' object to produce an answer:
- request_buffers.emplace_back(
- std::make_unique<std::vector<AnswerType>>());
+ request_buffers.emplace_back(std::make_unique<std::vector<char>>());
auto &request_buffer = *request_buffers.back();
if (answer_request)
- request_buffer = answer_request(other_rank, buffer_recv);
+ request_buffer = Utilities::pack(
+ answer_request(other_rank,
+ Utilities::unpack<RequestType>(buffer_recv)));
// Then initiate sending the answer back to the requester.
request_requests.emplace_back(std::make_unique<MPI_Request>());
ierr = MPI_Isend(request_buffer.data(),
- request_buffer.size() * sizeof(AnswerType),
- MPI_BYTE,
+ request_buffer.size(),
+ MPI_CHAR,
other_rank,
tag_deliver,
comm,
template <typename RequestType, typename AnswerType>
std::vector<unsigned int>
PEX<RequestType, AnswerType>::run(
- const std::vector<unsigned int> &targets,
- const std::function<std::vector<RequestType>(const unsigned int)>
- & create_request,
- const std::function<std::vector<AnswerType>(
- const unsigned int,
- const std::vector<RequestType> &)> &answer_request,
- const std::function<void(const unsigned int,
- const std::vector<AnswerType> &)>
+ const std::vector<unsigned int> & targets,
+ const std::function<RequestType(const unsigned int)> &create_request,
+ const std::function<AnswerType(const unsigned int, const RequestType &)>
+ &answer_request,
+ const std::function<void(const unsigned int, const AnswerType &)>
& process_answer,
const MPI_Comm &comm)
{
template <typename RequestType, typename AnswerType>
unsigned int
PEX<RequestType, AnswerType>::start_communication(
- const std::vector<unsigned int> &targets,
- const std::function<std::vector<RequestType>(const unsigned int)>
- & create_request,
- const MPI_Comm &comm)
+ const std::vector<unsigned int> & targets,
+ const std::function<RequestType(const unsigned int)> &create_request,
+ const MPI_Comm & comm)
{
#ifdef DEAL_II_WITH_MPI
const int tag_request = Utilities::MPI::internal::Tags::
// pack data which should be sent
auto &send_buffer = send_buffers[i];
- send_buffer = (create_request ? create_request(rank) :
- std::vector<RequestType>());
+ if (create_request)
+ send_buffer = Utilities::pack(create_request(rank));
// start to send data
auto ierr = MPI_Isend(send_buffer.data(),
- send_buffer.size() * sizeof(RequestType),
- MPI_BYTE,
+ send_buffer.size(),
+ MPI_CHAR,
rank,
tag_request,
comm,
template <typename RequestType, typename AnswerType>
void
PEX<RequestType, AnswerType>::answer_one_request(
- const unsigned int index,
- const std::function<std::vector<AnswerType>(
- const unsigned int,
- const std::vector<RequestType> &)> &answer_request,
- const MPI_Comm & comm)
+ const unsigned int index,
+ const std::function<AnswerType(const unsigned int, const RequestType &)>
+ & answer_request,
+ const MPI_Comm &comm)
{
#ifdef DEAL_II_WITH_MPI
const int tag_request = Utilities::MPI::internal::Tags::
"received. This algorithm does not expect this to happen."));
requesting_processes.insert(other_rank);
- std::vector<RequestType> buffer_recv;
-
// Actually get the incoming message:
int number_amount;
- ierr = MPI_Get_count(&status, MPI_BYTE, &number_amount);
+ ierr = MPI_Get_count(&status, MPI_CHAR, &number_amount);
AssertThrowMPI(ierr);
- Assert(number_amount % sizeof(RequestType) == 0, ExcInternalError());
- buffer_recv.resize(number_amount / sizeof(RequestType));
+ std::vector<char> buffer_recv(number_amount);
ierr = MPI_Recv(buffer_recv.data(),
number_amount,
- MPI_BYTE,
+ MPI_CHAR,
other_rank,
tag_request,
comm,
// the answer and post a send for it.
auto &request_buffer = requests_buffers[index];
request_buffer =
- (answer_request ? answer_request(other_rank, buffer_recv) :
- std::vector<AnswerType>());
+ (answer_request ?
+ Utilities::pack(answer_request(
+ other_rank, Utilities::unpack<RequestType>(buffer_recv))) :
+ std::vector<char>());
ierr = MPI_Isend(request_buffer.data(),
- request_buffer.size() * sizeof(AnswerType),
- MPI_BYTE,
+ request_buffer.size(),
+ MPI_CHAR,
other_rank,
tag_deliver,
comm,
void
PEX<RequestType, AnswerType>::process_incoming_answers(
const unsigned int n_targets,
- const std::function<void(const unsigned int,
- const std::vector<AnswerType> &)>
+ const std::function<void(const unsigned int, const AnswerType &)>
& process_answer,
const MPI_Comm &comm)
{
const auto other_rank = status.MPI_SOURCE;
int message_size;
{
- const int ierr = MPI_Get_count(&status, MPI_BYTE, &message_size);
+ const int ierr = MPI_Get_count(&status, MPI_CHAR, &message_size);
AssertThrowMPI(ierr);
}
- Assert(message_size % sizeof(AnswerType) == 0, ExcInternalError());
- std::vector<AnswerType> recv_buffer(message_size /
- sizeof(AnswerType));
+ std::vector<char> recv_buffer(message_size);
// Now actually receive the answer. Because the MPI_Probe
// above blocks until we have a message, we know that the
// following MPI_Recv call will immediately succeed.
{
const int ierr = MPI_Recv(recv_buffer.data(),
- recv_buffer.size() * sizeof(AnswerType),
- MPI_BYTE,
+ recv_buffer.size(),
+ MPI_CHAR,
other_rank,
tag_deliver,
comm,
}
if (process_answer)
- process_answer(other_rank, recv_buffer);
+ process_answer(other_rank,
+ Utilities::unpack<AnswerType>(recv_buffer));
}
#else
(void)n_targets;
template <typename RequestType, typename AnswerType>
std::vector<unsigned int>
Serial<RequestType, AnswerType>::run(
- const std::vector<unsigned int> &targets,
- const std::function<std::vector<RequestType>(const unsigned int)>
- & create_request,
- const std::function<std::vector<AnswerType>(
- const unsigned int,
- const std::vector<RequestType> &)> &answer_request,
- const std::function<void(const unsigned int,
- const std::vector<AnswerType> &)>
+ const std::vector<unsigned int> & targets,
+ const std::function<RequestType(const unsigned int)> &create_request,
+ const std::function<AnswerType(const unsigned int, const RequestType &)>
+ &answer_request,
+ const std::function<void(const unsigned int, const AnswerType &)>
& process_answer,
const MPI_Comm &comm)
{
// Since the caller indicates that there is a target, and since we
// know that it is the current process, let the process send
// something to itself.
- const std::vector<RequestType> request =
- (create_request ? create_request(0) : std::vector<RequestType>());
- const std::vector<AnswerType> answer =
- (answer_request ? answer_request(0, request) :
- std::vector<AnswerType>());
+ const RequestType request =
+ (create_request ? create_request(0) : RequestType());
+ const AnswerType answer =
+ (answer_request ? answer_request(0, request) : AnswerType());
if (process_answer)
process_answer(0, answer);
template <typename RequestType, typename AnswerType>
std::vector<unsigned int>
Selector<RequestType, AnswerType>::run(
- const std::vector<unsigned int> &targets,
- const std::function<std::vector<RequestType>(const unsigned int)>
- & create_request,
- const std::function<std::vector<AnswerType>(
- const unsigned int,
- const std::vector<RequestType> &)> &answer_request,
- const std::function<void(const unsigned int,
- const std::vector<AnswerType> &)>
+ const std::vector<unsigned int> & targets,
+ const std::function<RequestType(const unsigned int)> &create_request,
+ const std::function<AnswerType(const unsigned int, const RequestType &)>
+ &answer_request,
+ const std::function<void(const unsigned int, const AnswerType &)>
& process_answer,
const MPI_Comm &comm)
{
Assert(answer.size() == 0, ExcInternalError());
};
- Utilities::MPI::ConsensusAlgorithms::selector<char, char>(destinations,
- create_request,
- answer_request,
- read_answer,
- communicator);
+ Utilities::MPI::ConsensusAlgorithms::selector<std::vector<char>,
+ std::vector<char>>(
+ destinations,
+ create_request,
+ answer_request,
+ read_answer,
+ communicator);
}
true);
Utilities::MPI::ConsensusAlgorithms::Selector<
- std::pair<types::global_dof_index, types::global_dof_index>,
- unsigned int>(constrained_indices_process, mpi_communicator)
+ std::vector<std::pair<types::global_dof_index, types::global_dof_index>>,
+ std::vector<unsigned int>>(constrained_indices_process, mpi_communicator)
.run();
// step 2: collect all locally owned constraints
true);
Utilities::MPI::ConsensusAlgorithms::Selector<
- std::pair<types::global_dof_index, types::global_dof_index>,
- unsigned int>(locally_relevant_dofs_process, mpi_communicator)
+ std::vector<
+ std::pair<types::global_dof_index, types::global_dof_index>>,
+ std::vector<unsigned int>>(locally_relevant_dofs_process,
+ mpi_communicator)
.run();
const auto locally_relevant_dofs_by_ranks =
}
};
- Utilities::MPI::ConsensusAlgorithms::
- Selector<dealii::types::global_dof_index, unsigned int>()
- .run(targets,
- create_request,
- answer_request,
- process_answer,
- communicator_sm);
+ Utilities::MPI::ConsensusAlgorithms::Selector<
+ std::vector<dealii::types::global_dof_index>,
+ std::vector<unsigned int>>()
+ .run(targets,
+ create_request,
+ answer_request,
+ process_answer,
+ communicator_sm);
return cells;
}();
false);
Utilities::MPI::ConsensusAlgorithms::Selector<
- std::pair<types::global_cell_index, types::global_cell_index>,
- unsigned int>
+ std::vector<
+ std::pair<types::global_cell_index, types::global_cell_index>>,
+ std::vector<unsigned int>>
consensus_algorithm(process, communicator);
consensus_algorithm.run();
}
true);
Utilities::MPI::ConsensusAlgorithms::Selector<
- std::pair<types::global_cell_index, types::global_cell_index>,
- unsigned int>
+ std::vector<
+ std::pair<types::global_cell_index, types::global_cell_index>>,
+ std::vector<unsigned int>>
consensus_algorithm(process, communicator);
consensus_algorithm.run();
false);
Utilities::MPI::ConsensusAlgorithms::Selector<
- std::pair<types::global_cell_index, types::global_cell_index>,
- unsigned int>
+ std::vector<
+ std::pair<types::global_cell_index, types::global_cell_index>>,
+ std::vector<unsigned int>>
consensus_algorithm(process, communicator);
consensus_algorithm.run();
if (Utilities::MPI::min((my_destinations_are_unique ? 1 : 0), mpi_comm) ==
1)
{
- return ConsensusAlgorithms::nbx<char, char>(
+ return ConsensusAlgorithms::nbx<std::vector<char>, std::vector<char>>(
destinations, {}, {}, {}, mpi_comm);
}
if (Utilities::MPI::min((my_destinations_are_unique ? 1 : 0), mpi_comm) ==
1)
{
- return ConsensusAlgorithms::nbx<char, char>(
+ return ConsensusAlgorithms::nbx<std::vector<char>, std::vector<char>>(
destinations, {}, {}, {}, mpi_comm)
.size();
}
// partition (i.e. in the dictionary). This process returns the actual
// owner of the index.
ConsensusAlgorithms::Selector<
- std::pair<types::global_dof_index, types::global_dof_index>,
- unsigned int>
+ std::vector<
+ std::pair<types::global_dof_index, types::global_dof_index>>,
+ std::vector<unsigned int>>
consensus_algorithm(process, comm);
consensus_algorithm.run();
actually_owning_rank_list);
ConsensusAlgorithms::Selector<
- std::pair<types::global_dof_index, types::global_dof_index>,
- unsigned int>
+ std::vector<
+ std::pair<types::global_dof_index, types::global_dof_index>>,
+ std::vector<unsigned int>>
consensus_algo(temp, comm);
consensus_algo.run();
}
#include <deal.II/base/mpi_consensus_algorithms.templates.h>
+#include <boost/serialization/utility.hpp>
+
+
DEAL_II_NAMESPACE_OPEN
namespace Utilities
{
namespace ConsensusAlgorithms
{
- template class Process<unsigned int, unsigned int>;
+ template class Process<std::vector<unsigned int>,
+ std::vector<unsigned int>>;
- template class Interface<unsigned int, unsigned int>;
+ template class Interface<std::vector<unsigned int>,
+ std::vector<unsigned int>>;
- template class NBX<unsigned int, unsigned int>;
+ template class NBX<std::vector<unsigned int>, std::vector<unsigned int>>;
- template class PEX<unsigned int, unsigned int>;
+ template class PEX<std::vector<unsigned int>, std::vector<unsigned int>>;
- template class Serial<unsigned int, unsigned int>;
+ template class Serial<std::vector<unsigned int>,
+ std::vector<unsigned int>>;
- template class Selector<unsigned int, unsigned int>;
+ template class Selector<std::vector<unsigned int>,
+ std::vector<unsigned int>>;
- template class Process<
- std::pair<types::global_dof_index, types::global_dof_index>,
- unsigned int>;
+ template class Process<std::vector<std::pair<types::global_dof_index,
+ types::global_dof_index>>,
+ std::vector<unsigned int>>;
- template class Interface<
- std::pair<types::global_dof_index, types::global_dof_index>,
- unsigned int>;
+ template class Interface<std::vector<std::pair<types::global_dof_index,
+ types::global_dof_index>>,
+ std::vector<unsigned int>>;
- template class Selector<
- std::pair<types::global_dof_index, types::global_dof_index>,
- unsigned int>;
+ template class Selector<std::vector<std::pair<types::global_dof_index,
+ types::global_dof_index>>,
+ std::vector<unsigned int>>;
- template class NBX<
- std::pair<types::global_dof_index, types::global_dof_index>,
- unsigned int>;
+ template class NBX<std::vector<std::pair<types::global_dof_index,
+ types::global_dof_index>>,
+ std::vector<unsigned int>>;
- template class Serial<
- std::pair<types::global_dof_index, types::global_dof_index>,
- unsigned int>;
+ template class Serial<std::vector<std::pair<types::global_dof_index,
+ types::global_dof_index>>,
+ std::vector<unsigned int>>;
- template class PEX<
- std::pair<types::global_dof_index, types::global_dof_index>,
- unsigned int>;
+ template class PEX<std::vector<std::pair<types::global_dof_index,
+ types::global_dof_index>>,
+ std::vector<unsigned int>>;
#ifdef DEAL_II_WITH_64BIT_INDICES
- template class Process<types::global_dof_index, unsigned int>;
+ template class Process<std::vector<types::global_dof_index>,
+ std::vector<unsigned int>>;
- template class Interface<types::global_dof_index, unsigned int>;
+ template class Interface<std::vector<types::global_dof_index>,
+ std::vector<unsigned int>>;
- template class NBX<types::global_dof_index, unsigned int>;
+ template class NBX<std::vector<types::global_dof_index>,
+ std::vector<unsigned int>>;
- template class Serial<types::global_dof_index, unsigned int>;
+ template class Serial<std::vector<types::global_dof_index>,
+ std::vector<unsigned int>>;
- template class PEX<types::global_dof_index, unsigned int>;
+ template class PEX<std::vector<types::global_dof_index>,
+ std::vector<unsigned int>>;
- template class Selector<types::global_dof_index, unsigned int>;
+ template class Selector<std::vector<types::global_dof_index>,
+ std::vector<unsigned int>>;
#endif
- template class Process<char, char>;
+ template class Process<std::vector<char>, std::vector<char>>;
- template class Interface<char, char>;
+ template class Interface<std::vector<char>, std::vector<char>>;
- template class NBX<char, char>;
+ template class NBX<std::vector<char>, std::vector<char>>;
- template class PEX<char, char>;
+ template class PEX<std::vector<char>, std::vector<char>>;
- template class Serial<char, char>;
+ template class Serial<std::vector<char>, std::vector<char>>;
- template class Selector<char, char>;
+ template class Selector<std::vector<char>, std::vector<char>>;
} // namespace ConsensusAlgorithms
} // end of namespace MPI
true);
Utilities::MPI::ConsensusAlgorithms::Selector<
- std::pair<types::global_dof_index, types::global_dof_index>,
- unsigned int>
+ std::vector<
+ std::pair<types::global_dof_index, types::global_dof_index>>,
+ std::vector<unsigned int>>
consensus_algorithm(process, communicator);
consensus_algorithm.run();
// in the static partition (i.e. in the dictionary). This process
// returns the actual owner of the index.
ConsensusAlgorithms::Selector<
- std::pair<types::global_dof_index, types::global_dof_index>,
- unsigned int>
+ std::vector<
+ std::pair<types::global_dof_index, types::global_dof_index>>,
+ std::vector<unsigned int>>
consensus_algorithm(process, communicator);
consensus_algorithm.run();
false);
Utilities::MPI::ConsensusAlgorithms::Selector<
- std::pair<types::global_cell_index, types::global_cell_index>,
- unsigned int>
+ std::vector<
+ std::pair<types::global_cell_index, types::global_cell_index>>,
+ std::vector<unsigned int>>
consensus_algorithm(process, communicator);
consensus_algorithm.run();
}
}
};
- Utilities::MPI::ConsensusAlgorithms::selector<char, char>(
+ Utilities::MPI::ConsensusAlgorithms::selector<std::vector<char>,
+ std::vector<char>>(
potential_owners_ranks,
create_request,
answer_request,
};
- dealii::Utilities::MPI::ConsensusAlgorithms::selector<char, char>(
- relevant_processes,
- create_request,
- answer_request,
- process_answer,
- comm);
+ dealii::Utilities::MPI::ConsensusAlgorithms::
+ selector<std::vector<char>, std::vector<char>>(relevant_processes,
+ create_request,
+ answer_request,
+ process_answer,
+ comm);
}
/**
/*track_index_requests = */ true);
Utilities::MPI::ConsensusAlgorithms::Selector<
- std::pair<types::global_dof_index, types::global_dof_index>,
- unsigned int>
+ std::vector<
+ std::pair<types::global_dof_index, types::global_dof_index>>,
+ std::vector<unsigned int>>
consensus_algorithm(process, comm);
consensus_algorithm.run();
false);
Utilities::MPI::ConsensusAlgorithms::Selector<
- std::pair<types::global_cell_index, types::global_cell_index>,
- unsigned int>
+ std::vector<
+ std::pair<types::global_cell_index, types::global_cell_index>>,
+ std::vector<unsigned int>>
consensus_algorithm;
consensus_algorithm.run(process, communicator);
const unsigned int my_rank = dealii::Utilities::MPI::this_mpi_process(comm);
const unsigned int n_rank = dealii::Utilities::MPI::n_mpi_processes(comm);
- using T1 = unsigned int;
- using T2 = unsigned int;
+ using T1 = std::vector<unsigned int>;
+ using T2 = std::vector<unsigned int>;
const auto sources =
dealii::Utilities::MPI::ConsensusAlgorithms::selector<T1, T2>(
/* target_processes: */
std::vector<unsigned int>{(my_rank + 1) % n_rank},
/* create_request: */
- [my_rank](const unsigned int) { return std::vector<T1>({my_rank}); },
+ [my_rank](const unsigned int) { return T1({my_rank}); },
/* answer_request: */
- [my_rank](const unsigned int other_rank, const std::vector<T1> &request) {
+ [my_rank](const unsigned int other_rank, const T1 &request) {
AssertDimension(other_rank, request.front());
deallog << "ConsensusAlgorithmProcess::answer_request() passed!"
<< std::endl;
- return std::vector<T2>({my_rank});
+ return T2({my_rank});
},
/* process_answer: */
- [](const unsigned int other_rank, const std::vector<T2> &answer) {
+ [](const unsigned int other_rank, const T2 &answer) {
AssertDimension(other_rank, answer.front());
deallog << "ConsensusAlgorithmProcess::function_read_answer() passed!"
<< std::endl;