7 #ifndef COMPUTEHOMETUPLES_H 8 #define COMPUTEHOMETUPLES_H 99 #ifdef MEM_OPT_VERSION 100 template <
class T>
struct ElemTraits {
102 static signature* get_sig_pointer(
Molecule *mol) {
return mol->atomSigPool; }
103 static int get_sig_id(
const CompAtomExt &a) {
return a.sigId; }
106 template <>
struct ElemTraits <
ExclElem> {
108 static signature* get_sig_pointer(
Molecule *mol) {
return mol->exclSigPool; }
109 static int get_sig_id(
const CompAtomExt &a) {
return a.exclId; }
113 #ifdef USE_HOMETUPLES 121 Tuples(
int type) : type(type) {}
134 int getType() {
return type;}
135 virtual void submitTupleCount(
SubmitReduction *reduction,
int tupleCount)=0;
137 virtual int getNumTuples()=0;
138 virtual void* getTupleList()=0;
140 const std::vector<int>& pids = std::vector<int>())=0;
147 template <
class T,
class S,
class P>
class HomeTuples :
public Tuples {
149 std::vector<T> tupleList;
153 HomeTuples(
int type=-1) : Tuples(type) {}
155 #if __cplusplus < 201103L 159 virtual void* getTupleList() final {
160 return (
void*)tupleList.data();
163 virtual void submitTupleCount(
SubmitReduction *reduction,
int tupleCount)
final {
164 reduction->item(T::reductionChecksumLabel) += (
BigReal)tupleCount;
174 virtual int getNumTuples() final {
175 return tupleList.size();
179 const std::vector<int>& pids = std::vector<int>()) {
181 if (isBasePatch == NULL) {
182 NAMD_bug(
"NULL isBasePatch detected in HomeTuples::loadTuples()");
187 #ifdef MEM_OPT_VERSION 188 typename ElemTraits<T>::signature *allSigs;
190 int32 **tuplesByAtom;
194 const P *tupleValues;
199 #ifdef MEM_OPT_VERSION 200 allSigs = ElemTraits<T>::get_sig_pointer(node->
molecule);
202 T::getMoleculePointers(node->
molecule,
203 &numTuples, &tuplesByAtom, &tupleStructs);
206 T::getParameterPointers(node->
parameters, &tupleValues);
217 Real invLesFactor = lesOn ?
233 if (pids.size() == 0) ai = ai.begin();
235 int numPid = (pids.size() == 0) ? tuplePatchList.
size() : pids.size();
237 for (
int ipid=0;ipid < numPid;ipid++) {
242 if (pids.size() == 0) {
245 atomExt = (*ai).xExt;
257 for (
int j=0; j < numAtoms; j++)
260 #ifdef MEM_OPT_VERSION 261 typename ElemTraits<T>::signature *thisAtomSig =
262 &allSigs[ElemTraits<T>::get_sig_id(atomExt[j])];
264 T::getTupleInfo(thisAtomSig, &numTuples, &allTuples);
265 for(
int k=0; k<numTuples; k++) {
266 T t(atomExt[j].
id, &allTuples[k], tupleValues);
269 int32 *curTuple = tuplesByAtom[atomExt[j].
id];
270 for( ; *curTuple != -1; ++curTuple) {
271 T t(&tupleStructs[*curTuple],tupleValues);
274 aid[0] = atomMap->
localID(t.atomID[0]);
275 int homepatch = aid[0].
pid;
282 int fep_tuple_type = 0;
283 for (i=1; i < T::size; i++) {
284 aid[i] = atomMap->
localID(t.atomID[i]);
285 samepatch = samepatch && ( homepatch == aid[i].
pid );
294 if (sdScaling && is_fep_sd) {
303 for (i=0; i < num_unpert_bonds; i++) {
305 && t.atomID[0]==unpert_bonds[i].atom1
306 && t.atomID[1]==unpert_bonds[i].atom2) is_fep_sd = 0;
308 for (i=0; i < num_unpert_angles; i++) {
310 && t.atomID[0]==unpert_angles[i].atom1
311 && t.atomID[1]==unpert_angles[i].atom2
312 && t.atomID[2]==unpert_angles[i].atom3) is_fep_sd = 0;
314 for (i=0; i < num_unpert_dihedrals; i++) {
316 && t.atomID[0]==unpert_dihedrals[i].atom1
317 && t.atomID[1]==unpert_dihedrals[i].atom2
318 && t.atomID[2]==unpert_dihedrals[i].atom3
319 && t.atomID[3]==unpert_dihedrals[i].atom4) is_fep_sd = 0;
322 if (T::size < 4 && !soluteScalingAll) has_ss =
false;
323 if ( samepatch )
continue;
324 t.scale = (!has_les && !has_ss) ? 1.0 : ( has_les ? invLesFactor : soluteScalingFactor );
325 if (is_fep_ss) t.scale = (fep_tuple_type == 4) ? OneMinusLambda : Lambda;
326 if (is_fep_sd && sdScaling) t.scale = (fep_tuple_type == 4 || fep_tuple_type == 2) ? OneMinusLambda : Lambda;
328 for (i=1; i < T::size; i++) {
329 homepatch = patchMap->
downstream(homepatch,aid[i].pid);
331 if ( homepatch !=
notUsed && isBasePatch[homepatch] ) {
333 for (i=0; i < T::size; i++) {
336 #ifdef MEM_OPT_VERSION 339 iout <<
iWARN <<
"Tuple " << *curTuple <<
" with atoms ";
342 for( erri = 0; erri < T::size; erri++ ) {
343 iout << t.atomID[erri] <<
"(" << aid[erri].
pid <<
") ";
345 iout <<
"missing patch " << aid[i].
pid <<
"\n" <<
endi;
348 t.localIndex[i] = aid[i].
index;
351 #ifdef MEM_OPT_VERSION 355 for(i=0; i<T::size; i++){
359 if(!allfixed) tupleList.push_back(t);
361 tupleList.push_back(t);
364 tupleList.push_back(t);
379 #ifndef USE_HOMETUPLES 383 #ifdef MEM_OPT_VERSION 384 typename ElemTraits<T>::signature *allSigs;
386 int32 **tuplesByAtom;
390 const P *tupleValues;
393 #ifdef MEM_OPT_VERSION 394 allSigs = ElemTraits<T>::get_sig_pointer(node->
molecule);
396 T::getMoleculePointers(node->
molecule,
397 &numTuples, &tuplesByAtom, &tupleStructs);
400 T::getParameterPointers(node->
parameters, &tupleValues);
411 Real invLesFactor = lesOn ?
428 for ( ai = ai.
begin(); ai != ai.
end(); ai++ )
436 for (
int j=0; j < numAtoms; j++)
439 #ifdef MEM_OPT_VERSION 440 typename ElemTraits<T>::signature *thisAtomSig =
441 &allSigs[ElemTraits<T>::get_sig_id(atomExt[j])];
443 T::getTupleInfo(thisAtomSig, &numTuples, &allTuples);
444 for(
int k=0; k<numTuples; k++) {
445 T t(atomExt[j].
id, &allTuples[k], tupleValues);
448 int32 *curTuple = tuplesByAtom[atomExt[j].
id];
449 for( ; *curTuple != -1; ++curTuple) {
450 T t(&tupleStructs[*curTuple],tupleValues);
453 aid[0] = atomMap->
localID(t.atomID[0]);
454 int homepatch = aid[0].
pid;
461 int fep_tuple_type = 0;
462 for (i=1; i < T::size; i++) {
463 aid[i] = atomMap->
localID(t.atomID[i]);
464 samepatch = samepatch && ( homepatch == aid[i].
pid );
474 if (sdScaling && is_fep_sd) {
475 for (i=0; i < num_unpert_bonds; i++) {
477 && t.atomID[0]==unpert_bonds[i].
atom1 478 && t.atomID[1]==unpert_bonds[i].
atom2) is_fep_sd = 0;
480 for (i=0; i < num_unpert_angles; i++) {
482 && t.atomID[0]==unpert_angles[i].
atom1 483 && t.atomID[1]==unpert_angles[i].
atom2 484 && t.atomID[2]==unpert_angles[i].
atom3) is_fep_sd = 0;
486 for (i=0; i < num_unpert_dihedrals; i++) {
488 && t.atomID[0]==unpert_dihedrals[i].
atom1 489 && t.atomID[1]==unpert_dihedrals[i].
atom2 490 && t.atomID[2]==unpert_dihedrals[i].
atom3 491 && t.atomID[3]==unpert_dihedrals[i].
atom4) is_fep_sd = 0;
494 if (T::size < 4 && !soluteScalingAll) has_ss =
false;
495 if ( samepatch )
continue;
496 t.scale = (!has_les && !has_ss) ? 1.0 : ( has_les ? invLesFactor : soluteScalingFactor );
497 if (is_fep_ss) t.scale = (fep_tuple_type == 4) ? OneMinusLambda : Lambda;
498 if (is_fep_sd && sdScaling) t.scale = (fep_tuple_type == 4 || fep_tuple_type == 2) ? OneMinusLambda : Lambda;
500 for (i=1; i < T::size; i++) {
501 homepatch = patchMap->
downstream(homepatch,aid[i].pid);
503 if ( homepatch !=
notUsed && isBasePatch[homepatch] ) {
505 for (i=0; i < T::size; i++) {
508 #ifdef MEM_OPT_VERSION 511 iout <<
iWARN <<
"Tuple " << *curTuple <<
" with atoms ";
514 for( erri = 0; erri < T::size; erri++ ) {
515 iout << t.atomID[erri] <<
"(" << aid[erri].
pid <<
") ";
517 iout <<
"missing patch " << aid[i].
pid <<
"\n" <<
endi;
520 t.localIndex[i] = aid[i].
index;
523 #ifdef MEM_OPT_VERSION 528 for(i=0; i<T::size; i++){
532 if(!allfixed) tupleList.add(t);
550 #ifdef USE_HOMETUPLES 551 HomeTuples<T, S, P>* tuples;
578 pressureProfileSlabs = T::pressureProfileSlabs =
583 int numAtomTypePairs = n*n;
584 pressureProfileData =
new BigReal[3*pressureProfileSlabs*numAtomTypePairs];
586 pressureProfileReduction = NULL;
587 pressureProfileData = NULL;
589 doLoadTuples =
false;
591 #ifdef USE_HOMETUPLES 606 pressureProfileSlabs = T::pressureProfileSlabs =
611 int numAtomTypePairs = n*n;
612 pressureProfileData =
new BigReal[3*pressureProfileSlabs*numAtomTypePairs];
614 pressureProfileReduction = NULL;
615 pressureProfileData = NULL;
617 doLoadTuples =
false;
619 isBasePatch =
new char[nPatches];
621 for (i=0; i<nPatches; ++i) { isBasePatch[i] = 0; }
622 for (i=0; i<pids.
size(); ++i) { isBasePatch[pids[i]] = 1; }
623 #ifdef USE_HOMETUPLES 632 delete [] isBasePatch;
633 delete pressureProfileReduction;
634 delete pressureProfileData;
635 #ifdef USE_HOMETUPLES 636 if (tuples != NULL)
delete tuples;
646 #if defined(NAMD_CUDA) || defined(NAMD_HIP) 650 #ifdef USE_HOMETUPLES 651 tuples =
new HomeTuples<T, S, P>();
655 tuplePatchList.
clear();
659 for (pid=0; pid<nPatches; ++pid) {
660 if ( isBasePatch[pid] ) {
661 #if defined(NAMD_CUDA) || defined(NAMD_HIP) 672 for (pid=0; pid<nPatches; ++pid)
if ( isBasePatch[pid] ) {
674 for (
int i = 0; i < numNeighbors; ++i ) {
676 #if defined(NAMD_CUDA) || defined(NAMD_HIP) 684 setNumPatches(tuplePatchList.
size());
709 for (ap = ap.
begin(); ap != ap.
end(); ap++) {
718 BigReal reductionData[T::reductionDataSize];
720 int numAtomTypes = T::pressureProfileAtomTypes;
721 int numAtomTypePairs = numAtomTypes*numAtomTypes;
723 for (
int i = 0; i < T::reductionDataSize; ++i ) reductionData[i] = 0;
724 if (pressureProfileData) {
725 memset(pressureProfileData, 0, 3*pressureProfileSlabs*numAtomTypePairs*
sizeof(
BigReal));
728 newap = newap.
begin();
730 T::pressureProfileThickness = lattice.
c().
z / pressureProfileSlabs;
731 T::pressureProfileMin = lattice.
origin().
z - 0.5*lattice.
c().
z;
735 if ( doLoadTuples ) {
736 #ifdef USE_HOMETUPLES 741 doLoadTuples =
false;
744 #ifdef USE_HOMETUPLES 745 T *al = (T *)tuples->getTupleList();
746 const int ntuple = tuples->getNumTuples();
748 T *al = tupleList.
begin();
749 const int ntuple = tupleList.
size();
751 if ( ntuple ) T::computeForce(al, ntuple, reductionData, pressureProfileData);
752 tupleCount += ntuple;
757 T::submitReductionData(reductionData,reduction);
758 reduction->
item(T::reductionChecksumLabel) += (
BigReal)tupleCount;
761 if (pressureProfileReduction) {
765 const int arraysize = 3*pressureProfileSlabs;
766 const BigReal *data = pressureProfileData;
767 for (
int i=0; i<numAtomTypes; i++) {
768 for (
int j=0; j<numAtomTypes; j++) {
771 if (ii > jj) {
int tmp=ii; ii=jj; jj=tmp; }
772 const int reductionOffset =
773 (ii*numAtomTypes - (ii*(ii+1))/2 + jj)*arraysize;
774 for (
int k=0; k<arraysize; k++) {
775 pressureProfileReduction->
item(reductionOffset+k) += data[k];
780 pressureProfileReduction->
submit();
785 for (ap = ap.
begin(); ap != ap.
end(); ap++) {
Elem * find(const Elem &elem)
UniqueSet< TuplePatchElem > TuplePatchList
#define COMPUTE_PROXY_PRIORITY
int num_alch_unpert_Dihedrals
Box< Patch, CompAtom > * registerAvgPositionPickup(Compute *cid)
NAMD_HOST_DEVICE Vector c() const
static ProxyMgr * Object()
static void partition(int *order, const FullAtom *atoms, int begin, int end)
static PatchMap * Object()
Angle * alch_unpert_angles
virtual void submit(void)=0
SimParameters * simParameters
int num_alch_unpert_Bonds
BigReal * pressureProfileData
void startWork(const LDObjHandle &handle)
std::ostream & endi(std::ostream &s)
virtual ~ComputeHomeTuples()
int downstream(int pid1, int pid2)
int upstreamNeighbors(int pid, PatchID *neighbor_ids)
TuplePatchList tuplePatchList
ComputeHomeTuples(ComputeID c)
SubmitReduction * pressureProfileReduction
SubmitReduction * willSubmit(int setID, int size=-1)
std::ostream & iWARN(std::ostream &s)
int num_alch_unpert_Angles
unsigned char get_ss_type(int anum) const
int add(const Elem &elem)
static ReductionMgr * Object(void)
Patch * patch(PatchID pid)
virtual void initialize(void)
Dihedral * alch_unpert_dihedrals
Molecule stores the structural information for the system.
UniqueSetIter< T > begin(void) const
TuplePatchElem(Patch *p_param, Compute *cid)
int numPatches(void) const
void NAMD_bug(const char *err_msg)
TuplePatchElem(PatchID pid=-1)
BigReal soluteScalingFactor
int operator<(const TuplePatchElem &elem) const
LocalID localID(AtomID id)
PatchID getPatchID() const
Box< Patch, CompAtom > * positionBox
void createProxy(PatchID pid)
UniqueSetIter< T > end(void) const
virtual void doWork(void)
static LdbCoordinator * Object()
static AtomMap * Object()
unsigned char get_fep_type(int anum) const
void endWork(const LDObjHandle &handle)
ResizeArray< T > tupleList
int pressureProfileAtomTypes
int operator==(const TuplePatchElem &elem) const
SubmitReduction * reduction
ComputeHomeTuples(ComputeID c, PatchIDList &pids)
virtual void loadTuples(void)
Box< Patch, CompAtom > * avgPositionBox
UniqueSetIter< TuplePatchElem > TuplePatchListIter
Box< Patch, Results > * forceBox
NAMD_HOST_DEVICE Vector origin() const
void close(Data **const t)
Box< Patch, CompAtom > * registerPositionPickup(Compute *cid)
CompAtomExt * getCompAtomExtInfo()
Box< Patch, Results > * registerForceDeposit(Compute *cid)