23int main(
int argc,
char* argv[]) {
27 auto policy = std::make_unique<execution::PlanewaveMPIExecutionPolicy>();
37 if (options.print_version) {
46 if (!options.log_level.empty()) {
56 int world_rank_index = 0;
57 MPI_Comm_rank(MPI_COMM_WORLD, &world_rank_index);
72 int requested_number_of_pools = options.number_of_kpoint_pools_was_set
73 ? options.number_of_kpoint_pools
74 : input.number_of_kpoint_pools;
75 policy->configure_topology(requested_number_of_pools);
95 if (options.distribute_bands) {
96 policy->enable_band_distribution();
107 const char* pool_source =
108 options.number_of_kpoint_pools_was_set
110 : (input.number_of_kpoint_pools != 0 ?
"control.number_of_kpoint_pools"
120 int ranks_per_pool = policy->world_size() / std::max(policy->number_of_pools(), 1);
121 log::info(
"MPI topology: {} rank(s), {} k-point pool(s), {} rank(s) per pool ({}), "
122 "splitting {} within a pool",
123 policy->world_size(),
124 policy->number_of_pools(),
127 options.distribute_bands ?
"bands" :
"reciprocal space");
137 bool is_root = policy->is_root();
141 auto flavor =
create_flavor(input.calculation, std::move(iterator_factory));
144 log::info(
" Calculation type: {}", input.calculation);
146 generated::Results results = flavor->run(input);
149 input.output_directory +
"/" + input.prefix +
"_results.json");
160 long long global_fft_calls = profiling.fft_call_count.load();
161 long long global_davidson_iterations = profiling.davidson_iteration_count.load();
162 long long global_hamiltonian_applications =
163 profiling.hamiltonian_application_count.load();
165 MPI_IN_PLACE, &global_fft_calls, 1, MPI_LONG_LONG, MPI_SUM, 0, MPI_COMM_WORLD);
166 MPI_Reduce(MPI_IN_PLACE,
167 &global_davidson_iterations,
173 MPI_Reduce(MPI_IN_PLACE,
174 &global_hamiltonian_applications,
181 q3::log::info(
" Total FFT calls (all ranks): {}", global_fft_calls);
183 global_davidson_iterations);
184 q3::log::info(
" Total Hamiltonian applications (all ranks): {}",
185 global_hamiltonian_applications);
194 unsigned long long maximum_resident = profiling.peak_resident_bytes_now();
195 unsigned long long minimum_resident = maximum_resident;
196 MPI_Reduce(MPI_IN_PLACE,
199 MPI_UNSIGNED_LONG_LONG,
203 MPI_Reduce(MPI_IN_PLACE,
206 MPI_UNSIGNED_LONG_LONG,
210 if (maximum_resident > 0) {
211 q3::log::info(
" Peak resident memory per rank: max {}, min {}",
215 profiling.davidson_timing.print_summary();
220 long long local_davidson_iterations =
222 long long local_hamiltonian_applications =
224 MPI_Reduce(&local_fft_calls,
nullptr, 1, MPI_LONG_LONG, MPI_SUM, 0, MPI_COMM_WORLD);
226 &local_davidson_iterations,
nullptr, 1, MPI_LONG_LONG, MPI_SUM, 0, MPI_COMM_WORLD);
227 MPI_Reduce(&local_hamiltonian_applications,
234 unsigned long long local_resident =
237 &local_resident,
nullptr, 1, MPI_UNSIGNED_LONG_LONG, MPI_MAX, 0, MPI_COMM_WORLD);
239 &local_resident,
nullptr, 1, MPI_UNSIGNED_LONG_LONG, MPI_MIN, 0, MPI_COMM_WORLD);
242 }
catch (
const std::exception& exception) {
253 log::fatal(
"[rank " + std::to_string(world_rank_index) +
254 "] Fatal error: " + exception.what());
271 int is_finalized = 0;
272 MPI_Finalized(&is_finalized);
274 MPI_Abort(MPI_COMM_WORLD, 1);
int main(int argc, char *argv[])