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