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