00001 #include "charm++.h" 00002 00003 /* 00004 A (partial) array that "boomerangs" back to its original source. 00005 On the original PE, the array data is used in-place. 00006 On non-original PEs, the array data is dynamically allocated. 00007 */ 00008 template <typename T> 00009 class Boomarray : public CkConditional { 00010 public: 00011 /* Constructor used on *original* data. 00012 This class will keep a persistent pointer to this data, 00013 and use this data as storage whenever possible. 00014 Beware! This will crash if src migrates, checkpoints, etc! 00015 */ 00016 Boomarray(int count_, T *src_) 00017 :count(count_), ptr(src_), 00018 srcnode(CkMyNode()), srcptr(src_) { 00019 DebugPrintf("Boomarray constr\n"); 00020 } 00021 00022 /* Constructor used on *target* PE (migration) */ 00023 Boomarray() { 00024 DebugPrintf("Boomarray migration\n"); 00025 } 00026 00027 /* Destructor (frees memory on client) */ 00028 ~Boomarray() { DebugPrintf("~Boomarray\n"); if (ptr!=srcptr) free(ptr);} 00029 00030 /* Access the array */ 00031 double& operator[](int index) {return ptr[index];} 00032 00033 void pup(PUP::er &p) { 00034 DebugPrintf1("Boomarray::pup %s\n",p.isPacking()?"packing":(p.isSizing()?"sizing":"unpacking")); 00035 /* Move our housekeeping metadata */ 00036 p|count; 00037 p|srcnode; 00038 p|*(long *)&srcptr; /* pack as a long */ 00039 if (p.isUnpacking()) 00040 { /* gotta set up ptr */ 00041 if (CmiMyNode()==srcnode) /* back to same old processor */ 00042 ptr=srcptr; 00043 else /* living on a new processor */ 00044 ptr=(T *)malloc(count*sizeof(T)); 00045 } 00046 /* Move the underlying network data */ 00047 p(ptr,count); 00048 } 00049 00050 int size() { return count; } 00051 00052 private: 00053 /* Length of data (doubles) */ 00054 int count; 00055 /* Data to store (if not on original PE) */ 00056 T *ptr; 00057 00058 /* processor where the data originated */ 00059 int srcnode; 00060 /* pointer on original PE where data returns to */ 00061 T *srcptr; 00062 }; 00063