Files
Flux-openbuild/include/core/omp_config.h
2025-10-06 20:14:13 +00:00

54 lines
2.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#pragma once
#include <vector>
#include <omp.h>
namespace omp_config{
// Configure OpenMP behavior at runtime.
inline void omp_configure(int max_active_levels,
bool dynamic_threads,
const std::vector<int>& threads_per_level = {},
bool bind_close = true)
{
// 1) Allow nested parallel regions (levels of teams)
// Example: outer #pragma omp parallel ... { inner #pragma omp parallel ... }
omp_set_max_active_levels(max_active_levels); // 1 = only top-level; 2+ enables nesting
// 2) Let the runtime shrink/grow thread counts if it thinks it should
// (helps avoid oversubscription when you accidentally ask for too many threads)
omp_set_dynamic(dynamic_threads ? 1 : 0);
// 3) Thread binding (keep threads near their cores) is controlled via env vars,
// so here we just *recommend* a good default (see below). You *can* setenv()
// in code, but its cleaner to do it outside the program.
(void)bind_close; // documented below in env var section
// 4) Top-level default thread count (inner levels are usually set per region)
if (!threads_per_level.empty()) {
omp_set_num_threads(threads_per_level[0]); // e.g. 16 for the outermost team
// Inner levels:
// - Use num_threads(threads_per_level[L]) on the inner #pragma omp parallel
// - or set OMP_NUM_THREADS="outer,inner,inner2" as an environment variable
}
}
// ---------- Helper: may we create another team? ----------
inline bool omp_parallel_allowed() {
#ifdef _OPENMP
// If were not in parallel, we can spawn.
if (!omp_in_parallel()) return true;
// Already inside parallel: allow only if nesting is enabled and not at limit.
int level = omp_get_active_level(); // 0 outside parallel, 1 inside, ...
int maxlv = omp_get_max_active_levels(); // user/runtime cap
return static_cast<bool>(level < maxlv);
#else
return false; // no OpenMP → no extra teams
#endif
}
} // namespace omp_config