Skip to content

Commit 5f3014f

Browse files
committed
Revisit and improve reductions, primarily in the macro backend.
Treatment via both opening/closing macros and the reduction probe. Less dependent on probe order. Remove ProbeScopeStatus. Update to the OpenMP 6.0 way of declaring reductions. Less overhead in combiner expressions. Replace nestable locks by counting constructor calls. Introduce calls for querying further mutex identifiers in the backend layer. Reductions use address of parallel data as mutex identifier (both backends). Drop ID in declaration of custom reductions. Merge branch 'revisit/reductionsMacroBackend' into develop
2 parents 4986e33 + 0f1648e commit 5f3014f

11 files changed

Lines changed: 172 additions & 315 deletions

include/opdi/backend/backendInterface.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ namespace opdi {
4040

4141
virtual std::size_t getLockIdentifier(omp_lock_t* lock) = 0;
4242
virtual std::size_t getNestLockIdentifier(omp_nest_lock_t* lock) = 0;
43+
virtual std::size_t getCriticalIdentifier(std::string const& name) = 0;
44+
virtual std::size_t getReductionIdentifier() = 0;
4345

4446
virtual void* getParallelData() = 0;
4547
virtual void* getTaskData() = 0;

include/opdi/backend/macro/macroBackend.cpp

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,15 @@ std::stack<void*> opdi::DataTools::taskData;
3434

3535
std::stack<bool> opdi::ImplicitBarrierTools::implicitBarrierStack;
3636

37-
omp_lock_t opdi::ReductionTools::globalReducerLock;
38-
std::list<omp_nest_lock_t*> opdi::ReductionTools::individualReducerLocks;
39-
std::stack<bool> opdi::ReductionTools::reductionBarrierStack;
40-
41-
template<typename Type, int identifier>
42-
omp_nest_lock_t opdi::Reducer<Type, identifier>::reduceLock;
43-
44-
template<typename Type, int identifier>
45-
bool opdi::Reducer<Type, identifier>::isInitialized = false;
46-
47-
std::stack<opdi::ProbeScopeStatus::Status> opdi::ProbeScopeStatus::statusStack;
37+
omp_lock_t opdi::ReductionTools::globalReductionLock;
38+
std::list<omp_nest_lock_t*> opdi::ReductionTools::individualReductionLocks;
39+
std::stack<bool> opdi::ReductionTools::hasReductions;
40+
std::stack<bool> opdi::ReductionTools::needsBarrierBeforeReductions;
41+
std::stack<bool> opdi::ReductionTools::needsBarrierAfterReductions;
42+
int opdi::ReductionTools::implicitTaskNestingDepth = 0;
43+
44+
template<typename Type>
45+
size_t opdi::Reducer<Type>::nConstructorCalls = 0;
4846

4947
// global macro backend variables
5048

include/opdi/backend/macro/macroBackend.hpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@
4545
#include "macros.hpp"
4646
#include "mutexIdentifiers.hpp"
4747
#include "probes.hpp"
48-
#include "probeTools.hpp"
4948
#include "reductionTools.hpp"
5049

5150
namespace opdi {
@@ -58,7 +57,7 @@ namespace opdi {
5857
// remaining functions from backend interface
5958

6059
void init() {
61-
opdi_init_lock(&ReductionTools::globalReducerLock);
60+
opdi_init_lock(&ReductionTools::globalReductionLock);
6261

6362
// task data for initial implicit task is created in the logic layer
6463
}
@@ -68,15 +67,15 @@ namespace opdi {
6867
DataTools::popTaskData();
6968
assert(DataTools::getTaskData() == nullptr);
7069

71-
opdi_set_lock(&ReductionTools::globalReducerLock);
70+
opdi_set_lock(&ReductionTools::globalReductionLock);
7271

73-
for (auto lock : ReductionTools::individualReducerLocks) {
72+
for (auto lock : ReductionTools::individualReductionLocks) {
7473
opdi_destroy_nest_lock(lock);
7574
}
7675

77-
opdi_unset_lock(&ReductionTools::globalReducerLock);
76+
opdi_unset_lock(&ReductionTools::globalReductionLock);
7877

79-
opdi_destroy_lock(&ReductionTools::globalReducerLock);
78+
opdi_destroy_lock(&ReductionTools::globalReductionLock);
8079
}
8180

8281
void* getParallelData() {

include/opdi/backend/macro/macros.hpp

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -49,16 +49,20 @@
4949

5050
#define OPDI_FOR(...) \
5151
opdi::ImplicitBarrierTools::beginRegionWithImplicitBarrier(); \
52+
opdi::ReductionTools::beginRegionThatSupportsReductions(true); \
5253
OPDI_PRAGMA(omp for __VA_ARGS__ private(opdi::internalLoopProbe))
5354

5455
#define OPDI_END_FOR \
56+
opdi::ReductionTools::endRegionThatSupportsReductions(); \
5557
opdi::ImplicitBarrierTools::endRegionWithImplicitBarrier();
5658

5759
#define OPDI_SECTIONS(...) \
5860
opdi::ImplicitBarrierTools::beginRegionWithImplicitBarrier(); \
61+
opdi::ReductionTools::beginRegionThatSupportsReductions(true); \
5962
OPDI_PRAGMA(omp sections private(opdi::internalSectionsProbe) __VA_ARGS__)
6063

6164
#define OPDI_END_SECTIONS \
65+
opdi::ReductionTools::endRegionThatSupportsReductions(); \
6266
opdi::ImplicitBarrierTools::endRegionWithImplicitBarrier();
6367

6468
#define OPDI_SINGLE(...) \
@@ -161,15 +165,13 @@
161165
#define OPDI_CRITICAL_NAME(name) \
162166
OPDI_PRAGMA(omp critical (name)) \
163167
{ \
164-
std::size_t const opdiInternalCriticalIdentifier = \
165-
dynamic_cast<opdi::MacroBackend*>(opdi::backend)->getCriticalIdentifier(std::string(#name)); \
168+
std::size_t const opdiInternalCriticalIdentifier = opdi::backend->getCriticalIdentifier(std::string(#name)); \
166169
opdi::logic->onMutexAcquired(opdi::LogicInterface::MutexKind::Critical, opdiInternalCriticalIdentifier);
167170

168171
#define OPDI_CRITICAL_NAME_ARGS(name, ...) \
169172
OPDI_PRAGMA(omp critical (name) __VA_ARGS__) \
170173
{ \
171-
std::size_t const opdiInternalCriticalIdentifier = \
172-
dynamic_cast<opdi::MacroBackend*>(opdi::backend)->getCriticalIdentifier(std::string(#name)); \
174+
std::size_t const opdiInternalCriticalIdentifier = opdi::backend->getCriticalIdentifier(std::string(#name)); \
173175
opdi::logic->onMutexAcquired(opdi::LogicInterface::MutexKind::Critical, opdiInternalCriticalIdentifier);
174176

175177
#define OPDI_END_CRITICAL \
@@ -231,18 +233,27 @@
231233

232234
// reduction macros
233235

234-
#define OPDI_INTERNAL_DECLARE_REDUCTION(OP_NAME, TYPE, OP, INIT, ID) \
235-
TYPE operator OP (opdi::Reducer<TYPE, ID> const& lhs, \
236-
opdi::Reducer<TYPE, ID> const& rhs) { \
237-
return lhs.value OP rhs.value; \
238-
} \
239-
\
240-
OPDI_PRAGMA(omp declare reduction(OP_NAME : TYPE : \
241-
opdi::Reducer<TYPE, ID>(omp_out) = opdi::Reducer<TYPE, ID>(omp_out) OP opdi::Reducer<TYPE, ID>(omp_in)) \
242-
initializer(omp_priv = INIT))
243-
244-
#define OPDI_DECLARE_REDUCTION(OP_NAME, TYPE, OP, INIT) \
245-
OPDI_INTERNAL_DECLARE_REDUCTION(OP_NAME, TYPE, OP, INIT, __COUNTER__)
236+
#if _OPENMP >= 202411
237+
#define OPDI_DECLARE_REDUCTION(OP_NAME, TYPE, OP, INIT) \
238+
TYPE operator OP (opdi::Reducer<TYPE> const& lhs, \
239+
opdi::Reducer<TYPE> const& rhs) { \
240+
return lhs.value OP rhs.value; \
241+
} \
242+
\
243+
OPDI_PRAGMA(omp declare_reduction(OP_NAME : TYPE) \
244+
combiner(opdi::Reducer(omp_out) = opdi::Reducer(omp_out) OP opdi::Reducer(omp_in)) \
245+
initializer(omp_priv = INIT))
246+
#else
247+
#define OPDI_DECLARE_REDUCTION(OP_NAME, TYPE, OP, INIT) \
248+
TYPE operator OP (opdi::Reducer<TYPE> const& lhs, \
249+
opdi::Reducer<TYPE> const& rhs) { \
250+
return lhs.value OP rhs.value; \
251+
} \
252+
\
253+
OPDI_PRAGMA(omp declare reduction(OP_NAME : TYPE : \
254+
opdi::Reducer(omp_out) = opdi::Reducer(omp_out) OP opdi::Reducer(omp_in)) \
255+
initializer(omp_priv = INIT))
256+
#endif
246257

247258
#define OPDI_REDUCTION private(opdi::internalReductionProbe)
248259

include/opdi/backend/macro/mutexIdentifiers.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,7 @@ namespace opdi {
3636
private:
3737

3838
omp_lock_t criticalLock;
39-
4039
std::map<std::string, std::size_t> criticalIdentifiers;
41-
4240
std::size_t nextCriticalIdentifier;
4341

4442
public:
@@ -67,6 +65,10 @@ namespace opdi {
6765
return result;
6866
}
6967

68+
std::size_t getReductionIdentifier() {
69+
return reinterpret_cast<std::size_t>(opdi::backend->getParallelData());
70+
}
71+
7072
std::size_t getLockIdentifier(omp_lock_t* lock) {
7173
return reinterpret_cast<std::size_t>(lock);
7274
}

include/opdi/backend/macro/probeTools.hpp

Lines changed: 0 additions & 200 deletions
This file was deleted.

0 commit comments

Comments
 (0)