MADNESS  0.10.1
worldptr.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 worldptr.h
34  \brief The \c madness::detail::WorldPtr class for global pointers.
35  \ingroup world
36 */
37 
38 #ifndef MADNESS_WORLD_WORLDPTR_H__INCLUDED
39 #define MADNESS_WORLD_WORLDPTR_H__INCLUDED
40 
42 #include <madness/world/worldtypes.h> // for ProcessID
43 #include <madness/world/archive.h> // for wrap_opaque
44 #include <madness/world/world.h>
45 #include <algorithm> // for std::swap
46 #include <iostream> // for std::iostream
47 
48 /// \addtogroup world
49 /// @{
50 
51 namespace madness {
52 
53  namespace detail {
54 
55  /// \todo Brief description needed.
56 
57  /// \todo Description needed.
58  /// \tparam U Description needed.
59  template<typename U>
60  struct ptr_traits {
61  /// \todo Brief description needed.
62  typedef U & reference;
63  };
64 
65  /// Specialization of \c ptr_traits for type \c void.
66  template<>
67  struct ptr_traits<void> {
68  /// \todo Brief description needed.
69  typedef void reference;
70  };
71 
72  /// A global pointer address, valid anywhere in the world.
73 
74  /// Stores a globally addressable pointer. It can be sent to any
75  /// process in the world.
76  /// \tparam T The pointer type.
77  template <typename T>
78  class WorldPtr {
79  public:
80  typedef unsigned long worldidT; ///< World ID type.
81 
82  private:
83  World* world_; ///< A pointer to the world.
84  worldidT worldid_; ///< The world ID.
85  ProcessID rank_; ///< The rank of the node that the pointer belongs to.
86  T* pointer_; ///< The pointer being referenced.
87 
88  template<typename>
89  friend class WorldPtr;
90 
91  /// Current local rank.
92 
93  /// \return The rank of the current node. If the pointer is not
94  /// set, then -2.
95  /// \note -2 is returned so it is not equal to the null value of -1.
97  return (world_ != nullptr ? world_->rank() : -2);
98  }
99 
100  public:
101 
102  /// Alias for the pointer type.
103  typedef T* pointer;
104 
105  /// \todo Brief description needed.
107 
108 
109  /// Default constructor
110 
111  /// Creates a \c NULL pointer. There is no owner; i.e. the owner is
112  /// set to -1.
113  /// \todo Would it be worth adding a static constant \c ProcessID equal to -1 to signify an unowned pointer?
115  world_(nullptr),
116  worldid_(0),
117  rank_(-1),
118  pointer_(nullptr)
119  { }
120 
121 
122  /// %World pointer constructor.
123 
124  /// Construct a world pointer form a local pointer.
125  /// \param[in] w A reference to the local world.
126  /// \param[in] p The local pointer.
128  world_(&w),
129  worldid_(w.id() + 1),
130  rank_(w.rank()),
131  pointer_(p)
132  { }
133 
134 
135  /// Copy constructor
136 
137  /// \param[in] other The world pointer to be copied.
138  WorldPtr(const WorldPtr<T>& other) :
139  world_(other.world_),
140  worldid_(other.worldid_),
141  rank_(other.rank_),
142  pointer_(other.pointer_)
143  { }
144 
145 
146  /// Copy conversion constructor.
147 
148  /// Copy and convert a pointer from \c U* to \c T* type.
149  /// \tparam U The pointer type of the \c other pointer.
150  /// \param[in] other The world pointer to be copied.
151  /// \note \c U* must be implicitly convertible to \c T* type.
152  template <typename U>
153  WorldPtr(const WorldPtr<U>& other) :
154  world_(other.world_),
155  worldid_(other.worldid_),
156  rank_(other.rank_),
157  pointer_(other.pointer_)
158  { }
159 
160 
161  /// Copy assignment operator.
162 
163  /// \param[in] other The world pointer to be copied.
164  /// \return A reference to this object.
166  world_ = other.world_;
167  worldid_ = other.worldid_;
168  rank_ = other.rank_;
169  pointer_ = other.pointer_;
170 
171  return *this;
172  }
173 
174 
175  /// Copy conversion assignment operator.
176 
177  /// Copy and convert a pointer from \c U* to \c T* type.
178  /// \tparam U The pointer type of the \c other pointer.
179  /// \param[in] other The world pointer to be copied.
180  /// \return A reference to this object.
181  /// \note \c U* must be implicitly convertible to \c T* type.
182  template <typename U>
184  world_ = other.world_;
185  worldid_ = other.worldid_;
186  rank_ = other.rank_;
187  pointer_ = other.pointer_;
188 
189  return *this;
190  }
191 
192 
193  /// Check that the world pointer references a local pointer.
194 
195  /// \return True if the pointer points to a local address; false
196  /// if it points to a remote address or is NULL.
197  bool is_local() const {
198  return local_rank() == rank_;
199  }
200 
201 
202  /// Check that the world pointer has an owner.
203 
204  /// \return True if the pointer has a valid owner; false otherwise.
205  bool has_owner() const {
206  return (rank_ != -1) && (world_ != nullptr);
207  }
208 
209 
210  /// Pointer accessor.
211 
212  /// Get the pointer from the world pointer.
213  /// \note A default initialized pointer is not considered to be
214  /// local because it is not associated with a world.
215  /// \return The local pointer.
216  /// \throw MadnessException When the pointer references a remote
217  /// address.
218  pointer get() const {
219  // It is not safe to access this pointer remotely unless null.
221  return pointer_;
222  }
223 
224 
225  /// Dereference operator.
226 
227  /// Dereference the local pointer.
228  /// \return A reference to the local pointer.
229  /// \throw MadnessException If the pointer references a remote
230  /// address, or if the pointer is \c NULL.
232  // It is not safe to access a NULL pointer with this operator.
233  MADNESS_ASSERT(pointer_ != nullptr);
234  // It is not safe to access this pointer remotely.
236  return *pointer_;
237  }
238 
239 
240  /// Pointer arrow operator.
241 
242  /// Access members of the pointer.
243  /// \return The local pointer.
244  /// \throw MadnessException If the pointer references a remote
245  /// address, or if the pointer is \c NULL.
246  pointer operator->() const {
247  // It is not safe to access a NULL pointer with this operator.
248  MADNESS_ASSERT(pointer_ != nullptr);
249  // It is not safe to access this pointer remotely.
251  return pointer_;
252  }
253 
254 
255  /// Boolean conversion operator.
256 
257  /// \return True if the pointer is non-null; false otherwise.
258  operator bool () const {
259  return pointer_;
260  }
261 
262 
263  /// Boolean conversion (not) operator.
264 
265  /// \return True if the pointer is null; false otherwise.
266  bool operator ! () const {
267  return !pointer_;
268  }
269 
270 
271  /// Equality comparison operator.
272 
273  /// \tparam U Another pointer type.
274  /// \param[in] other The pointer to compare with.
275  /// \return True if the pointers refer to the same address from
276  /// the same node in the same world; false otherwise.
277  template <typename U>
278  bool operator==(const WorldPtr<U>& other) const {
279  return (pointer_ == other.pointer_) && (rank_ == other.rank_)
280  && (worldid_ == other.worldid_);
281  }
282 
283 
284  /// Inequality comparison operator.
285 
286  /// \tparam U Another pointer type.
287  /// \param[in] other The other pointer to compare with.
288  /// \return True if the pointers refer to different addresses or
289  /// different nodes or different worlds; false otherwise.
290  template <typename U>
291  bool operator!=(const WorldPtr<U>& other) const {
292  return (pointer_ != other.pointer_) || (rank_ != other.rank_)
293  || (worldid_ != other.worldid_);
294  }
295 
296 
297  /// Less-than comparison operator.
298 
299  /// This operator does a lexicographical comparison of world ID,
300  /// rank, and pointer (in that order).
301  /// \tparam U Another pointer type.
302  /// \param[in] other The other pointer to compare with.
303  /// \return True if the lexicographical comparison of world ID,
304  /// rank, and pointer is true; false otherwise.
305  template <typename U>
306  bool operator<(const WorldPtr<U>& other) const {
307  return (worldid_ < other.worldid_) ||
308  ((worldid_ == other.worldid_) && ((rank_ < other.rank_) ||
309  ((rank_ == other.rank_) && (pointer_ < other.pointer_))));
310  }
311 
312 
313  /// World accessor.
314 
315  /// \return A reference to the world (may be \c NULL).
316  /// \throw MadnessException When the pointer world has not been set
317  /// (i.e. when \c has_owner()==false).
318  World& get_world() const {
319  MADNESS_ASSERT(world_ != nullptr);
320  return *world_;
321  }
322 
323 
324  /// %World ID accessor.
325 
326  /// \return The world ID of the world that the pointer belongs to.
328  return worldid_ - 1;
329  }
330 
331 
332  /// Rank accessor.
333 
334  /// \todo Finish this sentence: If the pointer is not associated with
335  /// \return The rank of the process that owns the pointer.
336  ProcessID owner() const {
337  return rank_;
338  }
339 
340 
341  /// Swap the content of \c this with \c other.
342 
343  /// \tparam U The other world pointer type.
344  /// \param[in,out] other The other world pointer.
345  /// \note \c U* must be implicitly convertible to \c T* type.
346  template <typename U>
347  void swap(WorldPtr<U>& other) {
348  std::swap(world_, other.world_);
349  std::swap(worldid_, other.worldid_);
350  std::swap(rank_, other.rank_);
351  std::swap(pointer_, other.pointer_);
352  }
353 
354 
355  /// Deserialize the world pointer.
356 
357  /// Deserialize the world pointer for remote communication or write
358  /// to disk.
359  /// \tparam Archive The archive object type.
360  /// \param[in] ar The archive.
361  template <class Archive>
362  inline void load_internal_(const Archive& ar) {
364  world_ = (worldid_ != 0 ? World::world_from_id(get_worldid()) : nullptr);
365  }
366 
367  /// Serialize the world pointer.
368 
369  /// Serialize the world pointer for remote communication or write
370  /// to disk.
371  /// \tparam Archive The archive object type.
372  /// \param[in] ar The archive.
373  template <class Archive>
374  inline void store_internal_(const Archive& ar) const {
376  }
377 
378  /// Output stream insertion operator for world pointers.
379 
380  /// \param[in,out] out The output stream.
381  /// \param[in] p The world pointer.
382  /// \return The output stream.
383  /// \todo Does this \c friend function need to be implemented in the class or can we move it to a \c *.cc file?
384  friend std::ostream& operator<<(std::ostream& out, const WorldPtr<T>& p) {
385  out << "WorldPointer(ptr=" << p.pointer_ << ", rank=";
386  if(p.rank_ >= 0)
387  out << p.rank_;
388  else
389  out << "none";
390  out << ", worldid=";
391  if(p.worldid_ != 0)
392  out << (p.worldid_ - 1);
393  else
394  out << "none";
395  out << ")";
396  return out;
397  }
398  }; // class WorldPtr
399 
400 
401  /// Swap the content of \c l with \c r.
402 
403  /// \tparam T The world pointer type.
404  /// \param[in,out] l One world pointer.
405  /// \param[in,out] r The other world pointer.
406  template <typename T>
407  void swap(WorldPtr<T>& l, WorldPtr<T>& r) {
408  l.swap(r);
409  }
410 
411 
412  /// Greater-than comparison operator.
413 
414  /// This operator does a lexicographical comparison of world ID,
415  /// rank, and pointer (in that order).
416  /// \tparam T One pointer type.
417  /// \tparam U Another pointer type.
418  /// \param[in] left One pointer.
419  /// \param[in] right The other pointer.
420  /// \return True if the lexicographical comparison of world ID,
421  /// rank, and pointer is true; false otherwise.
422  template <typename T, typename U>
423  bool operator>(const WorldPtr<T>& left, const WorldPtr<U>& right) {
424  return right < left;
425  }
426 
427 
428  /// Less-than-equal-to comparison operator.
429 
430  /// This operator does a lexicographical comparison of world ID,
431  /// rank, and pointer (in that order).
432  /// \tparam T One pointer type.
433  /// \tparam U Another pointer type.
434  /// \param[in] left One pointer.
435  /// \param[in] right The other pointer.
436  /// \return True if the lexicographical comparison of world ID,
437  /// rank, and pointer is true; false otherwise.
438  template <typename T, typename U>
439  bool operator<=(const WorldPtr<T>& left, const WorldPtr<U>& right) {
440  return !(right < left);
441  }
442 
443 
444  /// Greater-than-equal-to comparison operator.
445 
446  /// This operator does a lexicographical comparison of world ID,
447  /// rank, and pointer (in that order).
448  /// \tparam T One pointer type.
449  /// \tparam U Another pointer type.
450  /// \param[in] left One pointer.
451  /// \param[in] right The other pointer.
452  /// \return True if the lexicographical comparison of world ID,
453  /// rank, and pointer is true; false otherwise.
454  template <typename T, typename U>
455  bool operator>=(const WorldPtr<T>& left, const WorldPtr<U>& right) {
456  return !(left < right);
457  }
458 
459  } // namespace detail
460 
461  namespace archive {
462 
463  /// Specialization of \c ArchiveLoadImpl for world pointers.
464 
465  /// \tparam Archive The archive type.
466  /// \tparam T The world pointer type.
467  template <typename Archive, typename T>
468  struct ArchiveLoadImpl<Archive, detail::WorldPtr<T> > {
469 
470  /// Load a world pointer from the archive.
471 
472  /// \param[in] ar The archive.
473  /// \param[out] p The world pointer.
474  static inline void load(const Archive& ar, detail::WorldPtr<T>& p) {
475  p.load_internal_(ar);
476  }
477  };
478 
479  /// Specialization of \c ArchiveStoreImpl for world pointers.
480 
481  /// \tparam Archive The archive type.
482  /// \tparam T The world pointer type.
483  template <typename Archive, typename T>
484  struct ArchiveStoreImpl<Archive, detail::WorldPtr<T> > {
485 
486  /// Store a world pointer from the archive.
487 
488  /// \param[in] ar The archive.
489  /// \param[in] p The world pointer.
490  static inline void store(const Archive& ar, const detail::WorldPtr<T>& p) {
491  p.store_internal_(ar);
492  }
493  };
494 
495  } // namespace archive
496 
497 } // namespace madness
498 
499 /// @}
500 
501 #endif // MADNESS_WORLD_WORLDPTR_H__INCLUDED
double w(double t, double eps)
Definition: DKops.h:22
Interface templates for the archives (serialization).
A parallel world class.
Definition: world.h:132
static World * world_from_id(std::uint64_t id)
Convert a World ID to a World pointer.
Definition: world.h:474
ProcessID rank() const
Returns the process rank in this World (same as MPI_Comm_rank()).
Definition: world.h:318
A global pointer address, valid anywhere in the world.
Definition: worldptr.h:78
WorldPtr()
Default constructor.
Definition: worldptr.h:114
pointer operator->() const
Pointer arrow operator.
Definition: worldptr.h:246
WorldPtr< T > & operator=(const WorldPtr< T > &other)
Copy assignment operator.
Definition: worldptr.h:165
T * pointer
Alias for the pointer type.
Definition: worldptr.h:103
WorldPtr(const WorldPtr< U > &other)
Copy conversion constructor.
Definition: worldptr.h:153
bool operator<(const WorldPtr< U > &other) const
Less-than comparison operator.
Definition: worldptr.h:306
worldidT worldid_
The world ID.
Definition: worldptr.h:84
bool operator==(const WorldPtr< U > &other) const
Equality comparison operator.
Definition: worldptr.h:278
ptr_traits< T >::reference reference
Definition: worldptr.h:106
unsigned long worldidT
World ID type.
Definition: worldptr.h:80
WorldPtr(World &w, T *p)
World pointer constructor.
Definition: worldptr.h:127
bool operator!=(const WorldPtr< U > &other) const
Inequality comparison operator.
Definition: worldptr.h:291
void swap(WorldPtr< U > &other)
Swap the content of this with other.
Definition: worldptr.h:347
void store_internal_(const Archive &ar) const
Serialize the world pointer.
Definition: worldptr.h:374
WorldPtr(const WorldPtr< T > &other)
Copy constructor.
Definition: worldptr.h:138
World * world_
A pointer to the world.
Definition: worldptr.h:83
worldidT get_worldid() const
World ID accessor.
Definition: worldptr.h:327
void load_internal_(const Archive &ar)
Deserialize the world pointer.
Definition: worldptr.h:362
ProcessID rank_
The rank of the node that the pointer belongs to.
Definition: worldptr.h:85
bool operator!() const
Boolean conversion (not) operator.
Definition: worldptr.h:266
bool is_local() const
Check that the world pointer references a local pointer.
Definition: worldptr.h:197
bool has_owner() const
Check that the world pointer has an owner.
Definition: worldptr.h:205
ProcessID owner() const
Rank accessor.
Definition: worldptr.h:336
WorldPtr< T > & operator=(const WorldPtr< U > &other)
Copy conversion assignment operator.
Definition: worldptr.h:183
friend std::ostream & operator<<(std::ostream &out, const WorldPtr< T > &p)
Output stream insertion operator for world pointers.
Definition: worldptr.h:384
T * pointer_
The pointer being referenced.
Definition: worldptr.h:86
pointer get() const
Pointer accessor.
Definition: worldptr.h:218
World & get_world() const
World accessor.
Definition: worldptr.h:318
reference operator*() const
Dereference operator.
Definition: worldptr.h:231
ProcessID local_rank() const
Current local rank.
Definition: worldptr.h:96
char * p(char *buf, const char *name, int k, int initial_level, double thresh, int order)
Definition: derivatives.cc:72
auto T(World &world, response_space &f) -> response_space
Definition: global_functions.cc:34
archive_array< unsigned char > wrap_opaque(const T *, unsigned int)
Factory function to wrap a pointer to contiguous data as an opaque (uchar) archive_array.
Definition: archive.h:925
Defines madness::MadnessException for exception handling.
#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
bool operator>=(const WorldPtr< T > &left, const WorldPtr< U > &right)
Greater-than-equal-to comparison operator.
Definition: worldptr.h:455
void swap(WorldPtr< T > &l, WorldPtr< T > &r)
Swap the content of l with r.
Definition: worldptr.h:407
bool operator<=(const WorldPtr< T > &left, const WorldPtr< U > &right)
Less-than-equal-to comparison operator.
Definition: worldptr.h:439
bool operator>(const WorldPtr< T > &left, const WorldPtr< U > &right)
Greater-than comparison operator.
Definition: worldptr.h:423
File holds all helper structures necessary for the CC_Operator and CC2 class.
Definition: DFParameters.h:10
static void load(const Archive &ar, detail::WorldPtr< T > &p)
Load a world pointer from the archive.
Definition: worldptr.h:474
Default load of an object via serialize(ar, t).
Definition: archive.h:666
static void store(const Archive &ar, const detail::WorldPtr< T > &p)
Store a world pointer from the archive.
Definition: worldptr.h:490
Default store of an object via serialize(ar, t).
Definition: archive.h:611
void reference
Definition: worldptr.h:69
Definition: worldptr.h:60
U & reference
Definition: worldptr.h:62
Declares the World class for the parallel runtime environment.
Defines types used by the parallel runtime.
int ProcessID
Used to clearly identify process number/rank.
Definition: worldtypes.h:43