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
Stack< CallbackInterface *, MAXCALLBACKS > callbackT
Definition dependency_interface.h:108
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
#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
Namespace for all elements and tools of MADNESS.
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.