From 6dbf35dddb95932e6e98d8e923f4ba87bf257b8e Mon Sep 17 00:00:00 2001 From: Paul Bauer Date: Fri, 2 Apr 2021 15:58:10 +0000 Subject: [PATCH] Replace gmx_mtop_ilistloop_all --- src/gromacs/domdec/domdec.cpp | 17 ++---- src/gromacs/fileio/tpxio.cpp | 8 +-- src/gromacs/gmxpreprocess/readir.cpp | 19 +++--- src/gromacs/listed_forces/disre.cpp | 28 ++++----- src/gromacs/listed_forces/orires.cpp | 20 +++---- src/gromacs/mdlib/settle.cpp | 10 ++-- src/gromacs/topology/mtop_util.cpp | 88 +++++++++++++--------------- src/gromacs/topology/mtop_util.h | 84 +++++++++++++++++++++----- 8 files changed, 152 insertions(+), 122 deletions(-) diff --git a/src/gromacs/domdec/domdec.cpp b/src/gromacs/domdec/domdec.cpp index 5b431017bc..d941620c12 100644 --- a/src/gromacs/domdec/domdec.cpp +++ b/src/gromacs/domdec/domdec.cpp @@ -1707,16 +1707,14 @@ static real* get_slb_frac(const gmx::MDLogger& mdlog, const char* dir, int nc, c static int multi_body_bondeds_count(const gmx_mtop_t& mtop) { - int n = 0; - gmx_mtop_ilistloop_t iloop = gmx_mtop_ilistloop_init(mtop); - int nmol = 0; - while (const InteractionLists* ilists = gmx_mtop_ilistloop_next(iloop, &nmol)) + int n = 0; + for (const auto ilists : IListRange(mtop)) { - for (auto& ilist : extractILists(*ilists, IF_BOND)) + for (auto& ilist : extractILists(ilists.list(), IF_BOND)) { if (NRAL(ilist.functionType) > 2) { - n += nmol * (ilist.iatoms.size() / ilistStride(ilist)); + n += ilists.nmol() * (ilist.iatoms.size() / ilistStride(ilist)); } } } @@ -1914,16 +1912,13 @@ static gmx_domdec_comm_t* init_dd_comm() /* Returns whether mtop contains constraints and/or vsites */ static bool systemHasConstraintsOrVsites(const gmx_mtop_t& mtop) { - auto* ilistLoop = gmx_mtop_ilistloop_init(mtop); - int nmol = 0; - while (const InteractionLists* ilists = gmx_mtop_ilistloop_next(ilistLoop, &nmol)) + for (const auto ilists : IListRange(mtop)) { - if (!extractILists(*ilists, IF_CONSTRAINT | IF_VSITE).empty()) + if (!extractILists(ilists.list(), IF_CONSTRAINT | IF_VSITE).empty()) { return true; } } - return false; } diff --git a/src/gromacs/fileio/tpxio.cpp b/src/gromacs/fileio/tpxio.cpp index 4bcf3256d6..74527a7581 100644 --- a/src/gromacs/fileio/tpxio.cpp +++ b/src/gromacs/fileio/tpxio.cpp @@ -2533,15 +2533,11 @@ static void do_molblock(gmx::ISerializer* serializer, gmx_molblock_t* molb, int static void set_disres_npair(gmx_mtop_t* mtop) { - gmx_mtop_ilistloop_t iloop; - int nmol; - gmx::ArrayRef ip = mtop->ffparams.iparams; - iloop = gmx_mtop_ilistloop_init(*mtop); - while (const InteractionLists* ilist = gmx_mtop_ilistloop_next(iloop, &nmol)) + for (const auto ilist : IListRange(*mtop)) { - const InteractionList& il = (*ilist)[F_DISRES]; + const InteractionList& il = ilist.list()[F_DISRES]; if (!il.empty()) { diff --git a/src/gromacs/gmxpreprocess/readir.cpp b/src/gromacs/gmxpreprocess/readir.cpp index 2c0e08c4fe..426bd68d39 100644 --- a/src/gromacs/gmxpreprocess/readir.cpp +++ b/src/gromacs/gmxpreprocess/readir.cpp @@ -4111,10 +4111,8 @@ static void check_disre(const gmx_mtop_t& mtop) static bool absolute_reference(const t_inputrec* ir, const gmx_mtop_t& sys, const bool posres_only, ivec AbsRef) { - int d, g, i; - gmx_mtop_ilistloop_t iloop; - int nmol; - const t_iparams* pr; + int d, g, i; + const t_iparams* pr; clear_ivec(AbsRef); @@ -4139,14 +4137,13 @@ static bool absolute_reference(const t_inputrec* ir, const gmx_mtop_t& sys, cons } /* Check for position restraints */ - iloop = gmx_mtop_ilistloop_init(sys); - while (const InteractionLists* ilist = gmx_mtop_ilistloop_next(iloop, &nmol)) + for (const auto ilist : IListRange(sys)) { - if (nmol > 0 && (AbsRef[XX] == 0 || AbsRef[YY] == 0 || AbsRef[ZZ] == 0)) + if (ilist.nmol() > 0 && (AbsRef[XX] == 0 || AbsRef[YY] == 0 || AbsRef[ZZ] == 0)) { - for (i = 0; i < (*ilist)[F_POSRES].size(); i += 2) + for (int i = 0; i < ilist.list()[F_POSRES].size(); i += 2) { - pr = &sys.ffparams.iparams[(*ilist)[F_POSRES].iatoms[i]]; + pr = &sys.ffparams.iparams[ilist.list()[F_POSRES].iatoms[i]]; for (d = 0; d < DIM; d++) { if (pr->posres.fcA[d] != 0) @@ -4155,10 +4152,10 @@ static bool absolute_reference(const t_inputrec* ir, const gmx_mtop_t& sys, cons } } } - for (i = 0; i < (*ilist)[F_FBPOSRES].size(); i += 2) + for (i = 0; i < ilist.list()[F_FBPOSRES].size(); i += 2) { /* Check for flat-bottom posres */ - pr = &sys.ffparams.iparams[(*ilist)[F_FBPOSRES].iatoms[i]]; + pr = &sys.ffparams.iparams[ilist.list()[F_FBPOSRES].iatoms[i]]; if (pr->fbposres.k != 0) { switch (pr->fbposres.geom) diff --git a/src/gromacs/listed_forces/disre.cpp b/src/gromacs/listed_forces/disre.cpp index 8a901875c7..de1928792a 100644 --- a/src/gromacs/listed_forces/disre.cpp +++ b/src/gromacs/listed_forces/disre.cpp @@ -81,11 +81,9 @@ void init_disres(FILE* fplog, t_state* state, gmx_bool bIsREMD) { - int fa, nmol, npair, np; - history_t* hist; - gmx_mtop_ilistloop_t iloop; - char* ptr; - int type_min, type_max; + history_t* hist; + char* ptr; + int type_min, type_max; if (gmx_mtop_ftype_count(mtop, F_DISRES) == 0) { @@ -137,10 +135,10 @@ void init_disres(FILE* fplog, dd->npair = 0; type_min = INT_MAX; type_max = 0; - iloop = gmx_mtop_ilistloop_init(mtop); - while (const InteractionLists* il = gmx_mtop_ilistloop_next(iloop, &nmol)) + for (const auto il : IListRange(mtop)) { - if (nmol > 1 && !(*il)[F_DISRES].empty() && ir->eDisre != DistanceRestraintRefinement::Ensemble) + if (il.nmol() > 1 && !il.list()[F_DISRES].empty() + && ir->eDisre != DistanceRestraintRefinement::Ensemble) { gmx_fatal(FARGS, "NMR distance restraints with multiple copies of the same molecule are " @@ -149,19 +147,17 @@ void init_disres(FILE* fplog, "a restraint potential (bonds type 10) instead."); } - np = 0; - for (fa = 0; fa < (*il)[F_DISRES].size(); fa += 3) + int np = 0; + for (int fa = 0; fa < il.list()[F_DISRES].size(); fa += 3) { - int type; - - type = (*il)[F_DISRES].iatoms[fa]; + int type = il.list()[F_DISRES].iatoms[fa]; np++; - npair = mtop.ffparams.iparams[type].disres.npair; + int npair = mtop.ffparams.iparams[type].disres.npair; if (np == npair) { - dd->nres += (ir->eDisre == DistanceRestraintRefinement::Ensemble ? 1 : nmol); - dd->npair += nmol * npair; + dd->nres += (ir->eDisre == DistanceRestraintRefinement::Ensemble ? 1 : il.nmol()); + dd->npair += il.nmol() * npair; np = 0; type_min = std::min(type_min, type); diff --git a/src/gromacs/listed_forces/orires.cpp b/src/gromacs/listed_forces/orires.cpp index 26de7b7725..6b41b649ea 100644 --- a/src/gromacs/listed_forces/orires.cpp +++ b/src/gromacs/listed_forces/orires.cpp @@ -121,26 +121,24 @@ void init_orires(FILE* fplog, od->eig = nullptr; od->v = nullptr; - int* nr_ex = nullptr; - int typeMin = INT_MAX; - int typeMax = 0; - gmx_mtop_ilistloop_t iloop = gmx_mtop_ilistloop_init(mtop); - int nmol; - while (const InteractionLists* il = gmx_mtop_ilistloop_next(iloop, &nmol)) - { - const int numOrires = (*il)[F_ORIRES].size(); - if (nmol > 1 && numOrires > 0) + int* nr_ex = nullptr; + int typeMin = INT_MAX; + int typeMax = 0; + for (const auto il : IListRange(mtop)) + { + const int numOrires = il.list()[F_ORIRES].size(); + if (il.nmol() > 1 && numOrires > 0) { gmx_fatal(FARGS, "Found %d copies of a molecule with orientation restrains while the current " "code only supports a single copy. If you want to ensemble average, run " "multiple copies of the system using the multi-sim feature of mdrun.", - nmol); + il.nmol()); } for (int i = 0; i < numOrires; i += 3) { - int type = (*il)[F_ORIRES].iatoms[i]; + int type = il.list()[F_ORIRES].iatoms[i]; int ex = mtop.ffparams.iparams[type].orires.ex; if (ex >= od->nex) { diff --git a/src/gromacs/mdlib/settle.cpp b/src/gromacs/mdlib/settle.cpp index 0ccadf81e9..24d0d58fb5 100644 --- a/src/gromacs/mdlib/settle.cpp +++ b/src/gromacs/mdlib/settle.cpp @@ -156,13 +156,11 @@ SettleData::SettleData(const gmx_mtop_t& mtop) : useSimd_(getenv("GMX_DISABLE_SIMD_KERNELS") == nullptr) { /* Check that we have only one settle type */ - int settle_type = -1; - gmx_mtop_ilistloop_t iloop = gmx_mtop_ilistloop_init(mtop); - int nmol; - const int nral1 = 1 + NRAL(F_SETTLE); - while (const InteractionLists* ilists = gmx_mtop_ilistloop_next(iloop, &nmol)) + int settle_type = -1; + const int nral1 = 1 + NRAL(F_SETTLE); + for (const auto ilists : IListRange(mtop)) { - const InteractionList& ilist = (*ilists)[F_SETTLE]; + const InteractionList& ilist = ilists.list()[F_SETTLE]; for (int i = 0; i < ilist.size(); i += nral1) { if (settle_type == -1) diff --git a/src/gromacs/topology/mtop_util.cpp b/src/gromacs/topology/mtop_util.cpp index 59e9e13356..42eb320ddd 100644 --- a/src/gromacs/topology/mtop_util.cpp +++ b/src/gromacs/topology/mtop_util.cpp @@ -238,70 +238,66 @@ gmx_bool gmx_mtop_atomloop_block_next(gmx_mtop_atomloop_block_t aloop, const t_a return TRUE; } -typedef struct gmx_mtop_ilistloop +IListIterator::IListIterator(const gmx_mtop_t& mtop, size_t molblock) : + mtop_(&mtop), + mblock_(molblock) { - const gmx_mtop_t* mtop; - int mblock; -} t_gmx_mtop_ilist; +} -gmx_mtop_ilistloop_t gmx_mtop_ilistloop_init(const gmx_mtop_t& mtop) +IListIterator& IListIterator::operator++() { - struct gmx_mtop_ilistloop* iloop = nullptr; - - snew(iloop, 1); - - iloop->mtop = &mtop; - iloop->mblock = -1; - - return iloop; + mblock_++; + return *this; } -static void gmx_mtop_ilistloop_destroy(gmx_mtop_ilistloop_t iloop) +bool IListIterator::operator==(const IListIterator& o) const { - sfree(iloop); + return mtop_ == o.mtop_ && mblock_ == o.mblock_; } -const InteractionLists* gmx_mtop_ilistloop_next(gmx_mtop_ilistloop_t iloop, int* nmol) +const InteractionLists& IListProxy::list() const { - if (iloop == nullptr) + // one past the end means we want to take the + // intermolecular list instead. + if (it_->mblock_ == it_->mtop_->molblock.size()) { - gmx_incons("gmx_mtop_ilistloop_next called without calling gmx_mtop_ilistloop_init"); + return *it_->mtop_->intermolecular_ilist; } - - iloop->mblock++; - if (iloop->mblock >= gmx::ssize(iloop->mtop->molblock)) + else { - if (iloop->mblock == gmx::ssize(iloop->mtop->molblock) && iloop->mtop->bIntermolecularInteractions) - { - *nmol = 1; - return iloop->mtop->intermolecular_ilist.get(); - } - - gmx_mtop_ilistloop_destroy(iloop); - return nullptr; + return it_->mtop_->moltype[it_->mtop_->molblock[it_->mblock_].type].ilist; } +} - *nmol = iloop->mtop->molblock[iloop->mblock].nmol; - - return &iloop->mtop->moltype[iloop->mtop->molblock[iloop->mblock].type].ilist; +int IListProxy::nmol() const +{ + // one past the end means we want to take the + // intermolecular list instead. + if (it_->mblock_ == it_->mtop_->molblock.size()) + { + return 1; + } + else + { + return it_->mtop_->molblock[it_->mblock_].nmol; + } } -typedef struct gmx_mtop_ilistloop_all + +IListRange::IListRange(const gmx_mtop_t& mtop) : begin_(mtop), end_(mtop, mtop.molblock.size()) { - const gmx_mtop_t* mtop; - size_t mblock; - int mol; - int a_offset; -} t_gmx_mtop_ilist_all; + if (mtop.bIntermolecularInteractions) + { + end_ = IListIterator(mtop, mtop.molblock.size() + 1); + } +} int gmx_mtop_ftype_count(const gmx_mtop_t& mtop, int ftype) { - int nmol = 0; - int n = 0; + int n = 0; - gmx_mtop_ilistloop_t iloop = gmx_mtop_ilistloop_init(mtop); - while (const InteractionLists* il = gmx_mtop_ilistloop_next(iloop, &nmol)) + for (const IListProxy il : IListRange(mtop)) { - n += nmol * (*il)[ftype].size() / (1 + NRAL(ftype)); + n += il.nmol() * il.list()[ftype].size() / (1 + NRAL(ftype)); } if (mtop.bIntermolecularInteractions) @@ -316,15 +312,13 @@ int gmx_mtop_interaction_count(const gmx_mtop_t& mtop, const int unsigned if_fla { int n = 0; - gmx_mtop_ilistloop_t iloop = gmx_mtop_ilistloop_init(mtop); - int nmol = 0; - while (const InteractionLists* il = gmx_mtop_ilistloop_next(iloop, &nmol)) + for (const IListProxy il : IListRange(mtop)) { for (int ftype = 0; ftype < F_NRE; ftype++) { if ((interaction_function[ftype].flags & if_flags) == if_flags) { - n += nmol * (*il)[ftype].size() / (1 + NRAL(ftype)); + n += il.nmol() * il.list()[ftype].size() / (1 + NRAL(ftype)); } } } diff --git a/src/gromacs/topology/mtop_util.h b/src/gromacs/topology/mtop_util.h index e4615c46bb..c8cbc57a17 100644 --- a/src/gromacs/topology/mtop_util.h +++ b/src/gromacs/topology/mtop_util.h @@ -157,6 +157,76 @@ private: AtomIterator begin_, end_; }; +class IListIterator; + +//! Proxy object returned from IListIterator +class IListProxy +{ +public: + //! Default constructor. + IListProxy(const IListIterator* it) : it_(it) {} + //! Access current global atom number. + const InteractionLists& list() const; + //! Access current molecule. + int nmol() const; + +private: + const IListIterator* it_; +}; + +/*! \brief + * Object that allows looping over all atoms in an mtop. + */ +class IListIterator : + public boost::stl_interfaces::proxy_iterator_interface +{ + using Base = + boost::stl_interfaces::proxy_iterator_interface; + +public: + //! Construct from topology. + explicit IListIterator(const gmx_mtop_t& mtop, size_t mblock = 0); + + //! Prefix increment. + IListIterator& operator++(); + using Base:: operator++; + + //! Equality comparison. + bool operator==(const IListIterator& o) const; + + //! Dereference operator. Returns proxy. + IListProxy operator*() const { return { this }; } + +private: + //! Global topology. + const gmx_mtop_t* mtop_; + //! Index of molecule block corresponding to the current location. + size_t mblock_; + + friend class IListProxy; +}; + + +/*! \brief + * Range over all interaction lists of topology. + * + * Includes the intermolecular interactions as the final element in the + * range if present. + */ +class IListRange +{ +public: + //! Default constructor. + explicit IListRange(const gmx_mtop_t& mtop); + //! Iterator to begin of range. + IListIterator& begin() { return begin_; } + //! Iterator to end of range. + IListIterator& end() { return end_; } + +private: + IListIterator begin_, end_; +}; + /* Abstract type for atom loop over atoms in all molecule blocks */ typedef struct gmx_mtop_atomloop_block* gmx_mtop_atomloop_block_t; @@ -180,20 +250,6 @@ gmx_mtop_atomloop_block_t gmx_mtop_atomloop_block_init(const gmx_mtop_t& mtop); gmx_bool gmx_mtop_atomloop_block_next(gmx_mtop_atomloop_block_t aloop, const t_atom** atom, int* nmol); -/* Abstract type for ilist loop over all ilists */ -typedef struct gmx_mtop_ilistloop* gmx_mtop_ilistloop_t; - -/* Initialize an ilist loop over all molecule types in the system. */ -gmx_mtop_ilistloop_t gmx_mtop_ilistloop_init(const gmx_mtop_t& mtop); - -/* Loop to the next molecule, - * When not at the end: - * returns a valid pointer to the next array ilist_mol[F_NRE], - * writes the number of molecules for this ilist in *nmol. - * When at the end, destroys iloop and returns nullptr. - */ -const InteractionLists* gmx_mtop_ilistloop_next(gmx_mtop_ilistloop_t iloop, int* nmol); - /* Returns the total number of interactions in the system of type ftype */ int gmx_mtop_ftype_count(const gmx_mtop_t& mtop, int ftype); -- 2.22.0