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
41namespace sc {
42
43#if 0 // this can be used to catch accidental conversions to int
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};
94inline distsize_t operator *(const int &a,const distsize_t &b)
95{ return a*b.s; }
96inline distsize_t operator +(const int &a,const distsize_t &b)
97{ return a+b.s; }
98inline distsize_t operator -(const int &a,const distsize_t &b)
99{ return a-b.s; }
100inline distsize_t operator /(const int &a,const distsize_t &b)
101{ return a/b.s; }
102inline distsize_t operator %(const int &a,const distsize_t &b)
103{ return a%b.s; }
104inline ostream& operator <<(ostream& o, const distsize_t &s) { return o<<s.s; }
105inline size_t distsize_to_size(const distsize_t &a) {return a.s;}
106#elif defined(HAVE_LONG_LONG)
107typedef unsigned long long distsize_t;
108typedef long long distssize_t;
109inline size_t distsize_to_size(const distsize_t &a) {return a;}
110#else
111typedef unsigned long distsize_t;
112typedef long distssize_t;
113inline size_t distsize_to_size(const distsize_t &a) {return a;}
114#endif
115
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);
244};
245
246
252template <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:
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
297template <class data_t>
299{
300 grp_ = grp;
301 accesstype_ = None;
302}
303
304template <class data_t>
305data_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
317template <class data_t>
318data_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
330template <class data_t>
331const 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
343template <class data_t>
344data_t *
345MemoryGrpBuf<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
351template <class data_t>
352data_t *
353MemoryGrpBuf<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
359template <class data_t>
360const data_t *
361MemoryGrpBuf<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
367template <class data_t>
368void
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:
Classes which need runtime information about themselves and their relationship to other classes can v...
Definition: class.h:244
static std::ostream & out0()
Return an ostream that writes from node 0.
The MemoryGrpBuf class provides access to pieces of the global shared memory that have been obtained ...
Definition: memory.h:253
int length() const
The length of the current bit of memory.
Definition: memory.h:291
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
void release()
Release the access to the chunk of global memory that was obtained with writeonly,...
Definition: memory.h:369
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
MemoryGrpBuf(const Ref< MemoryGrp > &)
Creates a new MemoryGrpBuf given a MemoryGrp reference.
Definition: memory.h:298
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
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
The MemoryGrp abstract class provides a way of accessing distributed memory in a parallel machine.
Definition: memory.h:124
virtual void sync()=0
Synchronizes all the nodes.
int size(int node)
Returns the amount of memory residing on node.
Definition: memory.h:165
static MemoryGrp * initial_memorygrp(int &argc, char **argv)
Create a memory group.
virtual void * obtain_readonly(distsize_t offset, int size)=0
This gives read access to the memory location. No locking is done.
static void set_default_memorygrp(const Ref< MemoryGrp > &)
The default memory group contains the primary memory group to be used by an application.
virtual void release_writeonly(void *data, distsize_t offset, int size)=0
This is called when write access is no longer needed.
virtual void set_localsize(size_t)=0
Set the size of locally held memory.
virtual void * localdata()=0
Returns a pointer to the local data.
virtual void release_readonly(void *data, distsize_t offset, int size)=0
This is called when read access is no longer needed.
int me() const
Returns who I am.
Definition: memory.h:150
distsize_t totalsize()
Returns the sum of all memory allocated on all nodes.
Definition: memory.h:170
virtual void activate()
Activate is called before the memory is to be used.
static MemoryGrp * get_default_memorygrp()
Returns the default memory group.
virtual void print(std::ostream &o=ExEnv::out0()) const
Prints out information about the object.
virtual void release_readwrite(void *data, distsize_t offset, int size)=0
This is called when read/write access is no longer needed.
virtual void * obtain_readwrite(distsize_t offset, int size)=0
Only one thread can have an unreleased obtain_readwrite at a time.
virtual void * malloc_local(size_t nbyte)
Allocate data that will be accessed locally only.
distsize_t offset(int node)
Returns the global offset to node's memory.
Definition: memory.h:168
int n() const
Returns how many nodes there are.
Definition: memory.h:152
virtual void free_local(void *data)
Free data that was allocated with malloc_local_double.
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's memory.
Definition: memory.h:163
virtual void deactivate()
Deactivate is called after the memory has been used.
virtual void * obtain_writeonly(distsize_t offset, int size)=0
This gives write access to the memory location. No locking is done.
virtual void catchup()
Processes outstanding requests.
A template class that maintains references counts.
Definition: ref.h:332
Definition: memory.h:44

Generated at Thu Jan 20 2022 00:00:00 for MPQC 2.3.1 using the documentation package Doxygen 1.9.4.