f6f8176d404bf4d7605a66ce040bd559b4d6d34b
[charm.git] / src / ck-core / ckarrayindex.h
1 #ifndef CKARRAYINDEX_H
2 #define CKARRAYINDEX_H
3
4 #include "pup.h"
5 #include "ckhashtable.h"
6 #include "charm.h"
7
8 /// Max number of integers in an array index
9 #ifndef CK_ARRAYINDEX_MAXLEN
10     #define CK_ARRAYINDEX_MAXLEN 3
11 #endif
12
13 #ifndef CK_ARRAYLISTENER_MAXLEN
14 # define CK_ARRAYLISTENER_MAXLEN 3
15 #endif
16
17 /** @warning: fwd declaration of child class to support crazy ptr cast
18  */
19 class CkArrayIndex;
20
21
22 /**
23  * Base class for array index objects used in charm.
24  *
25  * An array index is just a hash key; a run of integers
26  * used to look up an object in a hash table.
27  *
28  * @note: Should define *all* data members that make up an index object.
29  * @warning: Do not instantiate! Always create and use a child class
30  * @warning: Do not add constructors / destructors. Class participates in unions
31  *
32  * @note: Should be completely invisible to most client code except those that directly
33  * need to put index objects in unions. This happens only in a few entities in the charm
34  * codebase and should not happen at all in user codes.
35  */
36 struct CkArrayIndexBase
37 {
38     public:
39         ///Length of index in *integers*
40         short int nInts;
41         ///Number of dimensions in this index, not valid for user-defined indices
42         short int dimension;
43         /// The actual index data
44         union {
45             int index[CK_ARRAYINDEX_MAXLEN];
46             short int indexShorts[2 * CK_ARRAYINDEX_MAXLEN];
47         };
48
49         /// Obtain usable object from base object. @warning: Dangerous pointer cast to child class!!!
50         inline CkArrayIndex& asChild() const { return *(CkArrayIndex*)this; }
51
52         /// Permit serialization
53         void pup(PUP::er &p)
54         {
55             p|nInts;
56             p|dimension;
57             for (int i=0;i<nInts;i++) p|index[i];
58         }
59 };
60
61
62
63 /**
64  * Actual array index class intended for regular use
65  *
66  * @warning: Put all data members in base class or they may not be transmitted
67  * in envelopes or callbacks (basically in any entity that stores indices in a
68  * union). Only add behaviors to this class.
69  */
70 class CkArrayIndex: public CkArrayIndexBase
71 {
72     public:
73         /// Default
74         CkArrayIndex() { nInts=0; dimension=0; for (int i=0; i<CK_ARRAYINDEX_MAXLEN; i++) index[i] = 0; }
75
76         CkArrayIndex(int idx) {init(1,1,idx);};
77
78         /// Return a pointer to the actual index data
79         int *data(void)             {return index; }
80         /// Return a const pointer to the actual index data
81         const int *data(void) const {return index; }
82
83         /// Return the total number of elements (assuming a dense chare array)
84         int getCombinedCount(void) const
85         {
86             if      (dimension == 1) return data()[0];
87             else if (dimension == 2) return data()[0] * data()[1];
88             else if (dimension == 3) return data()[0] * data()[1] * data()[2];
89             else return 0;
90         }
91
92         /// Used for debug prints elsewhere
93         void print() { CmiPrintf("%d: %d %d %d\n", nInts, index[0], index[1], index[2]); }
94
95         /// Equality comparison
96         CmiBool operator==(const CkArrayIndex& idx) const
97         {
98             if (nInts != idx.nInts) return CmiFalse;
99             for (int i=0; i<nInts; i++)
100                 if (index[i] != idx.index[i]) return CmiFalse;
101             return CmiTrue;
102         }
103
104         /// These routines allow CkArrayIndex to be used in a CkHashtableT
105         inline CkHashCode hash(void) const
106         {
107             register int i;
108             register const int *d=data();
109             register CkHashCode ret=d[0];
110             for (i=1;i<nInts;i++)
111                 ret +=circleShift(d[i],10+11*i)+circleShift(d[i],9+7*i);
112             return ret;
113         }
114         ///
115         static CkHashCode staticHash(const void *a,size_t) { return ((const CkArrayIndex *)a)->hash(); }
116         ///
117         inline int compare(const CkArrayIndex &idx) const { return (idx == *this); }
118         ///
119         static int staticCompare(const void *a,const void *b, size_t)
120         { return (*(const CkArrayIndex *)a == *(const CkArrayIndex *)b); }
121
122         /**
123          * @note: input arrayID is ignored
124          * @todo: Chee Wai Lee had a FIXME note attached to this method because he
125          * felt it was a temporary solution
126          */
127         CmiObjId *getProjectionID(int arrayID)
128         {
129             CmiObjId *ret = new CmiObjId;
130             int i;
131             const int *data=this->data();
132             if (OBJ_ID_SZ>=this->nInts)
133             {
134                 for (i=0;i<this->nInts;i++)
135                     ret->id[i]=data[i];
136                 for (i=this->nInts;i<OBJ_ID_SZ;i++)
137                     ret->id[i]=0;
138             }
139             else
140             {
141                 //Must hash array index into LBObjid
142                 int j;
143                 for (j=0;j<OBJ_ID_SZ;j++)
144                     ret->id[j]=data[j];
145                 for (i=0;i<this->nInts;i++)
146                     for (j=0;j<OBJ_ID_SZ;j++)
147                         ret->id[j]+=circleShift(data[i],22+11*i*(j+1))+
148                             circleShift(data[i],21-9*i*(j+1));
149             }
150             return ret;
151         }
152
153     protected:
154         inline void init(const short num, const short dims, const int x, const int y=0, const int z=0)
155         {
156             nInts = num;
157             dimension = dims;
158             index[0] = x;
159             index[1] = y;
160             index[2] = z;
161             for (int i=3; i < CK_ARRAYINDEX_MAXLEN; i++)
162                 index[i] = 0;
163         }
164
165         inline void init(const short num, const short dims,
166                          const short u, const short v, const short w,
167                          const short x, const short y=0, const short z=0)
168         {
169             nInts = num;
170             dimension = dims;
171             indexShorts[0] = u;
172             indexShorts[1] = v;
173             indexShorts[2] = w;
174             indexShorts[3] = x;
175             indexShorts[4] = y;
176             indexShorts[5] = z;
177             for (int i=6; i < 2 * CK_ARRAYINDEX_MAXLEN; i++)
178                 indexShorts[i] = 0;
179         }
180 };
181
182
183 /**
184  * Support applications and other charm codes that still use the (now dead)
185  * CkArrayIndexMax class to manipulate array indices. All the functionality is
186  * now incorporated into the CkArrayIndex base class itself.
187  *
188  * It is recommended that newer code directly use the base class when there is
189  * need to handle an array index.
190  *
191  * @todo: After at least one minor release announcing the deprecation,
192  * CkArrayIndexMax should no longer be supported.
193  */
194 typedef CkArrayIndex CkArrayIndexMax;
195
196 class CkArray;
197
198 class CkArrayID {
199         CkGroupID _gid;
200 public:
201         CkArrayID() : _gid() { }
202         CkArrayID(CkGroupID g) :_gid(g) {}
203         inline void setZero(void) {_gid.setZero();}
204         inline int isZero(void) const {return _gid.isZero();}
205         operator CkGroupID() const {return _gid;}
206         CkArray *ckLocalBranch(void) const
207                 { return (CkArray *)CkLocalBranch(_gid); }
208         static CkArray *CkLocalBranch(CkArrayID id)
209                 { return (CkArray *)::CkLocalBranch(id); }
210         void pup(PUP::er &p) {p | _gid; }
211         int operator == (const CkArrayID& other) const {
212                 return (_gid == other._gid);
213         }
214     friend bool operator< (const CkArrayID &lhs, const CkArrayID &rhs) {
215         return (lhs._gid < rhs._gid);
216     }
217 };
218 PUPmarshall(CkArrayID)
219
220 #endif // CKARRAYINDEX_H
221