integrator.cpp
interactions.cpp
molecules.cpp
+ nbnxmsetuphelpers.cpp
particlesequencer.cpp
particletype.cpp
simulationstate.cpp
#include "gromacs/utility/smalloc.h"
#include "nblib/exception.h"
#include "nblib/kerneloptions.h"
+#include "nblib/nbnxmsetuphelpers.h"
#include "nblib/particletype.h"
#include "nblib/simulationstate.h"
namespace nblib
{
-//! Helper to translate between the different enumeration values.
-static Nbnxm::KernelType translateBenchmarkEnum(const SimdKernels& kernel)
-{
- int kernelInt = static_cast<int>(kernel);
- return static_cast<Nbnxm::KernelType>(kernelInt);
-}
-
-/*! \brief Checks the kernel setup
- *
- * Returns an error string when the kernel is not available.
- */
-static void checkKernelSetup(const NBKernelOptions& options)
-{
- if (options.nbnxmSimd >= SimdKernels::Count || options.nbnxmSimd == SimdKernels::SimdAuto)
- {
- throw InputException("Need a valid kernel SIMD type");
- }
- // Check SIMD support
- if ((options.nbnxmSimd != SimdKernels::SimdNo && !GMX_SIMD)
-#ifndef GMX_NBNXN_SIMD_4XN
- || options.nbnxmSimd == SimdKernels::Simd4XM
-#endif
-#ifndef GMX_NBNXN_SIMD_2XNN
- || options.nbnxmSimd == SimdKernels::Simd2XMM
-#endif
- )
- {
- throw InputException("The requested SIMD kernel was not set up at configuration time");
- }
-}
-
NbvSetupUtil::NbvSetupUtil() : gmxForceCalculator_(std::make_unique<GmxForceCalculator>()) {}
void NbvSetupUtil::setExecutionContext(const NBKernelOptions& options)
{
- // Todo: find a more general way to initialize hardware
- gmx_omp_nthreads_set(ModuleMultiThread::Pairsearch, options.numOpenMPThreads);
- gmx_omp_nthreads_set(ModuleMultiThread::Nonbonded, options.numOpenMPThreads);
+ setGmxNonBondedNThreads(options.numOpenMPThreads);
}
Nbnxm::KernelSetup NbvSetupUtil::getKernelSetup(const NBKernelOptions& options)
{
- checkKernelSetup(options);
-
- Nbnxm::KernelSetup kernelSetup;
-
- // The int enum options.nbnxnSimd is set up to match Nbnxm::KernelType + 1
- kernelSetup.kernelType = translateBenchmarkEnum(options.nbnxmSimd);
- // The plain-C kernel does not support analytical ewald correction
- if (kernelSetup.kernelType == Nbnxm::KernelType::Cpu4x4_PlainC)
- {
- kernelSetup.ewaldExclusionType = Nbnxm::EwaldExclusionType::Table;
- }
- else
- {
- kernelSetup.ewaldExclusionType = options.useTabulatedEwaldCorr
- ? Nbnxm::EwaldExclusionType::Table
- : Nbnxm::EwaldExclusionType::Analytical;
- }
-
- return kernelSetup;
+ return createKernelSetupCPU(options);
}
void NbvSetupUtil::setParticleInfoAllVdv(const size_t numParticles)
{
- particleInfoAllVdw_.resize(numParticles);
- for (size_t particleI = 0; particleI < numParticles; particleI++)
- {
- particleInfoAllVdw_[particleI] |= gmx::sc_atomInfo_HasVdw;
- particleInfoAllVdw_[particleI] |= gmx::sc_atomInfo_HasCharge;
- }
+ particleInfoAllVdw_ = createParticleInfoAllVdv(numParticles);
}
void NbvSetupUtil::setNonBondedParameters(const std::vector<ParticleType>& particleTypes,
const NonBondedInteractionMap& nonBondedInteractionMap)
{
- /* Todo: Refactor nbnxm to take nonbondedParameters_ directly
- *
- * initial self-handling of combination rules
- * size: 2*(numParticleTypes^2)
- */
- nonbondedParameters_.reserve(2 * particleTypes.size() * particleTypes.size());
-
- constexpr real c6factor = 6.0;
- constexpr real c12factor = 12.0;
-
- for (const ParticleType& particleType1 : particleTypes)
- {
- for (const ParticleType& particleType2 : particleTypes)
- {
- nonbondedParameters_.push_back(
- nonBondedInteractionMap.getC6(particleType1.name(), particleType2.name()) * c6factor);
- nonbondedParameters_.push_back(
- nonBondedInteractionMap.getC12(particleType1.name(), particleType2.name()) * c12factor);
- }
- }
+ nonbondedParameters_ = createNonBondedParameters(particleTypes, nonBondedInteractionMap);
}
void NbvSetupUtil::setAtomProperties(const std::vector<int>& particleTypeIdOfAllParticles,
// Note: the options and Nbnxm combination rule enums values should match
const int combinationRule = static_cast<int>(options.ljCombinationRule);
- checkKernelSetup(options); // throws exception is setup is invalid
+ checkKernelSetup(options.nbnxmSimd); // throws exception is setup is invalid
Nbnxm::KernelSetup kernelSetup = getKernelSetup(options);
gmxForceCalculator_->nbv_ = std::move(nbv);
}
-//! Computes the Ewald splitting coefficient for Coulomb
-static real ewaldCoeff(const real ewald_rtol, const real pairlistCutoff)
-{
- return calc_ewaldcoeff_q(pairlistCutoff, ewald_rtol);
-}
-
void NbvSetupUtil::setupStepWorkload(const NBKernelOptions& options)
{
- gmxForceCalculator_->stepWork_->computeForces = true;
- gmxForceCalculator_->stepWork_->computeNonbondedForces = true;
-
- if (options.computeVirialAndEnergy)
- {
- gmxForceCalculator_->stepWork_->computeVirial = true;
- gmxForceCalculator_->stepWork_->computeEnergy = true;
- }
+ gmxForceCalculator_->stepWork_ = std::make_unique<gmx::StepWorkload>(createStepWorkload(options));
}
void NbvSetupUtil::setupInteractionConst(const NBKernelOptions& options)
{
- gmxForceCalculator_->interactionConst_->vdwtype = VanDerWaalsType::Cut;
- gmxForceCalculator_->interactionConst_->vdw_modifier = InteractionModifiers::PotShift;
- gmxForceCalculator_->interactionConst_->rvdw = options.pairlistCutoff;
-
- switch (options.coulombType)
- {
- case CoulombType::Pme:
- gmxForceCalculator_->interactionConst_->eeltype = CoulombInteractionType::Pme;
- break;
- case CoulombType::Cutoff:
- gmxForceCalculator_->interactionConst_->eeltype = CoulombInteractionType::Cut;
- break;
- case CoulombType::ReactionField:
- gmxForceCalculator_->interactionConst_->eeltype = CoulombInteractionType::RF;
- break;
- case CoulombType::Count: throw InputException("Unsupported electrostatic interaction");
- }
- gmxForceCalculator_->interactionConst_->coulomb_modifier = InteractionModifiers::PotShift;
- gmxForceCalculator_->interactionConst_->rcoulomb = options.pairlistCutoff;
- // Note: values correspond to ic->coulomb_modifier = InteractionModifiers::PotShift
- gmxForceCalculator_->interactionConst_->dispersion_shift.cpot =
- -1.0 / gmx::power6(gmxForceCalculator_->interactionConst_->rvdw);
- gmxForceCalculator_->interactionConst_->repulsion_shift.cpot =
- -1.0 / gmx::power12(gmxForceCalculator_->interactionConst_->rvdw);
-
- // These are the initialized values but we leave them here so that later
- // these can become options.
- gmxForceCalculator_->interactionConst_->epsilon_r = 1.0;
- gmxForceCalculator_->interactionConst_->reactionFieldPermitivity = 1.0;
-
- /* Set the Coulomb energy conversion factor */
- if (gmxForceCalculator_->interactionConst_->epsilon_r != 0)
- {
- gmxForceCalculator_->interactionConst_->epsfac =
- ONE_4PI_EPS0 / gmxForceCalculator_->interactionConst_->epsilon_r;
- }
- else
- {
- /* eps = 0 is infinite dieletric: no Coulomb interactions */
- gmxForceCalculator_->interactionConst_->epsfac = 0;
- }
-
- calc_rffac(nullptr,
- gmxForceCalculator_->interactionConst_->epsilon_r,
- gmxForceCalculator_->interactionConst_->reactionFieldPermitivity,
- gmxForceCalculator_->interactionConst_->rcoulomb,
- &gmxForceCalculator_->interactionConst_->reactionFieldCoefficient,
- &gmxForceCalculator_->interactionConst_->reactionFieldShift);
-
- if (EEL_PME_EWALD(gmxForceCalculator_->interactionConst_->eeltype))
- {
- // Ewald coefficients, we ignore the potential shift
- gmxForceCalculator_->interactionConst_->ewaldcoeff_q = ewaldCoeff(1e-5, options.pairlistCutoff);
- if (gmxForceCalculator_->interactionConst_->ewaldcoeff_q <= 0)
- {
- throw InputException("Ewald coefficient should be > 0");
- }
- gmxForceCalculator_->interactionConst_->coulombEwaldTables =
- std::make_unique<EwaldCorrectionTables>();
- init_interaction_const_tables(nullptr, gmxForceCalculator_->interactionConst_.get(), 0, 0);
- }
+ gmxForceCalculator_->interactionConst_ =
+ std::make_unique<interaction_const_t>(createInteractionConst(options));
}
void NbvSetupUtil::setupForceRec(const matrix& box)
{
- assert((gmxForceCalculator_->forcerec_ && "Forcerec not initialized"));
- gmxForceCalculator_->forcerec_->nbfp = nonbondedParameters_;
- gmxForceCalculator_->forcerec_->shift_vec.resize(numShiftVectors);
- calc_shifts(box, gmxForceCalculator_->forcerec_->shift_vec);
+ updateForcerec(gmxForceCalculator_->forcerec_.get(), box);
}
void NbvSetupUtil::setParticlesOnGrid(const std::vector<Vec3>& coordinates, const Box& box)
--- /dev/null
+/*
+ * 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.
+ */
+/*! \internal \file
+ * \brief Utilities to setup GROMACS data structures for non-bonded force calculations.
+ *
+ * \author Victor Holanda <victor.holanda@cscs.ch>
+ * \author Joe Jordan <ejjordan@kth.se>
+ * \author Prashanth Kanduri <kanduri@cscs.ch>
+ * \author Sebastian Keller <keller@cscs.ch>
+ */
+#include "gromacs/ewald/ewald_utils.h"
+#include "gromacs/gpu_utils/device_stream_manager.h"
+#include "gromacs/gmxlib/nrnb.h"
+#include "gromacs/mdlib/forcerec.h"
+#include "gromacs/mdlib/gmx_omp_nthreads.h"
+#include "gromacs/mdlib/rf_util.h"
+#include "gromacs/mdtypes/forcerec.h"
+#include "gromacs/mdtypes/interaction_const.h"
+#include "gromacs/mdtypes/simulation_workload.h"
+#include "gromacs/nbnxm/atomdata.h"
+#include "gromacs/nbnxm/gpu_data_mgmt.h"
+#include "gromacs/nbnxm/nbnxm_gpu.h"
+#include "gromacs/nbnxm/nbnxm.h"
+#include "gromacs/nbnxm/nbnxm_simd.h"
+#include "gromacs/nbnxm/pairlistset.h"
+#include "gromacs/nbnxm/pairlistsets.h"
+#include "gromacs/nbnxm/pairsearch.h"
+#include "gromacs/pbcutil/pbc.h"
+#include "gromacs/utility/logger.h"
+#include "gromacs/utility/smalloc.h"
+#include "nblib/exception.h"
+#include "nblib/kerneloptions.h"
+#include "nblib/particletype.h"
+
+#include "nbnxmsetuphelpers.h"
+
+namespace nblib
+{
+
+int64_t findNumEnergyGroups(gmx::ArrayRef<int64_t> particleInteractionFlags)
+{
+ auto groupId = [](int code1, int code2) {
+ return (code1 & gmx::sc_atomInfo_EnergyGroupIdMask) < (code2 & gmx::sc_atomInfo_EnergyGroupIdMask);
+ };
+
+ int maxElement = *std::max_element(
+ std::begin(particleInteractionFlags), std::end(particleInteractionFlags), groupId);
+ return ((maxElement + 1) & gmx::sc_atomInfo_EnergyGroupIdMask);
+}
+
+Nbnxm::KernelType translateBenchmarkEnum(const SimdKernels& kernel)
+{
+ int kernelInt = static_cast<int>(kernel);
+ return static_cast<Nbnxm::KernelType>(kernelInt);
+}
+
+void checkKernelSetup(const SimdKernels nbnxmSimd)
+{
+ if (nbnxmSimd >= SimdKernels::Count || nbnxmSimd == SimdKernels::SimdAuto)
+ {
+ throw InputException("Need a valid kernel SIMD type");
+ }
+ // Check SIMD support
+ if ((nbnxmSimd != SimdKernels::SimdNo && !GMX_SIMD)
+#ifndef GMX_NBNXN_SIMD_4XN
+ || nbnxmSimd == SimdKernels::Simd4XM
+#endif
+#ifndef GMX_NBNXN_SIMD_2XNN
+ || nbnxmSimd == SimdKernels::Simd2XMM
+#endif
+ )
+ {
+ throw InputException("The requested SIMD kernel was not set up at configuration time");
+ }
+}
+
+Nbnxm::KernelSetup createKernelSetupCPU(const NBKernelOptions& options)
+{
+ checkKernelSetup(options.nbnxmSimd);
+
+ Nbnxm::KernelSetup kernelSetup;
+
+ // The int enum options.nbnxnSimd is set up to match Nbnxm::KernelType + 1
+ kernelSetup.kernelType = translateBenchmarkEnum(options.nbnxmSimd);
+
+ // The plain-C kernel does not support analytical ewald correction
+ if (kernelSetup.kernelType == Nbnxm::KernelType::Cpu4x4_PlainC)
+ {
+ kernelSetup.ewaldExclusionType = Nbnxm::EwaldExclusionType::Table;
+ }
+ else
+ {
+ kernelSetup.ewaldExclusionType = options.useTabulatedEwaldCorr
+ ? Nbnxm::EwaldExclusionType::Table
+ : Nbnxm::EwaldExclusionType::Analytical;
+ }
+
+ return kernelSetup;
+}
+
+std::vector<int64_t> createParticleInfoAllVdv(const size_t numParticles)
+
+{
+ std::vector<int64_t> particleInfoAllVdw(numParticles);
+ for (size_t particleI = 0; particleI < numParticles; particleI++)
+ {
+ particleInfoAllVdw[particleI] |= gmx::sc_atomInfo_HasVdw;
+ particleInfoAllVdw[particleI] |= gmx::sc_atomInfo_HasCharge;
+ }
+ return particleInfoAllVdw;
+}
+
+std::vector<real> createNonBondedParameters(const std::vector<ParticleType>& particleTypes,
+ const NonBondedInteractionMap& nonBondedInteractionMap)
+{
+ /* Todo: Refactor nbnxm to take nonbondedParameters_ directly
+ *
+ * initial self-handling of combination rules
+ * size: 2*(numParticleTypes^2)
+ */
+ std::vector<real> nonbondedParameters;
+ nonbondedParameters.reserve(2 * particleTypes.size() * particleTypes.size());
+
+ constexpr real c6factor = 6.0;
+ constexpr real c12factor = 12.0;
+
+ for (const ParticleType& particleType1 : particleTypes)
+ {
+ for (const ParticleType& particleType2 : particleTypes)
+ {
+ nonbondedParameters.push_back(
+ nonBondedInteractionMap.getC6(particleType1.name(), particleType2.name()) * c6factor);
+ nonbondedParameters.push_back(
+ nonBondedInteractionMap.getC12(particleType1.name(), particleType2.name()) * c12factor);
+ }
+ }
+ return nonbondedParameters;
+}
+
+gmx::StepWorkload createStepWorkload([[maybe_unused]] const NBKernelOptions& options)
+{
+ gmx::StepWorkload stepWorkload;
+ stepWorkload.computeForces = true;
+ stepWorkload.computeNonbondedForces = true;
+ stepWorkload.useGpuFBufferOps = false;
+ stepWorkload.useGpuXBufferOps = false;
+
+ return stepWorkload;
+}
+
+real ewaldCoeff(const real ewald_rtol, const real pairlistCutoff)
+{
+ return calc_ewaldcoeff_q(pairlistCutoff, ewald_rtol);
+}
+
+interaction_const_t createInteractionConst(const NBKernelOptions& options)
+{
+ interaction_const_t interactionConst;
+ interactionConst.vdwtype = VanDerWaalsType::Cut;
+ interactionConst.vdw_modifier = InteractionModifiers::PotShift;
+ interactionConst.rvdw = options.pairlistCutoff;
+
+ switch (options.coulombType)
+ {
+ case CoulombType::Pme: interactionConst.eeltype = CoulombInteractionType::Pme; break;
+ case CoulombType::Cutoff: interactionConst.eeltype = CoulombInteractionType::Cut; break;
+ case CoulombType::ReactionField:
+ interactionConst.eeltype = CoulombInteractionType::RF;
+ break;
+ case CoulombType::Count: throw InputException("Unsupported electrostatic interaction");
+ }
+ interactionConst.coulomb_modifier = InteractionModifiers::PotShift;
+ interactionConst.rcoulomb = options.pairlistCutoff;
+ // Note: values correspond to ic->coulomb_modifier = eintmodPOTSHIFT
+ interactionConst.dispersion_shift.cpot = -1.0 / gmx::power6(interactionConst.rvdw);
+ interactionConst.repulsion_shift.cpot = -1.0 / gmx::power12(interactionConst.rvdw);
+
+ // These are the initialized values but we leave them here so that later
+ // these can become options.
+ interactionConst.epsilon_r = 1.0;
+ interactionConst.reactionFieldPermitivity = 1.0;
+
+ /* Set the Coulomb energy conversion factor */
+ if (interactionConst.epsilon_r != 0)
+ {
+ interactionConst.epsfac = ONE_4PI_EPS0 / interactionConst.epsilon_r;
+ }
+ else
+ {
+ /* eps = 0 is infinite dieletric: no Coulomb interactions */
+ interactionConst.epsfac = 0;
+ }
+
+ calc_rffac(nullptr,
+ interactionConst.epsilon_r,
+ interactionConst.reactionFieldPermitivity,
+ interactionConst.rcoulomb,
+ &interactionConst.reactionFieldCoefficient,
+ &interactionConst.reactionFieldShift);
+
+
+ if (EEL_PME_EWALD(interactionConst.eeltype))
+ {
+ // Ewald coefficients, we ignore the potential shift
+ interactionConst.ewaldcoeff_q = ewaldCoeff(1e-5, options.pairlistCutoff);
+ if (interactionConst.ewaldcoeff_q <= 0)
+ {
+ throw InputException("Ewald coefficient should be > 0");
+ }
+ interactionConst.coulombEwaldTables = std::make_unique<EwaldCorrectionTables>();
+ init_interaction_const_tables(nullptr, &interactionConst, 0, 0);
+ }
+ return interactionConst;
+}
+
+void setGmxNonBondedNThreads(int numThreads)
+{
+ gmx_omp_nthreads_set(ModuleMultiThread::Pairsearch, numThreads);
+ gmx_omp_nthreads_set(ModuleMultiThread::Nonbonded, numThreads);
+}
+
+void updateForcerec(t_forcerec* forcerec, const matrix& box)
+{
+ assert(forcerec != nullptr && "Forcerec not initialized");
+ forcerec->shift_vec.resize(numShiftVectors);
+ calc_shifts(box, forcerec->shift_vec);
+}
+
+
+} // namespace nblib
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 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.
+ *
+ * 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.
+ */
+/*! \internal \file
+ * \brief Translation layer to GROMACS data structures for force calculations.
+ *
+ * \author Victor Holanda <victor.holanda@cscs.ch>
+ * \author Joe Jordan <ejjordan@kth.se>
+ * \author Prashanth Kanduri <kanduri@cscs.ch>
+ * \author Sebastian Keller <keller@cscs.ch>
+ */
+#ifndef NBLIB_NBNXMSETUPHELPERS_H
+#define NBLIB_NBNXMSETUPHELPERS_H
+
+#include "nblib/kerneloptions.h"
+#include "nblib/interactions.h"
+#include "nblib/particletype.h"
+
+struct nonbonded_verlet_t;
+struct t_forcerec;
+struct t_nrnb;
+struct interaction_const_t;
+struct gmx_enerdata_t;
+struct DeviceInformation;
+
+namespace gmx
+{
+class StepWorkload;
+class SimulationWorkload;
+class DeviceStreamManager;
+template<class T>
+class ArrayRef;
+} // namespace gmx
+
+namespace Nbnxm
+{
+enum class KernelType;
+struct KernelSetup;
+} // namespace Nbnxm
+
+namespace nblib
+{
+
+/*! \brief determine number of energy groups in an array of particle info flags
+ *
+ * Note: If the maximum energy group ID in the input is N, it is assumed that
+ * all the energy groups with IDs from 0...N-1 also exist.
+ */
+int64_t findNumEnergyGroups(gmx::ArrayRef<int64_t> particleInteractionFlags);
+
+//! Helper to translate between the different enumeration values.
+Nbnxm::KernelType translateBenchmarkEnum(const SimdKernels& kernel);
+
+/*! \brief Checks the kernel setup
+ *
+ * Throws an exception when the kernel is not available.
+ */
+void checkKernelSetup(SimdKernels nbnxmSimd);
+
+//! Creates and returns the kernel setup
+Nbnxm::KernelSetup createKernelSetupCPU(const NBKernelOptions& options);
+
+//! Create Particle info array to mark those that undergo VdV interaction
+std::vector<int64_t> createParticleInfoAllVdv(size_t numParticles);
+
+//! Create the non-bonded parameter vector in GROMACS format
+std::vector<real> createNonBondedParameters(const std::vector<ParticleType>& particleTypes,
+ const NonBondedInteractionMap& nonBondedInteractionMap);
+
+//! Create a step work object
+gmx::StepWorkload createStepWorkload(const NBKernelOptions& options);
+
+//! Computes the Ewald splitting coefficient for Coulomb
+real ewaldCoeff(real ewald_rtol, real pairlistCutoff);
+
+//! Creates an interaction_const_t object from NBKernelOptions
+interaction_const_t createInteractionConst(const NBKernelOptions& options);
+
+//! Set number of OpenMP threads in the GROMACS backend
+void setGmxNonBondedNThreads(int numThreads);
+
+//! Update the shift vectors in t_forcerec
+void updateForcerec(t_forcerec* forcerec, const matrix& box);
+
+} // namespace nblib
+
+#endif // NBLIB_NBNXMSETUPHELPERS_H
particletype.cpp
pbcholder.cpp
molecules.cpp
+ nbnxmsetup.cpp
topology.cpp
)
target_link_libraries(${exename} PRIVATE mdrun_test_infrastructure)
--- /dev/null
+/*
+ * 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.
+ */
+/*! \internal \file
+ * \brief
+ * Tests for nbnxm setup utilities
+ *
+ * \author Victor Holanda <victor.holanda@cscs.ch>
+ * \author Joe Jordan <ejjordan@kth.se>
+ * \author Prashanth Kanduri <kanduri@cscs.ch>
+ * \author Sebastian Keller <keller@cscs.ch>
+ */
+#include <cmath>
+
+#include "gromacs/utility/arrayref.h"
+#include "gromacs/mdtypes/forcerec.h"
+#include "gromacs/nbnxm/nbnxm.h"
+#include "gromacs/nbnxm/nbnxm_simd.h"
+#include "nblib/box.h"
+#include "nblib/nbnxmsetuphelpers.h"
+
+#include "testutils/testasserts.h"
+
+namespace nblib
+{
+namespace test
+{
+namespace
+{
+TEST(NbnxmSetupTest, findNumEnergyGroups)
+{
+ std::vector<int64_t> v(10);
+ int arbitraryGid = 7;
+
+ // this sets some bit outside the range of bits used for the group ID
+ // having all bits zero except those used for the group ID can otherwise hide bugs
+ v[5] |= gmx::sc_atomInfo_HasCharge;
+ v[5] = (v[5] & ~gmx::sc_atomInfo_EnergyGroupIdMask) | arbitraryGid;
+
+ int nEnergyGroups = arbitraryGid + 1;
+ EXPECT_EQ(nEnergyGroups, findNumEnergyGroups(v));
+}
+
+TEST(NbnxmSetupTest, canTranslateBenchmarkEnumAuto)
+{
+ auto kernel = SimdKernels::SimdAuto;
+ EXPECT_EQ(translateBenchmarkEnum(kernel), Nbnxm::KernelType::NotSet);
+}
+
+TEST(NbnxmSetupTest, canTranslateBenchmarkEnumNo)
+{
+ auto kernel = SimdKernels::SimdNo;
+ EXPECT_EQ(translateBenchmarkEnum(kernel), Nbnxm::KernelType::Cpu4x4_PlainC);
+}
+
+TEST(NbnxmSetupTest, canTranslateBenchmarkEnum2XM)
+{
+ auto kernel = SimdKernels::Simd2XMM;
+ EXPECT_EQ(translateBenchmarkEnum(kernel), Nbnxm::KernelType::Cpu4xN_Simd_2xNN);
+}
+
+TEST(NbnxmSetupTest, canTranslateBenchmarkEnum4XM)
+{
+ auto kernel = SimdKernels::Simd4XM;
+ EXPECT_EQ(translateBenchmarkEnum(kernel), Nbnxm::KernelType::Cpu4xN_Simd_4xN);
+}
+
+TEST(NbnxmSetupTest, CheckKernelSetupThrowsAuto)
+{
+ EXPECT_ANY_THROW(checkKernelSetup(SimdKernels::SimdAuto));
+}
+
+TEST(NbnxmSetupTest, CheckKernelSetupThrowsCount)
+{
+ EXPECT_ANY_THROW(checkKernelSetup(SimdKernels::Count));
+}
+
+TEST(NbnxmSetupTest, canCreateKernelSetupPlain)
+{
+ NBKernelOptions nbKernelOptions;
+ nbKernelOptions.nbnxmSimd = SimdKernels::SimdNo;
+ Nbnxm::KernelSetup kernelSetup = createKernelSetupCPU(nbKernelOptions);
+ EXPECT_EQ(kernelSetup.kernelType, Nbnxm::KernelType::Cpu4x4_PlainC);
+ EXPECT_EQ(kernelSetup.ewaldExclusionType, Nbnxm::EwaldExclusionType::Table);
+}
+
+TEST(NbnxmSetupTest, canCreateParticleInfoAllVdv)
+{
+ size_t numParticles = 2;
+ int64_t mask = 0;
+ mask |= gmx::sc_atomInfo_HasVdw;
+ mask |= gmx::sc_atomInfo_HasCharge;
+ std::vector<int64_t> refParticles = { mask, mask };
+ std::vector<int64_t> testParticles = createParticleInfoAllVdv(numParticles);
+ EXPECT_EQ(refParticles, testParticles);
+}
+
+TEST(NbnxmSetupTest, ewaldCoeffWorks)
+{
+ real ewald = ewaldCoeff(1e-5, 1.0);
+ gmx::test::FloatingPointTolerance tolerance = gmx::test::absoluteTolerance(1e-5);
+ EXPECT_REAL_EQ_TOL(ewald, 3.12341, tolerance);
+}
+
+TEST(NbnxmSetupTest, updateForcerecWorks)
+{
+ t_forcerec forcerec;
+ Box box(3);
+ EXPECT_NO_THROW(updateForcerec(&forcerec, box.legacyMatrix()));
+}
+
+// The following tests check if the user is allowed to specify configurations not permitted due
+// to conflicting compile time setup flags
+
+TEST(NbnxmSetupTest, canCheckKernelSetup)
+{
+ NBKernelOptions nbKernelOptions;
+ nbKernelOptions.nbnxmSimd = SimdKernels::SimdNo;
+#ifdef GMX_NBNXN_SIMD_4XN
+ nbKernelOptions.nbnxmSimd = SimdKernels::Simd4XM;
+#endif
+#ifdef GMX_NBNXN_SIMD_2XNN
+ nbKernelOptions.nbnxmSimd = SimdKernels::Simd2XMM;
+#endif
+ EXPECT_NO_THROW(checkKernelSetup(nbKernelOptions.nbnxmSimd));
+}
+
+// check if the user is allowed to ask for SimdKernels::Simd2XMM when NBLIB is not compiled with it
+#ifndef GMX_NBNXN_SIMD_2XNN
+TEST(NbnxmSetupTest, cannotCreateKernelSetupCPU2XM)
+{
+ NBKernelOptions nbKernelOptions;
+ nbKernelOptions.nbnxmSimd = SimdKernels::Simd2XMM;
+ nbKernelOptions.useTabulatedEwaldCorr = true;
+ EXPECT_ANY_THROW(createKernelSetupCPU(nbKernelOptions));
+}
+#endif
+
+// check if the user is allowed to ask for SimdKernels::Simd4XM when NBLIB is not compiled with it
+#ifndef GMX_NBNXN_SIMD_4XN
+TEST(NbnxmSetupTest, cannotCreateKernelSetupCPU4XM)
+{
+ NBKernelOptions nbKernelOptions;
+ nbKernelOptions.nbnxmSimd = SimdKernels::Simd4XM;
+ nbKernelOptions.useTabulatedEwaldCorr = false;
+ EXPECT_ANY_THROW(createKernelSetupCPU(nbKernelOptions));
+}
+#endif
+
+} // namespace
+} // namespace test
+} // namespace nblib
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 2020, 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.
- */
-/*! \internal \file
- * \brief
- * This implements nbnxn setup tests
- *
- * \author Victor Holanda <victor.holanda@cscs.ch>
- * \author Joe Jordan <ejjordan@kth.se>
- * \author Prashanth Kanduri <kanduri@cscs.ch>
- * \author Sebastian Keller <keller@cscs.ch>
- */
-#include "nblib/gmxsetup.h"
-#include "nblib/tests/testhelpers.h"
-#include "nblib/tests/testsystems.h"
-
-#include "testutils/testasserts.h"
-
-namespace nblib
-{
-
-namespace test
-{
-
-TEST(NBlibTest, CanConstructNbvSetupUtil)
-{
- ArgonSimulationStateBuilder argonSimulationStateBuilder;
- SimulationState system = argonSimulationStateBuilder.setupSimulationState();
- EXPECT_NO_THROW(NbvSetupUtil());
-}
-
-} // namespace test
-
-} // namespace nblib