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
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
77
78/// \addtogroup world
79/// @{
80
81namespace 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.
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
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
Definition worldhashmap.h:396
void erase(const iterator &it)
Definition worldhashmap.h:507
std::pair< iterator, bool > insert(const datumT &datum)
Definition worldhashmap.h:468
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
SafeMPI::Intracomm & comm()
Returns the associated SafeMPI communicator.
Definition worldmpi.h:286
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
Multi-threaded queue to manage and run tasks.
Definition world_task_queue.h:319
A parallel world class.
Definition world.h:132
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
void * get_user_state()
Returns a pointer to the user-managed local state set by set_user_state().
Definition world.h:295
map_ptr_to_idT map_ptr_to_id
inverse of map_id_to_ptr
Definition world.h:184
static World & get_default()
Default World object accessor.
Definition world.h:258
static World * default_world
Default world.
Definition world.h:141
static World * world_from_id(std::uint64_t id)
Convert a World ID to a World pointer.
Definition world.h:474
WorldTaskQueue & taskq
Task queue.
Definition world.h:204
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
ProcessID rank() const
Returns the process rank in this World (same as MPI_Comm_rank()).
Definition world.h:318
friend World & initialize(int &, char **&, const SafeMPI::Intracomm &, int, bool)
Definition world.cc:161
~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::optional< uniqueidT > id_from_ptr(std::shared_ptr< T > &ptr) const
Look up a unique ID from a local pointer.
Definition world.h:459
std::optional< uniqueidT > id_from_ptr(T *ptr) const
Look up an ID from a local pointer.
Definition world.h:429
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
ProcessID random_proc_not_me()
Returns a random process number [0,world.size()) that is not the calling process.
Definition world.h:580
static World * find_instance(const SafeMPI::Intracomm &comm)
Find the World (if it exists) corresponding to the given communicator.
Definition world.h:230
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
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
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 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
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
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
Namespace for all elements and tools of MADNESS.
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