MADNESS  version 0.9
worldfwd.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  $Id$
33 */
34 
314 #ifndef MADNESS_WORLD_WORLDFWD_H__INCLUDED
315 #define MADNESS_WORLD_WORLDFWD_H__INCLUDED
316 
317 #include <madness/madness_config.h>
318 
319 // #ifdef SEEK_SET
320 // #undef SEEK_SET
321 // #endif
322 // #ifdef SEEK_CUR
323 // #undef SEEK_CUR
324 // #endif
325 // #ifdef SEEK_END
326 // #undef SEEK_END
327 // #endif
328 
329 // Standerd C++ header files needed by world.h
330 #include <iostream>
331 #include <list>
332 #include <utility>
333 #include <cstddef>
334 
335 #ifdef HAVE_RANDOM
336 #include <stdlib.h>
337 #endif
338 
339 // Madness world header files needed by world
340 #include <madness/world/worldmpi.h>
344 #include <madness/world/uniqueid.h>
346 
347 namespace madness {
348 
349  class World;
350  class WorldTaskQueue;
351  class WorldAmInterface;
352  class WorldGopInterface;
353 
354  void redirectio(World& world);
355 
357 
365  World& initialize(int& argc, char**& argv);
366 
368 
378  World& initialize(int& argc, char**& argv, const SafeMPI::Intracomm& comm);
379 
381 
391  World& initialize(int& argc, char**& argv, const MPI_Comm& comm);
392 
394  void finalize();
395 
397  bool initialized();
398 
400  void print_stats(World& world);
401 
402  extern void xterm_debug(const char* path, const char* display);
403 
404  void error(const char *msg);
405 
406  template <typename T>
407  static void error(const char *msg, const T& data) {
408  std::cerr << "MADNESS: fatal error: " << msg << " " << data << std::endl;
410  }
411 
412 
414 
416  class World : private NO_DEFAULTS {
417  private:
418  friend class WorldAmInterface;
419  friend class WorldGopInterface;
420  friend World& initialize(int&, char**&, const SafeMPI::Intracomm&);
421  friend void finalize();
422 
423  // Static member variables
424  static unsigned long idbase;
425  static World* default_world;
426  static std::list<World*> worlds;
427 
428  struct hashvoidp {
429  inline std::size_t operator()(const void* p) const {
430  return std::size_t(p); // The ptr's are guaranteed to be unique
431  }
432  };
433 
434 // Mutex globalmutex; ///< Worldwide mutex
437  map_id_to_ptrT map_id_to_ptr;
438  map_ptr_to_idT map_ptr_to_id;
439 
440 
441  unsigned long _id;
442  unsigned long obj_id;
443  void* user_state;
444 
445  // Default copy constructor and assignment won't compile
446  // (which is good) due to reference members.
447 
448  public:
449  // Here we use Pimpl to both hide implementation details and also
450  // to partition the namespace for users as world.mpi, world.am, etc.
451  // We also embed a reference to this instance in the am and task
452  // instances so that they have access to everything.
453  //
454  // The downside is we cannot do much of anything here without
455  // using wrapper functions to foward the calls to the hidden
456  // class methods.
457 
458  // !!! Order of declaration is important for correct order of initialization !!!
463 
464  private:
465  unsigned int myrand_next;
466 
467  public:
470  World(const SafeMPI::Intracomm& comm);
471 
473 
477  static World* find_instance(const SafeMPI::Intracomm& comm) {
478  typedef std::list<World*>::const_iterator citer;
479  for(citer it = worlds.begin(); it != worlds.end(); ++it) {
480  if ((*it)->mpi.comm() == comm)
481  return *it;
482  }
483  return 0;
484  }
485 
487 
492  static World& get_default() {
493  MADNESS_ASSERT(default_world);
494  return *default_world;
495  }
496 
498 
506  void set_user_state(void* state) { user_state = state; }
507 
509 
511  void* get_user_state() { return user_state; }
512 
514  void clear_user_state() { user_state = NULL; }
515 
517 
520  void args(int argc, char**argv);
521 
523  unsigned long id() const { return _id; }
524 
526  ProcessID rank() const { return mpi.rank(); }
527 
528 
530  ProcessID nproc() const { return mpi.nproc(); }
531 
533  ProcessID size() const { return mpi.size(); }
534 
536 
545  uniqueidT unique_obj_id() { return uniqueidT(_id,obj_id++); }
546 
547 
548 
550 
563  template <typename T>
565  MADNESS_ASSERT(sizeof(T*) == sizeof(void *));
566  uniqueidT id = unique_obj_id();
567  map_id_to_ptr.insert(std::pair<uniqueidT,void*>(id,static_cast<void*>(ptr)));
568  map_ptr_to_id.insert(std::pair<void*,uniqueidT>(static_cast<void*>(ptr),id));
569  return id;
570  }
571 
572 
574  template <typename T>
575  void unregister_ptr(T* ptr) {
576  uniqueidT id = id_from_ptr(ptr); // Will be zero if invalid
577  map_id_to_ptr.erase(id);
578  map_ptr_to_id.erase((void *) ptr);
579  }
580 
581 
583 
585  template <typename T>
586  void unregister_ptr(const uniqueidT id) {
587  T* const ptr = ptr_from_id<T>(id);
588  map_id_to_ptr.erase(id);
589  map_ptr_to_id.erase((void *) ptr);
590  }
591 
592 
594 
596  template <typename T>
597  T* ptr_from_id(uniqueidT id) const {
598  map_id_to_ptrT::const_iterator it = map_id_to_ptr.find(id);
599  if (it == map_id_to_ptr.end())
600  return 0;
601  else
602  return (T*)(it->second);
603  }
604 
605 
607 
609  template <typename T>
610  const uniqueidT& id_from_ptr(T* ptr) const {
611  static uniqueidT invalidid(0,0);
612  map_ptr_to_idT::const_iterator it = map_ptr_to_id.find(ptr);
613  if (it == map_ptr_to_id.end())
614  return invalidid;
615  else
616  return it->second;
617  }
618 
619 
621 
628  static World* world_from_id(unsigned long id) {
629  // This is why C++ iterators are stupid, stupid, stupid, ..., gack!
630  for (std::list<World *>::iterator it=worlds.begin(); it != worlds.end(); ++it) {
631  if ((*it) && (*it)->_id == id) return *it;
632  }
633  return 0;
634  }
635 
636  private:
637 
638  // Cannot use bind_nullary here since SafeMPI::Request::Test is non-const
639  struct MpiRequestTester {
640  mutable SafeMPI::Request* r;
641  MpiRequestTester(SafeMPI::Request& r) : r(&r) {}
642  bool operator()() const {
643  return r->Test();
644  }
645  };
646 
647  public:
648 
650  static void inline await(SafeMPI::Request& request, bool dowork = true) {
651  ThreadPool::await(MpiRequestTester(request), dowork);
652  }
653 
655 
657  template <typename Probe>
658  static void inline await(const Probe& probe, bool dowork = true) {
659  ThreadPool::await(probe, dowork);
660  }
661 
662  void srand(unsigned long seed = 0ul) {
663  if (seed == 0) seed = rank();
664 #ifdef HAVE_RANDOM
665  srandom(seed);
666 #else
667  myrand_next = seed;
668  for (int i=0; i<1000; ++i) rand(); // Warmup
669 #endif // HAVE_RANDOM
670  }
671 
672 
674 
676  int rand() {
677 #ifdef HAVE_RANDOM
678  return int(random() & 0xfffffful);
679 #else
680  myrand_next = myrand_next * 1103515245UL + 12345UL;
681  return int((myrand_next>>8) & 0xfffffful);
682 #endif // HAVE_RANDOM
683  }
684 
685 
687  double drand() { return rand()/16777216.0; }
688 
690  ProcessID random_proc() { return rand()%size(); }
691 
693 
697  if (size() == 1) return -1;
698  ProcessID p;
699  do {
700  p = rand()%size();
701  } while (p == rank());
702  return p;
703  }
704 
705  ~World();
706  }; // class World
707 
708  namespace archive {
709 
710  template <typename, typename>
711  struct ArchiveLoadImpl;
712  template <typename, typename>
713  struct ArchiveStoreImpl;
714 
715  template <class Archive>
716  struct ArchiveLoadImpl<Archive,World*> {
717  static inline void load(const Archive& ar, World*& wptr) {
718  unsigned long id = 0ul;
719  ar & id;
720  wptr = World::world_from_id(id);
721  MADNESS_ASSERT(wptr);
722  }
723  }; // struct ArchiveLoadImpl<Archive,World*>
724 
725  template <class Archive>
726  struct ArchiveStoreImpl<Archive,World*> {
727  static inline void store(const Archive& ar, World* const & wptr) {
728  ar & wptr->id();
729  }
730  }; // struct ArchiveStoreImpl<Archive,World*>
731  } // namespace archive
732 } // namespace madness
733 
736 #endif // MADNESS_WORLD_WORLDFWD_H__INCLUDED
friend void finalize()
Call this once at the very end of your main program instead of calling MPI_Finalize.
Definition: world.cc:212
static void await(const Probe &probe, bool dowork=true)
Gracefully wait for a condition to become true ... executes tasks if any in queue.
Definition: worldfwd.h:658
void error(const char *msg)
Definition: world.cc:128
WorldGopInterface & gop
Global operations.
Definition: worldfwd.h:462
static void await(SafeMPI::Request &request, bool dowork=true)
Wait for MPI request to complete.
Definition: worldfwd.h:650
static World * find_instance(const SafeMPI::Intracomm &comm)
Find the World corresponding to the given communicator.
Definition: worldfwd.h:477
static World & get_default()
Default World object accessor.
Definition: worldfwd.h:492
static void load(const Archive &ar, World *&wptr)
Definition: worldfwd.h:717
iterator for hash
Definition: worldhashmap.h:190
double drand()
Returns a CRUDE, LOW-QUALITY, random number uniformly distributed in [0,1).
Definition: worldfwd.h:687
WorldMpiInterface & mpi
MPI interface.
Definition: worldfwd.h:459
Wrapper around MPI_Comm. Has a shallow copy constructor; use Create(Get_group()) for deep copy...
Definition: safempi.h:437
void clear_user_state()
Clears user-defined state ... same as set_user_state(0)
Definition: worldfwd.h:514
uniqueidT unique_obj_id()
Returns new universe-wide unique ID for objects created in this world. No comms.
Definition: worldfwd.h:545
ProcessID nproc() const
Returns the number of processes in this world (same as MPI_Comm_size())
Definition: worldfwd.h:530
unsigned long id() const
Returns the system-wide unique integer ID of this world.
Definition: worldfwd.h:523
Definition: uniqueid.h:46
void unregister_ptr(const uniqueidT id)
Unregister a unique id for a local pointer based on id.
Definition: worldfwd.h:586
void print_stats(World &world)
Call this to print misc. stats ... collective.
Definition: world.cc:305
ProcessID size() const
Returns the number of processes in this world (same as MPI_Comm_size())
Definition: worldfwd.h:533
This class wraps/extends the MPI interface for World.
Definition: worldmpi.h:245
World & initialize(int &argc, char **&argv)
Initialize the MADNESS runtime.
Definition: world.cc:134
static void await(const Probe &probe, bool dowork=true)
Gracefully wait for a condition to become true ... executes tasks if any in queue.
Definition: worldthread.h:1056
void Abort(int code=1) const
Definition: safempi.h:648
ProcessID random_proc_not_me()
Returns a random process number [0,world.size()) != current process.
Definition: worldfwd.h:696
Default store of a thingy via serialize(ar,t)
Definition: archive.h:708
bool Test(MPI_Status &status)
Definition: safempi.h:356
Implements WorldMpiInterface.
Multi-threaded queue to manage and run tasks.
Definition: worldtask.h:393
int size() const
Definition: worldmpi.h:354
static World * world_from_id(unsigned long id)
Convert world id to world pointer.
Definition: worldfwd.h:628
WorldAmInterface & am
AM interface.
Definition: worldfwd.h:460
Provides collectives that interoperate with the AM and task interfaces.
Definition: worldgop.h:147
int MPI_Comm
Definition: stubmpi.h:22
int rand()
Returns a CRUDE, LOW-QUALITY, random number uniformly distributed in [0,2**24).
Definition: worldfwd.h:676
const T1 &f1 return GTEST_2_TUPLE_() T(f0, f1)
World(const SafeMPI::Intracomm &comm)
Definition: world.cc:76
~World()
Definition: world.cc:120
void finalize()
Call this once at the very end of your main program instead of calling MPI_Finalize.
Definition: world.cc:212
Implements Dqueue, Thread, ThreadBase and ThreadPool.
Default load of a thingy via serialize(ar,t)
Definition: archive.h:718
ProcessID random_proc()
Returns a random process number [0,world.size())
Definition: worldfwd.h:690
uniqueidT register_ptr(T *ptr)
Associate a local pointer with a universe-wide unique id.
Definition: worldfwd.h:564
void unregister_ptr(T *ptr)
Unregister a unique id for a local pointer.
Definition: worldfwd.h:575
bool initialized()
Definition: world.cc:70
A parallel world with full functionality wrapping an MPI communicator.
Definition: worldfwd.h:416
void args(int argc, char **argv)
Processes command line arguments.
Definition: world.cc:111
Implements NO_DEFAULTS.
int ProcessID
Used to clearly identify process number/rank.
Definition: worldtypes.h:37
static void store(const Archive &ar, World *const &wptr)
Definition: worldfwd.h:727
ProcessID rank() const
Returns the process rank in this world (same as MPI_Comm_rank()))
Definition: worldfwd.h:526
Implements AM interface.
Definition: worldam.h:266
void redirectio(World &world)
Definition: redirectio.cc:45
Definition: safempi.h:243
int rank() const
Definition: worldmpi.h:350
WorldTaskQueue & taskq
Task queue.
Definition: worldfwd.h:461
void xterm_debug(const char *path, const char *display)
Definition: debug.cc:106
void set_user_state(void *state)
Sets a pointer to user-managed local state.
Definition: worldfwd.h:506
T * ptr_from_id(uniqueidT id) const
Look up local pointer from world-wide unique id.
Definition: worldfwd.h:597
Intracomm COMM_WORLD
Definition: safempi.cc:70
friend World & initialize(int &, char **&, const SafeMPI::Intracomm &)
Initialize the MADNESS runtime.
Definition: world.cc:142
void * get_user_state()
Returns pointer to user-managed state set by set_user_state()
Definition: worldfwd.h:511
const uniqueidT & id_from_ptr(T *ptr) const
Look up id from local pointer.
Definition: worldfwd.h:610
Holds machinery to set up Functions/FuncImpls using various Factories and Interfaces.
Definition: chem/atomutil.cc:45
void srand(unsigned long seed=0ul)
Definition: worldfwd.h:662
int nproc() const
Definition: worldmpi.h:352
Disables default copy constructor and assignment operators.
Definition: nodefaults.h:49
Defines and implements a concurrent hashmap.