*/
const MPI_Comm &comm;
+ /**
+ * Cache if job supports MPI.
+ */
+ const bool job_supports_mpi;
+
/**
* Rank of this process.
*/
clean_up_and_end_communication();
};
+ /**
+ * A serial fall back for the above classes to allow programming
+ * independently of whether MPI is used or not.
+ */
+ template <typename T1, typename T2>
+ class Serial : public Interface<T1, T2>
+ {
+ public:
+ /**
+ * Constructor.
+ *
+ * @param process Process to be run during consensus algorithm.
+ * @param comm MPI Communicator (ignored)
+ */
+ Serial(Process<T1, T2> &process, const MPI_Comm &comm);
+
+ /**
+ * @copydoc Interface::run()
+ */
+ virtual void
+ run() override;
+ };
+
/**
* A class which delegates its task to other
* ConsensusAlgorithms::Interface implementations depending on the number
const MPI_Comm & comm)
: process(process)
, comm(comm)
- , my_rank(Utilities::MPI::job_supports_mpi() ? this_mpi_process(comm) :
- 0)
- , n_procs(Utilities::MPI::job_supports_mpi() ? n_mpi_processes(comm) :
- 1)
+ , job_supports_mpi(Utilities::MPI::job_supports_mpi())
+ , my_rank(job_supports_mpi ? this_mpi_process(comm) : 0)
+ , n_procs(job_supports_mpi ? n_mpi_processes(comm) : 1)
{}
+ template <typename T1, typename T2>
+ Serial<T1, T2>::Serial(Process<T1, T2> &process, const MPI_Comm &comm)
+ : Interface<T1, T2>(process, comm)
+ {}
+
+
+
+ template <typename T1, typename T2>
+ void
+ Serial<T1, T2>::run()
+ {
+ const auto targets = this->process.compute_targets();
+
+ if (targets.size() == 0)
+ return; // nothing to do
+
+ AssertDimension(targets[0], 0);
+
+ std::vector<T1> send_buffer;
+ std::vector<T2> recv_buffer;
+ std::vector<T2> request_buffer;
+ std::vector<T1> buffer_recv;
+
+ this->process.create_request(0, send_buffer);
+ this->process.prepare_buffer_for_answer(0, recv_buffer);
+ this->process.answer_request(0, buffer_recv, request_buffer);
+ this->process.read_answer(0, recv_buffer);
+ }
+
+
+
template <typename T1, typename T2>
Selector<T1, T2>::Selector(Process<T1, T2> &process, const MPI_Comm &comm)
: Interface<T1, T2>(process, comm)
#endif
if (this->n_procs > 1)
consensus_algo.reset(new PEX<T1, T2>(process, comm));
+ else
+ consensus_algo.reset(new Serial<T1, T2>(process, comm));
}
void
Selector<T1, T2>::run()
{
- if (consensus_algo)
- consensus_algo->run();
+ consensus_algo->run();
}
template class PEX<unsigned int, unsigned int>;
+ template class Serial<unsigned int, unsigned int>;
+
template class Selector<unsigned int, unsigned int>;
std::pair<types::global_dof_index, types::global_dof_index>,
unsigned int>;
+ template class Serial<
+ std::pair<types::global_dof_index, types::global_dof_index>,
+ unsigned int>;
+
template class PEX<
std::pair<types::global_dof_index, types::global_dof_index>,
unsigned int>;
template class NBX<types::global_dof_index, unsigned int>;
+ template class Serial<types::global_dof_index, unsigned int>;
+
template class PEX<types::global_dof_index, unsigned int>;
template class Selector<types::global_dof_index, unsigned int>;