Commit c29e203b authored by peastman's avatar peastman
Browse files

Ensure valid atom order after loading a checkpoint

parent 9d9ffb01
...@@ -496,6 +496,11 @@ public: ...@@ -496,6 +496,11 @@ public:
* definitions and order to be revalidated. * definitions and order to be revalidated.
*/ */
bool invalidateMolecules(ComputeForceInfo* force); bool invalidateMolecules(ComputeForceInfo* force);
/**
* Make sure the current atom order is valid, based on the forces. If not, perform reordering
* to generate a new valid order. This method is only needed in very unusual situations.
*/
void validateAtomOrder();
/** /**
* Wait until all work that has been queued (kernel executions, asynchronous data transfers, etc.) * Wait until all work that has been queued (kernel executions, asynchronous data transfers, etc.)
* has been submitted to the device. This does not mean it has necessarily been completed. * has been submitted to the device. This does not mean it has necessarily been completed.
...@@ -508,6 +513,7 @@ protected: ...@@ -508,6 +513,7 @@ protected:
struct MoleculeGroup; struct MoleculeGroup;
class VirtualSiteInfo; class VirtualSiteInfo;
void findMoleculeGroups(); void findMoleculeGroups();
void resetAtomOrder();
/** /**
* This is the internal implementation of reorderAtoms(), templatized by the numerical precision in use. * This is the internal implementation of reorderAtoms(), templatized by the numerical precision in use.
*/ */
......
...@@ -376,6 +376,13 @@ bool ComputeContext::invalidateMolecules(ComputeForceInfo* force) { ...@@ -376,6 +376,13 @@ bool ComputeContext::invalidateMolecules(ComputeForceInfo* force) {
// atoms to their original order, rebuild the list of identical molecules, and sort them // atoms to their original order, rebuild the list of identical molecules, and sort them
// again. // again.
resetAtomOrder();
findMoleculeGroups();
reorderAtoms();
return true;
}
void ComputeContext::resetAtomOrder() {
ContextSelector selector(*this); ContextSelector selector(*this);
vector<mm_int4> newCellOffsets(numAtoms); vector<mm_int4> newCellOffsets(numAtoms);
if (getUseDoublePrecision()) { if (getUseDoublePrecision()) {
...@@ -436,12 +443,25 @@ bool ComputeContext::invalidateMolecules(ComputeForceInfo* force) { ...@@ -436,12 +443,25 @@ bool ComputeContext::invalidateMolecules(ComputeForceInfo* force) {
posCellOffsets[i] = newCellOffsets[i]; posCellOffsets[i] = newCellOffsets[i];
} }
getAtomIndexArray().upload(atomIndex); getAtomIndexArray().upload(atomIndex);
findMoleculeGroups();
for (auto listener : reorderListeners) for (auto listener : reorderListeners)
listener->execute(); listener->execute();
forceNextReorder = true; forceNextReorder = true;
}
void ComputeContext::validateAtomOrder() {
for (auto& mol : moleculeGroups) {
for (int atom : mol.atoms) {
set<int> identical;
for (int offset : mol.offsets)
identical.insert(atom+offset);
for (int i : identical)
if (identical.find(atomIndex[i]) == identical.end()) {
resetAtomOrder();
reorderAtoms(); reorderAtoms();
return true; return;
}
}
}
} }
void ComputeContext::forceReorder() { void ComputeContext::forceReorder() {
......
...@@ -424,6 +424,7 @@ void CudaUpdateStateDataKernel::loadCheckpoint(ContextImpl& context, istream& st ...@@ -424,6 +424,7 @@ void CudaUpdateStateDataKernel::loadCheckpoint(ContextImpl& context, istream& st
SimTKOpenMMUtilities::loadCheckpoint(stream); SimTKOpenMMUtilities::loadCheckpoint(stream);
for (auto listener : cu.getReorderListeners()) for (auto listener : cu.getReorderListeners())
listener->execute(); listener->execute();
cu.validateAtomOrder();
} }
class CudaCalcNonbondedForceKernel::ForceInfo : public CudaForceInfo { class CudaCalcNonbondedForceKernel::ForceInfo : public CudaForceInfo {
......
...@@ -441,6 +441,7 @@ void OpenCLUpdateStateDataKernel::loadCheckpoint(ContextImpl& context, istream& ...@@ -441,6 +441,7 @@ void OpenCLUpdateStateDataKernel::loadCheckpoint(ContextImpl& context, istream&
SimTKOpenMMUtilities::loadCheckpoint(stream); SimTKOpenMMUtilities::loadCheckpoint(stream);
for (auto listener : cl.getReorderListeners()) for (auto listener : cl.getReorderListeners())
listener->execute(); listener->execute();
cl.validateAtomOrder();
} }
class OpenCLCalcNonbondedForceKernel::ForceInfo : public OpenCLForceInfo { class OpenCLCalcNonbondedForceKernel::ForceInfo : public OpenCLForceInfo {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment