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 <atomic> // std::atomic
59#include <cstddef>
60#include <cstdint> // std::uint64_t
61#include <iostream>
62#include <list> // std::list
63#include <memory> // std::shared_ptr
64#include <optional> // std::optional
65#include <utility> // std::pair
66
67#ifdef HAVE_RANDOM
68#include <cstdlib>
69#endif
70
71// Madness world header files needed by world
79
80/// \addtogroup world
81/// @{
82
83namespace madness {
84
85 class World;
86 class WorldTaskQueue;
87 class WorldAmInterface;
88 class WorldGopInterface;
89
90 /// Print miscellaneous stats on a World.
91
92 /// This requires collective operations within the World.
93 /// \param[in] world The World to analyze.
94 void print_stats(World& world);
95
96 /// \todo Brief description needed.
97
98 /// \todo Detailed description needed.
99 /// \param path Description.
100 /// \param display Description.
101 extern void xterm_debug(const char* path, const char* display);
102
103 /// \todo Brief description needed.
104
105 /// \todo Detailed description needed. I imagine this prints/logs the supplied
106 /// error message and subsequently aborts the program.
107 /// \param[in] msg Message associated with the error.
108 void error(const char *msg);
109
110 /// Prints an error message, along with some data, and aborts the program.
111
112 /// \todo Does this function need to be static? (Esp. since it's in a header file...)
113 ///
114 /// \tparam T The type of data.
115 /// \param[in] msg The error message.
116 /// \param[in] data The data to be printed.
117 template <typename T>
118 static void error(const char *msg, const T& data);
119
120
121 /// A parallel world class.
122
123 /// World wraps a MPI communicator. Multiple worlds with different
124 /// communicators can co-exist.
125 ///
126 /// Here we use Pimpl to both hide implementation details and also
127 /// to partition the namespace for users as \c world.mpi, \c world.am, etc.
128 /// We also embed a reference to this instance in the \c am and \c task
129 /// instances so that they have access to everything.
130 ///
131 /// The downside is we cannot do much of anything here without
132 /// using wrapper functions to forward the calls to the hidden
133 /// class methods.
134 class World : private NO_DEFAULTS {
135 private:
136 friend class WorldAmInterface;
137 friend class WorldGopInterface;
138 friend World& initialize(int&, char**&, const SafeMPI::Intracomm&, int, bool);
139 friend void finalize();
140
141 // Static member variables
142 static std::pair<std::uint64_t, std::uint64_t> world_id__next_last; ///< Unique {next, last} world IDs to be used by this rank.
143 static World* default_world; ///< Default world.
144 static std::list<World*> worlds; ///< Maintains list of active worlds, EXCLUDES default_world
145
146 /// \todo Brief description needed.
147 struct hashuniqueT {
148 /// \todo Brief description needed.
149
150 /// \todo Descriptions needed.
151 /// \param[in] id The ID.
152 /// \return Return description needed.
153 inline std::size_t operator()(const uniqueidT& id) const {
154 return id.objid; // The object id's are guaranteed to be unique
155 }
156 };
157
158 /// \todo Brief description needed.
159 struct hashvoidp {
160 /// \todo Brief description needed.
161
162 /// \todo Descriptions needed.
163 /// \param[in] p Missing description.
164 /// \return Return description needed.
165 inline std::size_t operator()(const void* p) const {
166 return std::size_t(p); // The ptr's are guaranteed to be unique
167 }
168 };
169
170 // Mutex globalmutex; ///< Worldwide mutex
171 /// \todo Brief description of typedef needed.
173 /// \todo Brief description of typedef needed.
175
176 /// Maps unique ID of a global object to its local pointer
177 ///
178 /// \note Unique IDs are created by increasing `obj_id`. To be able to assign unique IDs to objects created in
179 /// different worlds, they must be created in exactly the same sequence in every process. Hence in general
180 /// object construction happens in main thread. Object construction first updates `obj_id`, then inserts ID
181 /// into this. The rest of code only knows about this object once it's been added to this map, hence
182 /// this map (NOT `obj_id`) defines the known objects. The only writers to map_id_to_ptr are
183 /// `{register,unregister}_ptr()`.
185 /// inverse of map_id_to_ptr
186 map_ptr_to_idT map_ptr_to_id; ///< \todo Verify: Map from a pointer to its unique hash ID.
187
188
189 std::uint64_t _id; ///< Universe wide unique ID of this world.
190 unsigned long obj_id; ///< Counter for generating unique IDs within this world.
191 void* user_state; ///< Holds a user-defined and managed local state.
192
193 /// Tracks the liveness of this \c World; cleared at the end of \c ~World.
194
195 /// Shared with the objects that memoize a reference to this \c World
196 /// (see \c WorldObjectBase) so that they can detect that it is gone.
197 /// \sa World::liveness
198 std::shared_ptr<std::atomic<bool>> alive;
199
200 // Default copy constructor and assignment won't compile
201 // (which is good) due to reference members.
202
203 /// initializes the value of world_id__next_last to {global_rank*2^32, (global_rank+1)*2^32-1}
204 /// \param global_rank rank of this process in COMM_WORLD
205 static void initialize_world_id_range(int global_rank);
206 /// \return next unique World id
207 static std::uint64_t next_world_id();
208
209
210
211 public:
212 // !!! Order of declaration is important for correct order of initialization !!!
213 WorldMpiInterface& mpi; ///< MPI interface.
214 WorldAmInterface& am; ///< AM interface.
215 WorldTaskQueue& taskq; ///< Task queue.
216 WorldGopInterface& gop; ///< Global operations.
217
218 private:
219 unsigned int myrand_next; ///< State of crude internal random number generator.
220
221 public:
222 /// Constructs a \c World from a communicator.
223
224 /// This function does not check if another \c World exists that uses
225 /// the same communicator. Use instance() to check this.
226 ///
227 /// \param[in] comm The communicator.
228 /// \param[in] fence if true, will synchronize ranks before exiting;
229 /// setting to false removes the extra synchronization
230 /// but may cause premature arrival of RMI messages
231 /// that refer to this world while it's being
232 /// registered
233 World(const SafeMPI::Intracomm& comm,
234 bool fence = true);
235
236 /// Find the World (if it exists) corresponding to the given communicator.
237
238 /// \param[in] comm The communicator.
239 /// \return Pointer to the World that was constructed from \c comm;
240 /// if such a World does not exist, return 0.
242 if (default_world->mpi.comm() == comm)
243 return default_world;
244 else {
245 typedef std::list<World *>::const_iterator citer;
246 for (citer it = worlds.begin(); it != worlds.end(); ++it) {
247 if ((*it)->mpi.comm() == comm)
248 return *it;
249 }
250 return nullptr;
251 }
252 }
253
254 /// Check if the World exists in the registry.
255
256 /// \param[in] world pointer to a World object
257 /// \return true if \c world exists
258 static bool exists(World* world) {
259 return world == default_world || std::find(worlds.begin(), worlds.end(), world) != worlds.end();
260 }
261
262 /// Default World object accessor.
263
264 /// This function returns a reference to the default world object; this
265 /// is the same World object that is returned by
266 /// madness::initialize().
267 /// \return A reference to the default World.
268 /// \throw madness::Exception if the MADNESS_DISABLE_WORLD_GET_DEFAULT preprocessor macro is defined
269 static World& get_default() {
270#ifdef MADNESS_DISABLE_WORLD_GET_DEFAULT
271 MADNESS_EXCEPTION("World::get_default() was called while disabled", 0);
272#endif
274 return *default_world;
275 }
276
277 /// Checks if the default World object corresponds to the given Intracomm
278
279 /// \param[in] comm The communicator.
280 /// \return true if \c comm is the default World object's communicator
281 /// \sa World::get_default()
282 static bool is_default(const SafeMPI::Intracomm& comm) {
283 auto* comm_world = find_instance(comm);
284 if (comm_world)
285 return default_world == comm_world;
286 else
287 return false;
288 }
289
290 /// Sets the user-managed local state.
291
292 /// Rather than having all remotely invoked actions carry all
293 /// of their data with them, they can access local state through
294 /// their \c World instance. The user is responsible for
295 /// consistently managing and freeing this data.
296 ///
297 /// A more PC C++ style would be for the app to put state in
298 /// a singleton.
299 /// \param[in] state The user-managed local state.
300 void set_user_state(void* state) { user_state = state; }
301
302 /// Returns a pointer to the user-managed local state set by set_user_state().
303
304 /// \return A pointer to the user-managed local state; NULL if
305 /// set_user_state() has not been invoked.
306 void* get_user_state() { return user_state; }
307
308 /// Clears the user-defined state.
309
310 /// This has the same effect as `set_user_state(0)`.
311 void clear_user_state() { user_state = nullptr; }
312
313 /// Processes command line arguments.
314
315 /// Mostly intended for \c World test codes, but also provides the
316 /// `-dx option` to start `x` debugger.
317 /// \param[in] argc The number of command-line arguments.
318 /// \param[in,out] argv The command-line arguments.
319 void args(int argc, char**argv);
320
321 /// Returns the system-wide unique integer ID of this \c World.
322 ///
323 /// \return The system-wide unique integer ID of this \c World.
324 unsigned long id() const { return _id; }
325
326 /// The type of the handle returned by \c liveness().
327 using liveness_handleT = std::shared_ptr<const std::atomic<bool>>;
328
329 /// Returns a handle reporting whether this \c World is still alive.
330
331 /// Unlike a \c World reference, the handle stays valid --- and
332 /// dereferenceable --- after this \c World has been destroyed, at which
333 /// point it reports \c false. This lets objects that memoize a \c World
334 /// reference (see \c WorldObjectBase) validate it before use, at the
335 /// cost of a relaxed atomic load. The handle becomes \c false at the
336 /// very end of \c ~World, i.e. objects destroyed by \c ~World itself
337 /// still observe their \c World as alive.
338 /// \return The liveness handle of this \c World.
339 liveness_handleT liveness() const { return alive; }
340
341 /// Returns the process rank in this \c World (same as MPI_Comm_rank()).
342
343 /// \return The process rank in this \c World.
344 ProcessID rank() const { return mpi.rank(); }
345
346 /// Returns the number of processes in this \c World (same as MPI_Comm_size()).
347
348 /// \return The number of processes in this \c World.
349 ProcessID nproc() const { return mpi.nproc(); }
350
351 /// Returns the number of processes in this \c World (same as MPI_Comm_size()).
352
353 /// \return The number of processes in this \c World.
354 ProcessID size() const { return mpi.size(); }
355
356 /// Creates a new universe-wide unique ID for objects created in this \c World. No comms.
357
358 /// You should consider using \c register_ptr(), \c unregister_ptr(),
359 /// \c id_from_ptr(), or \c ptr_from_id() rather than using this directly.
360 ///
361 /// Currently relies on this being called in the same order on
362 /// every process within the current \c World in order to avoid
363 /// synchronization.
364 ///
365 /// Unique IDs are created by increasing static counter.
366 /// The value obj_id=0 is invalid.
367 /// \return A new universe-wide unique ID for objects created in this \c World.
368 /// \warning This is not re-entrant, should be called from a single (typically, main) thread
372
373 /// Reports the next universe-wide unique ID generated by make_unique_obj_id() objects created in this \c World. No comms.
374
375 /// \return A the next universe-wide unique ID for objects created in this \c World.
376 /// \warning This is not re-entrant, should be called from a single (typically, main) thread
378 return uniqueidT(_id,obj_id);
379 }
380
381 /// Associate a local pointer with a universe-wide unique ID.
382
383 /// Use the routines \c register_ptr(), \c unregister_ptr(),
384 /// \c id_from_ptr(), \c ptr_from_id() to map distributed data
385 /// structures identified by the unique ID to/from
386 /// process-local data.
387 ///
388 /// \note The pointer will be internally cast to a (void *),
389 /// so don't use member pointers here.
390 ///
391 /// \note All unique objects of any type within a \c World must
392 /// presently be created in the same order on all processes so
393 /// as to guarantee the uniqueness without global
394 /// communication.
395 /// \tparam T The type of data to be associated.
396 /// \param[in] ptr Pointer to the data that will be associated
397 /// with a unique ID.
398 /// \return The unique ID associated with the supplied data.
399 template <typename T>
401 MADNESS_ASSERT(sizeof(T*) == sizeof(void *));
403 [[maybe_unused]] auto&& [it1, inserted1] = map_id_to_ptr.insert(std::pair<uniqueidT,void*>(id,static_cast<void*>(ptr)));
405 [[maybe_unused]] auto&& [it2, inserted2] = map_ptr_to_id.insert(std::pair<void*,uniqueidT>(static_cast<void*>(ptr),id));
407 return id;
408 }
409
410 /// Unregister a global object via its the unique ID.
411
412 /// \param[in] id The unique ID of the data to unregister.
413 void unregister_ptr(const uniqueidT id) {
414 // START critical section
416 [[maybe_unused]] auto found = map_id_to_ptr.find(acc, id);
417 MADNESS_ASSERT(found); // make sure id is valid
418
419 void* ptr = static_cast<void*>(acc->second);
420
421 // if NDEBUG is not defined, keep unregistered ptr IDs in map_id_to_ptr else remove them
422#ifdef NDEBUG
423 map_id_to_ptr.erase(acc); // END critical section
424#else
425 MADNESS_ASSERT(ptr); // ensure ID is not expired
426 acc->second = nullptr;
427 acc.release(); // END critical section
428#endif
431 }
432
433 /// Look up a local pointer from a world-wide unique ID.
434
435 /// \tparam T The type of the data to look up.
436 /// \param[in] id The unique ID of the data.
437 /// \return The local pointer (can be \c nullptr if \p id has been deregistered and
438 /// `NDEBUG` is not `#define`d); if \p id has not been registered then returns null optional
439 template <typename T>
440 [[nodiscard]] std::optional<T*> ptr_from_id(uniqueidT id) const {
442 [[maybe_unused]] auto found = map_id_to_ptr.find(acc, id);
443 if (!found)
444 return {};
445 else
446 return {static_cast<T *>(acc->second)};
447 }
448
449 /// Look up an ID from a local pointer.
450
451 /// \tparam T The type of the data to look up.
452 /// \param[in] ptr The local pointer.
453 /// \return Optional containing the unique ID if the pointer is registered, or a null optional if the pointer is not registered.
454 template <typename T>
455 [[nodiscard]] std::optional<uniqueidT> id_from_ptr(T* ptr) const {
457 [[maybe_unused]] auto found = map_ptr_to_id.find(acc, ptr);
458 if (!found)
459 return {};
460 else
461 return {acc->second};
462 }
463
464#ifndef MADNESS_DISABLE_SHARED_FROM_THIS
465
466 /// Look up a local pointer from a world-wide unique ID.
467
468 /// \tparam T The type of the data to look up.
469 /// \param[in] id The unique ID.
470 /// \return The pointer or a default constructed `std::shared_ptr` if
471 /// the ID is not found.
472 template <typename T>
473 [[nodiscard]] std::shared_ptr<T> shared_ptr_from_id(uniqueidT id) const {
474 std::optional<T*> ptr_opt = ptr_from_id<T>(id);
476 return (ptr_opt ? *ptr_opt->shared_from_this() : std::shared_ptr<T>());
477 }
478
479 /// Look up a unique ID from a local pointer.
480
481 /// \tparam T The type of the data to look up.
482 /// \param[in] ptr The local pointer.
483 /// \return Optional containing the unique ID, if the pointer is registered, or a null optional, if the pointer is not registered.
484 template <typename T>
485 [[nodiscard]] std::optional<uniqueidT> id_from_ptr(std::shared_ptr<T>& ptr) const {
486 return id_from_ptr(ptr.get());
487 }
488
489#endif // MADNESS_DISABLE_SHARED_FROM_THIS
490
491 /// Returns a vector of all unique IDs in this \c World.
492 std::vector<uniqueidT> get_object_ids() const {
493 std::vector<uniqueidT> ids;
494 for (auto it = map_id_to_ptr.begin(); it != map_id_to_ptr.end(); ++it)
495 ids.push_back(it->first);
496 return ids;
497 }
498
499 /// return a vector containing all world ids
500 static std::vector<unsigned long> get_world_ids() {
501 std::vector<unsigned long> ids;
502 for (auto it = worlds.begin(); it != worlds.end(); ++it)
503 ids.push_back((*it)->id());
504 return ids;
505
506 }
507
508 /// Convert a \c World ID to a \c World pointer.
509
510 /// The ID will only be valid if the process calling this routine
511 /// is a member of that \c World. Thus a \c NULL return value does not
512 /// necessarily mean that the \c World does not exist --- it could just
513 /// not include the calling process.
514 /// \param[in] id The ID of the \c World.
515 /// \return A pointer to the world associated with \c id, or \c NULL.
516 static World* world_from_id(std::uint64_t id) {
517 if (id != 0) {
518 for (std::list<World *>::iterator it = worlds.begin();
519 it != worlds.end(); ++it) {
520 if ((*it) && (*it)->_id == id)
521 return *it;
522 }
523 return nullptr;
524 }
525 else
526 return default_world;
527 }
528
529 private:
530
531 // Cannot use bind_nullary here since SafeMPI::Request::Test is non-const
532 /// \todo Brief description needed.
534 mutable SafeMPI::Request* r; ///< \todo Brief description needed.
535
536 /// \todo Brief description needed.
537
538 /// \todo Descriptions needed.
539 /// \param r Description needed.
541
542 /// \todo Brief description needed.
543
544 /// \todo Descriptions needed.
545 /// \return Description needed.
546 bool operator()() const {
547 return r->Test();
548 }
549 };
550
551 public:
552
553 /// Wait for a MPI request to complete.
554
555 /// \todo Descriptions needed.
556 /// \param[in,out] request The MPI request on which to wait.
557 /// \param dowork Work while waiting - default is true
558 static void inline await(SafeMPI::Request& request, bool dowork = true) {
559 ThreadPool::await(MpiRequestTester(request), dowork, true); // Last arg is sleep=true --- don't hard spin on MPI requests
560 }
561
562 /// Gracefully wait for a condition to become true.
563
564 /// In the mean time, execute any tasks in the queue.
565 /// \todo Descriptions needed.
566 /// \tparam Probe An object that, when called, returns the status.
567 /// \param[in] probe The conditional's test.
568 /// \param dowork Work while waiting - default is true
569 /// \param sleep Sleep instead of spin while waiting - default is false
570 template <typename Probe>
571 static void inline await(const Probe& probe, bool dowork = true, bool sleep=false) {
573 }
574
575 /// Crude seed function for random number generation.
576
577 /// \param[in] seed The seed.
578 /// \todo Since we're switching to C++11, would it be worth using the new C++11 random number generation capabilities?
579 void srand(unsigned long seed = 0ul) {
580 if (seed == 0) seed = rank();
581#ifdef HAVE_RANDOM
582 srandom(seed);
583#else
585 for (int i=0; i<1000; ++i) rand(); // Warmup
586#endif // HAVE_RANDOM
587 }
588
589
590 /// Returns a CRUDE, LOW-QUALITY, random number (integer) uniformly distributed in [0,2**24).
591
592 /// Each process has a distinct seed for the generator.
593 /// \return The random number.
594 /// \todo Since we're switching to C++11, would it be worth using the new C++11 random number generation capabilities?
595 int rand() {
596#ifdef HAVE_RANDOM
597 return int(random() & 0xfffffful);
598#else
599 myrand_next = myrand_next * 1103515245UL + 12345UL;
600 return int((myrand_next>>8) & 0xfffffful);
601#endif // HAVE_RANDOM
602 }
603
604
605 /// Returns a CRUDE, LOW-QUALITY, random number (real) uniformly distributed in [0,1).
606
607 /// Each process has a distinct seed for the generator.
608 /// \return The random number.
609 /// \todo Since we're switching to C++11, would it be worth using the new C++11 random number generation capabilities?
610 double drand() { return rand()/16777216.0; }
611
612 /// Returns a random process number; that is, an integer in [0,`world.size()`).
613
614 /// \return The random process number.
615 ProcessID random_proc() { return rand()%size(); }
616
617 /// Returns a random process number [0,`world.size()`) that is not the calling process.
618
619 /// It doesn't make any sense to call this with just one process, but just in
620 /// case, this returns -1 in the hope that you won't actually use the result.
621 /// \return The random process number, or -1.
623 if (size() == 1) return -1;
624 ProcessID p;
625 do {
626 p = rand()%size();
627 } while (p == rank());
628 return p;
629 }
630
631 ~World();
632 }; // class World
633
634 namespace archive {
635
636 /// Specialization of \c ArchiveLoadImpl for \c World pointers.
637
638 /// Helps in archiving (reading) \c World objects.
639 /// \tparam Archive The archive type.
640 template <class Archive>
642 /// Loads a \c World from the specified archive.
643
644 /// \note Aborts the program if a \c World cannot be read from the archive.
645 /// \param[in,out] ar The archive.
646 /// \param[out] wptr Pointer to the \c World.
647 static inline void load(const Archive& ar, World*& wptr) {
648 unsigned long id = 0ul;
649 ar & id;
652 }
653 }; // struct ArchiveLoadImpl<Archive,World*>
654
655 /// Specialization of \c ArchiveStoreImpl for \c World pointers.
656
657 /// Helps in archiving (writing) \c World objects.
658 /// \tparam Archive The archive type.
659 template <class Archive>
661 /// Writes a \c World to the specified archive.
662
663 /// \param[in,out] ar The archive.
664 /// \param[in] wptr Pointer to the \c World.
665 static inline void store(const Archive& ar, World* const & wptr) {
666 ar & wptr->id();
667 }
668 }; // struct ArchiveStoreImpl<Archive,World*>
669 } // namespace archive
670
671
672
673 // implementation of templated functions
674 template <typename T>
675 static void error(const char *msg, const T& data) {
676 std::cerr << "MADNESS: fatal error: " << msg << " " << data << std::endl;
678 }
679} // namespace madness
680
681/// @}
682
683#endif // MADNESS_WORLD_WORLD_H__INCLUDED
std::filesystem::path path
Definition InputWriter.cpp:3
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:497
void Abort(int code=1) const
Definition safempi.h:807
Definition safempi.h:296
bool Test(MPI_Status &status)
Definition safempi.h:416
Definition worldhashmap.h:396
iterator begin()
Definition worldhashmap.h:571
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 end()
Definition worldhashmap.h:583
iterator find(const keyT &key)
Definition worldhashmap.h:524
Definition worldhashmap.h:330
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:1450
Implements AM interface.
Definition worldam.h:207
Provides collectives that interoperate with the AM and task interfaces.
Definition worldgop.h:147
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:134
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:473
void * get_user_state()
Returns a pointer to the user-managed local state set by set_user_state().
Definition world.h:306
map_ptr_to_idT map_ptr_to_id
inverse of map_id_to_ptr
Definition world.h:186
static World & get_default()
Default World object accessor.
Definition world.h:269
static World * default_world
Default world.
Definition world.h:143
static World * world_from_id(std::uint64_t id)
Convert a World ID to a World pointer.
Definition world.h:516
WorldTaskQueue & taskq
Task queue.
Definition world.h:215
static bool is_default(const SafeMPI::Intracomm &comm)
Checks if the default World object corresponds to the given Intracomm.
Definition world.h:282
friend void finalize()
Call this once at the very end of your main program instead of MPI_Finalize().
Definition world.cc:246
liveness_handleT liveness() const
Returns a handle reporting whether this World is still alive.
Definition world.h:339
void set_user_state(void *state)
Sets the user-managed local state.
Definition world.h:300
void clear_user_state()
Clears the user-defined state.
Definition world.h:311
std::vector< uniqueidT > get_object_ids() const
Returns a vector of all unique IDs in this World.
Definition world.h:492
uniqueidT make_unique_obj_id()
Creates a new universe-wide unique ID for objects created in this World. No comms.
Definition world.h:369
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:142
void srand(unsigned long seed=0ul)
Crude seed function for random number generation.
Definition world.h:579
unsigned int myrand_next
State of crude internal random number generator.
Definition world.h:219
ProcessID rank() const
Returns the process rank in this World (same as MPI_Comm_rank()).
Definition world.h:344
std::shared_ptr< const std::atomic< bool > > liveness_handleT
The type of the handle returned by liveness().
Definition world.h:327
friend World & initialize(int &, char **&, const SafeMPI::Intracomm &, int, bool)
Definition world.cc:169
~World()
Definition world.cc:119
static void await(SafeMPI::Request &request, bool dowork=true)
Wait for a MPI request to complete.
Definition world.h:558
static void await(const Probe &probe, bool dowork=true, bool sleep=false)
Gracefully wait for a condition to become true.
Definition world.h:571
map_id_to_ptrT map_id_to_ptr
Definition world.h:184
static std::vector< unsigned long > get_world_ids()
return a vector containing all world ids
Definition world.h:500
WorldMpiInterface & mpi
MPI interface.
Definition world.h:213
std::optional< uniqueidT > id_from_ptr(std::shared_ptr< T > &ptr) const
Look up a unique ID from a local pointer.
Definition world.h:485
std::optional< uniqueidT > id_from_ptr(T *ptr) const
Look up an ID from a local pointer.
Definition world.h:455
std::uint64_t _id
Universe wide unique ID of this world.
Definition world.h:189
madness::ConcurrentHashMap< uniqueidT, void *, hashuniqueT > map_id_to_ptrT
Definition world.h:172
void args(int argc, char **argv)
Processes command line arguments.
Definition world.cc:110
void unregister_ptr(const uniqueidT id)
Unregister a global object via its the unique ID.
Definition world.h:413
ProcessID random_proc_not_me()
Returns a random process number [0,world.size()) that is not the calling process.
Definition world.h:622
static World * find_instance(const SafeMPI::Intracomm &comm)
Find the World (if it exists) corresponding to the given communicator.
Definition world.h:241
uniqueidT register_ptr(T *ptr)
Associate a local pointer with a universe-wide unique ID.
Definition world.h:400
static std::list< World * > worlds
Maintains list of active worlds, EXCLUDES default_world.
Definition world.h:144
ProcessID size() const
Returns the number of processes in this World (same as MPI_Comm_size()).
Definition world.h:354
unsigned long id() const
Definition world.h:324
madness::ConcurrentHashMap< void *, uniqueidT, hashvoidp > map_ptr_to_idT
Definition world.h:174
void * user_state
Holds a user-defined and managed local state.
Definition world.h:191
WorldGopInterface & gop
Global operations.
Definition world.h:216
double drand()
Returns a CRUDE, LOW-QUALITY, random number (real) uniformly distributed in [0,1).
Definition world.h:610
static bool exists(World *world)
Check if the World exists in the registry.
Definition world.h:258
std::optional< T * > ptr_from_id(uniqueidT id) const
Look up a local pointer from a world-wide unique ID.
Definition world.h:440
ProcessID nproc() const
Returns the number of processes in this World (same as MPI_Comm_size()).
Definition world.h:349
ProcessID random_proc()
Returns a random process number; that is, an integer in [0,world.size()).
Definition world.h:615
std::shared_ptr< std::atomic< bool > > alive
Tracks the liveness of this World; cleared at the end of ~World.
Definition world.h:198
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:377
unsigned long obj_id
Counter for generating unique IDs within this world.
Definition world.h:190
static std::uint64_t next_world_id()
Definition world.cc:142
static void initialize_world_id_range(int global_rank)
Definition world.cc:136
int rand()
Returns a CRUDE, LOW-QUALITY, random number (integer) uniformly distributed in [0,...
Definition world.h:595
WorldAmInterface & am
AM interface.
Definition world.h:214
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
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:274
void error(const char *msg)
Definition world.cc:147
void xterm_debug(const char *path, const char *display)
Definition debug.cc:118
static XNonlinearSolver< std::vector< Function< T, NDIM > >, T, vector_function_allocator< T, NDIM > > nonlinear_vector_solver(World &world, const long nvec)
Definition nonlinsol.h:371
Implements NO_DEFAULTS.
Definition test_ccpairfunction.cc:22
Definition world.h:533
bool operator()() const
Definition world.h:546
MpiRequestTester(SafeMPI::Request &r)
Definition world.h:540
SafeMPI::Request * r
Definition world.h:534
Definition world.h:147
std::size_t operator()(const uniqueidT &id) const
Definition world.h:153
Definition world.h:159
std::size_t operator()(const void *p) const
Definition world.h:165
static void load(const Archive &ar, World *&wptr)
Loads a World from the specified archive.
Definition world.h:647
Default load of an object via serialize(ar, t).
Definition archive.h:667
static void store(const Archive &ar, World *const &wptr)
Writes a World to the specified archive.
Definition world.h:665
Default store of an object via serialize(ar, t).
Definition archive.h:612
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