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
201
202 public:
203 // !!! Order of declaration is important for correct order of initialization !!!
204 WorldMpiInterface& mpi; ///< MPI interface.
205 WorldAmInterface& am; ///< AM interface.
206 WorldTaskQueue& taskq; ///< Task queue.
207 WorldGopInterface& gop; ///< Global operations.
208
209 private:
210 unsigned int myrand_next; ///< State of crude internal random number generator.
211
212 public:
213 /// Constructs a \c World from a communicator.
214
215 /// This function does not check if another \c World exists that uses
216 /// the same communicator. Use instance() to check this.
217 ///
218 /// \param[in] comm The communicator.
219 /// \param[in] fence if true, will synchronize ranks before exiting;
220 /// setting to false removes the extra synchronization
221 /// but may cause premature arrival of RMI messages
222 /// that refer to this world while it's being
223 /// registered
224 World(const SafeMPI::Intracomm& comm,
225 bool fence = true);
226
227 /// Find the World (if it exists) corresponding to the given communicator.
228
229 /// \param[in] comm The communicator.
230 /// \return Pointer to the World that was constructed from \c comm;
231 /// if such a World does not exist, return 0.
233 if (default_world->mpi.comm() == comm)
234 return default_world;
235 else {
236 typedef std::list<World *>::const_iterator citer;
237 for (citer it = worlds.begin(); it != worlds.end(); ++it) {
238 if ((*it)->mpi.comm() == comm)
239 return *it;
240 }
241 return nullptr;
242 }
243 }
244
245 /// Check if the World exists in the registry.
246
247 /// \param[in] world pointer to a World object
248 /// \return true if \c world exists
249 static bool exists(World* world) {
250 return world == default_world || std::find(worlds.begin(), worlds.end(), world) != worlds.end();
251 }
252
253 /// Default World object accessor.
254
255 /// This function returns a reference to the default world object; this
256 /// is the same World object that is returned by
257 /// madness::initialize().
258 /// \return A reference to the default World.
259 /// \throw madness::Exception if the MADNESS_DISABLE_WORLD_GET_DEFAULT preprocessor macro is defined
260 static World& get_default() {
261#ifdef MADNESS_DISABLE_WORLD_GET_DEFAULT
262 MADNESS_EXCEPTION("World::get_default() was called while disabled", 0);
263#endif
265 return *default_world;
266 }
267
268 /// Checks if the default World object corresponds to the given Intracomm
269
270 /// \param[in] comm The communicator.
271 /// \return true if \c comm is the default World object's communicator
272 /// \sa World::get_default()
273 static bool is_default(const SafeMPI::Intracomm& comm) {
274 auto* comm_world = find_instance(comm);
275 if (comm_world)
276 return default_world == comm_world;
277 else
278 return false;
279 }
280
281 /// Sets the user-managed local state.
282
283 /// Rather than having all remotely invoked actions carry all
284 /// of their data with them, they can access local state through
285 /// their \c World instance. The user is responsible for
286 /// consistently managing and freeing this data.
287 ///
288 /// A more PC C++ style would be for the app to put state in
289 /// a singleton.
290 /// \param[in] state The user-managed local state.
291 void set_user_state(void* state) { user_state = state; }
292
293 /// Returns a pointer to the user-managed local state set by set_user_state().
294
295 /// \return A pointer to the user-managed local state; NULL if
296 /// set_user_state() has not been invoked.
297 void* get_user_state() { return user_state; }
298
299 /// Clears the user-defined state.
300
301 /// This has the same effect as `set_user_state(0)`.
302 void clear_user_state() { user_state = nullptr; }
303
304 /// Processes command line arguments.
305
306 /// Mostly intended for \c World test codes, but also provides the
307 /// `-dx option` to start `x` debugger.
308 /// \param[in] argc The number of command-line arguments.
309 /// \param[in,out] argv The command-line arguments.
310 void args(int argc, char**argv);
311
312 /// Returns the system-wide unique integer ID of this \c World.
313 ///
314 /// \return The system-wide unique integer ID of this \c World.
315 unsigned long id() const { return _id; }
316
317 /// Returns the process rank in this \c World (same as MPI_Comm_rank()).
318
319 /// \return The process rank in this \c World.
320 ProcessID rank() const { return mpi.rank(); }
321
322 /// Returns the number of processes in this \c World (same as MPI_Comm_size()).
323
324 /// \return The number of processes in this \c World.
325 ProcessID nproc() const { return mpi.nproc(); }
326
327 /// Returns the number of processes in this \c World (same as MPI_Comm_size()).
328
329 /// \return The number of processes in this \c World.
330 ProcessID size() const { return mpi.size(); }
331
332 /// Creates a new universe-wide unique ID for objects created in this \c World. No comms.
333
334 /// You should consider using \c register_ptr(), \c unregister_ptr(),
335 /// \c id_from_ptr(), or \c ptr_from_id() rather than using this directly.
336 ///
337 /// Currently relies on this being called in the same order on
338 /// every process within the current \c World in order to avoid
339 /// synchronization.
340 ///
341 /// Unique IDs are created by increasing static counter.
342 /// The value obj_id=0 is invalid.
343 /// \return A new universe-wide unique ID for objects created in this \c World.
344 /// \warning This is not re-entrant, should be called from a single (typically, main) thread
348
349 /// Reports the next universe-wide unique ID generated by make_unique_obj_id() objects created in this \c World. No comms.
350
351 /// \return A the next universe-wide unique ID for objects created in this \c World.
352 /// \warning This is not re-entrant, should be called from a single (typically, main) thread
354 return uniqueidT(_id,obj_id);
355 }
356
357 /// Associate a local pointer with a universe-wide unique ID.
358
359 /// Use the routines \c register_ptr(), \c unregister_ptr(),
360 /// \c id_from_ptr(), \c ptr_from_id() to map distributed data
361 /// structures identified by the unique ID to/from
362 /// process-local data.
363 ///
364 /// \note The pointer will be internally cast to a (void *),
365 /// so don't use member pointers here.
366 ///
367 /// \note All unique objects of any type within a \c World must
368 /// presently be created in the same order on all processes so
369 /// as to guarantee the uniqueness without global
370 /// communication.
371 /// \tparam T The type of data to be associated.
372 /// \param[in] ptr Pointer to the data that will be associated
373 /// with a unique ID.
374 /// \return The unique ID associated with the supplied data.
375 template <typename T>
376 [[nodiscard]] uniqueidT register_ptr(T* ptr) {
377 MADNESS_ASSERT(sizeof(T*) == sizeof(void *));
379 [[maybe_unused]] auto&& [it1, inserted1] = map_id_to_ptr.insert(std::pair<uniqueidT,void*>(id,static_cast<void*>(ptr)));
380 MADNESS_ASSERT(inserted1);
381 [[maybe_unused]] auto&& [it2, inserted2] = map_ptr_to_id.insert(std::pair<void*,uniqueidT>(static_cast<void*>(ptr),id));
382 MADNESS_ASSERT(inserted2);
383 return id;
384 }
385
386 /// Unregister a global object via its the unique ID.
387
388 /// \param[in] id The unique ID of the data to unregister.
389 void unregister_ptr(const uniqueidT id) {
390 // START critical section
392 [[maybe_unused]] auto found = map_id_to_ptr.find(acc, id);
393 MADNESS_ASSERT(found); // make sure id is valid
394
395 void* ptr = static_cast<void*>(acc->second);
396
397 // if NDEBUG is not defined, keep unregistered ptr IDs in map_id_to_ptr else remove them
398#ifdef NDEBUG
399 map_id_to_ptr.erase(acc); // END critical section
400#else
401 MADNESS_ASSERT(ptr); // ensure ID is not expired
402 acc->second = nullptr;
403 acc.release(); // END critical section
404#endif
405 [[maybe_unused]] auto erased2 = map_ptr_to_id.try_erase(ptr);
406 MADNESS_ASSERT(erased2);
407 }
408
409 /// Look up a local pointer from a world-wide unique ID.
410
411 /// \tparam T The type of the data to look up.
412 /// \param[in] id The unique ID of the data.
413 /// \return The local pointer (can be \c nullptr if \p id has been deregistered and
414 /// `NDEBUG` is not `#define`d); if \p id has not been registered then returns null optional
415 template <typename T>
416 [[nodiscard]] std::optional<T*> ptr_from_id(uniqueidT id) const {
418 [[maybe_unused]] auto found = map_id_to_ptr.find(acc, id);
419 if (!found)
420 return {};
421 else
422 return {static_cast<T *>(acc->second)};
423 }
424
425 /// Look up an ID from a local pointer.
426
427 /// \tparam T The type of the data to look up.
428 /// \param[in] ptr The local pointer.
429 /// \return Optional containing the unique ID if the pointer is registered, or a null optional if the pointer is not registered.
430 template <typename T>
431 [[nodiscard]] std::optional<uniqueidT> id_from_ptr(T* ptr) const {
433 [[maybe_unused]] auto found = map_ptr_to_id.find(acc, ptr);
434 if (!found)
435 return {};
436 else
437 return {acc->second};
438 }
439
440#ifndef MADNESS_DISABLE_SHARED_FROM_THIS
441
442 /// Look up a local pointer from a world-wide unique ID.
443
444 /// \tparam T The type of the data to look up.
445 /// \param[in] id The unique ID.
446 /// \return The pointer or a default constructed `std::shared_ptr` if
447 /// the ID is not found.
448 template <typename T>
449 [[nodiscard]] std::shared_ptr<T> shared_ptr_from_id(uniqueidT id) const {
450 std::optional<T*> ptr_opt = ptr_from_id<T>(id);
451 if (ptr_opt) MADNESS_ASSERT(*ptr_opt);
452 return (ptr_opt ? *ptr_opt->shared_from_this() : std::shared_ptr<T>());
453 }
454
455 /// Look up a unique ID from a local pointer.
456
457 /// \tparam T The type of the data to look up.
458 /// \param[in] ptr The local pointer.
459 /// \return Optional containing the unique ID, if the pointer is registered, or a null optional, if the pointer is not registered.
460 template <typename T>
461 [[nodiscard]] std::optional<uniqueidT> id_from_ptr(std::shared_ptr<T>& ptr) const {
462 return id_from_ptr(ptr.get());
463 }
464
465#endif // MADNESS_DISABLE_SHARED_FROM_THIS
466
467 /// Returns a vector of all unique IDs in this \c World.
468 std::vector<uniqueidT> get_object_ids() const {
469 std::vector<uniqueidT> ids;
470 for (auto it = map_id_to_ptr.begin(); it != map_id_to_ptr.end(); ++it)
471 ids.push_back(it->first);
472 return ids;
473 }
474
475 /// return a vector containing all world ids
476 static std::vector<unsigned long> get_world_ids() {
477 std::vector<unsigned long> ids;
478 for (auto it = worlds.begin(); it != worlds.end(); ++it)
479 ids.push_back((*it)->id());
480 return ids;
481
482 }
483
484 /// Convert a \c World ID to a \c World pointer.
485
486 /// The ID will only be valid if the process calling this routine
487 /// is a member of that \c World. Thus a \c NULL return value does not
488 /// necessarily mean that the \c World does not exist --- it could just
489 /// not include the calling process.
490 /// \param[in] id The ID of the \c World.
491 /// \return A pointer to the world associated with \c id, or \c NULL.
492 static World* world_from_id(std::uint64_t id) {
493 if (id != 0) {
494 for (std::list<World *>::iterator it = worlds.begin();
495 it != worlds.end(); ++it) {
496 if ((*it) && (*it)->_id == id)
497 return *it;
498 }
499 return nullptr;
500 }
501 else
502 return default_world;
503 }
504
505 private:
506
507 // Cannot use bind_nullary here since SafeMPI::Request::Test is non-const
508 /// \todo Brief description needed.
510 mutable SafeMPI::Request* r; ///< \todo Brief description needed.
511
512 /// \todo Brief description needed.
513
514 /// \todo Descriptions needed.
515 /// \param r Description needed.
517
518 /// \todo Brief description needed.
519
520 /// \todo Descriptions needed.
521 /// \return Description needed.
522 bool operator()() const {
523 return r->Test();
524 }
525 };
526
527 public:
528
529 /// Wait for a MPI request to complete.
530
531 /// \todo Descriptions needed.
532 /// \param[in,out] request The MPI request on which to wait.
533 /// \param dowork Work while waiting - default is true
534 static void inline await(SafeMPI::Request& request, bool dowork = true) {
535 ThreadPool::await(MpiRequestTester(request), dowork, true); // Last arg is sleep=true --- don't hard spin on MPI requests
536 }
537
538 /// Gracefully wait for a condition to become true.
539
540 /// In the mean time, execute any tasks in the queue.
541 /// \todo Descriptions needed.
542 /// \tparam Probe An object that, when called, returns the status.
543 /// \param[in] probe The conditional's test.
544 /// \param dowork Work while waiting - default is true
545 /// \param sleep Sleep instead of spin while waiting - default is false
546 template <typename Probe>
547 static void inline await(const Probe& probe, bool dowork = true, bool sleep=false) {
548 ThreadPool::await(probe, dowork);
549 }
550
551 /// Crude seed function for random number generation.
552
553 /// \param[in] seed The seed.
554 /// \todo Since we're switching to C++11, would it be worth using the new C++11 random number generation capabilities?
555 void srand(unsigned long seed = 0ul) {
556 if (seed == 0) seed = rank();
557#ifdef HAVE_RANDOM
558 srandom(seed);
559#else
560 myrand_next = seed;
561 for (int i=0; i<1000; ++i) rand(); // Warmup
562#endif // HAVE_RANDOM
563 }
564
565
566 /// Returns a CRUDE, LOW-QUALITY, random number (integer) uniformly distributed in [0,2**24).
567
568 /// Each process has a distinct seed for the generator.
569 /// \return The random number.
570 /// \todo Since we're switching to C++11, would it be worth using the new C++11 random number generation capabilities?
571 int rand() {
572#ifdef HAVE_RANDOM
573 return int(random() & 0xfffffful);
574#else
575 myrand_next = myrand_next * 1103515245UL + 12345UL;
576 return int((myrand_next>>8) & 0xfffffful);
577#endif // HAVE_RANDOM
578 }
579
580
581 /// Returns a CRUDE, LOW-QUALITY, random number (real) uniformly distributed in [0,1).
582
583 /// Each process has a distinct seed for the generator.
584 /// \return The random number.
585 /// \todo Since we're switching to C++11, would it be worth using the new C++11 random number generation capabilities?
586 double drand() { return rand()/16777216.0; }
587
588 /// Returns a random process number; that is, an integer in [0,`world.size()`).
589
590 /// \return The random process number.
591 ProcessID random_proc() { return rand()%size(); }
592
593 /// Returns a random process number [0,`world.size()`) that is not the calling process.
594
595 /// It doesn't make any sense to call this with just one process, but just in
596 /// case, this returns -1 in the hope that you won't actually use the result.
597 /// \return The random process number, or -1.
599 if (size() == 1) return -1;
600 ProcessID p;
601 do {
602 p = rand()%size();
603 } while (p == rank());
604 return p;
605 }
606
607 ~World();
608 }; // class World
609
610 namespace archive {
611
612 /// Specialization of \c ArchiveLoadImpl for \c World pointers.
613
614 /// Helps in archiving (reading) \c World objects.
615 /// \tparam Archive The archive type.
616 template <class Archive>
617 struct ArchiveLoadImpl<Archive,World*> {
618 /// Loads a \c World from the specified archive.
619
620 /// \note Aborts the program if a \c World cannot be read from the archive.
621 /// \param[in,out] ar The archive.
622 /// \param[out] wptr Pointer to the \c World.
623 static inline void load(const Archive& ar, World*& wptr) {
624 unsigned long id = 0ul;
625 ar & id;
626 wptr = World::world_from_id(id);
627 MADNESS_ASSERT(wptr);
628 }
629 }; // struct ArchiveLoadImpl<Archive,World*>
630
631 /// Specialization of \c ArchiveStoreImpl for \c World pointers.
632
633 /// Helps in archiving (writing) \c World objects.
634 /// \tparam Archive The archive type.
635 template <class Archive>
636 struct ArchiveStoreImpl<Archive,World*> {
637 /// Writes a \c World to the specified archive.
638
639 /// \param[in,out] ar The archive.
640 /// \param[in] wptr Pointer to the \c World.
641 static inline void store(const Archive& ar, World* const & wptr) {
642 ar & wptr->id();
643 }
644 }; // struct ArchiveStoreImpl<Archive,World*>
645 } // namespace archive
646
647
648
649 // implementation of templated functions
650 template <typename T>
651 static void error(const char *msg, const T& data) {
652 std::cerr << "MADNESS: fatal error: " << msg << " " << data << std::endl;
654 }
655} // namespace madness
656
657/// @}
658
659#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
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
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:449
void * get_user_state()
Returns a pointer to the user-managed local state set by set_user_state().
Definition world.h:297
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:260
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:492
WorldTaskQueue & taskq
Task queue.
Definition world.h:206
static bool is_default(const SafeMPI::Intracomm &comm)
Checks if the default World object corresponds to the given Intracomm.
Definition world.h:273
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:291
void clear_user_state()
Clears the user-defined state.
Definition world.h:302
std::vector< uniqueidT > get_object_ids() const
Returns a vector of all unique IDs in this World.
Definition world.h:468
uniqueidT make_unique_obj_id()
Creates a new universe-wide unique ID for objects created in this World. No comms.
Definition world.h:345
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:555
unsigned int myrand_next
State of crude internal random number generator.
Definition world.h:210
ProcessID rank() const
Returns the process rank in this World (same as MPI_Comm_rank()).
Definition world.h:320
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:534
static void await(const Probe &probe, bool dowork=true, bool sleep=false)
Gracefully wait for a condition to become true.
Definition world.h:547
map_id_to_ptrT map_id_to_ptr
Definition world.h:182
static std::vector< unsigned long > get_world_ids()
return a vector containing all world ids
Definition world.h:476
WorldMpiInterface & mpi
MPI interface.
Definition world.h:204
std::optional< uniqueidT > id_from_ptr(std::shared_ptr< T > &ptr) const
Look up a unique ID from a local pointer.
Definition world.h:461
std::optional< uniqueidT > id_from_ptr(T *ptr) const
Look up an ID from a local pointer.
Definition world.h:431
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:389
ProcessID random_proc_not_me()
Returns a random process number [0,world.size()) that is not the calling process.
Definition world.h:598
static World * find_instance(const SafeMPI::Intracomm &comm)
Find the World (if it exists) corresponding to the given communicator.
Definition world.h:232
uniqueidT register_ptr(T *ptr)
Associate a local pointer with a universe-wide unique ID.
Definition world.h:376
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:330
unsigned long id() const
Definition world.h:315
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:207
double drand()
Returns a CRUDE, LOW-QUALITY, random number (real) uniformly distributed in [0,1).
Definition world.h:586
static bool exists(World *world)
Check if the World exists in the registry.
Definition world.h:249
std::optional< T * > ptr_from_id(uniqueidT id) const
Look up a local pointer from a world-wide unique ID.
Definition world.h:416
ProcessID nproc() const
Returns the number of processes in this World (same as MPI_Comm_size()).
Definition world.h:325
ProcessID random_proc()
Returns a random process number; that is, an integer in [0,world.size()).
Definition world.h:591
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:353
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:571
WorldAmInterface & am
AM interface.
Definition world.h:205
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:509
bool operator()() const
Definition world.h:522
MpiRequestTester(SafeMPI::Request &r)
Definition world.h:516
SafeMPI::Request * r
Definition world.h:510
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:623
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:641
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