array index: Introduce a union-friendly base class for ckarrayindex
authorRamprasad Venkataraman <ramv@illinois.edu>
Thu, 2 Jun 2011 22:05:37 +0000 (17:05 -0500)
committerRamprasad Venkataraman <ramv@illinois.edu>
Wed, 8 Jun 2011 15:37:42 +0000 (10:37 -0500)
There are only three entities in the charm codebase that put an array
index within a union:
    - envelope
    - callbacks
    - ckobjid

Create a base class that is used just by these three entities. CkArrayIndex is
now a safe and usable index class as it sports constructors, initialization
etc.  The remainder of the codebase and charm applications can and should use
the CkArrayIndex class.

Just at locations where the index objects in unions are handled, we provide a
somewhat "risky" cast operation from base to derived. This should be less
insane than casting across unrelated classes, which was the root of the
perennial problems with the original CkArrayIndex, IndexMax and IndexStruct
setup. However, we should actively explore mechanisms whereby even such casts
can be avoided without too much time/space costs.

src/ck-core/charm++.h
src/ck-core/ckarray.h
src/ck-core/ckcallback.C
src/ck-core/ckcallback.h
src/ck-core/ckobjid.h
src/ck-core/envelope.h

index ec3c2ccfcc6439f9262532c8c649ec06d72b0c4a..f2c138a4bc326afadc40be0b5368c385b21fe68e 100644 (file)
@@ -213,10 +213,15 @@ a run of integers used to look up an object in a hash table.
 /**
  * Base class for array index objects used in charm.
  *
+ * Should define *all* data members that make up an index object.
  * @warning: Do not instantiate! Always create and use a child class
  * @warning: Do not add constructors / destructors. Class participates in unions
+ *
+ * @note: Should be completely invisible to most client code except those that directly
+ * need to put index objects in unions. This happens only in a few entities in the charm
+ * codebase and should not happen at all in user codes.
  */
-class CkArrayIndex
+struct CkArrayIndexBase
 {
     public:
         ///Length of index in *integers*
@@ -229,10 +234,32 @@ class CkArrayIndex
             short int indexShorts[2 * CK_ARRAYINDEX_MAXLEN];
         };
 
+        /// Obtain usable object from base object. @warning: Dangerous pointer cast to child class!!!
+        inline CkArrayIndex& asChild() const { return *(CkArrayIndex*)this; }
+
+        /// Permit serialization
+        void pup(PUP::er &p)
+        {
+            p|nInts;
+            p|dimension;
+            for (int i=0;i<nInts;i++) p|index[i];
+        }
+};
+
 
-        /// Performs initialization. All child classes should call this in their constructors first
-        inline void init(void)  { nInts=0; dimension=0; for (int i=0; i<CK_ARRAYINDEX_MAXLEN; i++) index[i] = 0; }
 
+/**
+ * Actual array index class intended for regular use
+ *
+ * @warning: Put all data members in base class or they may not be transmitted
+ * in envelopes or callbacks (basically in any entity that stores indices in a
+ * union). Only add behaviors to this class.
+ */
+class CkArrayIndex: public CkArrayIndexBase
+{
+    public:
+        ///
+        CkArrayIndex() { nInts=0; dimension=0; for (int i=0; i<CK_ARRAYINDEX_MAXLEN; i++) index[i] = 0; }
         /// Return a pointer to the actual index data
         int *data(void)             {return index; }
         /// Return a const pointer to the actual index data
@@ -247,14 +274,6 @@ class CkArrayIndex
             else return 0;
         }
 
-        /// pup method for the index
-        void pup(PUP::er &p)
-        {
-            p|nInts;
-            p|dimension;
-            for (int i=0;i<nInts;i++) p|index[i];
-        }
-
         /// Used for debug prints elsewhere
         void print() { CmiPrintf("%d: %d %d %d\n", nInts, index[0], index[1], index[2]); }
 
index 2b81732e31f3a2dabf06248919d699360dabdf15..09f5d7977b787872e027d837d0f1a241c9c2566c 100644 (file)
@@ -76,7 +76,7 @@ inline void operator|(PUP::er &p,CkIndexMax &i) {
 /// Simple ArrayIndex classes: the key is just integer indices.
 class CkArrayIndex1D : public CkArrayIndex {
 public:
-       CkArrayIndex1D() { init(); nInts=1; dimension=1; }
+       CkArrayIndex1D() { nInts=1; dimension=1; }
        // CkIndex1D is an int, so that conversion is automatic
        CkArrayIndex1D(int i0) {
                index[0]=i0;nInts=1;dimension=1;
@@ -84,7 +84,7 @@ public:
 };
 class CkArrayIndex2D : public CkArrayIndex {
 public:
-       CkArrayIndex2D() { init(); nInts=2; dimension=2; }
+       CkArrayIndex2D() { nInts=2; dimension=2; }
        CkArrayIndex2D(int i0,int i1) {
                index[0]=i0;index[1]=i1;nInts=2;dimension=2;
        }
@@ -94,7 +94,7 @@ public:
 };
 class CkArrayIndex3D : public CkArrayIndex {
 public:
-       CkArrayIndex3D() { init(); nInts=3; dimension=3; }
+       CkArrayIndex3D() { nInts=3; dimension=3; }
        CkArrayIndex3D(int i0,int i1,int i2) {
                index[0]=i0;index[1]=i1;index[2]=i2;nInts=3;dimension=3;
        }
@@ -104,7 +104,7 @@ public:
 };
 class CkArrayIndex4D : public CkArrayIndex {
 public:
-       CkArrayIndex4D(){ init(); nInts=2; dimension=4; }
+       CkArrayIndex4D(){ nInts=2; dimension=4; }
        CkArrayIndex4D(short int i0,short int i1,short int i2,short int i3) {
                indexShorts[0]=i0;indexShorts[1]=i1;indexShorts[2]=i2;indexShorts[3]=i3;nInts=2;dimension=4;
        }
@@ -118,7 +118,7 @@ public:
 };
 class CkArrayIndex5D : public CkArrayIndex {
 public:
-       CkArrayIndex5D(){ init(); nInts=3; dimension=5; }
+       CkArrayIndex5D(){ nInts=3; dimension=5; }
        CkArrayIndex5D(short int i0,short int i1,short int i2,short int i3,short int i4) {
                indexShorts[0]=i0;indexShorts[1]=i1;indexShorts[2]=i2;indexShorts[3]=i3;indexShorts[4]=i4;nInts=3;dimension=5;
         }
@@ -133,7 +133,7 @@ public:
 };
 class CkArrayIndex6D : public CkArrayIndex {
 public:
-       CkArrayIndex6D(){ init(); nInts=3; dimension=6; }
+       CkArrayIndex6D(){ nInts=3; dimension=6; }
        CkArrayIndex6D(short int i0,short int i1,short int i2,short int i3,short int i4,short int i5) {
                indexShorts[0]=i0;indexShorts[1]=i1;indexShorts[2]=i2;indexShorts[3]=i3;indexShorts[4]=i4;indexShorts[5]=i5;nInts=3;dimension=6;
        }
index 107e4609b83887471eb4ab00b1422574cd0ec5f4..fa41dcc5e95a3a83d999142b3c62841ae0c44dfa 100644 (file)
@@ -219,11 +219,11 @@ void CkCallback::send(void *msg) const
                break;
        case sendArray: //Send message to an array element
                if (!msg) msg=CkAllocSysMsg();
-               CkSendMsgArray(d.array.ep,msg,d.array.id,d.array.idx);
+               CkSendMsgArray(d.array.ep,msg,d.array.id,d.array.idx.asChild());
                break;
        case isendArray: //inline send-to-array element
                if (!msg) msg=CkAllocSysMsg();
-               CkSendMsgArrayInline(d.array.ep,msg,d.array.id,d.array.idx);
+               CkSendMsgArrayInline(d.array.ep,msg,d.array.id,d.array.idx.asChild());
                break;
        case bcastGroup:
                if (!msg) msg=CkAllocSysMsg();
index 5878b802e1b018aed80ea85ad885fb7808814ca1..d2d8f39f3650b9d0a0600dffaae7448c2ccb6ffb 100644 (file)
@@ -77,7 +77,7 @@ private:
        struct s_array { //(sendArray, bcastArray)
                int ep; //Entry point to call
                CkGroupID id; //Array ID to call it on
-               CkArrayIndex idx; //Index to send to (if any)
+               CkArrayIndexBase idx; //Index to send to (if any)
        } array;
        struct s_ccsReply {
                CcsDelayedReply reply;
index 8987fddf231f41908ce89959ba624ab217a70097..895fede063ab9a4b80b157c7f1cd2ad730a35b1c 100644 (file)
@@ -11,7 +11,7 @@ union _ObjectID {
        } group; //also used for NodeGroups
        struct s_array{
                CkGroupID id; //array id
-               CkArrayIndex idx; //index
+               CkArrayIndexBase idx; //index
        } array;
 };
 
@@ -39,7 +39,7 @@ public:
                    ret += circleShift(data.group.id.idx,6);
                    break;
                case TypeArray:
-                   CkHashCode temp = data.array.idx.hash();
+                   CkHashCode temp = data.array.idx.asChild().hash();
                    //ret = circleShift(ret,13);
                    //ret += circleShift(temp,11);
                    ret += temp;
@@ -71,7 +71,7 @@ public:
                                break;
                        case TypeArray:
                                bool val;
-                               if(data.array.id == t.data.array.id && data.array.idx.compare(t.data.array.idx)){
+                               if(data.array.id == t.data.array.id && data.array.idx.asChild().compare(t.data.array.idx.asChild())){
                                        val = true;
                                }else{
                                        val = false;
index aab6c6862f93617b31d335a16d06c675da5fd1d9..c36f34486e90c3276492d188c579d4eb387afd61 100644 (file)
@@ -158,7 +158,7 @@ public:
         UShort arrayEp;        ///< Used only for array broadcasts
       } group;
       struct s_array{             ///< For arrays only (ArrayEltInitMsg, ForArrayEltMsg)
-        CkArrayIndex index; ///< Array element index
+        CkArrayIndexBase index; ///< Array element index
         int listenerData[CK_ARRAYLISTENER_MAXLEN]; ///< For creation
         CkGroupID arr;            ///< Array manager GID
         UChar hopCount;           ///< number of times message has been routed