MPQC
2.3.1
|
00001 // 00002 // memory.h 00003 // 00004 // Copyright (C) 1996 Limit Point Systems, Inc. 00005 // 00006 // Author: Curtis Janssen <cljanss@limitpt.com> 00007 // Maintainer: LPS 00008 // 00009 // This file is part of the SC Toolkit. 00010 // 00011 // The SC Toolkit is free software; you can redistribute it and/or modify 00012 // it under the terms of the GNU Library General Public License as published by 00013 // the Free Software Foundation; either version 2, or (at your option) 00014 // any later version. 00015 // 00016 // The SC Toolkit is distributed in the hope that it will be useful, 00017 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 // GNU Library General Public License for more details. 00020 // 00021 // You should have received a copy of the GNU Library General Public License 00022 // along with the SC Toolkit; see the file COPYING.LIB. If not, write to 00023 // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 00024 // 00025 // The U.S. Government is granted a limited license as per AL 91-7. 00026 // 00027 00028 #ifdef __GNUC__ 00029 #pragma interface 00030 #endif 00031 00032 #ifndef _util_group_memory_h 00033 #define _util_group_memory_h 00034 00035 #include <iostream> 00036 00037 #include <scconfig.h> 00038 #include <util/class/class.h> 00039 #include <util/group/thread.h> 00040 00041 namespace sc { 00042 00043 #if 0 // this can be used to catch accidental conversions to int 00044 class distsize_t { 00045 friend size_t distsize_to_size(const distsize_t &a); 00046 friend distsize_t operator *(const int &a,const distsize_t &b); 00047 friend distsize_t operator +(const int &a,const distsize_t &b); 00048 friend distsize_t operator -(const int &a,const distsize_t &b); 00049 friend distsize_t operator /(const int &a,const distsize_t &b); 00050 friend distsize_t operator %(const int &a,const distsize_t &b); 00051 friend ostream& operator <<(ostream& o, const distsize_t &s); 00052 private: 00053 unsigned long long s; 00054 public: 00055 distsize_t(): s(999999999999999LL) {} 00056 distsize_t(int a): s(a) {} 00057 distsize_t(unsigned int a): s(a) {} 00058 distsize_t(unsigned long long a): s(a) {} 00059 distsize_t &operator =(const distsize_t &a) 00060 { s=a.s; return *this; } 00061 distsize_t &operator +=(const distsize_t &a) 00062 { s+=a.s; return *this; } 00063 distsize_t operator *(const distsize_t &a) const 00064 { return s*a.s; } 00065 distsize_t operator +(const distsize_t &a) const 00066 { return s+a.s; } 00067 distsize_t operator -(const distsize_t &a) const 00068 { return s-a.s; } 00069 distsize_t operator /(const distsize_t &a) const 00070 { return s/a.s; } 00071 distsize_t operator %(const distsize_t &a) const 00072 { return s%a.s; } 00073 bool operator <(const distsize_t &a) const 00074 { return s<a.s; } 00075 bool operator <=(const distsize_t &a) const 00076 { return s<=a.s; } 00077 bool operator >(const distsize_t &a) const 00078 { return s>a.s; } 00079 bool operator >=(const distsize_t &a) const 00080 { return s>=a.s; } 00081 bool operator ==(const distsize_t &a) const 00082 { return s==a.s; } 00083 distsize_t operator *(const int &a) const 00084 { return s*a; } 00085 distsize_t operator +(const int &a) const 00086 { return s+a; } 00087 distsize_t operator -(const int &a) const 00088 { return s-a; } 00089 distsize_t operator /(const int &a) const 00090 { return s/a; } 00091 distsize_t operator %(const int &a) const 00092 { return s%a; } 00093 }; 00094 inline distsize_t operator *(const int &a,const distsize_t &b) 00095 { return a*b.s; } 00096 inline distsize_t operator +(const int &a,const distsize_t &b) 00097 { return a+b.s; } 00098 inline distsize_t operator -(const int &a,const distsize_t &b) 00099 { return a-b.s; } 00100 inline distsize_t operator /(const int &a,const distsize_t &b) 00101 { return a/b.s; } 00102 inline distsize_t operator %(const int &a,const distsize_t &b) 00103 { return a%b.s; } 00104 inline ostream& operator <<(ostream& o, const distsize_t &s) { return o<<s.s; } 00105 inline size_t distsize_to_size(const distsize_t &a) {return a.s;} 00106 #elif defined(HAVE_LONG_LONG) 00107 typedef unsigned long long distsize_t; 00108 typedef long long distssize_t; 00109 inline size_t distsize_to_size(const distsize_t &a) {return a;} 00110 #else 00111 typedef unsigned long distsize_t; 00112 typedef long distssize_t; 00113 inline size_t distsize_to_size(const distsize_t &a) {return a;} 00114 #endif 00115 00124 class MemoryGrp: public DescribedClass { 00125 private: 00126 Ref<ThreadLock> *locks_; 00127 int nlock_; 00128 00129 void init_locks(); 00130 00131 00132 protected: 00133 // derived classes must fill in all these 00134 // ~MemoryGrp deletes the arrays 00135 int me_; 00136 int n_; 00137 distsize_t *offsets_; // offsets_[n_] is the fence for all data 00138 00139 // set to nonzero for debugging information 00140 int debug_; 00141 00142 void obtain_local_lock(size_t start, size_t fence); 00143 void release_local_lock(size_t start, size_t fence); 00144 public: 00145 MemoryGrp(); 00146 MemoryGrp(const Ref<KeyVal>&); 00147 virtual ~MemoryGrp(); 00148 00150 int me() const { return me_; } 00152 int n() const { return n_; } 00153 00157 virtual void set_localsize(size_t) = 0; 00159 size_t localsize() { return distsize_to_size(offsets_[me_+1]-offsets_[me_]); } 00161 virtual void *localdata() = 0; 00163 distsize_t localoffset() { return offsets_[me_]; } 00165 int size(int node) 00166 { return distsize_to_size(offsets_[node+1] - offsets_[node]); } 00168 distsize_t offset(int node) { return offsets_[node]; } 00170 distsize_t totalsize() { return offsets_[n_]; } 00171 00173 virtual void activate(); 00175 virtual void deactivate(); 00176 00178 virtual void *obtain_writeonly(distsize_t offset, int size) = 0; 00184 virtual void *obtain_readwrite(distsize_t offset, int size) = 0; 00186 virtual void *obtain_readonly(distsize_t offset, int size) = 0; 00188 virtual void release_readonly(void *data, distsize_t offset, int size) = 0; 00190 virtual void release_writeonly(void *data, distsize_t offset, int size)=0; 00193 virtual void release_readwrite(void *data, distsize_t offset, int size)=0; 00194 00195 virtual void sum_reduction(double *data, distsize_t doffset, int dsize); 00196 virtual void sum_reduction_on_node(double *data, size_t doffset, int dsize, 00197 int node = -1); 00198 00202 virtual void sync() = 0; 00203 00208 virtual void* malloc_local(size_t nbyte); 00209 virtual double* malloc_local_double(size_t ndouble); 00210 00212 virtual void free_local(void *data); 00213 virtual void free_local_double(double *data); 00214 00221 virtual void catchup(); 00222 00224 virtual void print(std::ostream &o = ExEnv::out0()) const; 00225 00233 static MemoryGrp* initial_memorygrp(int &argc, char** argv); 00234 static MemoryGrp* initial_memorygrp(); 00237 static void set_default_memorygrp(const Ref<MemoryGrp>&); 00243 static MemoryGrp* get_default_memorygrp(); 00244 }; 00245 00246 00252 template <class data_t> 00253 class MemoryGrpBuf { 00254 Ref<MemoryGrp> grp_; 00255 enum AccessType { None, Read, Write, ReadWrite }; 00256 AccessType accesstype_; 00257 data_t *data_; 00258 distsize_t offset_; 00259 int length_; 00260 public: 00264 MemoryGrpBuf(const Ref<MemoryGrp> &); 00269 data_t *writeonly(distsize_t offset, int length); 00274 data_t *readwrite(distsize_t offset, int length); 00279 const data_t *readonly(distsize_t offset, int length); 00283 data_t *writeonly_on_node(size_t offset, int length, int node = -1); 00284 data_t *readwrite_on_node(size_t offset, int length, int node = -1); 00285 const data_t *readonly_on_node(size_t offset, int length, int node = -1); 00289 void release(); 00291 int length() const { return length_; } 00292 }; 00293 00295 // MemoryGrpBuf members 00296 00297 template <class data_t> 00298 MemoryGrpBuf<data_t>::MemoryGrpBuf(const Ref<MemoryGrp> & grp) 00299 { 00300 grp_ = grp; 00301 accesstype_ = None; 00302 } 00303 00304 template <class data_t> 00305 data_t * 00306 MemoryGrpBuf<data_t>::writeonly(distsize_t offset, int length) 00307 { 00308 if (accesstype_ != None) release(); 00309 data_ = (data_t *) grp_->obtain_writeonly(sizeof(data_t)*offset, 00310 sizeof(data_t)*length); 00311 offset_ = offset; 00312 length_ = length; 00313 accesstype_ = Write; 00314 return data_; 00315 } 00316 00317 template <class data_t> 00318 data_t * 00319 MemoryGrpBuf<data_t>::readwrite(distsize_t offset, int length) 00320 { 00321 if (accesstype_ != None) release(); 00322 data_ = (data_t *) grp_->obtain_readwrite(sizeof(data_t)*offset, 00323 sizeof(data_t)*length); 00324 offset_ = offset; 00325 length_ = length; 00326 accesstype_ = ReadWrite; 00327 return data_; 00328 } 00329 00330 template <class data_t> 00331 const data_t * 00332 MemoryGrpBuf<data_t>::readonly(distsize_t offset, int length) 00333 { 00334 if (accesstype_ != None) release(); 00335 data_ = (data_t *) grp_->obtain_readonly(sizeof(data_t)*offset, 00336 sizeof(data_t)*length); 00337 offset_ = offset; 00338 length_ = length; 00339 accesstype_ = Read; 00340 return data_; 00341 } 00342 00343 template <class data_t> 00344 data_t * 00345 MemoryGrpBuf<data_t>::writeonly_on_node(size_t offset, int length, int node) 00346 { 00347 if (node == -1) node = grp_->me(); 00348 return writeonly(offset + grp_->offset(node)/sizeof(data_t), length); 00349 } 00350 00351 template <class data_t> 00352 data_t * 00353 MemoryGrpBuf<data_t>::readwrite_on_node(size_t offset, int length, int node) 00354 { 00355 if (node == -1) node = grp_->me(); 00356 return readwrite(offset + grp_->offset(node)/sizeof(data_t), length); 00357 } 00358 00359 template <class data_t> 00360 const data_t * 00361 MemoryGrpBuf<data_t>::readonly_on_node(size_t offset, int length, int node) 00362 { 00363 if (node == -1) node = grp_->me(); 00364 return readonly(offset + grp_->offset(node)/sizeof(data_t), length); 00365 } 00366 00367 template <class data_t> 00368 void 00369 MemoryGrpBuf<data_t>::release() 00370 { 00371 if (accesstype_ == Write) 00372 grp_->release_writeonly((data_t *)data_, 00373 sizeof(data_t)*offset_, sizeof(data_t)*length_); 00374 if (accesstype_ == Read) 00375 grp_->release_readonly(data_, sizeof(data_t)*offset_, 00376 sizeof(data_t)*length_); 00377 if (accesstype_ == ReadWrite) 00378 grp_->release_readwrite(data_, sizeof(data_t)*offset_, 00379 sizeof(data_t)*length_); 00380 00381 accesstype_ = None; 00382 } 00383 00384 } 00385 00386 #endif 00387 00388 // Local Variables: 00389 // mode: c++ 00390 // c-file-style: "CLJ" 00391 // End: