MPQC  3.0.0-alpha
memory.h
1 //
2 // memory.h
3 //
4 // Copyright (C) 1996 Limit Point Systems, Inc.
5 //
6 // Author: Curtis Janssen <cljanss@limitpt.com>
7 // Maintainer: LPS
8 //
9 // This file is part of the SC Toolkit.
10 //
11 // The SC Toolkit is free software; you can redistribute it and/or modify
12 // it under the terms of the GNU Library General Public License as published by
13 // the Free Software Foundation; either version 2, or (at your option)
14 // any later version.
15 //
16 // The SC Toolkit is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU Library General Public License for more details.
20 //
21 // You should have received a copy of the GNU Library General Public License
22 // along with the SC Toolkit; see the file COPYING.LIB. If not, write to
23 // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24 //
25 // The U.S. Government is granted a limited license as per AL 91-7.
26 //
27 
28 #ifndef _util_group_memory_h
29 #define _util_group_memory_h
30 
31 #include <iostream>
32 
33 #include <mpqc_config.h>
34 #include <util/class/class.h>
35 #include <util/group/thread.h>
36 
37 namespace sc {
38 
39 #if 0 // this can be used to catch accidental conversions to int
40 class distsize_t {
41  friend size_t distsize_to_size(const distsize_t &a);
42  friend distsize_t operator *(const int &a,const distsize_t &b);
43  friend distsize_t operator +(const int &a,const distsize_t &b);
44  friend distsize_t operator -(const int &a,const distsize_t &b);
45  friend distsize_t operator /(const int &a,const distsize_t &b);
46  friend distsize_t operator %(const int &a,const distsize_t &b);
47  friend ostream& operator <<(ostream& o, const distsize_t &s);
48  private:
49  unsigned long long s;
50  public:
51  distsize_t(): s(999999999999999LL) {}
52  distsize_t(int a): s(a) {}
53  distsize_t(unsigned int a): s(a) {}
54  distsize_t(unsigned long long a): s(a) {}
55  distsize_t &operator =(const distsize_t &a)
56  { s=a.s; return *this; }
57  distsize_t &operator +=(const distsize_t &a)
58  { s+=a.s; return *this; }
59  distsize_t operator *(const distsize_t &a) const
60  { return s*a.s; }
61  distsize_t operator +(const distsize_t &a) const
62  { return s+a.s; }
63  distsize_t operator -(const distsize_t &a) const
64  { return s-a.s; }
65  distsize_t operator /(const distsize_t &a) const
66  { return s/a.s; }
67  distsize_t operator %(const distsize_t &a) const
68  { return s%a.s; }
69  bool operator <(const distsize_t &a) const
70  { return s<a.s; }
71  bool operator <=(const distsize_t &a) const
72  { return s<=a.s; }
73  bool operator >(const distsize_t &a) const
74  { return s>a.s; }
75  bool operator >=(const distsize_t &a) const
76  { return s>=a.s; }
77  bool operator ==(const distsize_t &a) const
78  { return s==a.s; }
79  distsize_t operator *(const int &a) const
80  { return s*a; }
81  distsize_t operator +(const int &a) const
82  { return s+a; }
83  distsize_t operator -(const int &a) const
84  { return s-a; }
85  distsize_t operator /(const int &a) const
86  { return s/a; }
87  distsize_t operator %(const int &a) const
88  { return s%a; }
89 };
90 inline distsize_t operator *(const int &a,const distsize_t &b)
91 { return a*b.s; }
92 inline distsize_t operator +(const int &a,const distsize_t &b)
93 { return a+b.s; }
94 inline distsize_t operator -(const int &a,const distsize_t &b)
95 { return a-b.s; }
96 inline distsize_t operator /(const int &a,const distsize_t &b)
97 { return a/b.s; }
98 inline distsize_t operator %(const int &a,const distsize_t &b)
99 { return a%b.s; }
100 inline ostream& operator <<(ostream& o, const distsize_t &s) { return o<<s.s; }
101 inline size_t distsize_to_size(const distsize_t &a) {return a.s;}
102 #elif defined(HAVE_LONG_LONG)
103 typedef unsigned long long distsize_t;
104 typedef long long distssize_t;
105 inline size_t distsize_to_size(const distsize_t &a) {return a;}
106 #else
107 typedef unsigned long distsize_t;
108 typedef long distssize_t;
109 inline size_t distsize_to_size(const distsize_t &a) {return a;}
110 #endif
111 
120 class MemoryGrp: public DescribedClass {
121  private:
122  Ref<ThreadLock> *locks_;
123  int nlock_;
124 
125  void init_locks();
126 
127 
128  protected:
129  // derived classes must fill in all these
130  // ~MemoryGrp deletes the arrays
131  int me_;
132  int n_;
133  distsize_t *offsets_; // offsets_[n_] is the fence for all data
134 
135  // set to nonzero for debugging information
136  int debug_;
137 
138  void obtain_local_lock(size_t start, size_t fence);
139  void release_local_lock(size_t start, size_t fence);
140  public:
141  MemoryGrp();
142  MemoryGrp(const Ref<KeyVal>&);
143  virtual ~MemoryGrp();
144 
146  int me() const { return me_; }
148  int n() const { return n_; }
149 
153  virtual void set_localsize(size_t) = 0;
155  size_t localsize() { return distsize_to_size(offsets_[me_+1]-offsets_[me_]); }
157  virtual void *localdata() = 0;
159  distsize_t localoffset() { return offsets_[me_]; }
161  int size(int node)
162  { return distsize_to_size(offsets_[node+1] - offsets_[node]); }
164  distsize_t offset(int node) { return offsets_[node]; }
166  distsize_t totalsize() { return offsets_[n_]; }
167 
169  virtual void activate();
171  virtual void deactivate();
172 
174  virtual void *obtain_writeonly(distsize_t offset, size_t size) = 0;
180  virtual void *obtain_readwrite(distsize_t offset, size_t size) = 0;
182  virtual void *obtain_readonly(distsize_t offset, size_t size) = 0;
184  virtual void release_readonly(void *data, distsize_t offset, size_t size) = 0;
186  virtual void release_writeonly(void *data, distsize_t offset, size_t size)=0;
189  virtual void release_readwrite(void *data, distsize_t offset, size_t size)=0;
190 
193  virtual void write(const void *data, distsize_t offset, size_t size);
194 
200  virtual void sum_reduction(double *data, distsize_t doffset, size_t dsize);
208  virtual void sum_reduction_on_node(double *data, size_t doffset, size_t dsize,
209  int node = -1);
210 
214  virtual void sync() = 0;
215 
220  virtual void* malloc_local(size_t nbyte);
224  double* malloc_local_double(size_t ndouble);
225 
227  virtual void free_local(void * & data);
229  void free_local_double(double * & data);
230 
237  virtual void catchup();
238 
242  virtual Ref<MemoryGrp> clone(void);
243 
245  virtual void print(std::ostream &o = ExEnv::out0()) const;
246 
254  static MemoryGrp* initial_memorygrp(int &argc, char** argv);
256  static MemoryGrp* initial_memorygrp();
259  static void set_default_memorygrp(const Ref<MemoryGrp>&);
266 };
267 
268 
274 template <class data_t>
276  Ref<MemoryGrp> grp_;
277  enum AccessType { None, Read, Write, ReadWrite };
278  AccessType accesstype_;
279  data_t *data_;
280  distsize_t offset_;
281  size_t length_;
282  public:
286  MemoryGrpBuf(const Ref<MemoryGrp> &);
291  data_t *writeonly(distsize_t offset, size_t length);
296  data_t *readwrite(distsize_t offset, size_t length);
301  const data_t *readonly(distsize_t offset, size_t length);
305  data_t *writeonly_on_node(size_t offset, size_t length, int node = -1);
309  data_t *readwrite_on_node(size_t offset, size_t length, int node = -1);
313  const data_t *readonly_on_node(size_t offset, size_t length, int node = -1);
317  void release();
319  size_t length() const { return length_; }
320 };
321 
323 // MemoryGrpBuf members
324 
325 template <class data_t>
327 {
328  grp_ = grp;
329  accesstype_ = None;
330 }
331 
332 template <class data_t>
333 data_t *
334 MemoryGrpBuf<data_t>::writeonly(distsize_t offset, size_t length)
335 {
336  if (accesstype_ != None) release();
337  data_ = (data_t *) grp_->obtain_writeonly(sizeof(data_t)*offset,
338  sizeof(data_t)*length);
339  offset_ = offset;
340  length_ = length;
341  accesstype_ = Write;
342  return data_;
343 }
344 
345 template <class data_t>
346 data_t *
347 MemoryGrpBuf<data_t>::readwrite(distsize_t offset, size_t length)
348 {
349  if (accesstype_ != None) release();
350  data_ = (data_t *) grp_->obtain_readwrite(sizeof(data_t)*offset,
351  sizeof(data_t)*length);
352  offset_ = offset;
353  length_ = length;
354  accesstype_ = ReadWrite;
355  return data_;
356 }
357 
358 template <class data_t>
359 const data_t *
360 MemoryGrpBuf<data_t>::readonly(distsize_t offset, size_t length)
361 {
362  if (accesstype_ != None) release();
363  data_ = (data_t *) grp_->obtain_readonly(sizeof(data_t)*offset,
364  sizeof(data_t)*length);
365  offset_ = offset;
366  length_ = length;
367  accesstype_ = Read;
368  return data_;
369 }
370 
371 template <class data_t>
372 data_t *
373 MemoryGrpBuf<data_t>::writeonly_on_node(size_t offset, size_t length, int node)
374 {
375  if (node == -1) node = grp_->me();
376  return writeonly(offset + grp_->offset(node)/sizeof(data_t), length);
377 }
378 
379 template <class data_t>
380 data_t *
381 MemoryGrpBuf<data_t>::readwrite_on_node(size_t offset, size_t length, int node)
382 {
383  if (node == -1) node = grp_->me();
384  return readwrite(offset + grp_->offset(node)/sizeof(data_t), length);
385 }
386 
387 template <class data_t>
388 const data_t *
389 MemoryGrpBuf<data_t>::readonly_on_node(size_t offset, size_t length, int node)
390 {
391  if (node == -1) node = grp_->me();
392  return readonly(offset + grp_->offset(node)/sizeof(data_t), length);
393 }
394 
395 template <class data_t>
396 void
398 {
399  if (accesstype_ == Write)
400  grp_->release_writeonly((data_t *)data_,
401  sizeof(data_t)*offset_, sizeof(data_t)*length_);
402  if (accesstype_ == Read)
403  grp_->release_readonly(data_, sizeof(data_t)*offset_,
404  sizeof(data_t)*length_);
405  if (accesstype_ == ReadWrite)
406  grp_->release_readwrite(data_, sizeof(data_t)*offset_,
407  sizeof(data_t)*length_);
408 
409  accesstype_ = None;
410 }
411 
412 }
413 
414 #endif
415 
416 // Local Variables:
417 // mode: c++
418 // c-file-style: "CLJ"
419 // End:
sc::MemoryGrp::release_writeonly
virtual void release_writeonly(void *data, distsize_t offset, size_t size)=0
This is called when write access is no longer needed.
sc::MemoryGrp::obtain_readonly
virtual void * obtain_readonly(distsize_t offset, size_t size)=0
This gives read access to the memory location. No locking is done.
sc::MemoryGrp::write
virtual void write(const void *data, distsize_t offset, size_t size)
This is used to write data directly.
sc::MemoryGrp::sum_reduction
virtual void sum_reduction(double *data, distsize_t doffset, size_t dsize)
Perform a sum reduction on double data.
sc::MemoryGrp::n
int n() const
Returns how many nodes there are.
Definition: memory.h:148
sc::MemoryGrpBuf::readwrite
data_t * readwrite(distsize_t offset, size_t length)
Request read write access to global memory at the global address offset and with size length.
Definition: memory.h:347
sc::MemoryGrpBuf::writeonly_on_node
data_t * writeonly_on_node(size_t offset, size_t length, int node=-1)
This behaves like writeonly, except the offset is local to the node specified by node.
Definition: memory.h:373
sc::MemoryGrp::offset
distsize_t offset(int node)
Returns the global offset to node's memory.
Definition: memory.h:164
sc::MemoryGrp::clone
virtual Ref< MemoryGrp > clone(void)
Returns a copy of this MemoryGrp specialization that provides an independent communication context.
sc::operator+
Ref< GaussianBasisSet > operator+(const Ref< GaussianBasisSet > &A, const Ref< GaussianBasisSet > &B)
Nonmember operator+ is more convenient to use than the member operator+.
sc::MemoryGrp::print
virtual void print(std::ostream &o=ExEnv::out0()) const
Prints out information about the object.
sc::MemoryGrpBuf::readonly_on_node
const data_t * readonly_on_node(size_t offset, size_t length, int node=-1)
This behaves like readonly, except the offset is local to the node specified by node.
Definition: memory.h:389
sc::MemoryGrp::catchup
virtual void catchup()
Processes outstanding requests.
sc::MemoryGrp::release_readwrite
virtual void release_readwrite(void *data, distsize_t offset, size_t size)=0
This is called when read/write access is no longer needed.
sc::Ref
A template class that maintains references counts.
Definition: ref.h:361
sc::MemoryGrp::set_default_memorygrp
static void set_default_memorygrp(const Ref< MemoryGrp > &)
The default memory group contains the primary memory group to be used by an application.
sc::MemoryGrp::sum_reduction_on_node
virtual void sum_reduction_on_node(double *data, size_t doffset, size_t dsize, int node=-1)
Perform a sum reduction on double data localized to a single node.
sc::MemoryGrp::obtain_readwrite
virtual void * obtain_readwrite(distsize_t offset, size_t size)=0
Only one thread can have an unreleased obtain_readwrite at a time.
sc::MemoryGrp::malloc_local_double
double * malloc_local_double(size_t ndouble)
Allocate double data that will be accessed locally only.
sc::MemoryGrp
The MemoryGrp abstract class provides a way of accessing distributed memory in a parallel machine.
Definition: memory.h:120
sc::MemoryGrpBuf::length
size_t length() const
The length of the current bit of memory.
Definition: memory.h:319
sc::MemoryGrp::deactivate
virtual void deactivate()
Deactivate is called after the memory has been used.
sc::MemoryGrp::size
int size(int node)
Returns the amount of memory residing on node.
Definition: memory.h:161
sc::MemoryGrpBuf::writeonly
data_t * writeonly(distsize_t offset, size_t length)
Request write only access to global memory at the global address offset and with size length.
Definition: memory.h:334
sc::MemoryGrp::malloc_local
virtual void * malloc_local(size_t nbyte)
Allocate data that will be accessed locally only.
sc::MemoryGrpBuf
The MemoryGrpBuf class provides access to pieces of the global shared memory that have been obtained ...
Definition: memory.h:275
sc::MemoryGrp::sync
virtual void sync()=0
Synchronizes all the nodes.
sc::MemoryGrp::obtain_writeonly
virtual void * obtain_writeonly(distsize_t offset, size_t size)=0
This gives write access to the memory location. No locking is done.
sc::MemoryGrp::free_local
virtual void free_local(void *&data)
Free data that was allocated with malloc_local, and set the pointer to 0.
sc::operator<<
std::vector< unsigned int > operator<<(const GaussianBasisSet &B, const GaussianBasisSet &A)
computes a map from basis functions in A to the equivalent basis functions in B.
sc::MemoryGrp::localsize
size_t localsize()
Returns the amount of memory residing locally on me().
Definition: memory.h:155
sc::MemoryGrp::me
int me() const
Returns who I am.
Definition: memory.h:146
sc::MemoryGrp::free_local_double
void free_local_double(double *&data)
Free data that was allocated with malloc_local_double, and set the pointer to 0
sc::MemoryGrp::get_default_memorygrp
static MemoryGrp * get_default_memorygrp()
Returns the default memory group.
sc::MemoryGrpBuf::readonly
const data_t * readonly(distsize_t offset, size_t length)
Request read only access to global memory at the global address offset and with size length.
Definition: memory.h:360
sc::MemoryGrpBuf::readwrite_on_node
data_t * readwrite_on_node(size_t offset, size_t length, int node=-1)
This behaves like readwrite, except the offset is local to the node specified by node.
Definition: memory.h:381
sc::MemoryGrp::localdata
virtual void * localdata()=0
Returns a pointer to the local data.
sc::MemoryGrpBuf::release
void release()
Release the access to the chunk of global memory that was obtained with writeonly,...
Definition: memory.h:397
sc::DescribedClass
Classes which need runtime information about themselves and their relationship to other classes can v...
Definition: class.h:233
mpqc::ci::operator<
bool operator<(const Space< Spin > &a, const Space< Spin > &b)
Compare two spaces by their rank.
Definition: subspace.hpp:44
sc::ExEnv::out0
static std::ostream & out0()
Return an ostream that writes from node 0.
sc::MemoryGrp::initial_memorygrp
static MemoryGrp * initial_memorygrp()
Create a memory group.
sc::MemoryGrp::set_localsize
virtual void set_localsize(size_t)=0
Set the size of locally held memory.
sc::MemoryGrpBuf::MemoryGrpBuf
MemoryGrpBuf(const Ref< MemoryGrp > &)
Creates a new MemoryGrpBuf given a MemoryGrp reference.
Definition: memory.h:326
sc::operator==
bool operator==(const Atom &a, const Atom &b)
sc::MemoryGrp::activate
virtual void activate()
Activate is called before the memory is to be used.
sc
Contains all MPQC code up to version 3.
Definition: mpqcin.h:14
sc::MemoryGrp::release_readonly
virtual void release_readonly(void *data, distsize_t offset, size_t size)=0
This is called when read access is no longer needed.
sc::MemoryGrp::localoffset
distsize_t localoffset()
Returns the global offset to this node's memory.
Definition: memory.h:159
sc::MemoryGrp::totalsize
distsize_t totalsize()
Returns the sum of all memory allocated on all nodes.
Definition: memory.h:166

Generated at Sun Jan 26 2020 23:24:01 for MPQC 3.0.0-alpha using the documentation package Doxygen 1.8.16.