From dbe0a321f343ea6667923b7469858342fcb2e3a1 Mon Sep 17 00:00:00 2001 From: Mark Abraham Date: Thu, 3 Jun 2021 14:58:26 +0000 Subject: [PATCH] Remove preprocessor usage for atomInfo --- api/nblib/gmxsetup.cpp | 5 +- src/gromacs/domdec/domdec.cpp | 1 + src/gromacs/domdec/domdec.h | 2 +- src/gromacs/domdec/domdec_constraints.cpp | 6 +- src/gromacs/domdec/localtopology.cpp | 3 +- src/gromacs/domdec/makebondedlinks.cpp | 17 ++-- src/gromacs/domdec/makebondedlinks.h | 10 +- src/gromacs/domdec/partition.cpp | 26 ++--- src/gromacs/domdec/redistribute.cpp | 2 +- src/gromacs/domdec/utility.cpp | 1 + src/gromacs/domdec/utility.h | 8 +- src/gromacs/mdlib/forcerec.cpp | 32 +++--- src/gromacs/mdrun/tpi.cpp | 4 +- src/gromacs/mdtypes/atominfo.h | 102 +++++++++++++++++++ src/gromacs/mdtypes/forcerec.h | 54 +--------- src/gromacs/nbnxm/atomdata.cpp | 17 ++-- src/gromacs/nbnxm/benchmark/bench_system.cpp | 11 +- src/gromacs/nbnxm/benchmark/bench_system.h | 2 +- src/gromacs/nbnxm/grid.cpp | 46 ++++----- src/gromacs/nbnxm/grid.h | 8 +- src/gromacs/nbnxm/gridset.cpp | 2 +- 21 files changed, 211 insertions(+), 148 deletions(-) create mode 100644 src/gromacs/mdtypes/atominfo.h diff --git a/api/nblib/gmxsetup.cpp b/api/nblib/gmxsetup.cpp index 30f14937ee..d5c17addd7 100644 --- a/api/nblib/gmxsetup.cpp +++ b/api/nblib/gmxsetup.cpp @@ -46,6 +46,7 @@ #include "gromacs/mdlib/forcerec.h" #include "gromacs/mdlib/gmx_omp_nthreads.h" #include "gromacs/mdlib/rf_util.h" +#include "gromacs/mdtypes/atominfo.h" #include "gromacs/mdtypes/forcerec.h" #include "gromacs/mdtypes/interaction_const.h" #include "gromacs/mdtypes/simulation_workload.h" @@ -136,8 +137,8 @@ void NbvSetupUtil::setParticleInfoAllVdv(const size_t numParticles) particleInfoAllVdw_.resize(numParticles); for (size_t particleI = 0; particleI < numParticles; particleI++) { - SET_CGINFO_HAS_VDW(particleInfoAllVdw_[particleI]); - SET_CGINFO_HAS_Q(particleInfoAllVdw_[particleI]); + particleInfoAllVdw_[particleI] |= gmx::sc_atomInfo_HasVdw; + particleInfoAllVdw_[particleI] |= gmx::sc_atomInfo_HasCharge; } } diff --git a/src/gromacs/domdec/domdec.cpp b/src/gromacs/domdec/domdec.cpp index 42770b651f..de3aaf1cb9 100644 --- a/src/gromacs/domdec/domdec.cpp +++ b/src/gromacs/domdec/domdec.cpp @@ -82,6 +82,7 @@ #include "gromacs/mdrun/mdmodules.h" #include "gromacs/mdtypes/commrec.h" #include "gromacs/mdtypes/forceoutput.h" +#include "gromacs/mdtypes/forcerec.h" #include "gromacs/mdtypes/inputrec.h" #include "gromacs/mdtypes/mdrunoptions.h" #include "gromacs/mdtypes/state.h" diff --git a/src/gromacs/domdec/domdec.h b/src/gromacs/domdec/domdec.h index 301c3c82b6..d35b02c539 100644 --- a/src/gromacs/domdec/domdec.h +++ b/src/gromacs/domdec/domdec.h @@ -66,7 +66,6 @@ #include "gromacs/math/vectypes.h" #include "gromacs/utility/real.h" -struct AtomInfoWithinMoleculeBlock; struct gmx_domdec_t; struct gmx_ddbox_t; struct gmx_domdec_zones_t; @@ -85,6 +84,7 @@ class GpuEventSynchronizer; namespace gmx { +struct AtomInfoWithinMoleculeBlock; class DeviceStreamManager; class ForceWithShiftForces; class MDLogger; diff --git a/src/gromacs/domdec/domdec_constraints.cpp b/src/gromacs/domdec/domdec_constraints.cpp index 17cb74fdcb..9a6813dfe2 100644 --- a/src/gromacs/domdec/domdec_constraints.cpp +++ b/src/gromacs/domdec/domdec_constraints.cpp @@ -61,8 +61,8 @@ #include "gromacs/math/vec.h" #include "gromacs/mdlib/constr.h" #include "gromacs/mdlib/gmx_omp_nthreads.h" +#include "gromacs/mdtypes/atominfo.h" #include "gromacs/mdtypes/commrec.h" -#include "gromacs/mdtypes/forcerec.h" // only for GET_CGINFO_* #include "gromacs/pbcutil/ishift.h" #include "gromacs/topology/ifunc.h" #include "gromacs/topology/mtop_lookup.h" @@ -236,7 +236,7 @@ static void atoms_to_settles(gmx_domdec_t* dd, int mb = 0; for (int a = cg_start; a < cg_end; a++) { - if (GET_CGINFO_SETTLE(atomInfo[a])) + if (atomInfo[a] & gmx::sc_atomInfo_Settle) { int a_gl = dd->globalAtomIndices[a]; int a_mol = 0; @@ -316,7 +316,7 @@ static void atoms_to_constraints(gmx_domdec_t* dd, int nhome = 0; for (int a = 0; a < dd->numHomeAtoms; a++) { - if (GET_CGINFO_CONSTR(atomInfo[a])) + if (atomInfo[a] & gmx::sc_atomInfo_Constraint) { int a_gl = dd->globalAtomIndices[a]; int molnr = 0; diff --git a/src/gromacs/domdec/localtopology.cpp b/src/gromacs/domdec/localtopology.cpp index ace7b43a1b..ac2bb05500 100644 --- a/src/gromacs/domdec/localtopology.cpp +++ b/src/gromacs/domdec/localtopology.cpp @@ -55,6 +55,7 @@ #include "gromacs/domdec/options.h" #include "gromacs/domdec/reversetopology.h" #include "gromacs/math/vec.h" +#include "gromacs/mdtypes/atominfo.h" #include "gromacs/mdtypes/forcerec.h" #include "gromacs/mdtypes/mdatom.h" #include "gromacs/pbcutil/pbc.h" @@ -721,7 +722,7 @@ static void make_exclusions_zone(ArrayRef globalAtomInd { exclusionsForAtom.clear(); - if (GET_CGINFO_EXCL_INTER(atomInfo[at])) + if (atomInfo[at] & gmx::sc_atomInfo_Exclusion) { int mb = 0; int mt = 0; diff --git a/src/gromacs/domdec/makebondedlinks.cpp b/src/gromacs/domdec/makebondedlinks.cpp index 265832f6a2..b7ed82790f 100644 --- a/src/gromacs/domdec/makebondedlinks.cpp +++ b/src/gromacs/domdec/makebondedlinks.cpp @@ -49,7 +49,7 @@ #include "gromacs/domdec/domdec_internal.h" #include "gromacs/domdec/options.h" #include "gromacs/domdec/reversetopology.h" -#include "gromacs/mdtypes/forcerec.h" +#include "gromacs/mdtypes/atominfo.h" #include "gromacs/utility/fatalerror.h" #include "gromacs/utility/smalloc.h" #include "gromacs/topology/block.h" @@ -85,9 +85,9 @@ static void check_link(t_blocka* link, int cg_gl, int cg_gl_j) } } -void makeBondedLinks(gmx_domdec_t* dd, - const gmx_mtop_t& mtop, - gmx::ArrayRef atomInfoForEachMoleculeBlock) +void makeBondedLinks(gmx_domdec_t* dd, + const gmx_mtop_t& mtop, + gmx::ArrayRef atomInfoForEachMoleculeBlock) { if (!dd->comm->systemInfo.filterBondedCommunication) @@ -144,7 +144,7 @@ void makeBondedLinks(gmx_domdec_t* dd, reverse_ilist_t ril; make_reverse_ilist(molt.ilist, &molt.atoms, rtOptions, AtomLinkRule::AllAtomsInBondeds, &ril); - AtomInfoWithinMoleculeBlock* atomInfoOfMoleculeBlock = &atomInfoForEachMoleculeBlock[mb]; + gmx::AtomInfoWithinMoleculeBlock* atomInfoOfMoleculeBlock = &atomInfoForEachMoleculeBlock[mb]; int mol = 0; for (mol = 0; mol < (mtop.bIntermolecularInteractions ? molb.nmol : 1); mol++) @@ -193,7 +193,7 @@ void makeBondedLinks(gmx_domdec_t* dd, } if (link->index[atomIndex + 1] - link->index[atomIndex] > 0) { - SET_CGINFO_BOND_INTER(atomInfoOfMoleculeBlock->atomInfo[a]); + atomInfoOfMoleculeBlock->atomInfo[a] |= gmx::sc_atomInfo_BondCommunication; numLinkedAtoms++; } } @@ -231,9 +231,8 @@ void makeBondedLinks(gmx_domdec_t* dd, && atomIndex - atomInfoOfMoleculeBlock->indexOfFirstAtomInMoleculeBlock < gmx::ssize(atomInfoOfMoleculeBlock->atomInfo)) { - SET_CGINFO_BOND_INTER( - atomInfoOfMoleculeBlock - ->atomInfo[atomIndex - atomInfoOfMoleculeBlock->indexOfFirstAtomInMoleculeBlock]); + atomInfoOfMoleculeBlock->atomInfo[atomIndex - atomInfoOfMoleculeBlock->indexOfFirstAtomInMoleculeBlock] |= + gmx::sc_atomInfo_BondCommunication; numLinkedAtoms++; } } diff --git a/src/gromacs/domdec/makebondedlinks.h b/src/gromacs/domdec/makebondedlinks.h index 01bc7a8366..7bb6f05c26 100644 --- a/src/gromacs/domdec/makebondedlinks.h +++ b/src/gromacs/domdec/makebondedlinks.h @@ -44,7 +44,6 @@ #ifndef GMX_DOMDEC_MAKEBONDEDLINKS_H #define GMX_DOMDEC_MAKEBONDEDLINKS_H -struct AtomInfoWithinMoleculeBlock; struct gmx_domdec_t; struct gmx_mtop_t; @@ -52,14 +51,15 @@ namespace gmx { template class ArrayRef; -} +struct AtomInfoWithinMoleculeBlock; +} // namespace gmx /*! \brief Generate a list of links between atoms that are linked by bonded interactions * * Also stores whether atoms are linked in \p atomInfoForEachMoleculeBlock. */ -void makeBondedLinks(gmx_domdec_t* dd, - const gmx_mtop_t& mtop, - gmx::ArrayRef atomInfoForEachMoleculeBlock); +void makeBondedLinks(gmx_domdec_t* dd, + const gmx_mtop_t& mtop, + gmx::ArrayRef atomInfoForEachMoleculeBlock); #endif diff --git a/src/gromacs/domdec/partition.cpp b/src/gromacs/domdec/partition.cpp index dc826b55e7..cbf0fe493f 100644 --- a/src/gromacs/domdec/partition.cpp +++ b/src/gromacs/domdec/partition.cpp @@ -479,7 +479,7 @@ static void dd_set_atominfo(gmx::ArrayRef index_gl, int cg0, int cg1, { if (fr != nullptr) { - gmx::ArrayRef atomInfoForEachMoleculeBlock = + gmx::ArrayRef atomInfoForEachMoleculeBlock = fr->atomInfoForEachMoleculeBlock; gmx::ArrayRef atomInfo = fr->atomInfo; @@ -1335,16 +1335,16 @@ void set_dd_dlb_max_cutoff(t_commrec* cr, real cutoff) } //! Merge atom buffers. -static void merge_cg_buffers(int ncell, - gmx_domdec_comm_dim_t* cd, - int pulse, - int* ncg_cell, - gmx::ArrayRef index_gl, - const int* recv_i, - gmx::ArrayRef x, - gmx::ArrayRef recv_vr, - gmx::ArrayRef atomInfoForEachMoleculeBlock, - gmx::ArrayRef atomInfo) +static void merge_cg_buffers(int ncell, + gmx_domdec_comm_dim_t* cd, + int pulse, + int* ncg_cell, + gmx::ArrayRef index_gl, + const int* recv_i, + gmx::ArrayRef x, + gmx::ArrayRef recv_vr, + gmx::ArrayRef atomInfoForEachMoleculeBlock, + gmx::ArrayRef atomInfo) { gmx_domdec_ind_t *ind, *ind_p; int p, cell, c, cg, cg0, cg1, cg_gl; @@ -1778,7 +1778,7 @@ static void get_zone_pulse_groups(gmx_domdec_t* dd, if (r2 < r_comm2 || (bDistBonded && ((bDistMB && rb2 < r_bcomm2) || (bDist2B && r2 < r_bcomm2)) && (!bBondComm - || (GET_CGINFO_BOND_INTER(atomInfo[cg]) + || ((atomInfo[cg] & gmx::sc_atomInfo_BondCommunication) && missing_link(*comm->bondedLinks, globalAtomGroupIndices[cg], *dd->ga2la))))) { /* Store the local and global atom group indices and position */ @@ -1905,7 +1905,7 @@ static void setup_dd_communication(gmx_domdec_t* dd, matrix box, gmx_ddbox_t* dd } zone_cg_range = zones->cg_range.data(); - gmx::ArrayRef atomInfoForEachMoleculeBlock = + gmx::ArrayRef atomInfoForEachMoleculeBlock = fr->atomInfoForEachMoleculeBlock; zone_cg_range[0] = 0; diff --git a/src/gromacs/domdec/redistribute.cpp b/src/gromacs/domdec/redistribute.cpp index 4225ff78fc..9cd6dfece9 100644 --- a/src/gromacs/domdec/redistribute.cpp +++ b/src/gromacs/domdec/redistribute.cpp @@ -765,7 +765,7 @@ void dd_redistribute_cg(FILE* fplog, /* We reuse the intBuffer without reacquiring since we are in the same scope */ DDBufferAccess& flagBuffer = moveBuffer; - gmx::ArrayRef atomInfoForEachMoleculeBlock = + gmx::ArrayRef atomInfoForEachMoleculeBlock = fr->atomInfoForEachMoleculeBlock; /* Temporarily store atoms passed to our rank at the end of the range */ diff --git a/src/gromacs/domdec/utility.cpp b/src/gromacs/domdec/utility.cpp index c302b69cf9..da53fc645b 100644 --- a/src/gromacs/domdec/utility.cpp +++ b/src/gromacs/domdec/utility.cpp @@ -44,6 +44,7 @@ #include "utility.h" +#include "gromacs/mdtypes/forcerec.h" #include "gromacs/mdtypes/state.h" #include "gromacs/utility/fatalerror.h" #include "gromacs/utility/smalloc.h" diff --git a/src/gromacs/domdec/utility.h b/src/gromacs/domdec/utility.h index ce65383f19..09c8b9a1e3 100644 --- a/src/gromacs/domdec/utility.h +++ b/src/gromacs/domdec/utility.h @@ -43,7 +43,7 @@ #define GMX_DOMDEC_DOMDEC_UTILITY_H #include "gromacs/math/vectypes.h" -#include "gromacs/mdtypes/forcerec.h" +#include "gromacs/mdtypes/atominfo.h" #include "domdec_internal.h" @@ -83,15 +83,15 @@ void make_tric_corr_matrix(int npbcdim, const matrix box, matrix tcm); void check_screw_box(const matrix box); /*! \brief Return the atom information flags for atom a */ -static inline int ddGetAtomInfo(gmx::ArrayRef atomInfoForEachMoleculeBlock, - int a) +static inline int ddGetAtomInfo(gmx::ArrayRef atomInfoForEachMoleculeBlock, + int a) { size_t index = 0; while (a >= atomInfoForEachMoleculeBlock[index].indexOfLastAtomInMoleculeBlock) { index++; } - const AtomInfoWithinMoleculeBlock& atomInfoOfMoleculeBlock = atomInfoForEachMoleculeBlock[index]; + const gmx::AtomInfoWithinMoleculeBlock& atomInfoOfMoleculeBlock = atomInfoForEachMoleculeBlock[index]; return atomInfoOfMoleculeBlock.atomInfo[(a - atomInfoOfMoleculeBlock.indexOfFirstAtomInMoleculeBlock) % atomInfoOfMoleculeBlock.atomInfo.size()]; diff --git a/src/gromacs/mdlib/forcerec.cpp b/src/gromacs/mdlib/forcerec.cpp index 0b090cd656..afbb29366b 100644 --- a/src/gromacs/mdlib/forcerec.cpp +++ b/src/gromacs/mdlib/forcerec.cpp @@ -198,8 +198,8 @@ enum class ConstraintTypeForAtom : int Settle, //! F_SETTLE active }; -static std::vector makeAtomInfoForEachMoleculeBlock(const gmx_mtop_t& mtop, - const t_forcerec* fr) +static std::vector +makeAtomInfoForEachMoleculeBlock(const gmx_mtop_t& mtop, const t_forcerec* fr) { std::vector atomUsesVdw(fr->ntype, false); for (int ai = 0; ai < fr->ntype; ai++) @@ -211,8 +211,8 @@ static std::vector makeAtomInfoForEachMoleculeBlock } } - std::vector atomInfoForEachMoleculeBlock; - int indexOfFirstAtomInMoleculeBlock = 0; + std::vector atomInfoForEachMoleculeBlock; + int indexOfFirstAtomInMoleculeBlock = 0; for (size_t mb = 0; mb < mtop.molblock.size(); mb++) { const gmx_molblock_t& molb = mtop.molblock[mb]; @@ -255,7 +255,7 @@ static std::vector makeAtomInfoForEachMoleculeBlock } } - AtomInfoWithinMoleculeBlock atomInfoOfMoleculeBlock; + gmx::AtomInfoWithinMoleculeBlock atomInfoOfMoleculeBlock; atomInfoOfMoleculeBlock.indexOfFirstAtomInMoleculeBlock = indexOfFirstAtomInMoleculeBlock; atomInfoOfMoleculeBlock.indexOfLastAtomInMoleculeBlock = indexOfFirstAtomInMoleculeBlock + molb.nmol * molt.atoms.nr; @@ -290,10 +290,10 @@ static std::vector makeAtomInfoForEachMoleculeBlock int& atomInfo = atomInfoOfMoleculeBlock.atomInfo[moleculeOffsetInBlock + a]; /* Store the energy group in atomInfo */ - int gid = getGroupType(mtop.groups, + int gid = getGroupType(mtop.groups, SimulationAtomGroupType::EnergyOutput, indexOfFirstAtomInMoleculeBlock + moleculeOffsetInBlock + a); - SET_CGINFO_GID(atomInfo, gid); + atomInfo = (atomInfo & ~gmx::sc_atomInfo_EnergyGroupIdMask) | gid; bool bHaveVDW = (atomUsesVdw[atom.type] || atomUsesVdw[atom.typeB]); bool bHaveQ = (atom.q != 0 || atom.qB != 0); @@ -311,25 +311,27 @@ static std::vector makeAtomInfoForEachMoleculeBlock switch (constraintTypeOfAtom[a]) { - case ConstraintTypeForAtom::Constraint: SET_CGINFO_CONSTR(atomInfo); break; - case ConstraintTypeForAtom::Settle: SET_CGINFO_SETTLE(atomInfo); break; + case ConstraintTypeForAtom::Constraint: + atomInfo |= gmx::sc_atomInfo_Constraint; + break; + case ConstraintTypeForAtom::Settle: atomInfo |= gmx::sc_atomInfo_Settle; break; default: break; } if (haveExclusions) { - SET_CGINFO_EXCL_INTER(atomInfo); + atomInfo |= gmx::sc_atomInfo_Exclusion; } if (bHaveVDW) { - SET_CGINFO_HAS_VDW(atomInfo); + atomInfo |= gmx::sc_atomInfo_HasVdw; } if (bHaveQ) { - SET_CGINFO_HAS_Q(atomInfo); + atomInfo |= gmx::sc_atomInfo_HasCharge; } if (fr->efep != FreeEnergyPerturbationType::No && PERTURBED(atom)) { - SET_CGINFO_FEP(atomInfo); + atomInfo |= gmx::sc_atomInfo_FreeEnergyPerturbation; } } } @@ -342,8 +344,8 @@ static std::vector makeAtomInfoForEachMoleculeBlock return atomInfoForEachMoleculeBlock; } -static std::vector expandAtomInfo(const int nmb, - gmx::ArrayRef atomInfoForEachMoleculeBlock) +static std::vector expandAtomInfo(const int nmb, + gmx::ArrayRef atomInfoForEachMoleculeBlock) { const int numAtoms = atomInfoForEachMoleculeBlock[nmb - 1].indexOfLastAtomInMoleculeBlock; diff --git a/src/gromacs/mdrun/tpi.cpp b/src/gromacs/mdrun/tpi.cpp index 606ab186ef..e84fdff31a 100644 --- a/src/gromacs/mdrun/tpi.cpp +++ b/src/gromacs/mdrun/tpi.cpp @@ -444,10 +444,10 @@ void LegacySimulator::do_tpi() fr->nbv->changePairlistRadii(inputrec->rlist, inputrec->rlist); ngid = groups->groups[SimulationAtomGroupType::EnergyOutput].size(); - gid_tp = GET_CGINFO_GID(fr->atomInfo[a_tp0]); + gid_tp = fr->atomInfo[a_tp0] & gmx::sc_atomInfo_EnergyGroupIdMask; for (int a = a_tp0 + 1; a < a_tp1; a++) { - if (GET_CGINFO_GID(fr->atomInfo[a]) != gid_tp) + if ((fr->atomInfo[a] & gmx::sc_atomInfo_EnergyGroupIdMask) != gid_tp) { fprintf(fplog, "NOTE: Atoms in the molecule to insert belong to different energy groups.\n" diff --git a/src/gromacs/mdtypes/atominfo.h b/src/gromacs/mdtypes/atominfo.h new file mode 100644 index 0000000000..013ea6cb56 --- /dev/null +++ b/src/gromacs/mdtypes/atominfo.h @@ -0,0 +1,102 @@ +/* + * This file is part of the GROMACS molecular simulation package. + * + * Copyright (c) 2021, by the GROMACS development team, led by + * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, + * and including many others, as listed in the AUTHORS file in the + * top-level source directory and at http://www.gromacs.org. + * + * GROMACS is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * GROMACS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with GROMACS; if not, see + * http://www.gnu.org/licenses, or write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * If you want to redistribute modifications to GROMACS, please + * consider that scientific software is very special. Version + * control is crucial - bugs must be traceable. We will be happy to + * consider code for inclusion in the official distribution, but + * derived work must not be called official GROMACS. Details are found + * in the README & COPYING files - if they are missing, get the + * official version at http://www.gromacs.org. + * + * To help us fund GROMACS development, we humbly ask that you cite + * the research papers on the package. Check out http://www.gromacs.org. + */ +/*! \libinternal \file + * + * \brief This file makes declarations used for storing bitfields + * describing each atom so that other modules can efficiently process + * them. + * + * \inlibraryapi + */ + +#ifndef GMX_MDTYPES_ATOMINFO_H +#define GMX_MDTYPES_ATOMINFO_H + +#include + +namespace gmx +{ + +/*! \brief Constants whose bit describes properties of atoms in + * AtomInfoWithinMoleculeBlock.atomInfo. + * + * No bit should exceed 1 << 63, so that it fits into a 64-bit + * integer. + * + * Since the tpx format support max 256 energy groups, we do the same + * here, reserving bits 0-7 for the energy-group ID. + */ +//! \{ +static constexpr int sc_atomInfo_FreeEnergyPerturbation = 1 << 15; +static constexpr int sc_atomInfo_Exclusion = 1 << 17; +static constexpr int sc_atomInfo_Constraint = 1 << 20; +static constexpr int sc_atomInfo_Settle = 1 << 21; +static constexpr int sc_atomInfo_BondCommunication = 1 << 22; +static constexpr int sc_atomInfo_HasVdw = 1 << 23; +static constexpr int sc_atomInfo_HasCharge = 1 << 24; +//! \} +//! The first 8 bits are reserved for energy-group ID +static constexpr int sc_atomInfo_EnergyGroupIdMask = 0b11111111; + +/*! \brief Contains information about each atom in a molecule block of + * the global topology. */ +struct AtomInfoWithinMoleculeBlock +{ + //! Index within the system of the first atom in the molecule block + int indexOfFirstAtomInMoleculeBlock = 0; + //! Index within the system of the last atom in the molecule block + int indexOfLastAtomInMoleculeBlock = 0; + /*! \brief Atom info for each atom in the block. + * + * The typical case is that all atoms are identical for each + * molecule of the block, and if so this vector has size equal to + * the number of atoms in the molecule. + * + * An example of an atypical case is QM/MM, where multiple + * molecules might be present and different molecules have + * different atoms within any one QM group or region. Now there are + * multiple kinds of molecules with the same connectivity, so we simply + * write out the atom info for the entire molecule block. Then the + * size equals the product of the number of atoms in the + * molecule and the number of molecules. + * + * The vector needs to be indexed accordingly. + */ + std::vector atomInfo; +}; + +} // namespace gmx + +#endif diff --git a/src/gromacs/mdtypes/forcerec.h b/src/gromacs/mdtypes/forcerec.h index 3aa4e28ec3..44477aa6f3 100644 --- a/src/gromacs/mdtypes/forcerec.h +++ b/src/gromacs/mdtypes/forcerec.h @@ -43,6 +43,7 @@ #include #include "gromacs/math/vectypes.h" +#include "gromacs/mdtypes/atominfo.h" #include "gromacs/mdtypes/md_enums.h" #include "gromacs/pbcutil/ishift.h" #include "gromacs/pbcutil/pbc.h" @@ -73,30 +74,6 @@ class PmePpCommGpu; class WholeMoleculeTransform; } // namespace gmx -/* macros for the atom info data in forcerec - * - * Since the tpx format support max 256 energy groups, we do the same here. - * Note that we thus have bits 8-14 still unused. - */ -#define SET_CGINFO_GID(cgi, gid) (cgi) = (((cgi) & ~255) | (gid)) -#define GET_CGINFO_GID(cgi) ((cgi)&255) -#define SET_CGINFO_FEP(cgi) (cgi) = ((cgi) | (1 << 15)) -#define GET_CGINFO_FEP(cgi) ((cgi) & (1 << 15)) -#define SET_CGINFO_EXCL_INTER(cgi) (cgi) = ((cgi) | (1 << 17)) -#define GET_CGINFO_EXCL_INTER(cgi) ((cgi) & (1 << 17)) -#define SET_CGINFO_CONSTR(cgi) (cgi) = ((cgi) | (1 << 20)) -#define GET_CGINFO_CONSTR(cgi) ((cgi) & (1 << 20)) -#define SET_CGINFO_SETTLE(cgi) (cgi) = ((cgi) | (1 << 21)) -#define GET_CGINFO_SETTLE(cgi) ((cgi) & (1 << 21)) -/* This bit is only used with bBondComm in the domain decomposition */ -#define SET_CGINFO_BOND_INTER(cgi) (cgi) = ((cgi) | (1 << 22)) -#define GET_CGINFO_BOND_INTER(cgi) ((cgi) & (1 << 22)) -#define SET_CGINFO_HAS_VDW(cgi) (cgi) = ((cgi) | (1 << 23)) -#define GET_CGINFO_HAS_VDW(cgi) ((cgi) & (1 << 23)) -#define SET_CGINFO_HAS_Q(cgi) (cgi) = ((cgi) | (1 << 24)) -#define GET_CGINFO_HAS_Q(cgi) ((cgi) & (1 << 24)) - - /* Value to be used in mdrun for an infinite cut-off. * Since we need to compare with the cut-off squared, * this value should be slighlty smaller than sqrt(GMX_FLOAT_MAX). @@ -105,33 +82,6 @@ class WholeMoleculeTransform; //! Check the cuttoff real cutoff_inf(real cutoff); -/*! \brief Contains information about each atom in a molecule block of - * the global topology. */ -struct AtomInfoWithinMoleculeBlock -{ - //! Index within the system of the first atom in the molecule block - int indexOfFirstAtomInMoleculeBlock = 0; - //! Index within the system of the last atom in the molecule block - int indexOfLastAtomInMoleculeBlock = 0; - /*! \brief Atom info for each atom in the block. - * - * The typical case is that all atoms are identical for each - * molecule of the block, and if so this vector has size equal to - * the number of atoms in the molecule. - * - * An example of an atypical case is QM/MM, where multiple - * molecules might be present and different molecules have - * different atoms within any one QM group or region. Now there are - * multiple kinds of molecules with the same connectivity, so we simply - * write out the atom info for the entire molecule block. Then the - * size equals the product of the number of atoms in the - * molecule and the number of molecules. - * - * The vector needs to be indexed accordingly. */ - std::vector atomInfo; -}; - - /* Forward declaration of type for managing Ewald tables */ struct gmx_ewald_tab_t; @@ -239,7 +189,7 @@ struct t_forcerec FreeEnergyPerturbationType efep = FreeEnergyPerturbationType::No; /* Information about atom properties for the molecule blocks in the global topology */ - std::vector atomInfoForEachMoleculeBlock; + std::vector atomInfoForEachMoleculeBlock; /* Information about atom properties for local and non-local atoms */ std::vector atomInfo; diff --git a/src/gromacs/nbnxm/atomdata.cpp b/src/gromacs/nbnxm/atomdata.cpp index 5337c8072e..4ccf58e213 100644 --- a/src/gromacs/nbnxm/atomdata.cpp +++ b/src/gromacs/nbnxm/atomdata.cpp @@ -861,8 +861,13 @@ static void nbnxn_atomdata_mask_fep(nbnxn_atomdata_t* nbat, const Nbnxm::GridSet } /* Copies the energy group indices to a reordered and packed array */ -static void -copy_egp_to_nbat_egps(const int* a, int na, int na_round, int na_c, int bit_shift, const int* in, int* innb) +static void copy_egp_to_nbat_egps(const int* a, + int na, + int na_round, + int na_c, + int bit_shift, + ArrayRef atomInfo, + int* atomInfoNb) { int i = 0, j = 0; for (; i < na; i += na_c) @@ -874,15 +879,15 @@ copy_egp_to_nbat_egps(const int* a, int na, int na_round, int na_c, int bit_shif int at = a[i + sa]; if (at >= 0) { - comb |= (GET_CGINFO_GID(in[at]) << (sa * bit_shift)); + comb |= (atomInfo[at] & sc_atomInfo_EnergyGroupIdMask) << (sa * bit_shift); } } - innb[j++] = comb; + atomInfoNb[j++] = comb; } /* Complete the partially filled last cell with fill */ for (; i < na_round; i += na_c) { - innb[j++] = 0; + atomInfoNb[j++] = 0; } } @@ -911,7 +916,7 @@ static void nbnxn_atomdata_set_energygroups(nbnxn_atomdata_t::Params* params, numAtoms, c_nbnxnCpuIClusterSize, params->neg_2log, - atomInfo.data(), + atomInfo, params->energrp.data() + grid.atomToCluster(atomOffset)); } } diff --git a/src/gromacs/nbnxm/benchmark/bench_system.cpp b/src/gromacs/nbnxm/benchmark/bench_system.cpp index 1ba1c01d90..767cbfaf09 100644 --- a/src/gromacs/nbnxm/benchmark/bench_system.cpp +++ b/src/gromacs/nbnxm/benchmark/bench_system.cpp @@ -50,6 +50,7 @@ #include "gromacs/math/vec.h" #include "gromacs/mdlib/dispersioncorrection.h" +#include "gromacs/mdtypes/atominfo.h" #include "gromacs/mdtypes/forcerec.h" #include "gromacs/nbnxm/nbnxm.h" #include "gromacs/pbcutil/ishift.h" @@ -179,18 +180,18 @@ BenchmarkSystem::BenchmarkSystem(const int multiplicationFactor, const std::stri // Oxgygen atomTypes[a] = typeOxygen; charges[a] = chargeOxygen; - SET_CGINFO_HAS_VDW(atomInfoAllVdw[a]); - SET_CGINFO_HAS_VDW(atomInfoOxygenVdw[a]); + atomInfoAllVdw[a] |= gmx::sc_atomInfo_HasVdw; + atomInfoOxygenVdw[a] |= gmx::sc_atomInfo_HasVdw; } else { // Hydrogen atomTypes[a] = typeHydrogen; charges[a] = chargeHydrogen; - SET_CGINFO_HAS_VDW(atomInfoAllVdw[a]); + atomInfoAllVdw[a] |= gmx::sc_atomInfo_HasVdw; } - SET_CGINFO_HAS_Q(atomInfoAllVdw[a]); - SET_CGINFO_HAS_Q(atomInfoOxygenVdw[a]); + atomInfoAllVdw[a] |= gmx::sc_atomInfo_HasCharge; + atomInfoOxygenVdw[a] |= gmx::sc_atomInfo_HasCharge; excls.pushBackListOfSize(numAtomsInMolecule); gmx::ArrayRef exclusionsForAtom = excls.back(); diff --git a/src/gromacs/nbnxm/benchmark/bench_system.h b/src/gromacs/nbnxm/benchmark/bench_system.h index acf0232669..f5e0bdd746 100644 --- a/src/gromacs/nbnxm/benchmark/bench_system.h +++ b/src/gromacs/nbnxm/benchmark/bench_system.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2019,2020, by the GROMACS development team, led by + * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. diff --git a/src/gromacs/nbnxm/grid.cpp b/src/gromacs/nbnxm/grid.cpp index a0de053ca6..bfd143a0a9 100644 --- a/src/gromacs/nbnxm/grid.cpp +++ b/src/gromacs/nbnxm/grid.cpp @@ -56,7 +56,7 @@ #include "gromacs/math/vec.h" #include "gromacs/mdlib/gmx_omp_nthreads.h" #include "gromacs/mdlib/updategroupscog.h" -#include "gromacs/mdtypes/forcerec.h" // only for GET_CGINFO_* +#include "gromacs/mdtypes/atominfo.h" #include "gromacs/nbnxm/atomdata.h" #include "gromacs/simd/simd.h" #include "gromacs/simd/vector_operations.h" @@ -798,12 +798,12 @@ static void print_bbsizes_supersub(FILE* fp, const Grid& grid) * * Sorts atoms on LJ coefficients: !=0 first, ==0 at the end. */ -static void sort_cluster_on_flag(int numAtomsInCluster, - int atomStart, - int atomEnd, - const int* atinfo, - gmx::ArrayRef order, - int* flags) +static void sort_cluster_on_flag(int numAtomsInCluster, + int atomStart, + int atomEnd, + gmx::ArrayRef atomInfo, + gmx::ArrayRef order, + int* flags) { constexpr int c_maxNumAtomsInCluster = 8; int sort1[c_maxNumAtomsInCluster]; @@ -818,15 +818,15 @@ static void sort_cluster_on_flag(int numAtomsInCluster, for (int s = atomStart; s < atomEnd; s += numAtomsInCluster) { /* Make lists for this (sub-)cell on atoms with and without LJ */ - int n1 = 0; - int n2 = 0; - gmx_bool haveQ = FALSE; - int a_lj_max = -1; + int n1 = 0; + int n2 = 0; + bool haveQ = false; + int a_lj_max = -1; for (int a = s; a < std::min(s + numAtomsInCluster, atomEnd); a++) { - haveQ = haveQ || GET_CGINFO_HAS_Q(atinfo[order[a]]); + haveQ = haveQ || bool(atomInfo[order[a]] & gmx::sc_atomInfo_HasCharge); - if (GET_CGINFO_HAS_VDW(atinfo[order[a]])) + if (atomInfo[order[a]] & (gmx::sc_atomInfo_HasVdw)) { sort1[n1++] = order[a]; a_lj_max = a; @@ -879,7 +879,7 @@ void Grid::fillCell(GridSetData* gridSetData, nbnxn_atomdata_t* nbat, int atomStart, int atomEnd, - const int* atinfo, + gmx::ArrayRef atomInfo, gmx::ArrayRef x, BoundingBox gmx_unused* bb_work_aligned) { @@ -897,7 +897,7 @@ void Grid::fillCell(GridSetData* gridSetData, sort_cluster_on_flag(geometry_.numAtomsICluster, atomStart, atomEnd, - atinfo, + atomInfo, atomIndices, flags_.data() + atomToCluster(atomStart) - cellOffset_); } @@ -912,7 +912,7 @@ void Grid::fillCell(GridSetData* gridSetData, fep_[cell] = 0; for (int at = atomStart; at < atomEnd; at++) { - if (atomIndices[at] >= 0 && GET_CGINFO_FEP(atinfo[atomIndices[at]])) + if (atomIndices[at] >= 0 && (atomInfo[atomIndices[at]] & gmx::sc_atomInfo_FreeEnergyPerturbation)) { fep_[cell] |= (1 << (at - atomStart)); } @@ -1025,7 +1025,7 @@ void Grid::fillCell(GridSetData* gridSetData, void Grid::sortColumnsCpuGeometry(GridSetData* gridSetData, int dd_zone, - const int* atinfo, + gmx::ArrayRef atomInfo, gmx::ArrayRef x, nbnxn_atomdata_t* nbat, const gmx::Range columnRange, @@ -1075,7 +1075,7 @@ void Grid::sortColumnsCpuGeometry(GridSetData* gridSetData, const int numAtomsLeftInColumn = std::max(numAtoms - (atomOffsetCell - atomOffset), 0); const int numAtomsCell = std::min(numAtomsPerCell, numAtomsLeftInColumn); - fillCell(gridSetData, nbat, atomOffsetCell, atomOffsetCell + numAtomsCell, atinfo, x, nullptr); + fillCell(gridSetData, nbat, atomOffsetCell, atomOffsetCell + numAtomsCell, atomInfo, x, nullptr); /* This copy to bbcz is not really necessary. * But it allows to use the same grid search code @@ -1100,7 +1100,7 @@ void Grid::sortColumnsCpuGeometry(GridSetData* gridSetData, /* Spatially sort the atoms within one grid column */ void Grid::sortColumnsGpuGeometry(GridSetData* gridSetData, int dd_zone, - const int* atinfo, + gmx::ArrayRef atomInfo, gmx::ArrayRef x, nbnxn_atomdata_t* nbat, const gmx::Range columnRange, @@ -1224,7 +1224,7 @@ void Grid::sortColumnsGpuGeometry(GridSetData* gridSetData, const int numAtomsX = std::min(subdiv_x, numAtomsInColumn - (atomOffsetX - atomOffset)); - fillCell(gridSetData, nbat, atomOffsetX, atomOffsetX + numAtomsX, atinfo, x, bb_work_aligned); + fillCell(gridSetData, nbat, atomOffsetX, atomOffsetX + numAtomsX, atomInfo, x, bb_work_aligned); } } } @@ -1370,7 +1370,7 @@ void Grid::setCellIndices(int ddZone, GridSetData* gridSetData, gmx::ArrayRef gridWork, const gmx::Range atomRange, - const int* atinfo, + gmx::ArrayRef atomInfo, gmx::ArrayRef x, const int numAtomsMoved, nbnxn_atomdata_t* nbat) @@ -1490,12 +1490,12 @@ void Grid::setCellIndices(int ddZone, if (geometry_.isSimple) { sortColumnsCpuGeometry( - gridSetData, ddZone, atinfo, x, nbat, columnRange, gridWork[thread].sortBuffer); + gridSetData, ddZone, atomInfo, x, nbat, columnRange, gridWork[thread].sortBuffer); } else { sortColumnsGpuGeometry( - gridSetData, ddZone, atinfo, x, nbat, columnRange, gridWork[thread].sortBuffer); + gridSetData, ddZone, atomInfo, x, nbat, columnRange, gridWork[thread].sortBuffer); } } GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR diff --git a/src/gromacs/nbnxm/grid.h b/src/gromacs/nbnxm/grid.h index 6c1a5b8b96..5c669446cd 100644 --- a/src/gromacs/nbnxm/grid.h +++ b/src/gromacs/nbnxm/grid.h @@ -349,7 +349,7 @@ public: GridSetData* gridSetData, gmx::ArrayRef gridWork, gmx::Range atomRange, - const int* atinfo, + gmx::ArrayRef atomInfo, gmx::ArrayRef x, int numAtomsMoved, nbnxn_atomdata_t* nbat); @@ -375,14 +375,14 @@ private: nbnxn_atomdata_t* nbat, int atomStart, int atomEnd, - const int* atinfo, + gmx::ArrayRef atomInfo, gmx::ArrayRef x, BoundingBox gmx_unused* bb_work_aligned); //! Spatially sort the atoms within the given column range, for CPU geometry void sortColumnsCpuGeometry(GridSetData* gridSetData, int dd_zone, - const int* atinfo, + gmx::ArrayRef atomInfo, gmx::ArrayRef x, nbnxn_atomdata_t* nbat, gmx::Range columnRange, @@ -391,7 +391,7 @@ private: //! Spatially sort the atoms within the given column range, for GPU geometry void sortColumnsGpuGeometry(GridSetData* gridSetData, int dd_zone, - const int* atinfo, + gmx::ArrayRef atomInfo, gmx::ArrayRef x, nbnxn_atomdata_t* nbat, gmx::Range columnRange, diff --git a/src/gromacs/nbnxm/gridset.cpp b/src/gromacs/nbnxm/gridset.cpp index 3070568e74..07d5f9a042 100644 --- a/src/gromacs/nbnxm/gridset.cpp +++ b/src/gromacs/nbnxm/gridset.cpp @@ -230,7 +230,7 @@ void GridSet::putOnGrid(const matrix box, /* Copy the already computed cell indices to the grid and sort, when needed */ grid.setCellIndices( - ddZone, cellOffset, &gridSetData_, gridWork_, atomRange, atomInfo.data(), x, numAtomsMoved, nbat); + ddZone, cellOffset, &gridSetData_, gridWork_, atomRange, atomInfo, x, numAtomsMoved, nbat); if (gridIndex == 0) { -- 2.22.0