fixed invalid write bug in freeCachedData
authorPritish Jetley <pjetley2@illinois.edu>
Mon, 17 Oct 2011 03:32:45 +0000 (22:32 -0500)
committerPritish Jetley <pjetley2@illinois.edu>
Mon, 17 Oct 2011 03:32:45 +0000 (22:32 -0500)
DataManager.cpp
DataManager.h
Messages.h
Node.h
Request.h
TreePiece.cpp
Worker.h
barnes.ci

index dc00176..64fec1a 100644 (file)
@@ -39,8 +39,6 @@ DataManager::DataManager() :
   numLocalTreePieces(-1),
   doneTreeBuild(false),
   treeMomentsReady(false),
-  recvdAllUniqueNodes(false),
-  numUniqueNodeMsgsRecvd(0),
   numTreePiecesDoneTraversals(0),
   prevIterationStart(0.0)
 {
@@ -618,7 +616,6 @@ void DataManager::makeMoments(){
 
   MomentsWorker mw(submittedParticles,
                    nodeTable,
-                   uniqueNodes,
                    myBuckets
                    );
   fillTrav.postorderTraversal(root,&mw);
@@ -697,120 +694,7 @@ void DataManager::receiveMoments(MomentsMsg *msg){
   delete msg;
 }
 
-void DataManager::exchangeUniqueNodes(){
-  int num = uniqueNodes.length();
-  MomentsExchangeMsg *msg = new (num,0) MomentsExchangeMsg;
-  for(int i = 0; i < num; i++){
-    Node<ForceData> *node = uniqueNodes[i];
-    msg->data[i] = *node;
-  }
-  msg->numNodes = num;
-  msg->fromPE = CkMyPe();
-  // XXX make allgather/all-to-all bcast more efficient
-  thisProxy.recvUniqueNodes(msg);
-}
-
-void DataManager::recvUniqueNodes(MomentsExchangeMsg *msg){
-  if(!doneTreeBuild){
-    uniqueNodeMsgs.push_back(msg); 
-    return;
-  }
-
-  extendTree(msg);
-  numUniqueNodeMsgsRecvd++;
-  afterMomentsUpdated();
-}
-
-void DataManager::processMomentUpdates(){
-  CkAssert(doneTreeBuild);
-  for(int i = 0; i < uniqueNodeMsgs.length(); i++){
-    MomentsExchangeMsg *msg = uniqueNodeMsgs[i];
-    extendTree(msg);
-  }
-  numUniqueNodeMsgsRecvd += uniqueNodeMsgs.length();
-  afterMomentsUpdated();
-}
-
-void DataManager::extendTree(MomentsExchangeMsg *msg){
-  if(msg->fromPE != CkMyPe()){
-    for(int i = 0; i < msg->numNodes; i++){
-      MomentsExchangeStruct &data = msg->data[i];
-      
-      CkAssert(data.key > Key(0));
-
-      Node<ForceData> *node = lookupNode(data.key);
-      if(node == NULL){
-        node = createNode(data.key);
-        CkAssert(data.type != Boundary);
-        if(data.type == Internal) node->setType(Remote);
-        else if(data.type == Bucket) node->setType(RemoteBucket);
-        else if(data.type == EmptyBucket) node->setType(RemoteEmptyBucket);
-      }
-      updateLeafMoments(node,data);
-    }
-  }
-  delete msg;
-}
-
-Node<ForceData> *DataManager::createNode(Key k){
-  Key curKey = Key(1);
-  int curDepth = 0;
-
-  if(root == NULL){
-    root = new Node<ForceData>(curKey,curDepth,NULL,0);
-    root->setType(Remote);
-    nodeTable[curKey] = root;
-  }
-
-  Node<ForceData> *curNode = root;
-
-  int kDepth = Node<ForceData>::getDepthFromKey(k);
-  Key mask = Key((1<<LOG_BRANCH_FACTOR)-1);
-  int nshift = ((kDepth-1)*LOG_BRANCH_FACTOR);
-  mask <<= nshift;
-
-  while(curKey != k){
-    CkAssert(curDepth >= 0);
-    CkAssert(curDepth < ((TREE_KEY_BITS-1)/LOG_BRANCH_FACTOR));
-
-    if(curNode->getNumChildren() == 0){
-      // need to create children of current node
-      Node<ForceData> *child = new Node<ForceData>[BRANCH_FACTOR];
-      curNode->setChildren(child,BRANCH_FACTOR);
-
-      int childDepth = curDepth+1;
-      Key childKey = (curKey << LOG_BRANCH_FACTOR);
-      for(int i = 0; i < BRANCH_FACTOR; i++){
-        child->setKey(childKey);
-        child->setDepth(childDepth);
-        child->setParent(curNode);
-        child->setType(Remote);
-
-        nodeTable[childKey] = child;
-        childKey++;
-        child++;
-      }
-    }
-
-    // the children of this node (now) exist
-    // they were created either during initial tree building
-    // or by the code above
-
-    int whichChild = ((k & mask)>>nshift);
-    nshift -= LOG_BRANCH_FACTOR;
-    mask >>= LOG_BRANCH_FACTOR;
-    curNode = curNode->getChild(whichChild);
-    curKey = ((curKey<<LOG_BRANCH_FACTOR)+whichChild);
-    
-    curDepth++;
-
-  }
-
-  return curNode;
-}
-
 void DataManager::updateLeafMoments(Node<ForceData> *node, MomentsExchangeStruct &data){
-  //node->data.moments = moments;
   copyMomentsToNode(node,data);
   TB_DEBUG("(%d) updateLeafMoments %lu\n", CkMyPe(), node->getKey());
   passMomentsUpward(node);
@@ -840,17 +724,6 @@ void DataManager::passMomentsUpward(Node<ForceData> *node){
   }
 }
 
-void DataManager::afterMomentsUpdated(){
-  if(numUniqueNodeMsgsRecvd == CkNumPes()){
-    numUniqueNodeMsgsRecvd = 0;
-    uniqueNodeMsgs.length() = 0;
-    recvdAllUniqueNodes = true;
-    if(treeMomentsReady){
-      startTraversal();
-    }
-  }
-}
-
 // doneTreeBuild: built local tree and sent out requests for remote 
 
 void DataManager::treeReady(){
@@ -923,6 +796,9 @@ void DataManager::requestParticles(Node<ForceData> *leaf, CutoffWorker<ForceData
   if(!request.sent){
     partReqs.incrRequests();
 
+    if(leaf->isCached()) request.parentCached = true;
+    else request.parentCached = false;
+
     RequestMsg *reqMsg = new (NUM_PRIORITY_BITS) RequestMsg(key,CkMyPe());
     *(int *)CkPriorityPtr(reqMsg) = REQUEST_PARTICLES_PRIORITY;
     CkSetQueueing(reqMsg,CK_QUEUEING_IFIFO);
@@ -980,6 +856,9 @@ void DataManager::requestNode(Node<ForceData> *leaf, CutoffWorker<ForceData> *wo
   if(!request.sent){
     nodeReqs.incrRequests();
 
+    if(leaf->isCached()) request.parentCached = true;
+    else request.parentCached = false;
+
     RequestMsg *reqMsg = new (NUM_PRIORITY_BITS) RequestMsg(key,CkMyPe());
     *(int *)CkPriorityPtr(reqMsg) = REQUEST_NODE_PRIORITY;
     CkSetQueueing(reqMsg,CK_QUEUEING_IFIFO);
@@ -1178,9 +1057,6 @@ void DataManager::advance(CkReductionMsg *msg){
   haveRanges = false;
   myBuckets.length() = 0;
   doneTreeBuild = false;
-  numUniqueNodeMsgsRecvd = 0;
-  uniqueNodes.length() = 0;
-  recvdAllUniqueNodes = false;
   treeMomentsReady = false;
   numTreePiecesDoneTraversals = 0;
 
@@ -1214,31 +1090,42 @@ void DataManager::recvUnivBoundingBox(CkReductionMsg *msg){
 
 void DataManager::freeCachedData(){
   map<Key,Request>::iterator it;
-  for(it = nodeRequestTable.begin(); it != nodeRequestTable.end(); it++){
+
+  for(it = particleRequestTable.begin(); it != particleRequestTable.end(); it++){
     Request &request = it->second;
     CkAssert(request.sent);
     CkAssert(request.data != NULL);
     CkAssert(request.requestors.length() == 0);
     CkAssert(request.msg != NULL);
+    
+    // no need to set the particles of a cached
+    // bucket to NULL: we will delete the bucket
+    // anyway
+    if(!request.parentCached){
+      request.parent->setParticles(NULL,0);
+    }
 
-    // tell the root of the nodes in this 
-    // fetched entry that its children don't
-    // exist anymore
-    request.parent->setChildren(NULL,0);
-
-    delete (NodeReplyMsg *)(request.msg);
+    delete (ParticleReplyMsg *)(request.msg);
   }
 
-  for(it = particleRequestTable.begin(); it != particleRequestTable.end(); it++){
+  for(it = nodeRequestTable.begin(); it != nodeRequestTable.end(); it++){
     Request &request = it->second;
     CkAssert(request.sent);
     CkAssert(request.data != NULL);
     CkAssert(request.requestors.length() == 0);
     CkAssert(request.msg != NULL);
 
-    request.parent->setParticles(NULL,0);
+    // tell the root of the nodes in this 
+    // fetched entry that its children don't
+    // exist anymore
+    // cached parents may be deleted before
+    // their children, so we don't set their
+    // children
+    if(!request.parentCached){
+      request.parent->setChildren(NULL,0);
+    }
 
-    delete (ParticleReplyMsg *)(request.msg);
+    delete (NodeReplyMsg *)(request.msg);
   }
 
   nodeRequestTable.clear();
@@ -1259,9 +1146,9 @@ void DataManager::quiescence(){
 }
 
 void DataManager::freeTree(){
-  FreeTreeWorker<ForceData> freeWorker;
-  fillTrav.postorderTraversal(root,&freeWorker); 
   if(root != NULL){
+    FreeTreeWorker<ForceData> freeWorker;
+    fillTrav.postorderTraversal(root,&freeWorker); 
     delete root;
     root = NULL;
   }
@@ -1283,14 +1170,6 @@ void DataManager::printTree(){
   ofs.close();
 }
 
-void DataManager::printBoundingBoxes(){
-  ostringstream oss;
-  oss << "bb.pe" << CkMyPe() << ".dat";
-  ofstream ofs(oss.str().c_str());
-  root->printBoundingBox(ofs);
-  ofs.close();
-}
-
 void DataManager::addBucketNodeInteractions(Key k, CmiUInt8 pn){
 #ifdef CHECK_NUM_INTERACTIONS
   Node<ForceData> *node = nodeTable[k];
@@ -1347,14 +1226,6 @@ void DataManager::kickDriftKick(OrientedBox<Real> &box, Real &energy){
   savedEnergy /= 2.0;
 }
 
-void DataManager::resetParticleAccelerations(){
-  for(int i = 0; i < myNumParticles; i++){
-    myParticles[i].acceleration.x = 0.0;
-    myParticles[i].acceleration.y = 0.0;
-    myParticles[i].acceleration.z = 0.0;
-  }
-}
-
 void DataManager::findMinVByA(DtReductionStruct &dtred){
   if(myNumParticles == 0) {
     dtred.haveNaN = false;
index 0aa9ac7..6973a20 100644 (file)
@@ -95,14 +95,9 @@ class DataManager : public CBase_DataManager {
   bool doneTreeBuild;
   //CkVec<RequestedMomentsDescriptor> requestedMoments;
   map<Key,Node<ForceData>*> nodeTable;
-  CkVec<Node<ForceData>*> uniqueNodes;
 
   map<Key,CkVec<int> > pendingMoments;
 
-  CkVec<MomentsExchangeMsg *> uniqueNodeMsgs;
-  int numUniqueNodeMsgsRecvd;
-  // I have recvd all unique nodes 
-  bool recvdAllUniqueNodes;
   // I have processed the moment 
   // contributions from all other PEs, so that
   // the tree on this PE is now ready for 
@@ -135,10 +130,8 @@ class DataManager : public CBase_DataManager {
   
   void senseTreePieces();
   void buildTree();
-  //void mergeTreePieces();
 
   void printTree();
-  void printBoundingBoxes();
   void flushParticles();
 
   void processSubmittedParticles();
@@ -147,13 +140,8 @@ class DataManager : public CBase_DataManager {
   void respondToMomentsRequest(Node<ForceData> *,CkVec<int>&);
   Node<ForceData> *lookupNode(Key k);
 
-  void exchangeUniqueNodes();
-  void processMomentUpdates();
-  void extendTree(MomentsExchangeMsg *msg);
-  Node<ForceData> *createNode(Key k);
   void updateLeafMoments(Node<ForceData> *node, MomentsExchangeStruct &data);
   void passMomentsUpward(Node<ForceData> *node);
-  void afterMomentsUpdated();
   void treeReady();
 
   void startTraversal();
@@ -163,7 +151,6 @@ class DataManager : public CBase_DataManager {
   void freeTree();
   void finishIteration();
 
-  void resetParticleAccelerations();
   void findMinVByA(DtReductionStruct &);
 
   void markNaNBuckets();
@@ -180,8 +167,6 @@ class DataManager : public CBase_DataManager {
   void sendParticlesToTreePiece(Node<NodeDescriptor> *nd, int tp);
 
   void receiveMoments(MomentsMsg *msg);
-  void recvUniqueNodes(MomentsExchangeMsg *msg);
-  
   
   // called by tree pieces
   void submitParticles(CkVec<ParticleMsg *> *vec, int numParticles, TreePiece *tp, Key smallestKey, Key largestKey); 
@@ -211,8 +196,6 @@ class DataManager : public CBase_DataManager {
 
   void addBucketNodeInteractions(Key k, CmiUInt8 pn);
   void addBucketPartInteractions(Key k, CmiUInt8 pp);
-
-  int getIteration() const {return iteration;}
 };
 
 #endif
index 9f51be8..38d826c 100644 (file)
@@ -20,14 +20,6 @@ struct RangeMsg : public CMessage_RangeMsg {
   int numTreePieces;
 };
 
-struct MomentsExchangeStruct;
-struct MomentsExchangeMsg : public CMessage_MomentsExchangeMsg {
-  MomentsExchangeStruct *data;
-
-  int numNodes;
-  int fromPE;
-};
-
 struct RequestMsg : public CMessage_RequestMsg {
   Key key;
   int replyTo;
@@ -50,6 +42,7 @@ struct NodeReplyMsg : public CMessage_NodeReplyMsg {
   int nn;
 };
 
+struct MomentsExchangeStruct;
 struct MomentsMsg : public CMessage_MomentsMsg {
   MomentsExchangeStruct data;
 
diff --git a/Node.h b/Node.h
index 314eb9d..80373bb 100644 (file)
--- a/Node.h
+++ b/Node.h
@@ -39,6 +39,8 @@ struct NodeCore {
   int ownerStart;
   int ownerEnd;
 
+  bool cached;
+
   NodeCore(){
     particleStart = NULL;
     numParticles = 0;
@@ -47,13 +49,14 @@ struct NodeCore {
     depth = -1;
     ownerStart = -1;
     ownerEnd = -1;
+    cached = false;
   }
 
   NodeCore(Key k, int d, Particle *p, int np) : 
     key(k), depth(d), 
     particleStart(p), numParticles(np),
     type(Invalid), numChildren(0),
-    ownerStart(-1), ownerEnd(-1)
+    ownerStart(-1), ownerEnd(-1), cached(false)
   {
   }
 };
@@ -319,11 +322,15 @@ class Node {
 
       buf->setParticles(NULL,0);
       buf->setType(makeRemote(buf->getType()));
+      buf->setCached();
 
       buf++;
     }
   }
 
+  void setCached(){ core.cached = true; }
+  bool isCached(){ return core.cached; }
+
   static NodeType makeRemote(NodeType type){
     switch(type){
       case Boundary : 
index 5967e7b..8935af9 100644 (file)
--- a/Request.h
+++ b/Request.h
@@ -36,6 +36,7 @@ struct Request {
   void *msg;
 
   Node<ForceData> *parent; 
+  bool parentCached;
 
   Request() : 
     data(NULL),
index a537028..e82ff52 100644 (file)
@@ -25,7 +25,7 @@ TreePiece::TreePiece() :
   numTraversalsDone(0)
 {
   myDM = dataManagerProxy.ckLocalBranch();
-  usesAtSync = true;
+  //usesAtSync = true;
 }
 
 void TreePiece::receiveParticles(ParticleMsg *msg){
index 12b4d5e..ff389c2 100644 (file)
--- a/Worker.h
+++ b/Worker.h
@@ -48,7 +48,6 @@ class MomentsWorker : public CutoffWorker<ForceData> {
   // useful treepieces+1
   CkVec<TreePieceDescriptor> &peTreePieces;
   map<Key,Node<ForceData>*> &nodeTable;
-  CkVec<Node<ForceData>*> &contributions;
   CkVec<Node<ForceData>*> &buckets;
 
   int curTP;
@@ -56,12 +55,10 @@ class MomentsWorker : public CutoffWorker<ForceData> {
   public: 
   MomentsWorker(CkVec<TreePieceDescriptor> &petps,
                 map<Key,Node<ForceData>*> &tab,
-                CkVec<Node<ForceData>*> &cont,
                 CkVec<Node<ForceData>*> &bucks
                 ) : 
     peTreePieces(petps),
     nodeTable(tab),
-    contributions(cont),
     buckets(bucks),
     curTP(0)
   {
index 42ae91e..92d696e 100644 (file)
--- a/barnes.ci
+++ b/barnes.ci
@@ -22,10 +22,6 @@ mainmodule barnes {
     Key keys[];
   };
 
-  message MomentsExchangeMsg {
-    MomentsExchangeStruct data[];
-  };
-
   message RequestMsg;
   message ParticleReplyMsg {
     ExternalParticle data[];
@@ -71,7 +67,6 @@ mainmodule barnes {
     entry void receiveSplitters(SplitterMsg *msg);
     entry void sendParticles(RangeMsg *msg);
     entry void receiveMoments(MomentsMsg *msg);
-    entry void recvUniqueNodes(MomentsExchangeMsg *msg);
 
     entry void recvParticles(ParticleReplyMsg *msg);
     entry void recvNode(NodeReplyMsg *msg);