| 1 | // This may look like C code, but it is really -*- C++ -*-
 | 
|---|
| 2 | //      Base array class - Memory organisation management
 | 
|---|
| 3 | //                     R. Ansari, C.Magneville   03/2000
 | 
|---|
| 4 | 
 | 
|---|
| 5 | #ifndef BaseArray_SEEN
 | 
|---|
| 6 | #define BaseArray_SEEN
 | 
|---|
| 7 | 
 | 
|---|
| 8 | #include "machdefs.h"
 | 
|---|
| 9 | #include <math.h>
 | 
|---|
| 10 | #include <iostream>
 | 
|---|
| 11 | #include "anydataobj.h"
 | 
|---|
| 12 | #include "mutyv.h"
 | 
|---|
| 13 | #include "dvlist.h"
 | 
|---|
| 14 | 
 | 
|---|
| 15 | 
 | 
|---|
| 16 | //! Maximum number of dimensions for an array 
 | 
|---|
| 17 | /*! \anchor BASEARRAY_MAXNDIMS */
 | 
|---|
| 18 | #define BASEARRAY_MAXNDIMS  5
 | 
|---|
| 19 | 
 | 
|---|
| 20 | namespace SOPHYA {  
 | 
|---|
| 21 | 
 | 
|---|
| 22 | //   ------------ classe template Array ----------- 
 | 
|---|
| 23 | //! Base class for template arrays
 | 
|---|
| 24 | class BaseArray : public AnyDataObj {
 | 
|---|
| 25 | public:
 | 
|---|
| 26 |   //! To define Array or Matrix memory mapping
 | 
|---|
| 27 |   enum MemoryMapping {
 | 
|---|
| 28 |     AutoMemoryMapping = -1,  //!< define Auto Memory Mapping
 | 
|---|
| 29 |     SameMemoryMapping = 0,   //!< define Same Memory Mapping
 | 
|---|
| 30 |     CMemoryMapping = 1,      //!< define C Memory Mapping
 | 
|---|
| 31 |     FortranMemoryMapping = 2 //!< define Fortran Memory Mapping
 | 
|---|
| 32 |     };
 | 
|---|
| 33 |   //! To define Vector type
 | 
|---|
| 34 |   enum VectorType {
 | 
|---|
| 35 |     AutoVectorType = -1,  //!< define Auto Vector Type
 | 
|---|
| 36 |     SameVectorType = 0,   //!< define Same Vector Type
 | 
|---|
| 37 |     ColumnVector = 1,     //!< define Column Vector Type
 | 
|---|
| 38 |     RowVector = 2         //!< define Row Vector Type
 | 
|---|
| 39 |     };
 | 
|---|
| 40 | 
 | 
|---|
| 41 |   // threshold for parallel routine call
 | 
|---|
| 42 |   static void    SetOpenMPSizeThreshold(sa_size_t thr=200000);
 | 
|---|
| 43 |   //! Get Size threshold for parallel routine call
 | 
|---|
| 44 |   static inline sa_size_t GetOpenMPSizeThreshold() { return openmp_size_threshold; }
 | 
|---|
| 45 | 
 | 
|---|
| 46 |   static void    SetMaxPrint(sa_size_t nprt=50, int_4 lev=0);   
 | 
|---|
| 47 |   //! Get maximum number of printed elements
 | 
|---|
| 48 |   static inline sa_size_t GetMaxPrint() { return max_nprt_; }
 | 
|---|
| 49 |   //! Get print  level
 | 
|---|
| 50 |   static inline int_4 GetPrintLevel() { return prt_lev_; }
 | 
|---|
| 51 | 
 | 
|---|
| 52 |   static short   SetDefaultMemoryMapping(short mm=CMemoryMapping);
 | 
|---|
| 53 |   //! Get Default Memory Mapping
 | 
|---|
| 54 |   static inline short GetDefaultMemoryMapping() { return default_memory_mapping; }
 | 
|---|
| 55 |   static short   SetDefaultVectorType(short vt=ColumnVector);
 | 
|---|
| 56 |   //! Get Default Vector Type
 | 
|---|
| 57 |   static inline short GetDefaultVectorType() { return default_vector_type; }
 | 
|---|
| 58 |   
 | 
|---|
| 59 |   // Creator / destructor
 | 
|---|
| 60 |   BaseArray();
 | 
|---|
| 61 |   virtual ~BaseArray();
 | 
|---|
| 62 | 
 | 
|---|
| 63 |   // Returns true if ndim and sizes are equal
 | 
|---|
| 64 |   virtual bool CompareSizes(const BaseArray& a, bool& smo) const;
 | 
|---|
| 65 | 
 | 
|---|
| 66 |   // Compacts \b size=1 array dimensions
 | 
|---|
| 67 |   virtual void CompactAllDim(); // suppresses all size==1 dimensions 
 | 
|---|
| 68 |   virtual void CompactTrailingDim(); // suppresses size==1 dimensions after the last size>1 dimension
 | 
|---|
| 69 | 
 | 
|---|
| 70 |   // Array dimensions
 | 
|---|
| 71 |   //! Return true if the array was allocated ( Rank() > 0 )
 | 
|---|
| 72 |   inline bool IsAllocated() const { return( (ndim_ > 0) ? true : false ); }
 | 
|---|
| 73 |   //! Return number of dimensions (array rank)
 | 
|---|
| 74 |   inline int_4 NbDimensions() const { return( ndim_ ); }
 | 
|---|
| 75 |   //! Return array rank (number of dimensions) 
 | 
|---|
| 76 |   inline int_4 Rank() const { return( ndim_ ); }
 | 
|---|
| 77 | 
 | 
|---|
| 78 |   //! Return total size of the array
 | 
|---|
| 79 |   inline sa_size_t Size() const { return(totsize_); }
 | 
|---|
| 80 |   //! Return size along the first dimension
 | 
|---|
| 81 |   inline sa_size_t SizeX() const { return(size_[0]); }
 | 
|---|
| 82 |   //! Return size along the second dimension
 | 
|---|
| 83 |   inline sa_size_t SizeY() const { return(size_[1]); }
 | 
|---|
| 84 |   //! Return size along the third dimension
 | 
|---|
| 85 |   inline sa_size_t SizeZ() const { return(size_[2]); }
 | 
|---|
| 86 |   //! Return size along the \b ka th dimension
 | 
|---|
| 87 |   inline sa_size_t Size(int_4 ka) const { return(size_[CheckDI(ka,1)]); }
 | 
|---|
| 88 | 
 | 
|---|
| 89 |   int_4 MaxSizeKA() const ;
 | 
|---|
| 90 | 
 | 
|---|
| 91 |   //! Get memory organization
 | 
|---|
| 92 |   inline short  GetMemoryMapping() const 
 | 
|---|
| 93 |          { return ( (marowi_ == 1) ? CMemoryMapping : FortranMemoryMapping) ; }
 | 
|---|
| 94 |   //! line index dimension
 | 
|---|
| 95 |   inline int_4    RowsKA() const {return marowi_; }
 | 
|---|
| 96 |   //! column index dimension
 | 
|---|
| 97 |   inline int_4    ColsKA() const {return macoli_; }
 | 
|---|
| 98 |   //! Index dimension of the elements of a vector
 | 
|---|
| 99 |   inline int_4    VectKA() const {return veceli_; }
 | 
|---|
| 100 |   void          SetMemoryMapping(short mm=AutoMemoryMapping);
 | 
|---|
| 101 | 
 | 
|---|
| 102 |   //! Get Vector type ( \b Line or \b Column vector )
 | 
|---|
| 103 |   inline short  GetVectorType() const 
 | 
|---|
| 104 |                 { return((marowi_ == veceli_) ? ColumnVector : RowVector); }
 | 
|---|
| 105 |   void SetVectorType(short vt=AutoVectorType);
 | 
|---|
| 106 | 
 | 
|---|
| 107 |   // memory organisation - packing information
 | 
|---|
| 108 |   //! return true if array is packed in memory
 | 
|---|
| 109 |   inline bool   IsPacked() const { return(moystep_ == 1); }
 | 
|---|
| 110 |   //! return true if array is packed along the first dimension
 | 
|---|
| 111 |   inline bool   IsPackedX() const { return(step_[0] == 1); }
 | 
|---|
| 112 |   //! return true if array is packed along the second dimension
 | 
|---|
| 113 |   inline bool   IsPackedY() const { return(step_[1] == 1); }
 | 
|---|
| 114 |   //! return true if array is packed along the third dimension
 | 
|---|
| 115 |   inline bool   IsPackedZ() const { return(step_[2] == 1); }
 | 
|---|
| 116 |   //! return true if array is packed along the \b ka th dimension
 | 
|---|
| 117 |   inline bool   IsPacked(int_4 ka) const { return(step_[CheckDI(ka,2)] == 1); }
 | 
|---|
| 118 | 
 | 
|---|
| 119 |   //! return the minimum step value along all the dimensions
 | 
|---|
| 120 |   inline sa_size_t MinStep() const  { return(minstep_); }
 | 
|---|
| 121 |   //! return the average step value along all the dimensions
 | 
|---|
| 122 |   inline sa_size_t AvgStep() const  { return(moystep_); }
 | 
|---|
| 123 |   //! return the step along the first dimension
 | 
|---|
| 124 |   inline sa_size_t StepX() const { return(step_[0]); }
 | 
|---|
| 125 |   //! return the step along the second dimension
 | 
|---|
| 126 |   inline sa_size_t StepY() const { return(step_[1]); }
 | 
|---|
| 127 |   //! return the step along the third dimension
 | 
|---|
| 128 |   inline sa_size_t StepZ() const { return(step_[2]); }
 | 
|---|
| 129 |   //! return the step along the \b ka th dimension
 | 
|---|
| 130 |   inline sa_size_t Step(int_4 ka) const { return(step_[CheckDI(ka,3)]); }
 | 
|---|
| 131 | 
 | 
|---|
| 132 |   int_4 MinStepKA() const ;
 | 
|---|
| 133 | 
 | 
|---|
| 134 |   // Offset of element ip
 | 
|---|
| 135 |   sa_size_t Offset(sa_size_t ip=0) const ;
 | 
|---|
| 136 |   // Offset of the i'th vector along axe ka 
 | 
|---|
| 137 |   sa_size_t Offset(int_4 ka, sa_size_t i) const ;
 | 
|---|
| 138 |   inline sa_size_t  Offset(sa_size_t ix, sa_size_t iy, sa_size_t iz, sa_size_t it=0, sa_size_t iu=0) const;  
 | 
|---|
| 139 |   // Index values of element ip
 | 
|---|
| 140 |   void           IndexAtPosition(sa_size_t ip, sa_size_t & ix, sa_size_t & iy, sa_size_t & iz, 
 | 
|---|
| 141 |                                  sa_size_t & it, sa_size_t & iu) const;
 | 
|---|
| 142 |   // an abstract element acces methode
 | 
|---|
| 143 |   virtual MuTyV & ValueAtPosition(sa_size_t ip) const = 0;
 | 
|---|
| 144 | 
 | 
|---|
| 145 |   // Pour recuperer pas et numero d'axe pour operations sur deux arrays
 | 
|---|
| 146 |   void   GetOpeParams(const BaseArray& a, bool smo, int_4& ax, int_4& axa, sa_size_t& step,
 | 
|---|
| 147 |                       sa_size_t& stepa, sa_size_t& gpas, sa_size_t& naxa) const;
 | 
|---|
| 148 |   // Impression, I/O, ...
 | 
|---|
| 149 |   void           Show(ostream& os, bool si=false) const;
 | 
|---|
| 150 |   //! Show information on \b cout
 | 
|---|
| 151 |   inline void    Show() const { Show(cout); }
 | 
|---|
| 152 |   virtual string InfoString() const;
 | 
|---|
| 153 | 
 | 
|---|
| 154 |   // Lecture,Ecriture sur fichier ASCII
 | 
|---|
| 155 |   //! Reads an array from an ASCII stream
 | 
|---|
| 156 |   virtual sa_size_t ReadASCII(istream& is, sa_size_t & nr, sa_size_t & nc,
 | 
|---|
| 157 |                               char clm='#', const char* sep=" \t") = 0;
 | 
|---|
| 158 |   //! Writes an array to an ASCII stream
 | 
|---|
| 159 |   virtual void   WriteASCII(ostream& os) const = 0;
 | 
|---|
| 160 | 
 | 
|---|
| 161 |   // DVList info Object
 | 
|---|
| 162 |   DVList& Info();
 | 
|---|
| 163 | 
 | 
|---|
| 164 | protected:
 | 
|---|
| 165 |   inline int_4 CheckDI(int_4 ka, int msg) const ;
 | 
|---|
| 166 |   inline void CheckBound(sa_size_t ix, sa_size_t iy, sa_size_t iz, sa_size_t it, sa_size_t iu, int msg) const ;
 | 
|---|
| 167 |   // Changing Sizes/NDim ... return true if OK
 | 
|---|
| 168 |   bool UpdateSizes(int_4 ndim, const sa_size_t * siz, sa_size_t step, sa_size_t offset, string & exmsg);
 | 
|---|
| 169 |   bool UpdateSizes(int_4 ndim, const sa_size_t * siz, const sa_size_t * step, sa_size_t offset, string & exmsg);
 | 
|---|
| 170 |   bool UpdateSizes(const BaseArray& a, string & exmsg);
 | 
|---|
| 171 |   static sa_size_t ComputeTotalSize(int_4 ndim, const sa_size_t * siz, sa_size_t step, sa_size_t offset) ;
 | 
|---|
| 172 |   //  Organisation memoire
 | 
|---|
| 173 |   static short SelectMemoryMapping(short mm);
 | 
|---|
| 174 |   static short SelectVectorType(short vt);
 | 
|---|
| 175 |   void UpdateMemoryMapping(short mm);
 | 
|---|
| 176 |   void UpdateMemoryMapping(BaseArray const & a, short mm);
 | 
|---|
| 177 | 
 | 
|---|
| 178 |   // Pour Extraction de sous-tableau 
 | 
|---|
| 179 |   virtual void UpdateSubArraySizes(BaseArray & ra, int_4 ndim, sa_size_t * siz, sa_size_t * pos, sa_size_t * step) const;
 | 
|---|
| 180 | 
 | 
|---|
| 181 |   int_4  ndim_; //!< number of dimensions of array
 | 
|---|
| 182 |   sa_size_t size_[BASEARRAY_MAXNDIMS]; //!< array of the size in each dimension
 | 
|---|
| 183 |   sa_size_t totsize_; //!< Total number of elements
 | 
|---|
| 184 |   sa_size_t offset_;  //!< global offset -\> position of elem[0] in DataBlock
 | 
|---|
| 185 |   //! two consecutive elements distance in a given dimension 
 | 
|---|
| 186 |   sa_size_t step_[BASEARRAY_MAXNDIMS];
 | 
|---|
| 187 |   sa_size_t minstep_; //!< minimal step (in any axes)
 | 
|---|
| 188 |   sa_size_t moystep_; //!< mean step, if == 0 --\> non regular steps
 | 
|---|
| 189 |   int_2  marowi_; //!< For matrices, Row index in dimensions
 | 
|---|
| 190 |   int_2  macoli_; //!< For matrices, Column index in dimensions
 | 
|---|
| 191 |   int_2  veceli_; //!< For vectors, dimension index = marowi_/macoli_ (Row/Col vectors)
 | 
|---|
| 192 |   int_2 arrtype_; //!< 0 a TArray, 1 TMatrix , 2 TVector
 | 
|---|
| 193 |   DVList* mInfo;    //!< Infos (variables) attached to the array
 | 
|---|
| 194 | 
 | 
|---|
| 195 |   static char * ck_op_msg_[6]; //!< Operation messages for CheckDI() CheckBound()
 | 
|---|
| 196 |   static sa_size_t max_nprt_; //!< maximum number of printed elements
 | 
|---|
| 197 |   static int_4 prt_lev_;  //!< Print level
 | 
|---|
| 198 |   static short default_memory_mapping; //!< Default memory mapping
 | 
|---|
| 199 |   static short default_vector_type;    //!< Default vector type Row/Column
 | 
|---|
| 200 |   static sa_size_t openmp_size_threshold; //!< Size limit for parallel routine calls
 | 
|---|
| 201 | };
 | 
|---|
| 202 | 
 | 
|---|
| 203 | // --------------------------------------------------
 | 
|---|
| 204 | //        Methodes inline de verification
 | 
|---|
| 205 | // --------------------------------------------------
 | 
|---|
| 206 | //! to verify the compatibility of the dimension index
 | 
|---|
| 207 | inline int_4 BaseArray::CheckDI(int_4 ka, int msg)  const
 | 
|---|
| 208 | {
 | 
|---|
| 209 |   if ( (ka < 0) || (ka >= ndim_) ) {
 | 
|---|
| 210 |     string txt = "BaseArray::CheckDimensionIndex/Error ";   txt += ck_op_msg_[msg];
 | 
|---|
| 211 |     throw(RangeCheckError(txt));
 | 
|---|
| 212 |   }
 | 
|---|
| 213 |   return(ka);
 | 
|---|
| 214 | }
 | 
|---|
| 215 | 
 | 
|---|
| 216 | //! to verify the compatibility of the indexes in all dimensions
 | 
|---|
| 217 | inline void BaseArray::CheckBound(sa_size_t ix, sa_size_t iy, sa_size_t iz, sa_size_t it, sa_size_t iu, int msg)  const
 | 
|---|
| 218 | {
 | 
|---|
| 219 |   if ( (ix >= size_[0]) || (ix < 0) || (iy >= size_[1]) || (iy < 0) || 
 | 
|---|
| 220 |        (iz >= size_[2]) || (iz < 0) || (it >= size_[3]) || (it < 0) ||
 | 
|---|
| 221 |        (iu >= size_[4]) || (iu < 0) )  {
 | 
|---|
| 222 |     string txt = "BaseArray::CheckArrayBound/Error ";   txt += ck_op_msg_[msg];
 | 
|---|
| 223 |     throw(RangeCheckError(txt));
 | 
|---|
| 224 |   }
 | 
|---|
| 225 |   return;
 | 
|---|
| 226 | }
 | 
|---|
| 227 | 
 | 
|---|
| 228 | 
 | 
|---|
| 229 | 
 | 
|---|
| 230 | // --------------------------------------------------
 | 
|---|
| 231 | //        Position d'un element
 | 
|---|
| 232 | // --------------------------------------------------
 | 
|---|
| 233 | //! Offset of element (ix,iy,iz,it,iu)
 | 
|---|
| 234 | inline sa_size_t BaseArray::Offset(sa_size_t ix, sa_size_t iy, sa_size_t iz, sa_size_t it, sa_size_t iu) const
 | 
|---|
| 235 | {
 | 
|---|
| 236 | #ifdef SO_BOUNDCHECKING
 | 
|---|
| 237 |   CheckBound(ix, iy, iz, it, iu, 4);
 | 
|---|
| 238 | #endif
 | 
|---|
| 239 |   return ( offset_+  ix*step_[0] + iy*step_[1] + iz*step_[2] +
 | 
|---|
| 240 |               it*step_[3] + iu*step_[4] );
 | 
|---|
| 241 | }
 | 
|---|
| 242 | 
 | 
|---|
| 243 | 
 | 
|---|
| 244 | } // Fin du namespace
 | 
|---|
| 245 | 
 | 
|---|
| 246 | #endif
 | 
|---|