memory.h

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 
00226     virtual Ref<MemoryGrp> clone(void);
00227 
00229     virtual void print(std::ostream &o = ExEnv::out0()) const;
00230 
00238     static MemoryGrp* initial_memorygrp(int &argc, char** argv);
00239     static MemoryGrp* initial_memorygrp();
00242     static void set_default_memorygrp(const Ref<MemoryGrp>&);
00248     static MemoryGrp* get_default_memorygrp();
00249 };
00250 
00251 
00257 template <class data_t>
00258 class MemoryGrpBuf {
00259     Ref<MemoryGrp> grp_;
00260     enum AccessType { None, Read, Write, ReadWrite };
00261     AccessType accesstype_;
00262     data_t *data_;
00263     distsize_t offset_;
00264     int length_;
00265   public:
00269     MemoryGrpBuf(const Ref<MemoryGrp> &);
00274     data_t *writeonly(distsize_t offset, int length);
00279     data_t *readwrite(distsize_t offset, int length);
00284     const data_t *readonly(distsize_t offset, int length);
00288     data_t *writeonly_on_node(size_t offset, int length, int node = -1);
00289     data_t *readwrite_on_node(size_t offset, int length, int node = -1);
00290     const data_t *readonly_on_node(size_t offset, int length, int node = -1);
00294     void release();
00296     int length() const { return length_; }
00297 };
00298 
00300 // MemoryGrpBuf members
00301 
00302 template <class data_t>
00303 MemoryGrpBuf<data_t>::MemoryGrpBuf(const Ref<MemoryGrp> & grp)
00304 {
00305   grp_ = grp;
00306   accesstype_ = None;
00307 }
00308 
00309 template <class data_t>
00310 data_t *
00311 MemoryGrpBuf<data_t>::writeonly(distsize_t offset, int length)
00312 {
00313   if (accesstype_ != None) release();
00314   data_ = (data_t *) grp_->obtain_writeonly(sizeof(data_t)*offset,
00315                                             sizeof(data_t)*length);
00316   offset_ = offset;
00317   length_ = length;
00318   accesstype_ = Write;
00319   return data_;
00320 }
00321 
00322 template <class data_t>
00323 data_t *
00324 MemoryGrpBuf<data_t>::readwrite(distsize_t offset, int length)
00325 {
00326   if (accesstype_ != None) release();
00327   data_ = (data_t *) grp_->obtain_readwrite(sizeof(data_t)*offset,
00328                                             sizeof(data_t)*length);
00329   offset_ = offset;
00330   length_ = length;
00331   accesstype_ = ReadWrite;
00332   return data_;
00333 }
00334 
00335 template <class data_t>
00336 const data_t *
00337 MemoryGrpBuf<data_t>::readonly(distsize_t offset, int length)
00338 {
00339   if (accesstype_ != None) release();
00340   data_ = (data_t *) grp_->obtain_readonly(sizeof(data_t)*offset,
00341                                            sizeof(data_t)*length);
00342   offset_ = offset;
00343   length_ = length;
00344   accesstype_ = Read;
00345   return data_;
00346 }
00347 
00348 template <class data_t>
00349 data_t *
00350 MemoryGrpBuf<data_t>::writeonly_on_node(size_t offset, int length, int node)
00351 {
00352   if (node == -1) node = grp_->me();
00353   return writeonly(offset + grp_->offset(node)/sizeof(data_t), length);
00354 }
00355 
00356 template <class data_t>
00357 data_t *
00358 MemoryGrpBuf<data_t>::readwrite_on_node(size_t offset, int length, int node)
00359 {
00360   if (node == -1) node = grp_->me();
00361   return readwrite(offset + grp_->offset(node)/sizeof(data_t), length);
00362 }
00363 
00364 template <class data_t>
00365 const data_t *
00366 MemoryGrpBuf<data_t>::readonly_on_node(size_t offset, int length, int node)
00367 {
00368   if (node == -1) node = grp_->me();
00369   return readonly(offset + grp_->offset(node)/sizeof(data_t), length);
00370 }
00371 
00372 template <class data_t>
00373 void
00374 MemoryGrpBuf<data_t>::release()
00375 {
00376   if (accesstype_ == Write)
00377       grp_->release_writeonly((data_t *)data_,
00378                               sizeof(data_t)*offset_, sizeof(data_t)*length_);
00379   if (accesstype_ == Read)
00380       grp_->release_readonly(data_, sizeof(data_t)*offset_,
00381                              sizeof(data_t)*length_);
00382   if (accesstype_ == ReadWrite)
00383       grp_->release_readwrite(data_, sizeof(data_t)*offset_,
00384                               sizeof(data_t)*length_);
00385 
00386   accesstype_ = None;
00387 }
00388 
00389 }
00390 
00391 #endif
00392 
00393 // Local Variables:
00394 // mode: c++
00395 // c-file-style: "CLJ"
00396 // End:

Generated at Wed Sep 5 14:02:30 2007 for MPQC 3.0.0-alpha using the documentation package Doxygen 1.5.2.
These pages are hosted on SourceForge.net