From: Berk Hess Date: Tue, 31 Oct 2017 10:03:02 +0000 (+0100) Subject: Also print 1x1 pair-list setup to log X-Git-Url: http://biod.pnpi.spb.ru/gitweb/?a=commitdiff_plain;h=38b853c1790a434d0ff071ee35407ab017777db9;p=alexxy%2Fgromacs.git Also print 1x1 pair-list setup to log mdrun now prints the equivalent 1x1 pair-list setup in addtion to the NxM list setup. This is to clarify that we can use short pair list buffers because of our cluster setup. The list setup is now also printed in case we have a single list. Removed the note on needing to increase nstlist with a GPU when we automatically change nstlist. Changed pick_nbnxn_kernel and nbnxn_atomdata_init to use mdlog to get correct spacing between paragraphs. Also cleaned up the verletbuf list setup getter functions. Change-Id: Ic7b5967b0a62aee9fee9837f60a134fd571ff405 --- diff --git a/src/gromacs/gmxpreprocess/grompp.cpp b/src/gromacs/gmxpreprocess/grompp.cpp index 2db01e8e5a..1fa731d17e 100644 --- a/src/gromacs/gmxpreprocess/grompp.cpp +++ b/src/gromacs/gmxpreprocess/grompp.cpp @@ -1628,7 +1628,6 @@ static void set_verlet_buffer(const gmx_mtop_t *mtop, matrix box, warninp_t wi) { - verletbuf_list_setup_t ls; real rlist_1x1; int n_nonlin_vsite; char warn_buf[STRLEN]; @@ -1636,15 +1635,19 @@ static void set_verlet_buffer(const gmx_mtop_t *mtop, printf("Determining Verlet buffer for a tolerance of %g kJ/mol/ps at %g K\n", ir->verletbuf_tol, buffer_temp); /* Calculate the buffer size for simple atom vs atoms list */ - ls.cluster_size_i = 1; - ls.cluster_size_j = 1; + VerletbufListSetup listSetup1x1; + listSetup1x1.cluster_size_i = 1; + listSetup1x1.cluster_size_j = 1; calc_verlet_buffer_size(mtop, det(box), ir, ir->nstlist, ir->nstlist - 1, - buffer_temp, &ls, &n_nonlin_vsite, &rlist_1x1); + buffer_temp, &listSetup1x1, + &n_nonlin_vsite, &rlist_1x1); /* Set the pair-list buffer size in ir */ - verletbuf_get_list_setup(FALSE, FALSE, &ls); + VerletbufListSetup listSetup4x4 = + verletbufGetSafeListSetup(ListSetupType::CpuNoSimd); calc_verlet_buffer_size(mtop, det(box), ir, ir->nstlist, ir->nstlist - 1, - buffer_temp, &ls, &n_nonlin_vsite, &ir->rlist); + buffer_temp, &listSetup4x4, + &n_nonlin_vsite, &ir->rlist); if (n_nonlin_vsite > 0) { @@ -1656,7 +1659,7 @@ static void set_verlet_buffer(const gmx_mtop_t *mtop, 1, 1, rlist_1x1, rlist_1x1-std::max(ir->rvdw, ir->rcoulomb)); printf("Set rlist, assuming %dx%d atom pair-list, to %.3f nm, buffer size %.3f nm\n", - ls.cluster_size_i, ls.cluster_size_j, + listSetup4x4.cluster_size_i, listSetup4x4.cluster_size_j, ir->rlist, ir->rlist-std::max(ir->rvdw, ir->rcoulomb)); printf("Note that mdrun will redetermine rlist based on the actual pair-list setup\n"); diff --git a/src/gromacs/mdlib/calc_verletbuf.cpp b/src/gromacs/mdlib/calc_verletbuf.cpp index e62e878ea2..f730510eea 100644 --- a/src/gromacs/mdlib/calc_verletbuf.cpp +++ b/src/gromacs/mdlib/calc_verletbuf.cpp @@ -84,7 +84,7 @@ * apart from the first two approximations. * * Note that apart from the effect of the above approximations, the actual - * drift of the total energy of a system can be order of magnitude smaller + * drift of the total energy of a system can be orders of magnitude smaller * due to cancellation of positive and negative drift for different pairs. */ @@ -107,43 +107,54 @@ typedef struct real md3; // -V''' at the cutoff } pot_derivatives_t; -void verletbuf_get_list_setup(bool makeSimdPairList, - bool makeGpuPairList, - verletbuf_list_setup_t *list_setup) +VerletbufListSetup verletbufGetListSetup(int nbnxnKernelType) +{ + /* Note that the current buffer estimation code only handles clusters + * of size 1, 2 or 4, so for 4x8 or 8x8 we use the estimate for 4x4. + */ + VerletbufListSetup listSetup; + + listSetup.cluster_size_i = nbnxn_kernel_to_cluster_i_size(nbnxnKernelType); + listSetup.cluster_size_j = nbnxn_kernel_to_cluster_j_size(nbnxnKernelType); + + if (nbnxnKernelType == nbnxnk8x8x8_GPU || + nbnxnKernelType == nbnxnk8x8x8_PlainC) + { + /* The GPU kernels (except for OpenCL) split the j-clusters in two halves */ + listSetup.cluster_size_j /= 2; + } + + return listSetup; +} + +VerletbufListSetup verletbufGetSafeListSetup(ListSetupType listType) { /* When calling this function we often don't know which kernel type we - * are going to use. W choose the kernel type with the smallest possible + * are going to use. We choose the kernel type with the smallest possible * i- and j-cluster sizes, so we potentially overestimate, but never * underestimate, the buffer drift. - * Note that the current buffer estimation code only handles clusters - * of size 1, 2 or 4, so for 4x8 or 8x8 we use the estimate for 4x4. */ + int nbnxnKernelType; - if (makeGpuPairList) + if (listType == ListSetupType::Gpu) { - /* The GPU kernels split the j-clusters in two halves */ - list_setup->cluster_size_i = nbnxn_kernel_to_cluster_i_size(nbnxnk8x8x8_GPU); - list_setup->cluster_size_j = nbnxn_kernel_to_cluster_j_size(nbnxnk8x8x8_GPU)/2; + nbnxnKernelType = nbnxnk8x8x8_GPU; } - else + else if (GMX_SIMD && listType == ListSetupType::CpuSimdWhenSupported) { - int kernel_type; - - kernel_type = nbnxnk4x4_PlainC; - - if (GMX_SIMD && makeSimdPairList) - { #ifdef GMX_NBNXN_SIMD_2XNN - /* We use the smallest cluster size to be on the safe side */ - kernel_type = nbnxnk4xN_SIMD_2xNN; + /* We use the smallest cluster size to be on the safe side */ + nbnxnKernelType = nbnxnk4xN_SIMD_2xNN; #else - kernel_type = nbnxnk4xN_SIMD_4xN; + nbnxnKernelType = nbnxnk4xN_SIMD_4xN; #endif - } - - list_setup->cluster_size_i = nbnxn_kernel_to_cluster_i_size(kernel_type); - list_setup->cluster_size_j = nbnxn_kernel_to_cluster_j_size(kernel_type); } + else + { + nbnxnKernelType = nbnxnk4x4_PlainC; + } + + return verletbufGetListSetup(nbnxnKernelType); } static gmx_bool @@ -799,7 +810,7 @@ void calc_verlet_buffer_size(const gmx_mtop_t *mtop, real boxvol, int nstlist, int list_lifetime, real reference_temperature, - const verletbuf_list_setup_t *list_setup, + const VerletbufListSetup *list_setup, int *n_nonlin_vsite, real *rlist) { diff --git a/src/gromacs/mdlib/calc_verletbuf.h b/src/gromacs/mdlib/calc_verletbuf.h index c494e137ec..9bd1ba8149 100644 --- a/src/gromacs/mdlib/calc_verletbuf.h +++ b/src/gromacs/mdlib/calc_verletbuf.h @@ -42,15 +42,11 @@ struct gmx_mtop_t; struct t_inputrec; -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct +struct VerletbufListSetup { int cluster_size_i; /* Cluster pair-list i-cluster size atom count */ int cluster_size_j; /* Cluster pair-list j-cluster size atom count */ -} verletbuf_list_setup_t; +}; /* Add a 5% and 10% rlist buffer for simulations without dynamics (EM, NM, ...) @@ -64,16 +60,23 @@ static const real verlet_buffer_ratio_nodynamics = 0.05; static const real verlet_buffer_ratio_NVE_T0 = 0.10; -/* Sets the pair-list setup assumed for the current Gromacs configuration. - * The setup with smallest cluster sizes is return, such that the Verlet - * buffer size estimated with this setup will be conservative. - * makeSimdPairList tells if to take into account SIMD, when supported. - * makeGpuPairList tells to estimate for GPU kernels (makeSimdPairList is ignored with makeGpuPairList==true) +/* Returns the pair-list setup for the given nbnxn kernel type. */ -void verletbuf_get_list_setup(bool makeSimdPairList, - bool makeGpuPairList, - verletbuf_list_setup_t *list_setup); +VerletbufListSetup verletbufGetListSetup(int nbnxnKernelType); +/* Enum for choosing the list type for verletbufGetSafeListSetup() */ +enum class ListSetupType +{ + CpuNoSimd, /* CPU Plain-C 4x4 list */ + CpuSimdWhenSupported, /* CPU 4xN list, where N=4 when the binary doesn't support SIMD or the smallest N supported by SIMD in this binary */ + Gpu /* GPU (8x2x)8x4 list */ +}; + +/* Returns the pair-list setup assumed for the current Gromacs configuration. + * The setup with smallest cluster sizes is returned, such that the Verlet + * buffer size estimated with this setup will be conservative. + */ +VerletbufListSetup verletbufGetSafeListSetup(ListSetupType listType); /* Calculate the non-bonded pair-list buffer size for the Verlet list * based on the particle masses, temperature, LJ types, charges @@ -82,7 +85,8 @@ void verletbuf_get_list_setup(bool makeSimdPairList, * for normal pair-list buffering, are passed separately, as in some cases * we want an estimate for different values than the ones set in the inputrec. * If reference_temperature < 0, the maximum coupling temperature will be used. - * The target is a maximum energy drift of ir->verletbuf_tol. + * The target is a maximum average energy jump per atom of + * ir->verletbuf_tol*nstlist*ir->delta_t over the lifetime of the list. * Returns the number of non-linear virtual sites. For these it's difficult * to determine their contribution to the drift exaclty, so we approximate. * Returns the pair-list cut-off. @@ -92,7 +96,7 @@ void calc_verlet_buffer_size(const gmx_mtop_t *mtop, real boxvol, int nstlist, int list_lifetime, real reference_temperature, - const verletbuf_list_setup_t *list_setup, + const VerletbufListSetup *list_setup, int *n_nonlin_vsite, real *rlist); @@ -124,8 +128,4 @@ void constrained_atom_sigma2(real kT_fac, real *sigma2_2d, real *sigma2_3d); -#ifdef __cplusplus -} -#endif - #endif diff --git a/src/gromacs/mdlib/forcerec.cpp b/src/gromacs/mdlib/forcerec.cpp index 60fafe10a3..f4889db728 100644 --- a/src/gromacs/mdlib/forcerec.cpp +++ b/src/gromacs/mdlib/forcerec.cpp @@ -1713,8 +1713,7 @@ const char *lookup_nbnxn_kernel_name(int kernel_type) return returnvalue; }; -static void pick_nbnxn_kernel(FILE *fp, - const gmx::MDLogger &mdlog, +static void pick_nbnxn_kernel(const gmx::MDLogger &mdlog, gmx_bool use_simd_kernels, gmx_bool bUseGPU, EmulateGpuNonbonded emulateGpu, @@ -1755,9 +1754,10 @@ static void pick_nbnxn_kernel(FILE *fp, } } - if (bDoNonbonded && fp != nullptr) + if (bDoNonbonded) { - fprintf(fp, "\nUsing %s %dx%d non-bonded kernels\n\n", + GMX_LOG(mdlog.info).asParagraph().appendTextFormatted( + "Using %s %dx%d nonbonded short-range kernels", lookup_nbnxn_kernel_name(*kernel_type), nbnxn_kernel_to_cluster_i_size(*kernel_type), nbnxn_kernel_to_cluster_j_size(*kernel_type)); @@ -2143,8 +2143,7 @@ init_interaction_const(FILE *fp, * init_gpu modifies it to set up NVML support. This could * happen during the detection phase, and deviceInfo could * the become const. */ -static void init_nb_verlet(FILE *fp, - const gmx::MDLogger &mdlog, +static void init_nb_verlet(const gmx::MDLogger &mdlog, nonbonded_verlet_t **nb_verlet, gmx_bool bFEP_NonBonded, const t_inputrec *ir, @@ -2184,7 +2183,7 @@ static void init_nb_verlet(FILE *fp, if (i == 0) /* local */ { - pick_nbnxn_kernel(fp, mdlog, fr->use_simd_kernels, + pick_nbnxn_kernel(mdlog, fr->use_simd_kernels, nbv->bUseGPU, nbv->emulateGpu, ir, &nbv->grp[i].kernel_type, &nbv->grp[i].ewald_excl, @@ -2199,7 +2198,7 @@ static void init_nb_verlet(FILE *fp, } nbv->listParams = std::unique_ptr(new NbnxnListParameters(ir->rlist)); - setupDynamicPairlistPruning(fp, ir, mtop, box, nbv->bUseGPU, fr->ic, + setupDynamicPairlistPruning(mdlog, ir, mtop, box, nbv->grp[0].kernel_type, fr->ic, nbv->listParams.get()); nbnxn_init_search(&nbv->nbs, @@ -2249,7 +2248,7 @@ static void init_nb_verlet(FILE *fp, snew(nbv->nbat, 1); bool bSimpleList = nbnxn_kernel_pairlist_simple(nbv->grp[0].kernel_type); - nbnxn_atomdata_init(fp, + nbnxn_atomdata_init(mdlog, nbv->nbat, nbv->grp[0].kernel_type, enbnxninitcombrule, @@ -2857,7 +2856,7 @@ void init_forcerec(FILE *fp, gmx_fatal(FARGS, "Verlet cutoff-scheme is not supported with Buckingham"); } - if (fp) + if (fp && fr->cutoff_scheme == ecutsGROUP) { fprintf(fp, "Cut-off's: NS: %g Coulomb: %g %s: %g\n", fr->rlist, ic->rcoulomb, fr->bBHAM ? "BHAM" : "LJ", ic->rvdw); @@ -3144,11 +3143,20 @@ void init_forcerec(FILE *fp, GMX_RELEASE_ASSERT(ir->rcoulomb == ir->rvdw, "With Verlet lists and no PME rcoulomb and rvdw should be identical"); } - init_nb_verlet(fp, mdlog, &fr->nbv, bFEP_NonBonded, ir, fr, + init_nb_verlet(mdlog, &fr->nbv, bFEP_NonBonded, ir, fr, cr, deviceInfo, mtop, box); } + if (fp != nullptr) + { + /* Here we switch from using mdlog, which prints the newline before + * the paragraph, to our old fprintf logging, which prints the newline + * after the paragraph, so we should add a newline here. + */ + fprintf(fp, "\n"); + } + if (ir->eDispCorr != edispcNO) { calc_enervirdiff(fp, ir->eDispCorr, fr); diff --git a/src/gromacs/mdlib/nbnxn_atomdata.cpp b/src/gromacs/mdlib/nbnxn_atomdata.cpp index ed10300eed..d6c6be8e23 100644 --- a/src/gromacs/mdlib/nbnxn_atomdata.cpp +++ b/src/gromacs/mdlib/nbnxn_atomdata.cpp @@ -61,7 +61,9 @@ #include "gromacs/utility/exceptions.h" #include "gromacs/utility/fatalerror.h" #include "gromacs/utility/gmxomp.h" +#include "gromacs/utility/logger.h" #include "gromacs/utility/smalloc.h" +#include "gromacs/utility/stringutil.h" using namespace gmx; // TODO: Remove when this file is moved into gmx namespace @@ -479,7 +481,7 @@ nbnxn_atomdata_init_simple_exclusion_masks(nbnxn_atomdata_t *nbat) #endif /* Initializes an nbnxn_atomdata_t data structure */ -void nbnxn_atomdata_init(FILE *fp, +void nbnxn_atomdata_init(const gmx::MDLogger &mdlog, nbnxn_atomdata_t *nbat, int nb_kernel_type, int enbnxninitcombrule, @@ -626,17 +628,18 @@ void nbnxn_atomdata_init(FILE *fp, nbat->free(nbat->nbfp_comb); } - if (fp) { + std::string mesg; if (nbat->comb_rule == ljcrNONE) { - fprintf(fp, "Using full Lennard-Jones parameter combination matrix\n\n"); + mesg = "Using full Lennard-Jones parameter combination matrix"; } else { - fprintf(fp, "Using %s Lennard-Jones combination rule\n\n", - nbat->comb_rule == ljcrGEOM ? "geometric" : "Lorentz-Berthelot"); + mesg = gmx::formatString("Using %s Lennard-Jones combination rule", + nbat->comb_rule == ljcrGEOM ? "geometric" : "Lorentz-Berthelot"); } + GMX_LOG(mdlog.info).asParagraph().appendText(mesg); } break; case enbnxninitcombruleGEOM: @@ -699,9 +702,9 @@ void nbnxn_atomdata_init(FILE *fp, if (!simple) { /* Energy groups not supported yet for super-sub lists */ - if (n_energygroups > 1 && fp != nullptr) + if (n_energygroups > 1) { - fprintf(fp, "\nNOTE: With GPUs, reporting energy group contributions is not supported\n\n"); + GMX_LOG(mdlog.warning).asParagraph().appendText("NOTE: With GPUs, reporting energy group contributions is not supported"); } nbat->nenergrp = 1; } @@ -761,10 +764,8 @@ void nbnxn_atomdata_init(FILE *fp, } if (nbat->bUseTreeReduce) { - if (fp) - { - fprintf(fp, "Using tree force reduction\n\n"); - } + GMX_LOG(mdlog.info).asParagraph().appendText("Using tree force reduction"); + snew(nbat->syncStep, nth); } } diff --git a/src/gromacs/mdlib/nbnxn_atomdata.h b/src/gromacs/mdlib/nbnxn_atomdata.h index 0d1bedfd51..d1d594e9e5 100644 --- a/src/gromacs/mdlib/nbnxn_atomdata.h +++ b/src/gromacs/mdlib/nbnxn_atomdata.h @@ -43,6 +43,11 @@ #include "gromacs/utility/basedefinitions.h" #include "gromacs/utility/real.h" +namespace gmx +{ +class MDLogger; +} + struct t_mdatoms; /* Default nbnxn allocation routine, allocates 32 byte aligned, @@ -79,7 +84,7 @@ enum { * to the atom data structure. * enbnxninitcombrule sets what combination rule data gets stored in nbat. */ -void nbnxn_atomdata_init(FILE *fp, +void nbnxn_atomdata_init(const gmx::MDLogger &mdlog, nbnxn_atomdata_t *nbat, int nb_kernel_type, int enbnxninitcombrule, diff --git a/src/gromacs/mdlib/nbnxn_tuning.cpp b/src/gromacs/mdlib/nbnxn_tuning.cpp index 3f91b13e3b..fe17c5b9c0 100644 --- a/src/gromacs/mdlib/nbnxn_tuning.cpp +++ b/src/gromacs/mdlib/nbnxn_tuning.cpp @@ -68,6 +68,8 @@ #include "gromacs/utility/cstringutil.h" #include "gromacs/utility/fatalerror.h" #include "gromacs/utility/gmxassert.h" +#include "gromacs/utility/logger.h" +#include "gromacs/utility/stringutil.h" /*! \brief Returns if we can (heuristically) change nstlist and rlist * @@ -127,9 +129,14 @@ void increaseNstlist(FILE *fp, t_commrec *cr, bool useOrEmulateGpuForNonbondeds, const gmx::CpuInfo &cpuinfo) { + if (!EI_DYNAMICS(ir->eI)) + { + /* Can only increase nstlist with dynamics */ + return; + } + float listfac_ok, listfac_max; int nstlist_orig, nstlist_prev; - verletbuf_list_setup_t ls; real rlistWithReferenceNstlist, rlist_inc, rlist_ok, rlist_max; real rlist_new, rlist_prev; size_t nstlist_ind = 0; @@ -151,10 +158,15 @@ void increaseNstlist(FILE *fp, t_commrec *cr, return; } - if (fp != nullptr && useOrEmulateGpuForNonbondeds && ir->nstlist < nstlist_try[0]) + /* With a GPU and fixed nstlist suggest tuning nstlist */ + if (fp != nullptr && + useOrEmulateGpuForNonbondeds && + ir->nstlist < nstlist_try[0] && + !supportsDynamicPairlistGenerationInterval(*ir)) { fprintf(fp, nstl_gpu, ir->nstlist); } + nstlist_ind = 0; while (nstlist_ind < NNSTL && ir->nstlist >= nstlist_try[nstlist_ind]) { @@ -200,6 +212,8 @@ void increaseNstlist(FILE *fp, t_commrec *cr, return; } + GMX_RELEASE_ASSERT(supportsDynamicPairlistGenerationInterval(*ir), "In all cases that do not support dynamic nstlist, we should have returned with an appropriate message above"); + if (useOrEmulateGpuForNonbondeds) { listfac_ok = c_nbnxnListSizeFactorGPU; @@ -225,7 +239,8 @@ void increaseNstlist(FILE *fp, t_commrec *cr, ir->nstlist = nstlist_cmdline; } - verletbuf_get_list_setup(TRUE, useOrEmulateGpuForNonbondeds, &ls); + ListSetupType listType = (useOrEmulateGpuForNonbondeds ? ListSetupType::Gpu : ListSetupType::CpuSimdWhenSupported); + VerletbufListSetup listSetup = verletbufGetSafeListSetup(listType); /* Allow rlist to make the list a given factor larger than the list * would be with the reference value for nstlist (10). @@ -233,11 +248,12 @@ void increaseNstlist(FILE *fp, t_commrec *cr, nstlist_prev = ir->nstlist; ir->nstlist = nbnxnReferenceNstlist; calc_verlet_buffer_size(mtop, det(box), ir, ir->nstlist, ir->nstlist - 1, - -1, &ls, nullptr, &rlistWithReferenceNstlist); + -1, &listSetup, + nullptr, &rlistWithReferenceNstlist); ir->nstlist = nstlist_prev; /* Determine the pair list size increase due to zero interactions */ - rlist_inc = nbnxn_get_rlist_effective_inc(ls.cluster_size_j, + rlist_inc = nbnxn_get_rlist_effective_inc(listSetup.cluster_size_j, mtop->natoms/det(box)); rlist_ok = (rlistWithReferenceNstlist + rlist_inc)*std::cbrt(listfac_ok) - rlist_inc; rlist_max = (rlistWithReferenceNstlist + rlist_inc)*std::cbrt(listfac_max) - rlist_inc; @@ -257,7 +273,7 @@ void increaseNstlist(FILE *fp, t_commrec *cr, } /* Set the pair-list buffer size in ir */ - calc_verlet_buffer_size(mtop, det(box), ir, ir->nstlist, ir->nstlist - 1, -1, &ls, nullptr, &rlist_new); + calc_verlet_buffer_size(mtop, det(box), ir, ir->nstlist, ir->nstlist - 1, -1, &listSetup, nullptr, &rlist_new); /* Does rlist fit in the box? */ bBox = (gmx::square(rlist_new) < max_cutoff2(ir->ePBC, box)); @@ -367,7 +383,7 @@ setDynamicPairlistPruningParameters(const t_inputrec *ir, const gmx_mtop_t *mtop, matrix box, gmx_bool useGpu, - const verletbuf_list_setup_t &listSetup, + const VerletbufListSetup &listSetup, bool userSetNstlistPrune, const interaction_const_t *ic, NbnxnListParameters *listParams) @@ -434,11 +450,40 @@ setDynamicPairlistPruningParameters(const t_inputrec *ir, } } -void setupDynamicPairlistPruning(FILE *fplog, +/*! \brief Returns a string describing the setup of a single pair-list + * + * \param[in] listName Short name of the list, can be "" + * \param[in] nstList The list update interval in steps + * \param[in] nstListForSpacing Update interval for setting the number characters for printing \p nstList + * \param[in] rList List cut-off radius + * \param[in] interactionCutoff The interaction cut-off, use for printing the list buffer size + */ +static std::string formatListSetup(const std::string &listName, + int nstList, + int nstListForSpacing, + real rList, + real interactionCutoff) +{ + std::string listSetup = " "; + if (!listName.empty()) + { + listSetup += listName + " list: "; + } + listSetup += "updated every "; + // Make the shortest int format string that fits nstListForSpacing + std::string nstListFormat = "%" + gmx::formatString("%d", gmx::formatString("%zu", nstListForSpacing).size()) + "d"; + listSetup += gmx::formatString(nstListFormat.c_str(), nstList); + listSetup += gmx::formatString(" steps, buffer %.3f nm, rlist %.3f nm\n", + rList - interactionCutoff, rList); + + return listSetup; +} + +void setupDynamicPairlistPruning(const gmx::MDLogger &mdlog, const t_inputrec *ir, const gmx_mtop_t *mtop, matrix box, - bool useGpu, + int nbnxnKernelType, const interaction_const_t *ic, NbnxnListParameters *listParams) { @@ -447,12 +492,14 @@ void setupDynamicPairlistPruning(FILE *fplog, /* Initialize the parameters to no dynamic list pruning */ listParams->useDynamicPruning = false; + const VerletbufListSetup ls = verletbufGetListSetup(nbnxnKernelType); + + /* Currently emulation mode does not support dual pair-lists */ + const bool useGpu = (nbnxnKernelType == nbnxnk8x8x8_GPU); + if (supportsDynamicPairlistGenerationInterval(*ir) && getenv("GMX_DISABLE_DYNAMICPRUNING") == NULL) { - verletbuf_list_setup_t ls; - verletbuf_get_list_setup(TRUE, TRUE, &ls); - /* Note that nstlistPrune can have any value independently of nstlist. * Actually applying rolling pruning is only useful when * nstlistPrune < nstlist -1 @@ -499,17 +546,51 @@ void setupDynamicPairlistPruning(FILE *fplog, { listParams->numRollingParts = 1; } + } + + std::string mesg; - if (fplog && listParams->useDynamicPruning) + const real interactionCutoff = std::max(ic->rcoulomb, ic->rvdw); + if (listParams->useDynamicPruning) + { + mesg += gmx::formatString("Using a dual %dx%d pair-list setup updated with dynamic%s pruning:\n", + ls.cluster_size_i, ls.cluster_size_j, + listParams->numRollingParts > 1 ? ", rolling" : ""); + mesg += formatListSetup("outer", ir->nstlist, ir->nstlist, listParams->rlistOuter, interactionCutoff); + mesg += formatListSetup("inner", listParams->nstlistPrune, ir->nstlist, listParams->rlistInner, interactionCutoff); + } + else + { + mesg += gmx::formatString("Using a %dx%d pair-list setup:\n", + ls.cluster_size_i, ls.cluster_size_j); + mesg += formatListSetup("", ir->nstlist, ir->nstlist, listParams->rlistOuter, interactionCutoff); + } + if (supportsDynamicPairlistGenerationInterval(*ir)) + { + VerletbufListSetup listSetup1x1 = { 1, 1 }; + real rlistOuter; + real rlistInner; + calc_verlet_buffer_size(mtop, det(box), ir, ir->nstlist, ir->nstlist - 1, + -1, &listSetup1x1, nullptr, &rlistOuter); + if (listParams->useDynamicPruning) { - const real interactionCutoff = std::max(ic->rcoulomb, ic->rvdw); - fprintf(fplog, - "Using a dual pair-list setup updated with dynamic%s pruning:\n" - " outer list: updated every %3d steps, buffer %.3f nm, rlist %.3f nm\n" - " inner list: updated every %3d steps, buffer %.3f nm, rlist %.3f nm\n", - listParams->numRollingParts > 1 ? ", rolling" : "", - ir->nstlist, listParams->rlistOuter - interactionCutoff, listParams->rlistOuter, - listParams->nstlistPrune, listParams->rlistInner - interactionCutoff, listParams->rlistInner); + int listLifeTime = listParams->nstlistPrune - (useGpu ? 0 : 1); + calc_verlet_buffer_size(mtop, det(box), ir, listParams->nstlistPrune, listLifeTime, + -1, &listSetup1x1, nullptr, &rlistInner); + } + + mesg += gmx::formatString("At tolerance %g kJ/mol/ps per atom, equivalent classical 1x1 list would be:\n", + ir->verletbuf_tol); + if (listParams->useDynamicPruning) + { + mesg += formatListSetup("outer", ir->nstlist, ir->nstlist, rlistOuter, interactionCutoff); + mesg += formatListSetup("inner", listParams->nstlistPrune, ir->nstlist, rlistInner, interactionCutoff); + } + else + { + mesg += formatListSetup("", ir->nstlist, ir->nstlist, rlistOuter, interactionCutoff); } } + + GMX_LOG(mdlog.info).asParagraph().appendText(mesg); } diff --git a/src/gromacs/mdlib/nbnxn_tuning.h b/src/gromacs/mdlib/nbnxn_tuning.h index 4f65131e53..47f3f6bf65 100644 --- a/src/gromacs/mdlib/nbnxn_tuning.h +++ b/src/gromacs/mdlib/nbnxn_tuning.h @@ -53,6 +53,7 @@ namespace gmx { class CpuInfo; +class MDLogger; } struct gmx_mtop_t; @@ -81,19 +82,19 @@ void increaseNstlist(FILE *fplog, t_commrec *cr, /*! \brief Set up the dynamic pairlist pruning * - * \param[in,out] fplog Log file - * \param[in] ir The input parameter record - * \param[in] mtop The global topology - * \param[in] box The unit cell - * \param[in] useGpu Tells if we are using a GPU for non-bondeds - * \param[in] ic The nonbonded interactions constants - * \param[in,out] listParams The list setup parameters + * \param[in,out] mdlog MD logger + * \param[in] ir The input parameter record + * \param[in] mtop The global topology + * \param[in] box The unit cell + * \param[in] nbnxnKernelType The type of nbnxn kernel used + * \param[in] ic The nonbonded interactions constants + * \param[in,out] listParams The list setup parameters */ -void setupDynamicPairlistPruning(FILE *fplog, +void setupDynamicPairlistPruning(const gmx::MDLogger &mdlog, const t_inputrec *ir, const gmx_mtop_t *mtop, matrix box, - bool useGpu, + int nbnxnKernelType, const interaction_const_t *ic, NbnxnListParameters *listParams); diff --git a/src/programs/mdrun/runner.cpp b/src/programs/mdrun/runner.cpp index d9f098c591..e603264be2 100644 --- a/src/programs/mdrun/runner.cpp +++ b/src/programs/mdrun/runner.cpp @@ -240,16 +240,16 @@ static void prepare_verlet_scheme(FILE *fplog, !(EI_MD(ir->eI) && ir->etc == etcNO)) { /* Update the Verlet buffer size for the current run setup */ - verletbuf_list_setup_t ls; - real rlist_new; /* Here we assume SIMD-enabled kernels are being used. But as currently * calc_verlet_buffer_size gives the same results for 4x8 and 4x4 * and 4x2 gives a larger buffer than 4x4, this is ok. */ - verletbuf_get_list_setup(true, makeGpuPairList, &ls); + ListSetupType listType = (makeGpuPairList ? ListSetupType::Gpu : ListSetupType::CpuSimdWhenSupported); + VerletbufListSetup listSetup = verletbufGetSafeListSetup(listType); - calc_verlet_buffer_size(mtop, det(box), ir, ir->nstlist, ir->nstlist - 1, -1, &ls, nullptr, &rlist_new); + real rlist_new; + calc_verlet_buffer_size(mtop, det(box), ir, ir->nstlist, ir->nstlist - 1, -1, &listSetup, nullptr, &rlist_new); if (rlist_new != ir->rlist) { @@ -257,7 +257,7 @@ static void prepare_verlet_scheme(FILE *fplog, { fprintf(fplog, "\nChanging rlist from %g to %g for non-bonded %dx%d atom kernels\n\n", ir->rlist, rlist_new, - ls.cluster_size_i, ls.cluster_size_j); + listSetup.cluster_size_i, listSetup.cluster_size_j); } ir->rlist = rlist_new; }