#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2012,2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by
+# Copyright (c) 2012,2013,2014,2015,2016,2017,2018,2019, 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.
endif()
elseif(CPU_DETECTION_FEATURES MATCHES " avx2 ")
if(CPU_DETECTION_FEATURES MATCHES " amd ")
- set(OUTPUT_SIMD "AVX2_128")
+ gmx_run_cpu_detection(family)
+ gmx_run_cpu_detection(model)
+ set(ZEN1_MODELS 1 17 8 24)
+ if("${CPU_DETECTION_FAMILY}" STREQUAL "23" AND "${CPU_DETECTION_MODEL}" IN_LIST ZEN1_MODELS)
+ # Zen/Zen+, where 128-bit AVX2 will be faster
+ set(OUTPUT_SIMD "AVX2_128")
+ else()
+ # Zen2 or later, where 256-bit AVX2 should be faster
+ set(OUTPUT_SIMD "AVX2_256")
+ endif()
else()
+ # not AMD
set(OUTPUT_SIMD "AVX2_256")
endif()
elseif(CPU_DETECTION_FEATURES MATCHES " avx ")
if(NOT MPI_FOUND)
find_package(MPI)
if(MPI_C_FOUND)
- set(MPI_COMPILE_FLAGS ${MPI_C_COMPILE_FLAGS})
- set(MPI_LINKER_FLAGS ${MPI_C_LINK_FLAGS})
- include_directories(SYSTEM ${MPI_C_INCLUDE_PATH})
- list(APPEND GMX_COMMON_LIBRARIES ${MPI_C_LIBRARIES})
+ set(MPI_COMPILE_FLAGS ${MPI_C_COMPILE_FLAGS})
+ set(MPI_LINKER_FLAGS ${MPI_C_LINK_FLAGS})
+ include_directories(SYSTEM ${MPI_C_INCLUDE_PATH})
+ list(APPEND GMX_COMMON_LIBRARIES ${MPI_C_LIBRARIES})
endif()
set(MPI_FOUND ${MPI_C_FOUND})
else()
Fixes where mdrun could behave incorrectly
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Fix incorrect pressure when atoms in CMAP cross a box boundary
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+
+The virial calculation and thus the pressure would be incorrect
+when the second and third atom involved in a CHARMM CMAP correction
+term would reside in different periodic images. This can happen when
+a protein is positioned over a box boundary. Note that the energy
+and forces were correct, but sampling was affected when pressure
+coupling was applied when a protein crossed a box boundary.
+
+:issue:`2845`
+:issue:`2867`
+
+Fix incorrect LJ cut-off on GPU when rvdw < rcoulomb
+""""""""""""""""""""""""""""""""""""""""""""""""""""
+
+When rvdw was chosen by the user to be smaller than rcoulomb in the mdp file,
+the LJ cut-off would initially be set to the Coulomb cut-off for computing
+non-bonded interactions on the GPU. This only affected energy minimization,
+mdrun -rerun and the first 2*nstlist steps of a normal MD run, since the correct
+LJ cut-off is set when PME tuning (on by default) starts after 2*nstlist steps
+(unless PME tuning was disabled with -notunepme).
+
+:issue:`3056`
+
+
Fix (unlikely) missing bonded forces with CUDA GPUs and domain decomposition
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Fixes for ``gmx`` tools
^^^^^^^^^^^^^^^^^^^^^^^
+Fix grompp not adding angle constraints between constraints
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+
+When using the mdp option constraints=all-angles, angles involving
+bonds supplied as constraints in the topology would be removed,
+but not replaced by angle constraints.
+
+:issue:`3067`
+
Fix bug in gmx xpm2ps
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
*/
for (int ftype = 0; (ftype < F_NRE); ftype++)
{
- if (interaction_function[ftype].flags & IF_BTYPE)
+ if (interaction_function[ftype].flags & IF_CHEMBOND)
{
InteractionsOfType *bonds = &(plist[ftype]);
real param = std::sqrt( b_ij*b_ij + b_jk*b_jk -
2.0*b_ij*b_jk*cos(DEG2RAD*ang->c0()));
std::vector<real> forceParm = {param, param};
+ if (ftype == F_CONNBONDS ||
+ ftype_a == F_CONNBONDS)
+ {
+ gmx_fatal(FARGS, "Can not constrain all angles when they involved bonds of type %s",
+ interaction_function[F_CONNBONDS].longname);
+ }
/* apply law of cosines */
#ifdef DEBUG
printf("p: %d, q: %d, dist: %12.5e\n", atomNumbers[0],
rvec_inc(fshift[t21], f1_k);
rvec_inc(fshift[t31], f1_l);
- rvec_inc(fshift[t21], f2_i);
+ rvec_inc(fshift[t12], f2_i);
rvec_inc(fshift[CENTRAL], f2_j);
rvec_inc(fshift[t22], f2_k);
rvec_inc(fshift[t32], f2_l);
/*! Selects the Ewald kernel type, analytical on SM 3.0 and later, tabulated on
earlier GPUs, single or twin cut-off. */
-static int pick_ewald_kernel_type(bool bTwinCut)
+static int pick_ewald_kernel_type(const interaction_const_t &ic)
{
+ bool bTwinCut = (ic.rcoulomb != ic.rvdw);
bool bUseAnalyticalEwald, bForceAnalyticalEwald, bForceTabulatedEwald;
int kernel_type;
}
else if ((EEL_PME(ic->eeltype) || ic->eeltype == eelEWALD))
{
- /* Initially rcoulomb == rvdw, so it's surely not twin cut-off. */
- nbp->eeltype = pick_ewald_kernel_type(false);
+ nbp->eeltype = pick_ewald_kernel_type(*ic);
}
else
{
set_cutoff_parameters(nbp, ic, nbv->pairlistSets().params());
- nbp->eeltype = pick_ewald_kernel_type(ic->rcoulomb != ic->rvdw);
+ nbp->eeltype = pick_ewald_kernel_type(*ic);
GMX_RELEASE_ASSERT(ic->coulombEwaldTables, "Need valid Coulomb Ewald correction tables");
init_ewald_coulomb_force_table(*ic->coulombEwaldTables, nbp);
#include "gpu_types.h"
#include "locality.h"
+struct interaction_const_t;
struct nbnxn_atomdata_t;
struct gmx_wallcycle;
enum class GpuTaskCompletion;
/*! \brief Selects the Ewald kernel type, analytical or tabulated, single or twin cut-off. */
GPU_FUNC_QUALIFIER
-int gpu_pick_ewald_kernel_type(bool gmx_unused bTwinCut) GPU_FUNC_TERM_WITH_RETURN(-1);
+int nbnxn_gpu_pick_ewald_kernel_type(const interaction_const_t gmx_unused &ic) GPU_FUNC_TERM_WITH_RETURN(-1);
/*! \brief Initialization for X buffer operations on GPU.
* Called on the NS step and performs (re-)allocations and memory copies. !*/
/*! \brief Selects the Ewald kernel type, analytical or tabulated, single or twin cut-off. */
-int gpu_pick_ewald_kernel_type(const bool bTwinCut)
+int nbnxn_gpu_pick_ewald_kernel_type(const interaction_const_t &ic)
{
+ bool bTwinCut = (ic.rcoulomb != ic.rvdw);
bool bUseAnalyticalEwald, bForceAnalyticalEwald, bForceTabulatedEwald;
int kernel_type;
}
else if ((EEL_PME(ic->eeltype) || ic->eeltype == eelEWALD))
{
- /* Initially rcoulomb == rvdw, so it's surely not twin cut-off. */
- *gpu_eeltype = gpu_pick_ewald_kernel_type(false);
+ *gpu_eeltype = nbnxn_gpu_pick_ewald_kernel_type(*ic);
}
else
{
set_cutoff_parameters(nbp, ic, nbv->pairlistSets().params());
- nbp->eeltype = gpu_pick_ewald_kernel_type(ic->rcoulomb != ic->rvdw);
+ nbp->eeltype = nbnxn_gpu_pick_ewald_kernel_type(*ic);
GMX_RELEASE_ASSERT(ic->coulombEwaldTables, "Need valid Coulomb Ewald correction tables");
init_ewald_coulomb_force_table(*ic->coulombEwaldTables, nbp, nb->dev_rundata);
return name.at(s);
}
+namespace
+{
+
+
+//! Helper to detect correct AMD Zen architecture.
+bool
+cpuIsAmdZen1(const CpuInfo &cpuInfo)
+{
+ // Both Zen/Zen+/Zen2 have family==23
+ // Model numbers for Zen:
+ // 1) Naples, Whitehaven, Summit ridge, and Snowy Owl
+ // 17) Raven ridge
+ // Model numbers for Zen+:
+ // 8) Pinnacle Ridge
+ // 24) Picasso
+ return (cpuInfo.vendor() == gmx::CpuInfo::Vendor::Amd &&
+ cpuInfo.family() == 23 &&
+ (cpuInfo.model() == 1 || cpuInfo.model() == 17 ||
+ cpuInfo.model() == 8 || cpuInfo.model() == 24) );
+}
+
+} // namespace
+
+
SimdType
simdSuggested(const CpuInfo &c)
{
case CpuInfo::Vendor::Hygon:
if (c.feature(CpuInfo::Feature::X86_Avx2))
{
- // AMD Ryzen supports 256-bit AVX2, but performs better with 128-bit
+ // AMD Zen supports 256-bit AVX2, but Zen1 performs better with 128-bit
// since it can execute two independent such instructions per cycle,
// and wider SIMD has slightly lower efficiency in GROMACS.
- suggested = SimdType::X86_Avx2_128;
+ // However... Zen2 supports full-width execution of 256-bit AVX2,
+ // so we only want to apply this hack to Zen/Zen+.
+ suggested = cpuIsAmdZen1(c) ? SimdType::X86_Avx2_128 : SimdType::X86_Avx2;
}
else if (c.feature(CpuInfo::Feature::X86_Avx))
{