MPQC  2.3.1
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 #ifdef __GNUC__
29 #pragma interface
30 #endif
31 
32 #ifndef _util_group_memory_h
33 #define _util_group_memory_h
34 
35 #include <iostream>
36 
37 #include <scconfig.h>
38 #include <util/class/class.h>
39 #include <util/group/thread.h>
40 
41 namespace sc {
42 
43 #if 0 // this can be used to catch accidental conversions to int
44 class distsize_t {
45  friend size_t distsize_to_size(const distsize_t &a);
46  friend distsize_t operator *(const int &a,const distsize_t &b);
47  friend distsize_t operator +(const int &a,const distsize_t &b);
48  friend distsize_t operator -(const int &a,const distsize_t &b);
49  friend distsize_t operator /(const int &a,const distsize_t &b);
50  friend distsize_t operator %(const int &a,const distsize_t &b);
51  friend ostream& operator <<(ostream& o, const distsize_t &s);
52  private:
53  unsigned long long s;
54  public:
55  distsize_t(): s(999999999999999LL) {}
56  distsize_t(int a): s(a) {}
57  distsize_t(unsigned int a): s(a) {}
58  distsize_t(unsigned long long a): s(a) {}
59  distsize_t &operator =(const distsize_t &a)
60  { s=a.s; return *this; }
61  distsize_t &operator +=(const distsize_t &a)
62  { s+=a.s; return *this; }
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  distsize_t operator /(const distsize_t &a) const
70  { return s/a.s; }
71  distsize_t 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  bool operator >=(const distsize_t &a) const
80  { return s>=a.s; }
81  bool operator ==(const distsize_t &a) const
82  { return s==a.s; }
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  distsize_t operator /(const int &a) const
90  { return s/a; }
91  distsize_t operator %(const int &a) const
92  { return s%a; }
93 };
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 distsize_t operator /(const int &a,const distsize_t &b)
101 { return a/b.s; }
102 inline distsize_t operator %(const int &a,const distsize_t &b)
103 { return a%b.s; }
104 inline ostream& operator <<(ostream& o, const distsize_t &s) { return o<<s.s; }
105 inline size_t distsize_to_size(const distsize_t &a) {return a.s;}
106 #elif defined(HAVE_LONG_LONG)
107 typedef unsigned long long distsize_t;
108 typedef long long distssize_t;
109 inline size_t distsize_to_size(const distsize_t &a) {return a;}
110 #else
111 typedef unsigned long distsize_t;
112 typedef long distssize_t;
113 inline size_t distsize_to_size(const distsize_t &a) {return a;}
114 #endif
115 
124 class MemoryGrp: public DescribedClass {
125  private:
126  Ref<ThreadLock> *locks_;
127  int nlock_;
128 
129  void init_locks();
130 
131 
132  protected:
133  // derived classes must fill in all these
134  // ~MemoryGrp deletes the arrays
135  int me_;
136  int n_;
137  distsize_t *offsets_; // offsets_[n_] is the fence for all data
138 
139  // set to nonzero for debugging information
140  int debug_;
141 
142  void obtain_local_lock(size_t start, size_t fence);
143  void release_local_lock(size_t start, size_t fence);
144  public:
145  MemoryGrp();
146  MemoryGrp(const Ref<KeyVal>&);
147  virtual ~MemoryGrp();
148 
150  int me() const { return me_; }
152  int n() const { return n_; }
153 
157  virtual void set_localsize(size_t) = 0;
159  size_t localsize() { return distsize_to_size(offsets_[me_+1]-offsets_[me_]); }
161  virtual void *localdata() = 0;
163  distsize_t localoffset() { return offsets_[me_]; }
165  int size(int node)
166  { return distsize_to_size(offsets_[node+1] - offsets_[node]); }
168  distsize_t offset(int node) { return offsets_[node]; }
170  distsize_t totalsize() { return offsets_[n_]; }
171 
173  virtual void activate();
175  virtual void deactivate();
176 
178  virtual void *obtain_writeonly(distsize_t offset, int size) = 0;
184  virtual void *obtain_readwrite(distsize_t offset, int size) = 0;
186  virtual void *obtain_readonly(distsize_t offset, int size) = 0;
188  virtual void release_readonly(void *data, distsize_t offset, int size) = 0;
190  virtual void release_writeonly(void *data, distsize_t offset, int size)=0;
193  virtual void release_readwrite(void *data, distsize_t offset, int size)=0;
194 
195  virtual void sum_reduction(double *data, distsize_t doffset, int dsize);
196  virtual void sum_reduction_on_node(double *data, size_t doffset, int dsize,
197  int node = -1);
198 
202  virtual void sync() = 0;
203 
208  virtual void* malloc_local(size_t nbyte);
209  virtual double* malloc_local_double(size_t ndouble);
210 
212  virtual void free_local(void *data);
213  virtual void free_local_double(double *data);
214 
221  virtual void catchup();
222 
224  virtual void print(std::ostream &o = ExEnv::out0()) const;
225 
233  static MemoryGrp* initial_memorygrp(int &argc, char** argv);
234  static MemoryGrp* initial_memorygrp();
237  static void set_default_memorygrp(const Ref<MemoryGrp>&);
244 };
245 
246 
252 template <class data_t>
254  Ref<MemoryGrp> grp_;
255  enum AccessType { None, Read, Write, ReadWrite };
256  AccessType accesstype_;
257  data_t *data_;
258  distsize_t offset_;
259  int length_;
260  public:
264  MemoryGrpBuf(const Ref<MemoryGrp> &);
269  data_t *writeonly(distsize_t offset, int length);
274  data_t *readwrite(distsize_t offset, int length);
279  const data_t *readonly(distsize_t offset, int length);
283  data_t *writeonly_on_node(size_t offset, int length, int node = -1);
284  data_t *readwrite_on_node(size_t offset, int length, int node = -1);
285  const data_t *readonly_on_node(size_t offset, int length, int node = -1);
289  void release();
291  int length() const { return length_; }
292 };
293 
295 // MemoryGrpBuf members
296 
297 template <class data_t>
299 {
300  grp_ = grp;
301  accesstype_ = None;
302 }
303 
304 template <class data_t>
305 data_t *
307 {
308  if (accesstype_ != None) release();
309  data_ = (data_t *) grp_->obtain_writeonly(sizeof(data_t)*offset,
310  sizeof(data_t)*length);
311  offset_ = offset;
312  length_ = length;
313  accesstype_ = Write;
314  return data_;
315 }
316 
317 template <class data_t>
318 data_t *
320 {
321  if (accesstype_ != None) release();
322  data_ = (data_t *) grp_->obtain_readwrite(sizeof(data_t)*offset,
323  sizeof(data_t)*length);
324  offset_ = offset;
325  length_ = length;
326  accesstype_ = ReadWrite;
327  return data_;
328 }
329 
330 template <class data_t>
331 const data_t *
333 {
334  if (accesstype_ != None) release();
335  data_ = (data_t *) grp_->obtain_readonly(sizeof(data_t)*offset,
336  sizeof(data_t)*length);
337  offset_ = offset;
338  length_ = length;
339  accesstype_ = Read;
340  return data_;
341 }
342 
343 template <class data_t>
344 data_t *
345 MemoryGrpBuf<data_t>::writeonly_on_node(size_t offset, int length, int node)
346 {
347  if (node == -1) node = grp_->me();
348  return writeonly(offset + grp_->offset(node)/sizeof(data_t), length);
349 }
350 
351 template <class data_t>
352 data_t *
353 MemoryGrpBuf<data_t>::readwrite_on_node(size_t offset, int length, int node)
354 {
355  if (node == -1) node = grp_->me();
356  return readwrite(offset + grp_->offset(node)/sizeof(data_t), length);
357 }
358 
359 template <class data_t>
360 const data_t *
361 MemoryGrpBuf<data_t>::readonly_on_node(size_t offset, int length, int node)
362 {
363  if (node == -1) node = grp_->me();
364  return readonly(offset + grp_->offset(node)/sizeof(data_t), length);
365 }
366 
367 template <class data_t>
368 void
370 {
371  if (accesstype_ == Write)
372  grp_->release_writeonly((data_t *)data_,
373  sizeof(data_t)*offset_, sizeof(data_t)*length_);
374  if (accesstype_ == Read)
375  grp_->release_readonly(data_, sizeof(data_t)*offset_,
376  sizeof(data_t)*length_);
377  if (accesstype_ == ReadWrite)
378  grp_->release_readwrite(data_, sizeof(data_t)*offset_,
379  sizeof(data_t)*length_);
380 
381  accesstype_ = None;
382 }
383 
384 }
385 
386 #endif
387 
388 // Local Variables:
389 // mode: c++
390 // c-file-style: "CLJ"
391 // End:
virtual void deactivate()
Deactivate is called after the memory has been used.
void release()
Release the access to the chunk of global memory that was obtained with writeonly, readwrite, readonly, writeonly_on_node, readwrite_on_node, and readonly_on_node.
Definition: memory.h:369
virtual void free_local(void *data)
Free data that was allocated with malloc_local_double.
virtual void set_localsize(size_t)=0
Set the size of locally held memory.
virtual void * obtain_readwrite(distsize_t offset, int size)=0
Only one thread can have an unreleased obtain_readwrite at a time.
const data_t * readonly(distsize_t offset, int length)
Request read only access to global memory at the global address offset and with size length...
Definition: memory.h:332
virtual void sync()=0
Synchronizes all the nodes.
int n() const
Returns how many nodes there are.
Definition: memory.h:152
virtual void activate()
Activate is called before the memory is to be used.
virtual void release_readwrite(void *data, distsize_t offset, int size)=0
This is called when read/write access is no longer needed.
static void set_default_memorygrp(const Ref< MemoryGrp > &)
The default memory group contains the primary memory group to be used by an application.
Definition: memory.h:44
distsize_t totalsize()
Returns the sum of all memory allocated on all nodes.
Definition: memory.h:170
Classes which need runtime information about themselves and their relationship to other classes can v...
Definition: class.h:244
int length() const
The length of the current bit of memory.
Definition: memory.h:291
data_t * writeonly(distsize_t offset, int length)
Request write only access to global memory at the global address offset and with size length...
Definition: memory.h:306
A template class that maintains references counts.
Definition: ref.h:332
MemoryGrpBuf(const Ref< MemoryGrp > &)
Creates a new MemoryGrpBuf given a MemoryGrp reference.
Definition: memory.h:298
virtual void * obtain_writeonly(distsize_t offset, int size)=0
This gives write access to the memory location. No locking is done.
data_t * readwrite(distsize_t offset, int length)
Request read write access to global memory at the global address offset and with size length...
Definition: memory.h:319
virtual void catchup()
Processes outstanding requests.
virtual void print(std::ostream &o=ExEnv::out0()) const
Prints out information about the object.
int me() const
Returns who I am.
Definition: memory.h:150
The MemoryGrp abstract class provides a way of accessing distributed memory in a parallel machine...
Definition: memory.h:124
data_t * writeonly_on_node(size_t offset, int length, int node=-1)
These behave like writeonly, readwrite, and readonly, except the offset is local to the node specifie...
Definition: memory.h:345
Definition: mpqcin.h:13
static MemoryGrp * get_default_memorygrp()
Returns the default memory group.
int size(int node)
Returns the amount of memory residing on node.
Definition: memory.h:165
virtual void * malloc_local(size_t nbyte)
Allocate data that will be accessed locally only.
static std::ostream & out0()
Return an ostream that writes from node 0.
virtual void release_writeonly(void *data, distsize_t offset, int size)=0
This is called when write access is no longer needed.
virtual void release_readonly(void *data, distsize_t offset, int size)=0
This is called when read access is no longer needed.
distsize_t offset(int node)
Returns the global offset to node&#39;s memory.
Definition: memory.h:168
virtual void * localdata()=0
Returns a pointer to the local data.
The MemoryGrpBuf class provides access to pieces of the global shared memory that have been obtained ...
Definition: memory.h:253
size_t localsize()
Returns the amount of memory residing locally on me().
Definition: memory.h:159
distsize_t localoffset()
Returns the global offset to this node&#39;s memory.
Definition: memory.h:163
virtual void * obtain_readonly(distsize_t offset, int size)=0
This gives read access to the memory location. No locking is done.

Generated at Fri Feb 16 2018 01:48:56 for MPQC 2.3.1 using the documentation package Doxygen 1.8.14.