diff --git a/src/libs/ck-libs/collide/collide_util.C b/src/libs/ck-libs/collide/collide_util.C index 3148fdbf5c..5a533f3a59 100644 --- a/src/libs/ck-libs/collide/collide_util.C +++ b/src/libs/ck-libs/collide/collide_util.C @@ -49,7 +49,7 @@ void CollideGrid3d::init(const vector3d &Norigin,//Grid voxel corner 0,0,0 sizes[i]=desiredSize[i]; #endif ((double *)scales)[i]=1.0/((double *)sizes)[i]; - testMapping(*this,i,((double *)origin)[i],((double *)sizes)[i]); + //testMapping(*this,i,((double *)origin)[i],((double *)sizes)[i]); } } diff --git a/src/libs/ck-libs/collide/collidecharm.C b/src/libs/ck-libs/collide/collidecharm.C index 68b4440579..b6e928548d 100644 --- a/src/libs/ck-libs/collide/collidecharm.C +++ b/src/libs/ck-libs/collide/collidecharm.C @@ -4,6 +4,7 @@ */ #include "charm++.h" #include "collidecharm_impl.h" +#include #define COLLIDE_TRACE 0 #if COLLIDE_TRACE @@ -51,6 +52,17 @@ CkGroupID CollideDistributedClient(CkCallback clientCb) return cl; } +/// Call this on all processors at restart to reinitialize the Collision client +/// with correct clientFn and clientParam. +void CollideSerialClientRestart( + CollideHandle h, + CollisionClientFn clientFn, + void *clientParam ) +{ + CProxy_collideMgr mgr(h); + mgr.ckLocalBranch()->reinitClient(clientFn, clientParam); +} + /// Create a collider group to contribute objects to. /// Should be called on processor 0. CollideHandle CollideCreate(const CollideGrid3d &gridMap, @@ -329,7 +341,7 @@ static const char * voxName(const CkIndex3D &idx,char *buf,int n) { collideMgr::collideMgr(const CollideGrid3d &gridMap_, const CProxy_collideClient &client_, const CProxy_collideVoxel &voxels) - :thisproxy(thisgroup), voxelProxy(voxels), + :voxelProxy(voxels), gridMap(gridMap_), client(client_), aggregator(gridMap,this) { steps=0; @@ -340,6 +352,27 @@ collideMgr::collideMgr(const CollideGrid3d &gridMap_, collisionStarted = false; } +collideMgr::collideMgr(CkMigrateMessage* m) : + CBase_collideMgr(m), + gridMap(CollideGrid3d(CkVector3d(0, 0, 0),CkVector3d(2, 100, 2))), + aggregator(gridMap,this) +{ + steps=0; + nContrib=0; + contribCount=0; + msgsSent=msgsRecvd=0; + totalLocalVoxels = -1; + collisionStarted = false; +} + +// Reinitialize collideClient's state on restart +void collideMgr::reinitClient( + CollisionClientFn clientFn, + void *clientParam ) +{ + client.ckLocalBranch()->setClient(clientFn, clientParam); +} + //Maintain contributor registration count void collideMgr::registerContributor(int chunkNo) { @@ -417,7 +450,8 @@ void collideMgr::tryAdvance(void) steps++; contribCount=0; msgsSent=msgsRecvd=0; - contribute(CkCallback(CkReductionTarget(collideMgr,reductionFinished), thisProxy[0])); + CProxy_collideMgr proxy(ckGetGroupID()); + contribute(CkCallback(CkReductionTarget(collideMgr,reductionFinished), proxy[0])); } } @@ -426,8 +460,9 @@ void collideMgr::reductionFinished(void) { CM_STATUS("collideMgr::reductionFinished"); //Broadcast Collision start: - thisProxy.determineNumVoxels(); - voxelProxy.initiateCollision(thisProxy); + CProxy_collideMgr proxy(ckGetGroupID()); + proxy.determineNumVoxels(); + voxelProxy.initiateCollision(proxy); } void collideMgr::checkRegistrationComplete() { @@ -586,6 +621,10 @@ void collideVoxel::startCollision(int step, CC_STATUS("} startCollision"); } +collideClient::collideClient() {} + +collideClient::collideClient(CkMigrateMessage* m) : Group(m) {} + collideClient::~collideClient() {} /********************** serialCollideClient *****************/ @@ -596,6 +635,13 @@ serialCollideClient::serialCollideClient(void) { useCb = false; } +serialCollideClient::serialCollideClient(CkMigrateMessage* m) : collideClient(m) +{ + clientFn = NULL; + clientParam = NULL; + clientCb = CkCallback(CkCallback::ignore); +} + serialCollideClient::serialCollideClient(CkCallback clientCb_) { clientFn=NULL; clientParam=NULL; @@ -626,8 +672,9 @@ void serialCollideClient::reductionDone(CkReductionMsg *msg) { int nColl=msg->getSize()/sizeof(Collision); CM_STATUS("serialCollideClient with "<getData()); + } else //FIXME: never registered a client CkAbort("Forgot to call serialCollideClient::setClient!\n"); delete msg; diff --git a/src/libs/ck-libs/collide/collidecharm.ci b/src/libs/ck-libs/collide/collidecharm.ci index 7676bbd32a..0761c61273 100644 --- a/src/libs/ck-libs/collide/collidecharm.ci +++ b/src/libs/ck-libs/collide/collidecharm.ci @@ -3,7 +3,7 @@ module collidecharm { group collideClient { }; - group serialCollideClient : collideClient { + group [migratable] serialCollideClient : collideClient { entry serialCollideClient(); entry serialCollideClient(CkCallback clientCb_); entry void reductionDone(CkReductionMsg *m); @@ -13,7 +13,7 @@ module collidecharm { entry distributedCollideClient(CkCallback clientCb_); }; - group collideMgr { + group [migratable] collideMgr { entry collideMgr(CollideGrid3d gridMap, CProxy_collideClient client, CkArrayID cells); diff --git a/src/libs/ck-libs/collide/collidecharm.h b/src/libs/ck-libs/collide/collidecharm.h index cb595a95b6..09831fdeff 100644 --- a/src/libs/ck-libs/collide/collidecharm.h +++ b/src/libs/ck-libs/collide/collidecharm.h @@ -9,6 +9,9 @@ #include "collide_util.h" #include "collidecharm.decl.h" +/// This client function is called on PE 0 with a Collision list +typedef void (*CollisionClientFn)(void *param,int nColl,Collision *colls); + /********************** collideClient ***************** A place for the assembled Collision lists to go. Each voxel calls this "Collisions" method with their @@ -22,16 +25,17 @@ */ class collideClient : public Group { public: + collideClient(); + collideClient(CkMigrateMessage* m); virtual ~collideClient(); virtual void collisions(int step,CollisionList &colls) =0; + virtual void setClient(CollisionClientFn clientFn, + void *clientParam) = 0; }; /********************** serialCollideClient ***************** Reduces the Collision list down to processor 0. */ -/// This client function is called on PE 0 with a Collision list -typedef void (*CollisionClientFn)(void *param,int nColl,Collision *colls); - /// Call this on processor 0 to build a Collision client that /// just calls this serial routine on processor 0 with the final, /// complete Collision list. @@ -47,6 +51,13 @@ CkGroupID CollideDistributedClient(CkCallback clientCb); /****************** Collision Interface ******************/ typedef CkGroupID CollideHandle; +/// Call this on all processors at restart to reinitialize the Collision client +/// with the correct clientFn and clientParam. +void CollideSerialClientRestart( + CollideHandle h, + CollisionClientFn clientFn, + void *clientParam ); + /// Create a collider group to contribute objects to. /// Should be called on processor 0. CollideHandle CollideCreate(const CollideGrid3d &gridMap, diff --git a/src/libs/ck-libs/collide/collidecharm_impl.h b/src/libs/ck-libs/collide/collidecharm_impl.h index 8ea606fd39..2794f91eea 100644 --- a/src/libs/ck-libs/collide/collidecharm_impl.h +++ b/src/libs/ck-libs/collide/collidecharm_impl.h @@ -101,7 +101,6 @@ class CollisionAggregator { class collideMgr : public CBase_collideMgr { - CProxy_collideMgr thisproxy; private: void status(const char *msg) { CkPrintf("CMgr pe %d> %s\n",CkMyPe(),msg); @@ -131,11 +130,26 @@ class collideMgr : public CBase_collideMgr collideMgr(const CollideGrid3d &gridMap, const CProxy_collideClient &client, const CProxy_collideVoxel &voxels); + collideMgr(CkMigrateMessage* m); + + void pup(PUP::er &p) { + // The migrate constructor does not initialize Group/CkReductionMgr state. + // Restore it explicitly so group reductions have a valid thisProxy/tree. + Group::pup(p); + p | voxelProxy; + p | gridMap; + p | client; + } //Maintain contributor registration count void registerContributor(int chunkNo); void unregisterContributor(int chunkNo); + // Reinitialize collideClient's state on restart + void reinitClient( + CollisionClientFn clientFn, + void *clientParam ); + //Clients call this to contribute their objects void addBoxes(int chunkNo, int n, const bbox3d* boxes, const int* prio); @@ -194,6 +208,13 @@ class serialCollideClient : public collideClient { public: serialCollideClient(void); serialCollideClient(CkCallback clientCb_); + serialCollideClient(CkMigrateMessage *m); + void pup(PUP::er &p) { + // The reduction callback in collisions() relies on Group/CkReductionMgr + // state restored by Group::pup(), including thisgroup and thisProxy. + Group::pup(p); + p | useCb; + } /// Call this client function on processor 0: void setClient(CollisionClientFn clientFn,void *clientParam); @@ -216,6 +237,7 @@ class distributedCollideClient : public collideClient { /// Called by voxel array on each processor: virtual void collisions(int step,CollisionList &colls); + void setClient(CollisionClientFn, void *) {} }; diff --git a/src/libs/ck-libs/collide/threadCollide.C b/src/libs/ck-libs/collide/threadCollide.C index 4a5c7ca321..51a94486ff 100644 --- a/src/libs/ck-libs/collide/threadCollide.C +++ b/src/libs/ck-libs/collide/threadCollide.C @@ -77,6 +77,9 @@ class threadCollideMgr : public CBase_threadCollideMgr contrib[chunkNo]=NULL; } + /// Placeholder for collideClient's restart reinitialization interface. + void setClient(CollisionClientFn, void *) {} + /// collideClient interface (called by voxels) /// Splits up collisions by destination PE void collisions(int step,CollisionList &colls);