00001
00007 #include "InfoStream.h"
00008 #include "PatchMgr.decl.h"
00009 #include "PatchMgr.h"
00010
00011 #include "NamdTypes.h"
00012
00013 #include "HomePatch.h"
00014 #include "PatchMap.h"
00015 #include "AtomMap.h"
00016
00017 #ifdef USE_COMM_LIB
00018 #include "ComlibManager.h"
00019 #endif
00020
00021 #include "main.decl.h"
00022 #include "main.h"
00023
00024 #include "WorkDistrib.decl.h"
00025 #include "WorkDistrib.h"
00026 #include "Node.h"
00027 #include "SimParameters.h"
00028
00029 #include "packmsg.h"
00030
00031
00032 #define MIN_DEBUG_LEVEL 3
00033 #include "Debug.h"
00034
00035
00036
00037 PatchMgr::PatchMgr()
00038 {
00039
00040
00041
00042 if (CkpvAccess(PatchMgr_instance) == NULL) {
00043 CkpvAccess(PatchMgr_instance) = this;
00044 } else {
00045 iout << iFILE << iERROR << iPE
00046 << "PatchMgr instanced twice on same processor!" << endi;
00047 CkExit();
00048 }
00049
00050
00051 patchMap = PatchMap::Instance();
00052 patchMap->registerPatchMgr(this);
00053
00054
00055 migrationCountdown = 0;
00056 combineMigrationMsgs = new MigrateAtomsCombinedMsg*[CkNumPes()];
00057 }
00058
00059 PatchMgr::~PatchMgr()
00060 {
00061 HomePatchListIter hi(homePatches);
00062 for ( hi = hi.begin(); hi != hi.end(); hi++) {
00063 HomePatchElem* elem = homePatches.find(HomePatchElem(hi->pid));
00064 delete elem->patch;
00065 }
00066 delete [] combineMigrationMsgs;
00067 }
00068
00069 void PatchMgr::preCreateHomePatch(PatchID pid, int atomCnt){
00070 HomePatch *patch = new HomePatch(pid, atomCnt);
00071 homePatches.load(HomePatchElem(pid, patch));
00072 patchMap->registerPatch(pid, patch);
00073 }
00074
00075 void PatchMgr::createHomePatch(PatchID pid, FullAtomList a)
00076 {
00077 HomePatch *patch = new HomePatch(pid, a);
00078 homePatches.load(HomePatchElem(pid, patch));
00079 patchMap->registerPatch(pid, patch);
00080 }
00081
00082
00083
00084
00085 void PatchMgr::movePatch(PatchID pid, NodeID nodeID)
00086 {
00087 move.load(MovePatch(pid,nodeID));
00088 }
00089
00090 void PatchMgr::sendOneHomePatch(int patchId, int nodeId){
00091 HomePatch *p = homePatch(patchId);
00092 patchMap->unregisterPatch(patchId, p);
00093
00094 MovePatchesMsg *msg = new MovePatchesMsg(patchId, p->atom);
00095
00096
00097 CProxy_PatchMgr cp(thisgroup);
00098 #if CHARM_VERSION > 050402
00099 cp[nodeId].recvMovePatches(msg);
00100 #else
00101 cp.recvMovePatches(msg, nodeId);
00102 #endif
00103
00104
00105
00106
00107 delete p;
00108 homePatches.del(HomePatchElem(patchId));
00109 }
00110
00111
00112
00113 void PatchMgr::sendMovePatches()
00114 {
00115 if (! move.size())
00116 return;
00117
00118 MovePatchListIter m(move);
00119 for ( m = m.begin(); m != m.end(); m++) {
00120 HomePatch *p = homePatch(m->pid);
00121 patchMap->unregisterPatch(m->pid, p);
00122
00123 MovePatchesMsg *msg = new MovePatchesMsg(m->pid, p->atom);
00124
00125
00126 CProxy_PatchMgr cp(thisgroup);
00127 #if CHARM_VERSION > 050402
00128 cp[m->nodeID].recvMovePatches(msg);
00129 #else
00130 cp.recvMovePatches(msg, m->nodeID);
00131 #endif
00132
00133
00134
00135
00136 delete p;
00137 homePatches.del(HomePatchElem(m->pid));
00138 }
00139 move.resize(0);
00140 }
00141
00142 void PatchMgr::recvMovePatches(MovePatchesMsg *msg) {
00143
00144 createHomePatch(msg->pid, msg->atom);
00145 delete msg;
00146
00147
00148
00149
00150
00151 }
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162 void PatchMgr::sendAtoms(PatchID pid, FullAtomList a) {
00163
00164 MovePatchesMsg *msg = new MovePatchesMsg(pid, a);
00165
00166 CProxy_PatchMgr cp(thisgroup);
00167 #if CHARM_VERSION > 050402
00168 cp[patchMap->node(pid)].recvAtoms(msg);
00169 #else
00170 cp.recvAtoms(msg, patchMap->node(pid));
00171 #endif
00172
00173 }
00174
00175 void PatchMgr::recvAtoms(MovePatchesMsg *msg) {
00176 patchMap->homePatch(msg->pid)->reinitAtoms(msg->atom);
00177 delete msg;
00178 }
00179
00180
00181
00182
00183 void PatchMgr::sendMigrationMsg(PatchID src, MigrationInfo m) {
00184 MigrateAtomsMsg *msg = new MigrateAtomsMsg(src,m.destPatchID,m.mList);
00185 CProxy_PatchMgr cp(thisgroup);
00186 #if CHARM_VERSION > 050402
00187 cp[m.destNodeID].recvMigrateAtoms(msg);
00188 #else
00189 cp.recvMigrateAtoms(msg, m.destNodeID);
00190 #endif
00191 }
00192
00193
00194
00195 void PatchMgr::sendMigrationMsgs(PatchID src, MigrationInfo *m, int numMsgs) {
00196
00197
00198
00199
00200
00201 if ( ! migrationCountdown )
00202 {
00203
00204 numHomePatches = patchMap->numHomePatches();
00205 migrationCountdown = numHomePatches;
00206 int numPes = CkNumPes();
00207 for ( int i = 0; i < numPes; ++i ) combineMigrationMsgs[i] = 0;
00208 }
00209 for (int i=0; i < numMsgs; i++) {
00210 int destNodeID = m[i].destNodeID;
00211 if ( 1 )
00212 {
00213 if ( ! combineMigrationMsgs[destNodeID] )
00214 {
00215 combineMigrationMsgs[destNodeID] = new MigrateAtomsCombinedMsg();
00216 }
00217 combineMigrationMsgs[destNodeID]->add(src,m[i].destPatchID,m[i].mList);
00218 }
00219 else
00220 {
00221
00222 }
00223 }
00224 migrationCountdown -= 1;
00225
00226 if ( ! migrationCountdown )
00227 {
00228 int numPes = CkNumPes();
00229 for ( int destNodeID = 0; destNodeID < numPes; ++destNodeID )
00230 if ( combineMigrationMsgs[destNodeID] )
00231 {
00232 DebugM(3,"Sending MigrateAtomsCombinedMsg to node " << destNodeID << "\n");
00233 CProxy_PatchMgr cp(thisgroup);
00234 #if CHARM_VERSION > 050402
00235 cp[destNodeID].recvMigrateAtomsCombined(combineMigrationMsgs[destNodeID]);
00236 #else
00237 cp.recvMigrateAtomsCombined(combineMigrationMsgs[destNodeID],destNodeID);
00238 #endif
00239 }
00240 }
00241 }
00242
00243
00244 void PatchMgr::recvMigrateAtoms (MigrateAtomsMsg *msg) {
00245
00246 PatchMap::Object()->homePatch(msg->destPatchID)->depositMigration(msg);
00247 }
00248
00249 void PatchMgr::recvMigrateAtomsCombined (MigrateAtomsCombinedMsg *msg)
00250 {
00251 DebugM(3,"Received MigrateAtomsCombinedMsg with " << msg->srcPatchID.size() << " messages.\n");
00252 msg->distribute();
00253 delete msg;
00254 }
00255
00256 void PatchMgr::moveAtom(MoveAtomMsg *msg) {
00257 LocalID lid = AtomMap::Object()->localID(msg->atomid);
00258 if ( lid.pid != notUsed ) {
00259 HomePatch *hp = patchMap->homePatch(lid.pid);
00260 if ( hp ) {
00261 FullAtom &a = hp->atom[lid.index];
00262 if ( msg->moveto ) {
00263 a.fixedPosition = msg->coord;
00264 } else {
00265 a.fixedPosition = hp->lattice.reverse_transform(a.position,a.transform);
00266 a.fixedPosition += msg->coord;
00267 }
00268 a.position = hp->lattice.apply_transform(a.fixedPosition,a.transform);
00269 }
00270 }
00271 delete msg;
00272 }
00273
00274 void PatchMgr::moveAllBy(MoveAllByMsg *msg) {
00275
00276 for (HomePatchElem *elem = homePatches.begin(); elem != homePatches.end(); elem++) {
00277 HomePatch *hp = elem->patch;
00278 for (int i=0; i<hp->getNumAtoms(); i++) {
00279 FullAtom &a = hp->atom[i];
00280 a.fixedPosition = hp->lattice.reverse_transform(a.position,a.transform);
00281 a.fixedPosition += msg->offset;
00282 a.position = hp->lattice.apply_transform(a.fixedPosition,a.transform);
00283 }
00284 }
00285 delete msg;
00286 }
00287
00288 void PatchMgr::setLattice(SetLatticeMsg *msg) {
00289
00290 for (HomePatchElem *elem = homePatches.begin(); elem != homePatches.end(); elem++) {
00291 HomePatch *hp = elem->patch;
00292 hp->lattice = msg->lattice;
00293 }
00294
00295 Node::Object()->simParameters->lattice = msg->lattice;
00296 }
00297
00298 PACK_MSG(MovePatchesMsg,
00299 PACK(fromNodeID);
00300 PACK(pid);
00301 PACK_RESIZE(atom);
00302 )
00303
00304
00305 #include "PatchMgr.def.h"
00306