38 #ifndef MADNESS_WORLD_DEPENDENCY_INTERFACE_H__INCLUDED
39 #define MADNESS_WORLD_DEPENDENCY_INTERFACE_H__INCLUDED
56 #include <unordered_map>
77 #ifdef MADNESS_TASK_DEBUG_TRACE
80 const auto caller_str = caller;
81 auto it = callers_.find(caller_str);
82 if (it != callers_.end())
92 #ifdef MADNESS_TASK_DEBUG_TRACE
93 std::unordered_map<std::string,int> callers_;
112 #ifdef MADNESS_TASK_DEBUG_TRACE
113 volatile int max_ndepend;
114 constexpr
static const bool print_debug =
false;
126 while (!cb.
empty()) {
145 #ifdef MADNESS_TASK_DEBUG_TRACE
150 #ifdef MADNESS_TASK_DEBUG_TRACE
151 callers_[caller] =
ndep;
153 print(
"DependencyInterface debug ctor: this=",
this,
" caller=", caller,
" ndepend=",
ndepend);
165 #ifdef MADNESS_TASK_DEBUG_TRACE
169 int ndep_debug()
const {
170 return std::accumulate(begin(callers_), end(callers_), 0,
171 [](
int partial_sum,
auto& x) {
return partial_sum + x.second; });
191 #ifdef MADNESS_TASK_DEBUG_TRACE
206 #ifdef MADNESS_TASK_DEBUG_TRACE
207 if (print_debug && !callers_.empty())
208 print(
"DependencyInterface::register_callback: this=",
this,
" ndepend=",
ndepend);
235 #ifdef MADNESS_TASK_DEBUG_TRACE
236 if (print_debug && !callers_.empty())
237 print(
"DependencyInterface::register_final_callback: this=",
this,
" ndepend=",
ndepend);
254 #ifdef MADNESS_TASK_DEBUG_TRACE
255 if (!callers_.empty())
256 error(
"DependencyInterface::inc() called for an object that is being debugged",
"");
267 #ifdef MADNESS_TASK_DEBUG_TRACE
268 if (!callers_.empty())
269 error(
"DependencyInterface::dec() called for an object that is being debugged",
"");
291 #ifdef MADNESS_TASK_DEBUG_TRACE
292 const auto caller_str = caller;
293 auto it = callers_.find(caller_str);
294 if (it != callers_.end())
297 callers_[caller] = 1;
298 max_ndepend =
std::max(
static_cast<int>(max_ndepend),
static_cast<int>(
ndepend));
299 if (
ndep() != ndep_debug())
300 error(
"DependencyInterface::inc_debug(): ndepend != ndepend_debug, caller = ", caller);
302 print(
"DependencyInterface::inc_debug: this=",
this,
" caller=", caller,
" ndep=", callers_[caller],
" ndepend=",
ndepend);
311 #ifdef MADNESS_TASK_DEBUG_TRACE
312 const auto caller_str = caller;
313 auto it = callers_.find(caller_str);
314 if (it != callers_.end()) {
318 assert(
false &&
"DependencyInterface::dec_debug() called without matching inc_debug()");
323 #ifdef MADNESS_TASK_DEBUG_TRACE
324 if (
ndep() != ndep_debug())
325 error(
"DependencyInterface::dec_debug(): ndepend != ndepend_debug, caller = ", caller);
327 print(
"DependencyInterface::dec_debug: callback spawned, this=",
this,
" caller=", caller,
" ndep=", it->second-1,
" ndepend=",
ndepend-1);
335 #ifdef MADNESS_TASK_DEBUG_TRACE
338 print(
"DependencyInterface::dec_debug: this=",
this,
" caller=", caller,
" ndep=", it->second-1,
" ndepend=",
ndepend-1);
343 #ifdef MADNESS_TASK_DEBUG_TRACE
353 #ifdef MADNESS_ASSERTIONS_THROW
355 error(
"DependencyInterface::~DependencyInterface(): ndepend =",
ndepend);
359 #ifdef MADNESS_TASK_DEBUG_TRACE
360 if (!callers_.empty()) {
363 print(
"DependencyInterface dtor: this=",
this,
" max_ndepend=", max_ndepend);
366 #ifdef MADNESS_TASK_DEBUG_TRACE
367 for(
const auto&
c: callers_) {
369 const auto error_msg = std::string(
"ndepend=") + std::to_string(
c.second) +
" for caller " +
c.first;
370 error(
"DependencyInterface::~DependencyInterface(): ", error_msg);
377 #ifdef MADNESS_TASK_DEBUG_TRACE
378 std::unordered_map<std::string, int> callers_;
The class used for callbacks (e.g., dependency tracking).
Definition: dependency_interface.h:61
virtual void notify()=0
Invoked by the callback to notify when a dependency is satisfied.
virtual void notify_debug(const char *caller)
Same as notify(), but tracks how many times called from each caller.
Definition: dependency_interface.h:67
virtual void notify_debug_impl(const char *caller)
Definition: dependency_interface.h:76
virtual ~CallbackInterface()
Definition: dependency_interface.h:73
Provides an interface for tracking dependencies.
Definition: dependency_interface.h:100
int ndep() const
Returns the number of unsatisfied dependencies.
Definition: dependency_interface.h:160
void inc()
Increment the number of dependencies.
Definition: dependency_interface.h:251
void register_final_callback(CallbackInterface *callback)
Registers the final callback to be executed when ndepend==0; immediately invoked if ndepend==0.
Definition: dependency_interface.h:229
virtual ~DependencyInterface()
Destructor.
Definition: dependency_interface.h:352
void dec()
Decrement the number of dependencies and invoke the callback if ndepend==0.
Definition: dependency_interface.h:262
bool probe() const
Returns true if ndepend == 0 (no unsatisfied dependencies).
Definition: dependency_interface.h:178
void register_callback(CallbackInterface *callback)
Registers a callback that will be executed when ndepend==0; immediately invoked if ndepend==0.
Definition: dependency_interface.h:201
void dec_debug(const char *caller)
Definition: dependency_interface.h:306
volatile callbackT callbacks
Called ONCE by dec() when ndepend==0.
Definition: dependency_interface.h:109
std::atomic< int > ndepend
Counts dependencies. For a valid object ndepend >= 0, after the final callback is executed ndepend is...
Definition: dependency_interface.h:105
volatile CallbackInterface * final_callback
The "final" callback can destroy the task, always invoked last, the object is in an invalid state (nd...
Definition: dependency_interface.h:111
void notify()
Invoked by callbacks to notify of dependencies being satisfied.
Definition: dependency_interface.h:183
static const int MAXCALLBACKS
Maximum number of callbacks.
Definition: dependency_interface.h:107
void inc_debug(const char *caller)
Same as inc(), but keeps track of caller; calling dec_debug() will signal error if no matching inc_de...
Definition: dependency_interface.h:287
void do_callbacks(callbackT &cb) const
Definition: dependency_interface.h:125
void notify_debug(const char *caller)
Overload of CallbackInterface::notify_debug(), updates dec()
Definition: dependency_interface.h:189
DependencyInterface(int ndep=0)
Definition: dependency_interface.h:136
DependencyInterface(int ndep, const char *caller)
Definition: dependency_interface.h:144
Mutex that is applied/released at start/end of a scope.
Definition: worldmutex.h:239
Spinlock using pthread spinlock operations.
Definition: worldmutex.h:253
Dynamically sized Stack with small stack size optimization.
Definition: stack.h:154
bool empty() const
Check if the stack is empty.
Definition: stack.h:387
reference top()
Get the last item pushed onto the stack.
Definition: stack.h:355
void push(const_reference value)
Push a new item onto the stack.
Definition: stack.h:318
void pop()
Pop an item off of the stack.
Definition: stack.h:345
#define max(a, b)
Definition: lda.h:51
#define MADNESS_ASSERT(condition)
Assert a condition that should be free of side-effects since in release builds this might be a no-op.
Definition: madness_exception.h:134
File holds all helper structures necessary for the CC_Operator and CC2 class.
Definition: DFParameters.h:10
void print(const T &t, const Ts &... ts)
Print items to std::cout (items separated by spaces) and terminate with a new line.
Definition: print.h:225
void error(const char *msg)
Definition: world.cc:139
Defines simple templates for printing to std::cout "a la Python".
static const double c
Definition: relops.cc:10
Implement Stack for a fixed-size stack container.
Declares the World class for the parallel runtime environment.
Implements Mutex, MutexFair, Spinlock, ConditionVariable.