34#ifdef Q3_WITH_FFTW_MPI
54 int already_initialized = 0;
55 MPI_Initialized(&already_initialized);
56 if (!already_initialized) {
57 MPI_Init(
nullptr,
nullptr);
58#ifdef Q3_USE_FFTW_THREADS
65 const char* omp_env = std::getenv(
"OMP_NUM_THREADS");
66 if (omp_env && std::atoi(omp_env) > 1) {
71#ifdef Q3_WITH_FFTW_MPI
74 owns_mpi_lifecycle_ =
true;
77 MPI_Comm_rank(MPI_COMM_WORLD, &world_rank_index_);
78 MPI_Comm_size(MPI_COMM_WORLD, &world_size_);
100 if (number_of_groups < 1 || number_of_groups > world_size_) {
101 throw std::invalid_argument(
"MPIExecutionPolicy: number_of_groups out of range.");
109 const int group_size = world_size_ / number_of_groups;
194 MPI_Finalized(&finalized);
198 if (std::uncaught_exceptions() > 0) {
204 if (owns_mpi_lifecycle_) {
205 MPI_Barrier(MPI_COMM_WORLD);
227 serial_policy_.
dot_product(number_of_elements, vector_x, vector_y);
241 serial_policy_.
add_scaled_vector(number_of_elements, scaling_factor, vector_x, vector_y);
251 return std::sqrt(std::real(dot));
255 return world_rank_index_ == 0;
271 int total_number_of_elements = local_number_of_elements;
276 return total_number_of_elements;
311 int number_of_elements)
const override {
320 int )
const override {
322 std::memcpy(full_data, local_data, local_count *
sizeof(
Real));
331 displacements[rank] = displacements[rank - 1] + receive_counts[rank - 1];
333 MPI_Allgatherv(local_data,
337 receive_counts.data(),
338 displacements.data(),
346 return world_rank_index_;
356 return MPI_COMM_WORLD;
386 const int* displacements)
const override {
400 MPI_Allgatherv(MPI_IN_PLACE,
445 int world_rank_index_ = 0;
447 bool owns_mpi_lifecycle_ =
false;
Real norm(int number_of_elements, const ComplexValue *vector_x) const override
MPI_Comm group_communicator_
void broadcast_across_bands(int *data, int number_of_elements) const override
Integer overload, for the counts that decide collective sizes.
int world_rank_index() const
void reduce_group_distributed_result(ComplexValue *data, int number_of_elements) const override
MPI_Comm get_world_communicator() const
int band_distribution_rank_index_
void configure_group_topology(int number_of_groups)
int band_distribution_size_
int band_distribution_rank_index() const override
void enable_band_distribution()
ComplexValue dot_product(int number_of_elements, const ComplexValue *vector_x, const ComplexValue *vector_y) const override
void allgather_within_group(const Real *local_data, int local_count, Real *full_data, int) const override
void reduce_within_group(Real *data, int number_of_elements) const override
~MPIExecutionPolicy() override
int global_number_of_elements(int local_number_of_elements) const override
void reduce_across_bands(Real *data, int number_of_elements) const override
int number_of_processes() const override
MPIExecutionPolicy(const MPIExecutionPolicy &)=delete
void broadcast_from_group_root(ComplexValue *data, int number_of_elements) const override
bool is_root() const override
int band_distribution_size() const override
void broadcast_from_group_root(Real *data, int number_of_elements) const override
int group_rank_index() const override
void broadcast_across_bands(Real *data, int number_of_elements) const override
Real overload, for eigenvalues – the numbers convergence decisions are made from.
void add_scaled_vector(int number_of_elements, ComplexValue scaling_factor, const ComplexValue *vector_x, ComplexValue *vector_y) const override
MPI_Comm get_group_communicator() const
MPIExecutionPolicy & operator=(const MPIExecutionPolicy &)=delete
void disable_group_distribution()
int group_size() const override
void reduce_within_group(ComplexValue *data, int number_of_elements) const override
void broadcast_across_bands(ComplexValue *data, int number_of_elements) const override
void allgather_across_bands(ComplexValue *data, const int *counts, const int *displacements) const override
ComplexValue dot_product(int number_of_elements, const ComplexValue *vector_x, const ComplexValue *vector_y) const override
void add_scaled_vector(int number_of_elements, ComplexValue scaling_factor, const ComplexValue *vector_x, ComplexValue *vector_y) const override
MPI_Datatype complex_datatype()
int sum_complex_in_place(Complex *data, int number_of_elements, MPI_Comm communicator)
In-place complex MPI_SUM – see sum_complex().