MADNESS  0.10.1
world.h
Go to the documentation of this file.
1 /*
2  This file is part of MADNESS.
3 
4  Copyright (C) 2007,2010 Oak Ridge National Laboratory
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 
20  For more information please contact:
21 
22  Robert J. Harrison
23  Oak Ridge National Laboratory
24  One Bethel Valley Road
25  P.O. Box 2008, MS-6367
26 
27  email: harrisonrj@ornl.gov
28  tel: 865-241-3937
29  fax: 865-572-0680
30 */
31 
32 /**
33  \file world.h
34  \brief Declares the \c World class for the parallel runtime environment.
35  \ingroup world
36 
37  \todo More detailed description of this file.
38 
39  \todo Are some of the forward declarations in this file necessary? A quick inspection suggests most of the functions before the World class don't need to be declared first...
40 */
41 
42 #ifndef MADNESS_WORLD_WORLD_H__INCLUDED
43 #define MADNESS_WORLD_WORLD_H__INCLUDED
44 
45 #include <madness/madness_config.h>
46 
47 // #ifdef SEEK_SET
48 // #undef SEEK_SET
49 // #endif
50 // #ifdef SEEK_CUR
51 // #undef SEEK_CUR
52 // #endif
53 // #ifdef SEEK_END
54 // #undef SEEK_END
55 // #endif
56 
57 // Standard C++ header files needed by MADworld.h
58 #include <cstddef>
59 #include <cstdint> // std::uint64_t
60 #include <iostream>
61 #include <list> // std::list
62 #include <optional> // std::optional
63 #include <utility> // std::pair
64 
65 #ifdef HAVE_RANDOM
66 #include <cstdlib>
67 #endif
68 
69 // Madness world header files needed by world
71 #include <madness/world/worldmpi.h>
74 #include <madness/world/thread.h>
75 #include <madness/world/uniqueid.h>
77 
78 /// \addtogroup world
79 /// @{
80 
81 namespace madness {
82 
83  class World;
84  class WorldTaskQueue;
85  class WorldAmInterface;
86  class WorldGopInterface;
87 
88  /// Print miscellaneous stats on a World.
89 
90  /// This requires collective operations within the World.
91  /// \param[in] world The World to analyze.
92  void print_stats(World& world);
93 
94  /// \todo Brief description needed.
95 
96  /// \todo Detailed description needed.
97  /// \param path Description.
98  /// \param display Description.
99  extern void xterm_debug(const char* path, const char* display);
100 
101  /// \todo Brief description needed.
102 
103  /// \todo Detailed description needed. I imagine this prints/logs the supplied
104  /// error message and subsequently aborts the program.
105  /// \param[in] msg Message associated with the error.
106  void error(const char *msg);
107 
108  /// Prints an error message, along with some data, and aborts the program.
109 
110  /// \todo Does this function need to be static? (Esp. since it's in a header file...)
111  ///
112  /// \tparam T The type of data.
113  /// \param[in] msg The error message.
114  /// \param[in] data The data to be printed.
115  template <typename T>
116  static void error(const char *msg, const T& data);
117 
118 
119  /// A parallel world class.
120 
121  /// World wraps a MPI communicator. Multiple worlds with different
122  /// communicators can co-exist.
123  ///
124  /// Here we use Pimpl to both hide implementation details and also
125  /// to partition the namespace for users as \c world.mpi, \c world.am, etc.
126  /// We also embed a reference to this instance in the \c am and \c task
127  /// instances so that they have access to everything.
128  ///
129  /// The downside is we cannot do much of anything here without
130  /// using wrapper functions to forward the calls to the hidden
131  /// class methods.
132  class World : private NO_DEFAULTS {
133  private:
134  friend class WorldAmInterface;
135  friend class WorldGopInterface;
136  friend World& initialize(int&, char**&, const SafeMPI::Intracomm&, int, bool);
137  friend void finalize();
138 
139  // Static member variables
140  static std::pair<std::uint64_t, std::uint64_t> world_id__next_last; ///< Unique {next, last} world IDs to be used by this rank.
141  static World* default_world; ///< Default world.
142  static std::list<World*> worlds; ///< Maintains list of active worlds, EXCLUDES default_world
143 
144  /// \todo Brief description needed.
145  struct hashuniqueT {
146  /// \todo Brief description needed.
147 
148  /// \todo Descriptions needed.
149  /// \param[in] id The ID.
150  /// \return Return description needed.
151  inline std::size_t operator()(const uniqueidT& id) const {
152  return id.objid; // The object id's are guaranteed to be unique
153  }
154  };
155 
156  /// \todo Brief description needed.
157  struct hashvoidp {
158  /// \todo Brief description needed.
159 
160  /// \todo Descriptions needed.
161  /// \param[in] p Missing description.
162  /// \return Return description needed.
163  inline std::size_t operator()(const void* p) const {
164  return std::size_t(p); // The ptr's are guaranteed to be unique
165  }
166  };
167 
168  // Mutex globalmutex; ///< Worldwide mutex
169  /// \todo Brief description of typedef needed.
171  /// \todo Brief description of typedef needed.
173 
174  /// Maps unique ID of a global object to its local pointer
175  ///
176  /// \note Unique IDs are created by increasing `obj_id`. To be able to assign unique IDs to objects created in
177  /// different worlds, they must be created in exactly the same sequence in every process. Hence in general
178  /// object construction happens in main thread. Object construction first updates `obj_id`, then inserts ID
179  /// into this. The rest of code only knows about this object once it's been added to this map, hence
180  /// this map (NOT `obj_id`) defines the known objects. The only writers to map_id_to_ptr are
181  /// `{register,unregister}_ptr()`.
183  /// inverse of map_id_to_ptr
184  map_ptr_to_idT map_ptr_to_id; ///< \todo Verify: Map from a pointer to its unique hash ID.
185 
186 
187  std::uint64_t _id; ///< Universe wide unique ID of this world.
188  unsigned long obj_id; ///< Counter for generating unique IDs within this world.
189  void* user_state; ///< Holds a user-defined and managed local state.
190 
191  // Default copy constructor and assignment won't compile
192  // (which is good) due to reference members.
193 
194  /// initializes the value of world_id__next_last to {global_rank*2^32, (global_rank+1)*2^32-1}
195  /// \param global_rank rank of this process in COMM_WORLD
196  static void initialize_world_id_range(int global_rank);
197  /// \return next unique World id
198  static std::uint64_t next_world_id();
199 
200  public:
201  // !!! Order of declaration is important for correct order of initialization !!!
202  WorldMpiInterface& mpi; ///< MPI interface.
203  WorldAmInterface& am; ///< AM interface.
204  WorldTaskQueue& taskq; ///< Task queue.
205  WorldGopInterface& gop; ///< Global operations.
206 
207  private:
208  unsigned int myrand_next; ///< State of crude internal random number generator.
209 
210  public:
211  /// Constructs a \c World from a communicator.
212 
213  /// This function does not check if another \c World exists that uses
214  /// the same communicator. Use instance() to check this.
215  ///
216  /// \param[in] comm The communicator.
217  /// \param[in] fence if true, will synchronize ranks before exiting;
218  /// setting to false removes the extra synchronization
219  /// but may cause premature arrival of RMI messages
220  /// that refer to this world while it's being
221  /// registered
222  World(const SafeMPI::Intracomm& comm,
223  bool fence = true);
224 
225  /// Find the World (if it exists) corresponding to the given communicator.
226 
227  /// \param[in] comm The communicator.
228  /// \return Pointer to the World that was constructed from \c comm;
229  /// if such a World does not exist, return 0.
230  static World* find_instance(const SafeMPI::Intracomm& comm) {
231  if (default_world->mpi.comm() == comm)
232  return default_world;
233  else {
234  typedef std::list<World *>::const_iterator citer;
235  for (citer it = worlds.begin(); it != worlds.end(); ++it) {
236  if ((*it)->mpi.comm() == comm)
237  return *it;
238  }
239  return nullptr;
240  }
241  }
242 
243  /// Check if the World exists in the registry.
244 
245  /// \param[in] world pointer to a World object
246  /// \return true if \c world exists
247  static bool exists(World* world) {
248  return world == default_world || std::find(worlds.begin(), worlds.end(), world) != worlds.end();
249  }
250 
251  /// Default World object accessor.
252 
253  /// This function returns a reference to the default world object; this
254  /// is the same World object that is returned by
255  /// madness::initialize().
256  /// \return A reference to the default World.
257  /// \throw madness::Exception if the MADNESS_DISABLE_WORLD_GET_DEFAULT preprocessor macro is defined
258  static World& get_default() {
259 #ifdef MADNESS_DISABLE_WORLD_GET_DEFAULT
260  MADNESS_EXCEPTION("World::get_default() was called while disabled", 0);
261 #endif
263  return *default_world;
264  }
265 
266  /// Checks if the default World object corresponds to the given Intracomm
267 
268  /// \param[in] comm The communicator.
269  /// \return true if \c comm is the default World object's communicator
270  /// \sa World::get_default()
271  static bool is_default(const SafeMPI::Intracomm& comm) {
272  auto* comm_world = find_instance(comm);
273  if (comm_world)
274  return default_world == comm_world;
275  else
276  return false;
277  }
278 
279  /// Sets the user-managed local state.
280 
281  /// Rather than having all remotely invoked actions carry all
282  /// of their data with them, they can access local state through
283  /// their \c World instance. The user is responsible for
284  /// consistently managing and freeing this data.
285  ///
286  /// A more PC C++ style would be for the app to put state in
287  /// a singleton.
288  /// \param[in] state The user-managed local state.
289  void set_user_state(void* state) { user_state = state; }
290 
291  /// Returns a pointer to the user-managed local state set by set_user_state().
292 
293  /// \return A pointer to the user-managed local state; NULL if
294  /// set_user_state() has not been invoked.
295  void* get_user_state() { return user_state; }
296 
297  /// Clears the user-defined state.
298 
299  /// This has the same effect as `set_user_state(0)`.
300  void clear_user_state() { user_state = nullptr; }
301 
302  /// Processes command line arguments.
303 
304  /// Mostly intended for \c World test codes, but also provides the
305  /// `-dx option` to start `x` debugger.
306  /// \param[in] argc The number of command-line arguments.
307  /// \param[in,out] argv The command-line arguments.
308  void args(int argc, char**argv);
309 
310  /// Returns the system-wide unique integer ID of this \c World.
311  ///
312  /// \return The system-wide unique integer ID of this \c World.
313  unsigned long id() const { return _id; }
314 
315  /// Returns the process rank in this \c World (same as MPI_Comm_rank()).
316 
317  /// \return The process rank in this \c World.
318  ProcessID rank() const { return mpi.rank(); }
319 
320  /// Returns the number of processes in this \c World (same as MPI_Comm_size()).
321 
322  /// \return The number of processes in this \c World.
323  ProcessID nproc() const { return mpi.nproc(); }
324 
325  /// Returns the number of processes in this \c World (same as MPI_Comm_size()).
326 
327  /// \return The number of processes in this \c World.
328  ProcessID size() const { return mpi.size(); }
329 
330  /// Creates a new universe-wide unique ID for objects created in this \c World. No comms.
331 
332  /// You should consider using \c register_ptr(), \c unregister_ptr(),
333  /// \c id_from_ptr(), or \c ptr_from_id() rather than using this directly.
334  ///
335  /// Currently relies on this being called in the same order on
336  /// every process within the current \c World in order to avoid
337  /// synchronization.
338  ///
339  /// Unique IDs are created by increasing static counter.
340  /// The value obj_id=0 is invalid.
341  /// \return A new universe-wide unique ID for objects created in this \c World.
342  /// \warning This is not re-entrant, should be called from a single (typically, main) thread
344  return uniqueidT(_id,obj_id++);
345  }
346 
347  /// Reports the next universe-wide unique ID generated by make_unique_obj_id() objects created in this \c World. No comms.
348 
349  /// \return A the next universe-wide unique ID for objects created in this \c World.
350  /// \warning This is not re-entrant, should be called from a single (typically, main) thread
352  return uniqueidT(_id,obj_id);
353  }
354 
355  /// Associate a local pointer with a universe-wide unique ID.
356 
357  /// Use the routines \c register_ptr(), \c unregister_ptr(),
358  /// \c id_from_ptr(), \c ptr_from_id() to map distributed data
359  /// structures identified by the unique ID to/from
360  /// process-local data.
361  ///
362  /// \note The pointer will be internally cast to a (void *),
363  /// so don't use member pointers here.
364  ///
365  /// \note All unique objects of any type within a \c World must
366  /// presently be created in the same order on all processes so
367  /// as to guarantee the uniqueness without global
368  /// communication.
369  /// \tparam T The type of data to be associated.
370  /// \param[in] ptr Pointer to the data that will be associated
371  /// with a unique ID.
372  /// \return The unique ID associated with the supplied data.
373  template <typename T>
374  [[nodiscard]] uniqueidT register_ptr(T* ptr) {
375  MADNESS_ASSERT(sizeof(T*) == sizeof(void *));
377  [[maybe_unused]] auto&& [it1, inserted1] = map_id_to_ptr.insert(std::pair<uniqueidT,void*>(id,static_cast<void*>(ptr)));
378  MADNESS_ASSERT(inserted1);
379  [[maybe_unused]] auto&& [it2, inserted2] = map_ptr_to_id.insert(std::pair<void*,uniqueidT>(static_cast<void*>(ptr),id));
380  MADNESS_ASSERT(inserted2);
381  return id;
382  }
383 
384  /// Unregister a global object via its the unique ID.
385 
386  /// \param[in] id The unique ID of the data to unregister.
387  void unregister_ptr(const uniqueidT id) {
388  // START critical section
390  [[maybe_unused]] auto found = map_id_to_ptr.find(acc, id);
391  MADNESS_ASSERT(found); // make sure id is valid
392 
393  void* ptr = static_cast<void*>(acc->second);
394 
395  // if NDEBUG is not defined, keep unregistered ptr IDs in map_id_to_ptr else remove them
396 #ifdef NDEBUG
397  map_id_to_ptr.erase(acc); // END critical section
398 #else
399  MADNESS_ASSERT(ptr); // ensure ID is not expired
400  acc->second = nullptr;
401  acc.release(); // END critical section
402 #endif
403  [[maybe_unused]] auto erased2 = map_ptr_to_id.try_erase(ptr);
404  MADNESS_ASSERT(erased2);
405  }
406 
407  /// Look up a local pointer from a world-wide unique ID.
408 
409  /// \tparam T The type of the data to look up.
410  /// \param[in] id The unique ID of the data.
411  /// \return The local pointer (can be \c nullptr if \p id has been deregistered and
412  /// `NDEBUG` is not `#define`d); if \p id has not been registered then returns null optional
413  template <typename T>
414  [[nodiscard]] std::optional<T*> ptr_from_id(uniqueidT id) const {
416  [[maybe_unused]] auto found = map_id_to_ptr.find(acc, id);
417  if (!found)
418  return {};
419  else
420  return {static_cast<T *>(acc->second)};
421  }
422 
423  /// Look up an ID from a local pointer.
424 
425  /// \tparam T The type of the data to look up.
426  /// \param[in] ptr The local pointer.
427  /// \return Optional containing the unique ID if the pointer is registered, or a null optional if the pointer is not registered.
428  template <typename T>
429  [[nodiscard]] std::optional<uniqueidT> id_from_ptr(T* ptr) const {
431  [[maybe_unused]] auto found = map_ptr_to_id.find(acc, ptr);
432  if (!found)
433  return {};
434  else
435  return {acc->second};
436  }
437 
438 #ifndef MADNESS_DISABLE_SHARED_FROM_THIS
439 
440  /// Look up a local pointer from a world-wide unique ID.
441 
442  /// \tparam T The type of the data to look up.
443  /// \param[in] id The unique ID.
444  /// \return The pointer or a default constructed `std::shared_ptr` if
445  /// the ID is not found.
446  template <typename T>
447  [[nodiscard]] std::shared_ptr<T> shared_ptr_from_id(uniqueidT id) const {
448  std::optional<T*> ptr_opt = ptr_from_id<T>(id);
449  if (ptr_opt) MADNESS_ASSERT(*ptr_opt);
450  return (ptr_opt ? *ptr_opt->shared_from_this() : std::shared_ptr<T>());
451  }
452 
453  /// Look up a unique ID from a local pointer.
454 
455  /// \tparam T The type of the data to look up.
456  /// \param[in] ptr The local pointer.
457  /// \return Optional containing the unique ID, if the pointer is registered, or a null optional, if the pointer is not registered.
458  template <typename T>
459  [[nodiscard]] std::optional<uniqueidT> id_from_ptr(std::shared_ptr<T>& ptr) const {
460  return id_from_ptr(ptr.get());
461  }
462 
463 #endif // MADNESS_DISABLE_SHARED_FROM_THIS
464 
465 
466  /// Convert a \c World ID to a \c World pointer.
467 
468  /// The ID will only be valid if the process calling this routine
469  /// is a member of that \c World. Thus a \c NULL return value does not
470  /// necessarily mean that the \c World does not exist --- it could just
471  /// not include the calling process.
472  /// \param[in] id The ID of the \c World.
473  /// \return A pointer to the world associated with \c id, or \c NULL.
474  static World* world_from_id(std::uint64_t id) {
475  if (id != 0) {
476  for (std::list<World *>::iterator it = worlds.begin();
477  it != worlds.end(); ++it) {
478  if ((*it) && (*it)->_id == id)
479  return *it;
480  }
481  return nullptr;
482  }
483  else
484  return default_world;
485  }
486 
487  private:
488 
489  // Cannot use bind_nullary here since SafeMPI::Request::Test is non-const
490  /// \todo Brief description needed.
492  mutable SafeMPI::Request* r; ///< \todo Brief description needed.
493 
494  /// \todo Brief description needed.
495 
496  /// \todo Descriptions needed.
497  /// \param r Description needed.
499 
500  /// \todo Brief description needed.
501 
502  /// \todo Descriptions needed.
503  /// \return Description needed.
504  bool operator()() const {
505  return r->Test();
506  }
507  };
508 
509  public:
510 
511  /// Wait for a MPI request to complete.
512 
513  /// \todo Descriptions needed.
514  /// \param[in,out] request The MPI request on which to wait.
515  /// \param dowork Work while waiting - default is true
516  static void inline await(SafeMPI::Request& request, bool dowork = true) {
517  ThreadPool::await(MpiRequestTester(request), dowork, true); // Last arg is sleep=true --- don't hard spin on MPI requests
518  }
519 
520  /// Gracefully wait for a condition to become true.
521 
522  /// In the mean time, execute any tasks in the queue.
523  /// \todo Descriptions needed.
524  /// \tparam Probe An object that, when called, returns the status.
525  /// \param[in] probe The conditional's test.
526  /// \param dowork Work while waiting - default is true
527  /// \param sleep Sleep instead of spin while waiting - default is false
528  template <typename Probe>
529  static void inline await(const Probe& probe, bool dowork = true, bool sleep=false) {
530  ThreadPool::await(probe, dowork);
531  }
532 
533  /// Crude seed function for random number generation.
534 
535  /// \param[in] seed The seed.
536  /// \todo Since we're switching to C++11, would it be worth using the new C++11 random number generation capabilities?
537  void srand(unsigned long seed = 0ul) {
538  if (seed == 0) seed = rank();
539 #ifdef HAVE_RANDOM
540  srandom(seed);
541 #else
542  myrand_next = seed;
543  for (int i=0; i<1000; ++i) rand(); // Warmup
544 #endif // HAVE_RANDOM
545  }
546 
547 
548  /// Returns a CRUDE, LOW-QUALITY, random number (integer) uniformly distributed in [0,2**24).
549 
550  /// Each process has a distinct seed for the generator.
551  /// \return The random number.
552  /// \todo Since we're switching to C++11, would it be worth using the new C++11 random number generation capabilities?
553  int rand() {
554 #ifdef HAVE_RANDOM
555  return int(random() & 0xfffffful);
556 #else
557  myrand_next = myrand_next * 1103515245UL + 12345UL;
558  return int((myrand_next>>8) & 0xfffffful);
559 #endif // HAVE_RANDOM
560  }
561 
562 
563  /// Returns a CRUDE, LOW-QUALITY, random number (real) uniformly distributed in [0,1).
564 
565  /// Each process has a distinct seed for the generator.
566  /// \return The random number.
567  /// \todo Since we're switching to C++11, would it be worth using the new C++11 random number generation capabilities?
568  double drand() { return rand()/16777216.0; }
569 
570  /// Returns a random process number; that is, an integer in [0,`world.size()`).
571 
572  /// \return The random process number.
573  ProcessID random_proc() { return rand()%size(); }
574 
575  /// Returns a random process number [0,`world.size()`) that is not the calling process.
576 
577  /// It doesn't make any sense to call this with just one process, but just in
578  /// case, this returns -1 in the hope that you won't actually use the result.
579  /// \return The random process number, or -1.
581  if (size() == 1) return -1;
582  ProcessID p;
583  do {
584  p = rand()%size();
585  } while (p == rank());
586  return p;
587  }
588 
589  ~World();
590  }; // class World
591 
592  namespace archive {
593 
594  /// Specialization of \c ArchiveLoadImpl for \c World pointers.
595 
596  /// Helps in archiving (reading) \c World objects.
597  /// \tparam Archive The archive type.
598  template <class Archive>
599  struct ArchiveLoadImpl<Archive,World*> {
600  /// Loads a \c World from the specified archive.
601 
602  /// \note Aborts the program if a \c World cannot be read from the archive.
603  /// \param[in,out] ar The archive.
604  /// \param[out] wptr Pointer to the \c World.
605  static inline void load(const Archive& ar, World*& wptr) {
606  unsigned long id = 0ul;
607  ar & id;
608  wptr = World::world_from_id(id);
609  MADNESS_ASSERT(wptr);
610  }
611  }; // struct ArchiveLoadImpl<Archive,World*>
612 
613  /// Specialization of \c ArchiveStoreImpl for \c World pointers.
614 
615  /// Helps in archiving (writing) \c World objects.
616  /// \tparam Archive The archive type.
617  template <class Archive>
618  struct ArchiveStoreImpl<Archive,World*> {
619  /// Writes a \c World to the specified archive.
620 
621  /// \param[in,out] ar The archive.
622  /// \param[in] wptr Pointer to the \c World.
623  static inline void store(const Archive& ar, World* const & wptr) {
624  ar & wptr->id();
625  }
626  }; // struct ArchiveStoreImpl<Archive,World*>
627  } // namespace archive
628 
629 
630 
631  // implementation of templated functions
632  template <typename T>
633  static void error(const char *msg, const T& data) {
634  std::cerr << "MADNESS: fatal error: " << msg << " " << data << std::endl;
636  }
637 } // namespace madness
638 
639 /// @}
640 
641 #endif // MADNESS_WORLD_WORLD_H__INCLUDED
Disables default copy constructor and assignment operators.
Definition: nodefaults.h:49
Wrapper around MPI_Comm. Has a shallow copy constructor; use Create(Get_group()) for deep copy.
Definition: safempi.h:490
void Abort(int code=1) const
Definition: safempi.h:800
Definition: safempi.h:289
bool Test(MPI_Status &status)
Definition: safempi.h:409
std::pair< iterator, bool > insert(const datumT &datum)
Definition: worldhashmap.h:468
void erase(const iterator &it)
Definition: worldhashmap.h:507
bool try_erase(const keyT &key)
Definition: worldhashmap.h:502
iterator find(const keyT &key)
Definition: worldhashmap.h:524
Definition: worldhashmap.h:330
void release()
Definition: worldhashmap.h:380
static void await(const Probe &probe, bool dowork=true, bool sleep=false)
Gracefully wait for a condition to become true, executing any tasks in the queue.
Definition: thread.h:1444
Implements AM interface.
Definition: worldam.h:207
Provides collectives that interoperate with the AM and task interfaces.
Definition: worldgop.h:145
This class wraps/extends the MPI interface for World.
Definition: worldmpi.h:266
int nproc() const
Access the total number of processes.
Definition: worldmpi.h:444
int size() const
Access the total number of processes.
Definition: worldmpi.h:449
int rank() const
Access the rank of this process.
Definition: worldmpi.h:439
SafeMPI::Intracomm & comm()
Returns the associated SafeMPI communicator.
Definition: worldmpi.h:286
Multi-threaded queue to manage and run tasks.
Definition: world_task_queue.h:319
A parallel world class.
Definition: world.h:132
World(const SafeMPI::Intracomm &comm, bool fence=true)
Constructs a World from a communicator.
Definition: world.cc:81
static World * world_from_id(std::uint64_t id)
Convert a World ID to a World pointer.
Definition: world.h:474
map_ptr_to_idT map_ptr_to_id
inverse of map_id_to_ptr
Definition: world.h:184
std::shared_ptr< T > shared_ptr_from_id(uniqueidT id) const
Look up a local pointer from a world-wide unique ID.
Definition: world.h:447
static World * default_world
Default world.
Definition: world.h:141
WorldTaskQueue & taskq
Task queue.
Definition: world.h:204
std::optional< uniqueidT > id_from_ptr(T *ptr) const
Look up an ID from a local pointer.
Definition: world.h:429
static bool is_default(const SafeMPI::Intracomm &comm)
Checks if the default World object corresponds to the given Intracomm.
Definition: world.h:271
friend void finalize()
Call this once at the very end of your main program instead of MPI_Finalize().
Definition: world.cc:232
void set_user_state(void *state)
Sets the user-managed local state.
Definition: world.h:289
void clear_user_state()
Clears the user-defined state.
Definition: world.h:300
uniqueidT make_unique_obj_id()
Creates a new universe-wide unique ID for objects created in this World. No comms.
Definition: world.h:343
static std::pair< std::uint64_t, std::uint64_t > world_id__next_last
Unique {next, last} world IDs to be used by this rank.
Definition: world.h:140
void srand(unsigned long seed=0ul)
Crude seed function for random number generation.
Definition: world.h:537
unsigned int myrand_next
State of crude internal random number generator.
Definition: world.h:208
static World & get_default()
Default World object accessor.
Definition: world.h:258
ProcessID rank() const
Returns the process rank in this World (same as MPI_Comm_rank()).
Definition: world.h:318
~World()
Definition: world.cc:117
static void await(SafeMPI::Request &request, bool dowork=true)
Wait for a MPI request to complete.
Definition: world.h:516
static void await(const Probe &probe, bool dowork=true, bool sleep=false)
Gracefully wait for a condition to become true.
Definition: world.h:529
map_id_to_ptrT map_id_to_ptr
Definition: world.h:182
WorldMpiInterface & mpi
MPI interface.
Definition: world.h:202
std::uint64_t _id
Universe wide unique ID of this world.
Definition: world.h:187
madness::ConcurrentHashMap< uniqueidT, void *, hashuniqueT > map_id_to_ptrT
Definition: world.h:170
void args(int argc, char **argv)
Processes command line arguments.
Definition: world.cc:108
void unregister_ptr(const uniqueidT id)
Unregister a global object via its the unique ID.
Definition: world.h:387
std::optional< T * > ptr_from_id(uniqueidT id) const
Look up a local pointer from a world-wide unique ID.
Definition: world.h:414
ProcessID random_proc_not_me()
Returns a random process number [0,world.size()) that is not the calling process.
Definition: world.h:580
uniqueidT register_ptr(T *ptr)
Associate a local pointer with a universe-wide unique ID.
Definition: world.h:374
static std::list< World * > worlds
Maintains list of active worlds, EXCLUDES default_world.
Definition: world.h:142
ProcessID size() const
Returns the number of processes in this World (same as MPI_Comm_size()).
Definition: world.h:328
unsigned long id() const
Definition: world.h:313
static World * find_instance(const SafeMPI::Intracomm &comm)
Find the World (if it exists) corresponding to the given communicator.
Definition: world.h:230
madness::ConcurrentHashMap< void *, uniqueidT, hashvoidp > map_ptr_to_idT
Definition: world.h:172
void * user_state
Holds a user-defined and managed local state.
Definition: world.h:189
WorldGopInterface & gop
Global operations.
Definition: world.h:205
double drand()
Returns a CRUDE, LOW-QUALITY, random number (real) uniformly distributed in [0,1).
Definition: world.h:568
static bool exists(World *world)
Check if the World exists in the registry.
Definition: world.h:247
friend World & initialize(int &, char **&, const SafeMPI::Intracomm &, int, bool)
Definition: world.cc:161
ProcessID nproc() const
Returns the number of processes in this World (same as MPI_Comm_size()).
Definition: world.h:323
ProcessID random_proc()
Returns a random process number; that is, an integer in [0,world.size()).
Definition: world.h:573
uniqueidT next_unique_obj_id() const
Reports the next universe-wide unique ID generated by make_unique_obj_id() objects created in this Wo...
Definition: world.h:351
unsigned long obj_id
Counter for generating unique IDs within this world.
Definition: world.h:188
static std::uint64_t next_world_id()
Definition: world.cc:134
void * get_user_state()
Returns a pointer to the user-managed local state set by set_user_state().
Definition: world.h:295
static void initialize_world_id_range(int global_rank)
Definition: world.cc:128
int rand()
Returns a CRUDE, LOW-QUALITY, random number (integer) uniformly distributed in [0,...
Definition: world.h:553
std::optional< uniqueidT > id_from_ptr(std::shared_ptr< T > &ptr) const
Look up a unique ID from a local pointer.
Definition: world.h:459
WorldAmInterface & am
AM interface.
Definition: world.h:203
Class for unique global IDs.
Definition: uniqueid.h:53
char * p(char *buf, const char *name, int k, int initial_level, double thresh, int order)
Definition: derivatives.cc:72
std::filesystem::path path
Definition: excited_state_calc.cpp:25
auto T(World &world, response_space &f) -> response_space
Definition: global_functions.cc:34
Macros and tools pertaining to the configuration of MADNESS.
#define MADNESS_EXCEPTION(msg, value)
Macro for throwing a MADNESS exception.
Definition: madness_exception.h:119
#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
Intracomm COMM_WORLD
Definition: safempi.cc:67
File holds all helper structures necessary for the CC_Operator and CC2 class.
Definition: DFParameters.h:10
void print_stats(World &world)
Print miscellaneous stats on a World.
Definition: world.cc:260
void error(const char *msg)
Definition: world.cc:139
void xterm_debug(const char *path, const char *display)
Definition: debug.cc:116
Implements NO_DEFAULTS.
Definition: test_ccpairfunction.cc:22
Definition: world.h:491
bool operator()() const
Definition: world.h:504
MpiRequestTester(SafeMPI::Request &r)
Definition: world.h:498
SafeMPI::Request * r
Definition: world.h:492
Definition: world.h:145
std::size_t operator()(const uniqueidT &id) const
Definition: world.h:151
Definition: world.h:157
std::size_t operator()(const void *p) const
Definition: world.h:163
static void load(const Archive &ar, World *&wptr)
Loads a World from the specified archive.
Definition: world.h:605
Default load of an object via serialize(ar, t).
Definition: archive.h:666
static void store(const Archive &ar, World *const &wptr)
Writes a World to the specified archive.
Definition: world.h:623
Default store of an object via serialize(ar, t).
Definition: archive.h:611
Implements Dqueue, Thread, ThreadBase and ThreadPool.
Defines and implements a concurrent hashmap.
Declares the functions that initialize the parallel runtime.
Implements WorldMpiInterface.
int ProcessID
Used to clearly identify process number/rank.
Definition: worldtypes.h:43