Merge branch 'release-2019' into master
authorPaul Bauer <paul.bauer.q@gmail.com>
Wed, 20 Feb 2019 12:50:49 +0000 (13:50 +0100)
committerPaul Bauer <paul.bauer.q@gmail.com>
Wed, 20 Feb 2019 12:50:49 +0000 (13:50 +0100)
Kept the way topologyinformation was removed from solvate and
insert_molecules in 2019.

Resolved Conflicts:
cmake/gmxVersionInfo.cmake
docs/CMakeLists.txt
docs/user-guide/mdp-options.rst
src/gromacs/gmxpreprocess/insert-molecules.cpp
src/gromacs/gmxpreprocess/solvate.cpp
src/gromacs/mdlib/nbnxn_cuda/nbnxn_cuda_kernel_utils.cuh
src/gromacs/mdlib/nbnxn_ocl/nbnxn_ocl_kernel_utils.clh
src/gromacs/mdlib/sim_util.cpp
src/gromacs/trajectoryanalysis/topologyinformation.cpp

Change-Id: I2576133c4bc7a3c55cedb29e9832bb5afa8fe76f

43 files changed:
cmake/gmxManageNvccConfig.cmake
cmake/gmxManageOpenCL.cmake
cmake/gmxSimdFlags.cmake
cmake/gmxVersionInfo.cmake
docs/CMakeLists.txt
docs/install-guide/index.rst
docs/reference-manual/special/electric-fields.rst
docs/release-notes/2018/2018.4.rst
docs/release-notes/2018/2018.5.rst
docs/release-notes/2019/2019.1.rst
docs/release-notes/2019/2019.2.rst [new file with mode: 0644]
docs/release-notes/index.rst
docs/user-guide/mdp-options.rst
docs/user-guide/mdrun-performance.rst
src/gromacs/CMakeLists.txt
src/gromacs/domdec/partition.cpp
src/gromacs/ewald/pme.cpp
src/gromacs/ewald/pme.h
src/gromacs/ewald/tests/pmetestcommon.cpp
src/gromacs/ewald/tests/testhardwarecontexts.cpp
src/gromacs/gmxana/gmx_tune_pme.cpp
src/gromacs/gmxpreprocess/insert_molecules.cpp
src/gromacs/gmxpreprocess/readir.cpp
src/gromacs/gmxpreprocess/solvate.cpp
src/gromacs/mdlib/constr.cpp
src/gromacs/mdlib/constr.h
src/gromacs/mdlib/force.cpp
src/gromacs/mdlib/sim_util.cpp
src/gromacs/mdrun/rerun.cpp
src/gromacs/mdrun/runner.cpp
src/gromacs/nbnxm/cuda/nbnxm_cuda_kernel_utils.cuh
src/gromacs/nbnxm/opencl/nbnxm_ocl_kernel_utils.clh
src/gromacs/simd/tests/simd_floatingpoint_util.cpp
src/gromacs/taskassignment/decidegpuusage.cpp
src/gromacs/taskassignment/decidegpuusage.h
src/gromacs/taskassignment/resourcedivision.cpp
src/gromacs/trajectoryanalysis/tests/index.ndx [new file with mode: 0644]
src/gromacs/trajectoryanalysis/tests/rdf.cpp
src/gromacs/trajectoryanalysis/tests/refdata/RdfModuleTest_SelectionsFromBothTopologyFileAndIndexFileWork.xml [new file with mode: 0644]
src/gromacs/trajectoryanalysis/tests/refdata/RdfModuleTest_SelectionsSolelyFromIndexFileWork.xml [new file with mode: 0644]
src/gromacs/trajectoryanalysis/tests/topologyinformation.cpp
src/gromacs/trajectoryanalysis/topologyinformation.cpp
src/programs/mdrun/tests/pmetest.cpp

index c4a5abaaf4697ebe00d073c8f5b334c909b0d651..f88297e960f2c1a52cecaf9f11a96cefe63bf250 100644 (file)
@@ -163,7 +163,15 @@ list(APPEND GMX_CUDA_NVCC_FLAGS "${CUDA_HOST_COMPILER_OPTIONS}")
 string(TOUPPER "${CMAKE_BUILD_TYPE}" _build_type)
 gmx_check_if_changed(_cuda_nvcc_executable_or_flags_changed CUDA_NVCC_EXECUTABLE CUDA_NVCC_FLAGS CUDA_NVCC_FLAGS_${_build_type})
 
-if(_cuda_nvcc_executable_or_flags_changed OR CUDA_HOST_COMPILER_CHANGED OR NOT GMX_NVCC_WORKS)
+# We would like to be helpful and reject the host compiler with a
+# clear error message at configure time, rather than let nvcc
+# later reject the host compiler as not supported when the first
+# CUDA source file is built. We've implemented that for current
+# nvcc running on Unix-like systems, but e.g. changes to nvcc
+# will further affect the limited portability of this checking
+# code. Set the CMake variable GMX_NVCC_WORKS on if you want to
+# bypass this check.
+if((_cuda_nvcc_executable_or_flags_changed OR CUDA_HOST_COMPILER_CHANGED OR NOT GMX_NVCC_WORKS) AND NOT WIN32)
     message(STATUS "Check for working NVCC/C compiler combination")
     execute_process(COMMAND ${CUDA_NVCC_EXECUTABLE} -ccbin ${CUDA_HOST_COMPILER} -c ${CUDA_NVCC_FLAGS} ${CUDA_NVCC_FLAGS_${_build_type}} ${CMAKE_SOURCE_DIR}/cmake/TestCUDA.cu
         RESULT_VARIABLE _cuda_test_res
index 9fd5a4f726015241f6cd09a72f7c1e81309f1eaa..8170b531c0269a89b77a396316ecbc0758f8bdd4 100644 (file)
@@ -1,7 +1,7 @@
 #
 # This file is part of the GROMACS molecular simulation package.
 #
-# Copyright (c) 2012,2013,2014,2015,2018, by the GROMACS development team, led by
+# Copyright (c) 2012,2013,2014,2015,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.
@@ -64,6 +64,13 @@ add_definitions(${OpenCL_DEFINITIONS})
 
 include_directories(SYSTEM ${OpenCL_INCLUDE_DIRS})
 
+# Ensure the OpenCL implementation is 64-bit, because we only support that;
+# Note that this can only be revised if the cl_mem size assumptions made
+# (originally in pme-gpu-types.h) are relieved.
+if (NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
+    message(FATAL_ERROR "The OpenCL implementation is only supported on 64-bit platforms.")
+endif()
+
 set(GMX_OPENCL_NB_CLUSTER_SIZE 8 CACHE STRING "Cluster size used by nonbonded OpenCL kernel. Set to 4 for Intel GPUs.")
 mark_as_advanced(GMX_OPENCL_NB_CLUSTER_SIZE)
 
index bf17e6af819fd29be44935b6b1cbeb60b88e95e4..3dce16fc942189fc4343d8d4ac891e7f34042c38 100644 (file)
@@ -58,14 +58,19 @@ macro(find_power_vsx_toolchain_flags TOOLCHAIN_C_FLAGS_VARIABLE TOOLCHAIN_CXX_FL
         # VSX uses the same function API as Altivec/VMX, so make sure we tune for the current CPU and not VMX.
         # By putting these flags here rather than in the general compiler flags file we can safely assume
         # that we are at least on Power7 since that is when VSX appeared.
+
+        # NOTE:  Enabling instruction fusion on Power8/9 using -mpower8-fusion/-mpower9-fusion
+        #        seems to produce buggy code (see #2747, #2746, #2734).
+        #        Note that instruction fusion does have considerable performance benefits
+        #        (up to 8% measured with gcc 8) if the issue is resolved the flag can be re-enabled.
         gmx_run_cpu_detection(brand)
         if(CPU_DETECTION_BRAND MATCHES "POWER7")
             gmx_test_cflag(GNU_C_VSX_POWER7   "-mcpu=power7 -mtune=power7" ${TOOLCHAIN_C_FLAGS_VARIABLE})
             gmx_test_cflag(GNU_CXX_VSX_POWER7 "-mcpu=power7 -mtune=power7" ${TOOLCHAIN_CXX_FLAGS_VARIABLE})
         elseif(CPU_DETECTION_BRAND MATCHES "POWER8")
             # Enable power8 vector extensions on such platforms.
-            gmx_test_cflag(GNU_C_VSX_POWER8   "-mcpu=power8 -mpower8-vector -mpower8-fusion" ${TOOLCHAIN_C_FLAGS_VARIABLE})
-            gmx_test_cflag(GNU_CXX_VSX_POWER8 "-mcpu=power8 -mpower8-vector -mpower8-fusion" ${TOOLCHAIN_CXX_FLAGS_VARIABLE})
+            gmx_test_cflag(GNU_C_VSX_POWER8   "-mcpu=power8 -mpower8-vector" ${TOOLCHAIN_C_FLAGS_VARIABLE})
+            gmx_test_cflag(GNU_CXX_VSX_POWER8 "-mcpu=power8 -mpower8-vector" ${TOOLCHAIN_CXX_FLAGS_VARIABLE})
         elseif(CPU_DETECTION_BRAND MATCHES "POWER9")
             # Enable power9 vector extensions on such platforms.
             # TODO consider whether adding " -mpower9-vector -mpower9-fusion"
index a804d132e93ba529643f81edfbd2d54df1548ba9..5dcffe6707ad6cc4538176a3f3440b213c8da930 100644 (file)
@@ -83,7 +83,6 @@
 #       This ID is used for the source code tarball.
 #   GMX_MANUAL_DOI_ID
 #       Same as above, but for the reference manual.
-# Setting and retrieving of those variables is handled in gmxCheckReleaseDOI.cmake
 # They are collected into a single section below.
 # The following variables are set based on these:
 #   GMX_VERSION            String composed from GMX_VERSION_* numeric variables
index 8ad2e04f5a0fa9e773899a049354432bb002a513..9f6c80457a8492f81970588fc1ee8a9412cb69bf 100644 (file)
@@ -377,6 +377,7 @@ if (SPHINX_FOUND)
         release-notes/deprecated-functionality.rst
         release-notes/portability.rst
         release-notes/miscellaneous.rst
+        release-notes/2019/2019.2.rst
         release-notes/2019/2019.1.rst
         release-notes/2019/major/highlights.rst
         release-notes/2019/major/features.rst
index 20d3b60d44c9174a0997d2aea3a34f5bd0af3485..76cf1f8ad367c42b47d30b8808544deba7762e25 100644 (file)
@@ -194,7 +194,8 @@ version for |Gromacs| code as used as the host compiler for nvcc.
 
 To make it possible to use other accelerators, |Gromacs| also includes
 OpenCL_ support. The minimum OpenCL version required is
-|REQUIRED_OPENCL_MIN_VERSION|. The current OpenCL implementation is recommended for
+|REQUIRED_OPENCL_MIN_VERSION| and only 64-bit implementations are supported.
+The current OpenCL implementation is recommended for
 use with GCN-based AMD GPUs, and on Linux we recommend the ROCm runtime.
 Intel integrated GPUs are supported with the Neo drivers.
 OpenCL is also supported with NVIDIA GPUs, but using
@@ -203,7 +204,8 @@ recommended. Also note that there are performance limitations (inherent
 to the NVIDIA OpenCL runtime).
 It is not possible to configure both CUDA and OpenCL
 support in the same build of |Gromacs|, nor to support both
-Intel and other vendors' GPUs with OpenCL.
+Intel and other vendors' GPUs with OpenCL. A 64-bit implementation
+of OpenCL is required and therefore OpenCL is only supported on 64-bit platforms.
 
 .. _mpi-support:
 
index c6c892af3ecd21ca16dd56ff13385b6c5010fc89..50e627bf756279f7f498181e32d212c79a87226b 100644 (file)
@@ -1,3 +1,5 @@
+.. _electric fields:
+
 Electric fields
 ---------------
 
@@ -8,9 +10,10 @@ A pulsed and oscillating electric field can be applied according to:
 
 where :math:`E_0` is the field strength, the angular frequency
 :math:`\omega = 2\pi c/\lambda`, :math:`t_0` is the time
-at of the peak in the field strength and :math:`\sigma` is the with of
+at of the peak in the field strength and :math:`\sigma` is the width of
 the pulse. Special cases occur when :math:`\sigma` = 0 (non-pulsed
-field) and for :math:`\omega` is 0 (static field).
+field) and for :math:`\omega` is 0 (static field). See
+:mdp:`electric-field-x` for more details.
 
 This simulated laser-pulse was applied to simulations of melting
 ice \ :ref:`146 <refCaleman2008a>`. A pulsed electric field may look ike
index 6ad3e1cbc31e182a7bb9cd44b519086aba570015..91e574bb474ad431d8248603959180b090c1fb17 100644 (file)
@@ -18,7 +18,7 @@ or LJ PME mesh forces would be scaled with lambda. Note that this bug
 did not affect the, usual, setup where charges or atom types are actually
 perturbed.
 
-:issue: `2640`
+:issue:`2640`
 
 Add constraint contribution to foreign Hamiltonian differences
 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
@@ -27,7 +27,7 @@ The contribution of perturbed constraints was missing from the foreign
 Hamiltonian values. This is important for free energy calculations,
 such as BAR.
 
-:issue: `2703`
+:issue:`2703`
 
 Add mass contribution to foreign Hamiltonian differences
 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
@@ -35,7 +35,7 @@ Add mass contribution to foreign Hamiltonian differences
 For free energy calculations with perturbed masses, the kinetic energy
 contribution was missing from the foreign Hamiltonian values.
 
-:issue: `2703`
+:issue:`2703`
 
 Work around bugs with expanded ensemble runs
 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
@@ -45,8 +45,8 @@ with the velocity Verlet integrator with nstcalcenergy>1 or with
 other integrators when nstexpanded was not a multiple of nstcalcenergy.
 In these cases mdrun now sets nstcalcenergy to 1.
 
-:issue: `2714`
-:issue: `2718`
+:issue:`2714`
+:issue:`2718`
 
 Checkpoint continuations require suitable .tpr files
 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
@@ -57,7 +57,7 @@ a particular result, but the use of that option is already deprecated.
 Use gmx grompp or gmx convert-tpr to make a .tpr file that expresses
 the intent.
 
-:issue: `2717`
+:issue:`2717`
 
 Fixes for ``gmx`` tools
 ^^^^^^^^^^^^^^^^^^^^^^^
index 692026c05cc5e0050e7d1dea21eed749fea48b2f..563fc3314780d88924c3db7ce772d561afcd7c3e 100644 (file)
@@ -25,7 +25,7 @@ Make large PME grids work on GPU
 PME grids with size along Z larger than 511 would make mdrun exit
 with a cryptic CUDA error.
 
-:issue: `2779`
+:issue:`2779`
 
 Fix LINCS accuracy with OpenMP when constraint triangles are present
 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
@@ -36,7 +36,7 @@ of iterations as normal constraints. With OpenMP this would only happen
 when the last OpenMP thread has at least one such triangle. This would
 cause a slight loss of accuracy in inhomogeneous systems.
 
-:issue: `2808`
+:issue:`2808`
 
 Fix acceleration with ``cos-acceleration``
 """"""""""""""""""""""""""""""""""""""""""
@@ -44,7 +44,7 @@ Fix acceleration with ``cos-acceleration``
 A factor of 2 was missing from the acceleration value, leading to incorrect
 results when e.g. calculating viscosities.
 
-:issue: `2572`
+:issue:`2572`
 
 Fix checkpoint restart of tpr with infinite step count
 """"""""""""""""""""""""""""""""""""""""""""""""""""""
@@ -73,8 +73,8 @@ This only works for writing .xtc files. The code and documentation now
 works correctly with .gro files, which was changed in 2016 release series so that
 it would only write fixed-width columns.
 
-:issue: `2813`
-:issue: `2037`
+:issue:`2813`
+:issue:`2037`
 
 Fixes to improve portability
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -90,7 +90,7 @@ resonances in the kinetic energy and pressure/volume can appear when
 the two coupling times involved are similar. Now grompp warns when ``tau-p``
 is less than two times ``tau-t``.
 
-:issue: `2749`
+:issue:`2749`
 
 Fixed efficiency issue with shell code minimization
 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
@@ -98,7 +98,7 @@ Fixed efficiency issue with shell code minimization
 Code cleanup touching unnecessarily complex code created an efficiency
 issue.  Both the issue and some of the complexity are now fixed.
 
-:issue: `2705`
+:issue:`2705`
 
 Added code generation support for NVIDIA Turing GPUs
 """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
index 99aaaa1a72f3616904b982c6294613eccf665f4d..b6972117e832f3635ea1dc44f4eb5e803b91bbc0 100644 (file)
@@ -1,7 +1,7 @@
 GROMACS 2019.1 release notes
 ----------------------------
 
-This version was released on TODO, 2019. These release notes
+This version was released on February 15, 2019. These release notes
 document the changes that have taken place in GROMACS since the
 initial version 2019, to fix known issues. It also incorporates all
 fixes made in version 2018.5 and earlier, which you can find described
@@ -11,50 +11,119 @@ Fixes where mdrun could behave incorrectly
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 Fix error with 2D/3D dynamic load balancing
--------------------------------------------
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 
-With 2D or 3D domain decomposition with dynamics load balancing,
+With 2D or 3D domain decomposition with dynamic load balancing,
 mdrun would exit with the error "The domain decomposition grid
-as shifted too much .." when a cell size was limited.
+has shifted too much .." when a cell size was limited.
+
+:issue:`2830`
+
+Fix incorrect LJ repulsion force switching on GPUs
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+
+When using a CUDA or OpenCL GPU, the coefficient for the second order
+term for the LJ repulsion in the force switching function, called 'A'
+in the manual, had the wrong sign. This lead to very small errors in
+the forces and the pressure. Note that the dispersion force switching
+was correct. Although the effect on individual atoms pairs was negligible,
+their combined effect on the pressure could lead to deformation of
+CHARMM membrane systems, where LJ force switching is regularly applied.
+
+:issue:`2845`
 
-:issue: `2830`
 
 Fix segmentation fault in mdrun with domain decomposition
----------------------------------------------------------
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+
+:issue:`2813`
+
+Fix segmentation fault with energy minimization with the group scheme
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+
+Using energy minimization in combination with the group cutoff scheme
+and domain decomposition could lead to a segmentation fault.
+
+:issue:`2813`
+
+Correct free-energy Delta H output with mass lambda's
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+
+When separate lambda parameters were used for perturbed mass
+free-energy contributions, these contributions were double counted
+in the Delta H output used for BAR calculations. Note that dH/dlambda
+was always correct
+
+:issue:`2703`
+:issue:`2849`
 
-:issue: `2813`
+Prevent mdrun -rerun from writing incorrect free-energy output
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+
+Now mdrun -rerun exits with a fatal error when masses or constraints
+are perturbed. Their contributions to Hamiltonian differences and
+derivatives were incorrectly set to zero in version 2019.
+
+:issue:`2849`
 
 Fix possible division by zero in enforced-rotation code
--------------------------------------------------------
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 
-:issue: `1431`
+:issue:`1431`
 
 Fixes for ``gmx`` tools
 ^^^^^^^^^^^^^^^^^^^^^^^
 
 Fix trjconv -ndec
----------------------------------------------------------
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 
 This only works for writing .xtc files. The code and documentation now
 works correctly with .gro files, which was changed in 2016 release series so that
 it would only write fixed-width columns.
 
-:issue: `2824`
-:issue: `2037`
+:issue:`2824`
+:issue:`2037`
+
+Fix using index file groups when .tpr file not supplied
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+
+Selections that use groups from a supplied index file can
+again be used even when a .tpr file is not supplied.
+
+:issue:`2847`
+
+Fix tune_pme
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 
+The tool did not work due to a file reading error that is fixed now.
+
+:issue:`2827`
 
 Fixes that affect portability
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 With MSVC, disabled internal clFFT fallback used for OpenCL support
--------------------------------------------------------------------
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+
 GROMACS requires MSVC 2017, and the GROMACS OpenCL build requires
 clFFT. If clFFT is found on the user's system, then all may be well,
 but the version of clFFT bundled within GROMACS cannot be built
 because only MSVC 2010 is supported by clFFT at this time. A
 configure-time fatal error is now issued in this case.
 
-:issue: `2500`
+:issue:`2500`
+
+Explicitly require 64-bit platforms for OpenCL
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+
+A 64-bit OpenCL runtime is required by GROMACS.
+All known OpenCL implementations on 64-bit platforms are 64-bit
+(and there are no known 32-bit platforms with 64-bit OpenCL),
+hence we require a 64-bit platform at configure-time in OpenCL builds.
+A known unsupported 32-bit platform is ARMv7.
 
 Miscellaneous
 ^^^^^^^^^^^^^
+
+Improved docs for applying electric fields
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
diff --git a/docs/release-notes/2019/2019.2.rst b/docs/release-notes/2019/2019.2.rst
new file mode 100644 (file)
index 0000000..9283293
--- /dev/null
@@ -0,0 +1,26 @@
+GROMACS 2019.2 release notes
+----------------------------
+
+This version was released on TODO, 2019. These release notes
+document the changes that have taken place in GROMACS since the
+initial version 2019.1, to fix known issues. It also incorporates all
+fixes made in version 2018.5 and earlier, which you can find described
+in the :ref:`release-notes`.
+
+.. Note to developers!
+   Please use """"""" to underline the individual entries for fixed issues in the subfolders,
+   otherwise the formatting on the webpage is messed up.
+   Also, please use the syntax :issue:`number` to reference issues on redmine, without the
+   a space between the colon and number!
+
+Fixes where mdrun could behave incorrectly
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Fixes for ``gmx`` tools
+^^^^^^^^^^^^^^^^^^^^^^^
+
+Fixes that affect portability
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Miscellaneous
+^^^^^^^^^^^^^
index ac2a9646f992ee4abd381635cf2e1e43762d50ce..b0d564b938b259ac453d586122c83db2daba1522 100644 (file)
@@ -46,6 +46,7 @@ Patch releases
 .. toctree::
    :maxdepth: 1
 
+   2019/2019.2
    2019/2019.1
 
 Major release
index ead69bfce4fe30c8c451563bd72ade01d1c9d66a..3801cb8d331224c259404895f7b08a0bc319e320 100644 (file)
@@ -3041,28 +3041,29 @@ Non-equilibrium MD
 Electric fields
 ^^^^^^^^^^^^^^^
 
-.. mdp:: electric-field-x ; electric-field-y ; electric-field-z
+.. mdp:: electric-field-x
+.. mdp:: electric-field-y
+.. mdp:: electric-field-z
 
    Here you can specify an electric field that optionally can be
    alternating and pulsed. The general expression for the field
    has the form of a gaussian laser pulse:
 
-   E(t) = E0 exp ( -(t-t0)\ :sup:`2`/(2 sigma\ :sup:`2`) ) cos(omega (t-t0))
+   .. math:: E(t) = E_0 \exp\left[-\frac{(t-t_0)^2}{2\sigma^2}\right]\cos\left[\omega (t-t_0)\right]
 
    For example, the four parameters for direction x are set in the
-   three fields of ``electric-field-x`` (and similar for y and z)
-   like
+   fields of :mdp:`electric-field-x` (and similar for ``electric-field-y``
+   and ``electric-field-z``) like
 
-   electric-field-x  = E0 omega t0 sigma
+   ``electric-field-x  = E0 omega t0 sigma``
 
-   In the special case that sigma = 0, the exponential term is omitted
-   and only the cosine term is used. If also omega = 0 a static
-   electric field is applied.
+   with units (respectively) V nm\ :sup:`-1`, ps\ :sup:`-1`, ps, ps.
 
-   More details in Carl Caleman and David van der Spoel: Picosecond
-   Melting of Ice by an Infrared Laser Pulse - A Simulation Study.
-   Angew. Chem. Intl. Ed. 47 pp. 14 17-1420 (2008)
+   In the special case that ``sigma = 0``, the exponential term is omitted
+   and only the cosine term is used. If also ``omega = 0`` a static
+   electric field is applied.
 
+   Read more at :ref:`electric fields` and in ref. \ :ref:`146 <refCaleman2008a>`.
 
 
 Mixed quantum/classical molecular dynamics
index 5b8017cb4e21ed6392de8c90a67c12806822a0ec..5dc37bf6544cff25f72c11f83cc3eef94edb424b 100644 (file)
@@ -202,6 +202,8 @@ installation on multiple different machines, it is convenient to compile the ana
 the lowest common SIMD instruction set (as these rely little on SIMD acceleration), but for best
 performance :ref:`mdrun <gmx mdrun>` should be compiled separately for each machine.
 
+.. TODO add a note on AVX throttle and its impact on MPI-parallel and GPU accelerated runs
+
 Process(-or) level parallelization via OpenMP
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -1139,8 +1141,16 @@ Performance considerations for GPU tasks
    with the GPUs focused on the calculation of the NB.
 
 #) With fast/modern GPUs and/or slow/old CPUs with few cores,
-   it generally helps to have the GPU do PME. With very few/weak
-   cores, it can help to have the GPU do bonded interactions also.
+   it generally helps to have the GPU do PME.
+
+#) Offloading bonded work to a GPU will often not improve simulation performance
+   as efficient CPU-based kernels can complete the bonded computation
+   before the GPU is done with other offloaded work. Therefore,
+   `gmx mdrun` will default to no bonded offload when PME is offloaded.
+   Typical cases where performance can be improvement with bonded offload are:
+   with significant bonded work (e.g. pure lipid or mostly polymer systems with little solvent),
+   with very few and/or slow CPU cores per GPU, or when the CPU does
+   other computation (e.g. PME, free energy).
 
 #) It *is* possible to use multiple GPUs with PME offload
    by letting e.g.
@@ -1228,7 +1238,7 @@ The minimum OpenCL version required is |REQUIRED_OPENCL_MIN_VERSION|. See
 also the :ref:`known limitations <opencl-known-limitations>`.
 
 Devices from the AMD GCN architectures (all series) are compatible
-and regularly tested; NVIDIA Fermi and later (compute capability 2.0)
+and regularly tested; NVIDIA Kepler and later (compute capability 3.0)
 are known to work, but before doing production runs always make sure that the |Gromacs| tests
 pass successfully on the hardware.
 
index 71d72783dac0c09e7614d92b97b56422e45368d9..82de302e9d2683d2634b361b532c91037e3eea23 100644 (file)
@@ -282,7 +282,7 @@ endif()
 # source files, and issue warnings about that. Remove the use of
 # -Wno-missing-prototypes here and above when the group scheme is
 # removed.
-if (HAS_NO_MISSING_PROTO AND "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
+if (HAS_NO_MISSING_PROTO AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
     target_compile_options(libgromacs_generated PRIVATE "-Wno-missing-prototypes")
 endif()
 if (HAS_NO_MSVC_UNUSED)
index 83ffe74855a82633455142c29b360b8769ce0134..d2764efd62f3497826aa2de90bd72f79279f44c7 100644 (file)
@@ -2709,8 +2709,11 @@ static void dd_sort_order(const gmx_domdec_t *dd,
 
     const int  movedValue = NSGRID_SIGNAL_MOVED_FAC*fr->ns->grid->ncells;
 
-    if (ncg_home_old >= 0)
+    if (ncg_home_old >= 0 && !sort->sorted.empty())
     {
+        GMX_RELEASE_ASSERT(sort->sorted.size() == static_cast<size_t>(ncg_home_old),
+                           "The sorting buffer should contain the old home charge group indices");
+
         std::vector<gmx_cgsort_t> &stationary = sort->stationary;
         std::vector<gmx_cgsort_t> &moved      = sort->moved;
 
@@ -3466,6 +3469,16 @@ void dd_partition_system(FILE                    *fplog,
 
         wallcycle_sub_stop(wcycle, ewcsDD_GRID);
     }
+    else
+    {
+        /* With the group scheme the sorting array is part of the DD state,
+         * but it just got out of sync, so mark as invalid by emptying it.
+         */
+        if (ir->cutoff_scheme == ecutsGROUP)
+        {
+            comm->sort->sorted.clear();
+        }
+    }
 
     if (comm->useUpdateGroups)
     {
index f906a04e45a9d120cd6d8cf9bea7ba9474d644ad..7221c3b9a9f7e1b9d5af975faa19c15ee063ad6f 100644 (file)
@@ -133,33 +133,48 @@ static bool
 addMessageIfNotSupported(const std::list<std::string> &errorReasons,
                          std::string                  *error)
 {
-    bool foundErrorReasons = errorReasons.empty();
-    if (!foundErrorReasons && error)
+    bool isSupported = errorReasons.empty();
+    if (!isSupported && error)
     {
         std::string regressionTestMarker = "PME GPU does not support";
         // this prefix is tested for in the regression tests script gmxtest.pl
-        *error = regressionTestMarker + ": " + gmx::joinStrings(errorReasons, "; ") + ".";
+        *error = regressionTestMarker;
+        if (errorReasons.size() == 1)
+        {
+            *error += " " + errorReasons.back();
+        }
+        else
+        {
+            *error += ": " + gmx::joinStrings(errorReasons, "; ");
+        }
+        *error += ".";
     }
-    return foundErrorReasons;
+    return isSupported;
 }
 
-bool pme_gpu_supports_build(const gmx_hw_info_t &hwinfo,
-                            std::string         *error)
+bool pme_gpu_supports_build(std::string *error)
 {
     std::list<std::string> errorReasons;
     if (GMX_DOUBLE)
     {
-        errorReasons.emplace_back("double precision");
+        errorReasons.emplace_back("a double-precision build");
     }
     if (GMX_GPU == GMX_GPU_NONE)
     {
-        errorReasons.emplace_back("non-GPU build of GROMACS");
+        errorReasons.emplace_back("a non-GPU build");
     }
+    return addMessageIfNotSupported(errorReasons, error);
+}
+
+bool pme_gpu_supports_hardware(const gmx_hw_info_t &hwinfo,
+                               std::string         *error)
+{
+    std::list<std::string> errorReasons;
     if (GMX_GPU == GMX_GPU_OPENCL)
     {
         if (!areAllGpuDevicesFromAmd(hwinfo.gpu_info))
         {
-            errorReasons.emplace_back("only AMD devices are supported");
+            errorReasons.emplace_back("non-AMD devices");
         }
     }
     return addMessageIfNotSupported(errorReasons, error);
index 5a4956a8b7c21a047feffa284a837a2e57228f5e..f4dffeed6ac6031d82b6efa94b4fb38bedd95ed8 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by
+ * Copyright (c) 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.
@@ -251,14 +251,22 @@ void gmx_pme_reinit_atoms(const gmx_pme_t *pme, int nAtoms, const real *charges)
  * TODO: this partly duplicates an internal PME assert function
  * pme_gpu_check_restrictions(), except that works with a
  * formed gmx_pme_t structure. Should that one go away/work with inputrec?
+ *
+ * \param[out] error   If non-null, the error message when PME is not supported on GPU.
+ *
+ * \returns true if PME can run on GPU on this build, false otherwise.
+ */
+bool pme_gpu_supports_build(std::string *error);
+
+/*! \brief Checks whether the detected (GPU) hardware allows to run PME on GPU.
  *
  * \param[in]  hwinfo  Information about the detected hardware
  * \param[out] error   If non-null, the error message when PME is not supported on GPU.
  *
  * \returns true if PME can run on GPU on this build, false otherwise.
  */
-bool pme_gpu_supports_build(const gmx_hw_info_t &hwinfo,
-                            std::string         *error);
+bool pme_gpu_supports_hardware(const gmx_hw_info_t &hwinfo,
+                               std::string         *error);
 
 /*! \brief Checks whether the input system allows to run PME on GPU.
  * TODO: this partly duplicates an internal PME assert function
index c3fe624c5ca9904fcca3964f0f9bc4ef8d4a7dd8..ad8905d0fdd27587f95514e1f21e07489f1e5adf 100644 (file)
@@ -85,7 +85,8 @@ bool pmeSupportsInputForMode(const gmx_hw_info_t &hwinfo,
             break;
 
         case CodePath::GPU:
-            implemented = (pme_gpu_supports_build(hwinfo, nullptr) &&
+            implemented = (pme_gpu_supports_build(nullptr) &&
+                           pme_gpu_supports_hardware(hwinfo, nullptr) &&
                            pme_gpu_supports_input(*inputRec, mtop, nullptr));
             break;
 
index 6157cd3dd1bc251fe7a692e58c5800ba70865aab..e15c37c3a1f1c2eae738e2b2f7fd84c77d6e1682 100644 (file)
@@ -113,7 +113,8 @@ void PmeTestEnvironment::SetUp()
     hardwareContexts_.emplace_back(std::make_unique<TestHardwareContext>(CodePath::CPU, "", nullptr));
 
     hardwareInfo_ = hardwareInit();
-    if (!pme_gpu_supports_build(*hardwareInfo_, nullptr))
+    if (!pme_gpu_supports_build(nullptr) ||
+        !pme_gpu_supports_hardware(*hardwareInfo_, nullptr))
     {
         // PME can only run on the CPU, so don't make any more test contexts.
         return;
index c0285e4a189d11c47c8b5581cfdef8611a0ae5af..264d2d8e0cfc3007d1b22c7c013a3ab6e7f042f0 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2009,2010,2011,2012,2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by
+ * Copyright (c) 2009,2010,2011,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.
@@ -2169,7 +2169,7 @@ int gmx_tune_pme(int argc, char *argv[])
         { efLOG, "-err",    "bencherr", ffWRITE },
         { efTPR, "-so",     "tuned",    ffWRITE },
         /* mdrun: */
-        { efTPR, nullptr,      nullptr,       ffREAD },
+        { efTPR, "-s",      nullptr,       ffREAD },
         { efTRN, "-o",      nullptr,       ffWRITE },
         { efCOMPRESSED, "-x", nullptr,     ffOPTWR },
         { efCPT, "-cpi",    nullptr,       ffOPTRD },
index 572c385516faf0094710afd2bfaeb227ca9dfcde..8f7df5bbbce7ffc533f485cd36be65b0f8e33dde 100644 (file)
 #include "gromacs/topology/symtab.h"
 #include "gromacs/topology/topology.h"
 #include "gromacs/trajectory/trajectoryframe.h"
-#include "gromacs/trajectoryanalysis/topologyinformation.h"
 #include "gromacs/utility/cstringutil.h"
 #include "gromacs/utility/exceptions.h"
 #include "gromacs/utility/fatalerror.h"
 #include "gromacs/utility/smalloc.h"
-#include "gromacs/utility/unique_cptr.h"
 
 using gmx::RVec;
 
@@ -330,10 +328,11 @@ class InsertMolecules : public ICommandLineOptionsModule, public ITopologyProvid
         {
             clear_rvec(newBox_);
             clear_rvec(deltaR_);
+            clear_mat(box_);
         }
 
         // From ITopologyProvider
-        gmx_mtop_t *getTopology(bool /*required*/) override { return topInfo_.mtop(); }
+        gmx_mtop_t *getTopology(bool /*required*/) override { return &top_; }
         int getAtomCount() override { return 0; }
 
         // From ICommandLineOptionsModule
@@ -363,7 +362,10 @@ class InsertMolecules : public ICommandLineOptionsModule, public ITopologyProvid
         RotationType        enumRot_;
         Selection           replaceSel_;
 
-        TopologyInformation topInfo_;
+        gmx_mtop_t          top_;
+        std::vector<RVec>   x_;
+        matrix              box_;
+        int                 ePBC_;
 };
 
 void InsertMolecules::initOptions(IOptionsContainer                 *options,
@@ -493,9 +495,14 @@ void InsertMolecules::optionsFinished()
 
     if (!inputConfFile_.empty())
     {
+        bool  bTprFileWasRead;
+        rvec *temporaryX = nullptr;
         fprintf(stderr, "Reading solute configuration\n");
-        topInfo_.fillFromInputFile(inputConfFile_);
-        if (topInfo_.mtop()->natoms == 0)
+        readConfAndTopology(inputConfFile_.c_str(), &bTprFileWasRead, &top_,
+                            &ePBC_, &temporaryX, nullptr, box_);
+        x_.assign(temporaryX, temporaryX + top_.natoms);
+        sfree(temporaryX);
+        if (top_.natoms == 0)
         {
             fprintf(stderr, "Note: no atoms in %s\n", inputConfFile_.c_str());
         }
@@ -504,29 +511,16 @@ void InsertMolecules::optionsFinished()
 
 int InsertMolecules::run()
 {
-    const char       *outputTitle = topInfo_.name();
-    std::vector<RVec> xOutput;
-    matrix            box = {{ 0 }};
-    if (topInfo_.hasTopology())
-    {
-        xOutput = copyOf(topInfo_.x());
-        topInfo_.getBox(box);
-    }
-    else
-    {
-        xOutput.resize(topInfo_.mtop()->natoms);
-    }
-    auto          atomsSolute = topInfo_.copyAtoms();
     std::set<int> removableAtoms;
     if (replaceSel_.isValid())
     {
         t_pbc       pbc;
-        set_pbc(&pbc, topInfo_.ePBC(), box);
+        set_pbc(&pbc, ePBC_, box_);
         t_trxframe *fr;
         snew(fr, 1);
-        fr->natoms = topInfo_.mtop()->natoms;
+        fr->natoms = x_.size();
         fr->bX     = TRUE;
-        fr->x      = as_rvec_array(xOutput.data());
+        fr->x      = as_rvec_array(x_.data());
         selections_.evaluate(fr, &pbc);
         sfree(fr);
         removableAtoms.insert(replaceSel_.atomIndices().begin(),
@@ -536,59 +530,70 @@ int InsertMolecules::run()
         // individual atoms.
     }
 
-    int ePBCForOutput = topInfo_.ePBC();
+    int ePBCForOutput = ePBC_;
     if (bBox_)
     {
         ePBCForOutput = epbcXYZ;
-        clear_mat(box);
-        box[XX][XX] = newBox_[XX];
-        box[YY][YY] = newBox_[YY];
-        box[ZZ][ZZ] = newBox_[ZZ];
+        clear_mat(box_);
+        box_[XX][XX] = newBox_[XX];
+        box_[YY][YY] = newBox_[YY];
+        box_[ZZ][ZZ] = newBox_[ZZ];
     }
-    if (det(box) == 0)
+    if (det(box_) == 0)
     {
         gmx_fatal(FARGS, "Undefined solute box.\nCreate one with gmx editconf "
                   "or give explicit -box command line option");
     }
 
-    fprintf(stderr, "Reading molecule configuration\n");
-    TopologyInformation      topInfoForInsertedMolecule;
-    topInfoForInsertedMolecule.fillFromInputFile(insertConfFile_);
-    auto                     atomsInserted = topInfoForInsertedMolecule.atoms();
-    std::vector<RVec>        xInserted     = copyOf(topInfoForInsertedMolecule.x());
-
-    if (topInfoForInsertedMolecule.mtop()->natoms == 0)
-    {
-        gmx_fatal(FARGS, "No molecule in %s, please check your input",
-                  insertConfFile_.c_str());
-    }
-    if (outputTitle == nullptr)
-    {
-        outputTitle = topInfoForInsertedMolecule.name();
-    }
-    if (positionFile_.empty())
+    gmx_mtop_t         topInserted;
+    t_atoms            atomsInserted;
+    std::vector<RVec>  xInserted;
     {
-        center_molecule(xInserted);
+        bool        bTprFileWasRead;
+        int         ePBC_dummy;
+        matrix      box_dummy;
+        rvec       *temporaryX;
+        readConfAndTopology(insertConfFile_.c_str(), &bTprFileWasRead, &topInserted,
+                            &ePBC_dummy, &temporaryX, nullptr, box_dummy);
+        xInserted.assign(temporaryX, temporaryX + topInserted.natoms);
+        sfree(temporaryX);
+        atomsInserted = gmx_mtop_global_atoms(&topInserted);
+        if (atomsInserted.nr == 0)
+        {
+            gmx_fatal(FARGS, "No molecule in %s, please check your input",
+                      insertConfFile_.c_str());
+        }
+        if (top_.name == nullptr)
+        {
+            top_.name = topInserted.name;
+        }
+        if (positionFile_.empty())
+        {
+            center_molecule(xInserted);
+        }
     }
 
-    auto              symtabInserted = duplicateSymtab(&topInfo_.mtop()->symtab);
-    const sfree_guard symtabInsertedGuard(symtabInserted);
+    t_atoms atoms = gmx_mtop_global_atoms(&top_);
+
     /* add nmol_ins molecules of atoms_ins
        in random orientation at random place */
     insert_mols(nmolIns_, nmolTry_, seed_, defaultDistance_, scaleFactor_,
-                atomsSolute.get(), symtabInserted, &xOutput, removableAtoms, *atomsInserted, xInserted,
-                ePBCForOutput, box, positionFile_, deltaR_, enumRot_);
+                &atoms, &top_.symtab, &x_, removableAtoms, atomsInserted, xInserted,
+                ePBCForOutput, box_, positionFile_, deltaR_, enumRot_);
 
     /* write new configuration to file confout */
     fprintf(stderr, "Writing generated configuration to %s\n",
             outputConfFile_.c_str());
-    write_sto_conf(outputConfFile_.c_str(), outputTitle, atomsSolute.get(),
-                   as_rvec_array(xOutput.data()), nullptr, ePBCForOutput, box);
+    write_sto_conf(outputConfFile_.c_str(), *top_.name, &atoms,
+                   as_rvec_array(x_.data()), nullptr, ePBCForOutput, box_);
 
     /* print size of generated configuration */
     fprintf(stderr, "\nOutput configuration contains %d atoms in %d residues\n",
-            atomsSolute->nr, atomsSolute->nres);
-    done_symtab(symtabInserted);
+            atoms.nr, atoms.nres);
+
+    done_atom(&atoms);
+    done_atom(&atomsInserted);
+
     return 0;
 }
 
index 2804ab3a1ab74f4762e276a3ddbb0afd2a93daa4..f9b1f27e2c8c8cbfab2dc1cb9aa259f2f5002039 100644 (file)
@@ -1531,12 +1531,6 @@ static void do_fep_params(t_inputrec *ir, char fep_lambda[][STRLEN], char weight
         expand->nstexpanded = fep->nstdhdl;
         /* if you don't specify nstexpanded when doing expanded ensemble free energy calcs, it is set to nstdhdl */
     }
-    if ((expand->nstexpanded < 0) && ir->bSimTemp)
-    {
-        expand->nstexpanded = 2*static_cast<int>(ir->opts.tau_t[0]/ir->delta_t);
-        /* if you don't specify nstexpanded when doing expanded ensemble simulated tempering, it is set to
-           2*tau_t just to be careful so it's not to frequent  */
-    }
 }
 
 
@@ -3683,6 +3677,17 @@ void do_index(const char* mdparin, const char *ndx,
         gmx_fatal(FARGS, "Can only have energy group pair tables in combination with user tables for VdW and/or Coulomb");
     }
 
+    /* final check before going out of scope if simulated tempering variables
+     * need to be set to default values.
+     */
+    if ((ir->expandedvals->nstexpanded < 0) && ir->bSimTemp)
+    {
+        ir->expandedvals->nstexpanded = 2*static_cast<int>(ir->opts.tau_t[0]/ir->delta_t);
+        warning(wi, gmx::formatString("the value for nstexpanded was not specified for "
+                                      " expanded ensemble simulated tempering. It is set to 2*tau_t (%d) "
+                                      "by default, but it is recommended to set it to an explicit value!",
+                                      ir->expandedvals->nstexpanded));
+    }
     for (i = 0; (i < grps->nr); i++)
     {
         sfree(gnames[i]);
index 60fa35e97cd941905fa394c0208f3cd9db5ec6b3..bf44bd395e803a013bc8a71a4191f255e7942e83 100644 (file)
 #include "gromacs/topology/atomprop.h"
 #include "gromacs/topology/atoms.h"
 #include "gromacs/topology/atomsbuilder.h"
+#include "gromacs/topology/mtop_util.h"
 #include "gromacs/topology/topology.h"
-#include "gromacs/trajectoryanalysis/topologyinformation.h"
 #include "gromacs/utility/arraysize.h"
 #include "gromacs/utility/cstringutil.h"
 #include "gromacs/utility/fatalerror.h"
 #include "gromacs/utility/futil.h"
 #include "gromacs/utility/gmxassert.h"
 #include "gromacs/utility/smalloc.h"
-#include "gromacs/utility/unique_cptr.h"
 
 using gmx::RVec;
 
@@ -638,30 +637,30 @@ static void removeExtraSolventMolecules(t_atoms *atoms, std::vector<RVec> *x,
     remover.removeMarkedAtoms(atoms);
 }
 
-static void add_solv(const char *filename,
-                     const gmx::TopologyInformation &topInfo,
-                     t_atoms *atoms,
+static void add_solv(const char *filename, t_atoms *atoms,
+                     t_symtab *symtab,
                      std::vector<RVec> *x, std::vector<RVec> *v,
-                     matrix box, AtomProperties *aps,
+                     int ePBC, matrix box, AtomProperties *aps,
                      real defaultDistance, real scaleFactor,
                      real rshell, int max_sol)
 {
-    gmx::TopologyInformation topInfoSolvent;
-    topInfoSolvent.fillFromInputFile(gmx::findLibraryFile(filename));
-    auto                     atomsSolvent = topInfoSolvent.copyAtoms();
-    std::vector<RVec>        xSolvent, vSolvent;
-    matrix                   boxSolvent = {{ 0 }};
-    if (topInfoSolvent.hasTopology())
-    {
-        xSolvent = copyOf(topInfoSolvent.x());
-        vSolvent = copyOf(topInfoSolvent.v());
-        topInfoSolvent.getBox(boxSolvent);
-    }
-    else
-    {
-        xSolvent.resize(atomsSolvent->nr);
-        vSolvent.resize(atomsSolvent->nr);
-    }
+    gmx_mtop_t        topSolvent;
+    std::vector<RVec> xSolvent, vSolvent;
+    matrix            boxSolvent = {{ 0 }};
+    int               ePBCSolvent;
+
+    fprintf(stderr, "Reading solvent configuration\n");
+    bool              bTprFileWasRead;
+    rvec             *temporaryX = nullptr, *temporaryV = nullptr;
+    readConfAndTopology(gmx::findLibraryFile(filename).c_str(), &bTprFileWasRead, &topSolvent,
+                        &ePBCSolvent, &temporaryX, &temporaryV, boxSolvent);
+    t_atoms *atomsSolvent;
+    snew(atomsSolvent, 1);
+    *atomsSolvent = gmx_mtop_global_atoms(&topSolvent);
+    xSolvent.assign(temporaryX, temporaryX + topSolvent.natoms);
+    sfree(temporaryX);
+    vSolvent.assign(temporaryV, temporaryV + topSolvent.natoms);
+    sfree(temporaryV);
     if (gmx::boxIsZero(boxSolvent))
     {
         gmx_fatal(FARGS, "No box information for solvent in %s, please use a properly formatted file\n",
@@ -678,12 +677,12 @@ static void add_solv(const char *filename,
     const std::vector<real> exclusionDistances(
             makeExclusionDistances(atoms, aps, defaultDistance, scaleFactor));
     std::vector<real>       exclusionDistances_solvt(
-            makeExclusionDistances(atomsSolvent.get(), aps, defaultDistance, scaleFactor));
+            makeExclusionDistances(atomsSolvent, aps, defaultDistance, scaleFactor));
 
     /* generate a new solvent configuration */
     fprintf(stderr, "Generating solvent configuration\n");
     t_pbc pbc;
-    set_pbc(&pbc, topInfo.ePBC(), box);
+    set_pbc(&pbc, ePBC, box);
     if (!gmx::boxesAreEqual(boxSolvent, box))
     {
         if (TRICLINIC(boxSolvent))
@@ -692,22 +691,22 @@ static void add_solv(const char *filename,
                       "You can try to pass the same box for -cp and -cs.");
         }
         /* apply pbc for solvent configuration for whole molecules */
-        rm_res_pbc(atomsSolvent.get(), &xSolvent, boxSolvent);
-        replicateSolventBox(atomsSolvent.get(), &xSolvent, &vSolvent, &exclusionDistances_solvt,
+        rm_res_pbc(atomsSolvent, &xSolvent, boxSolvent);
+        replicateSolventBox(atomsSolvent, &xSolvent, &vSolvent, &exclusionDistances_solvt,
                             boxSolvent, box);
-        if (topInfo.ePBC() != epbcNONE)
+        if (ePBC != epbcNONE)
         {
-            removeSolventBoxOverlap(atomsSolvent.get(), &xSolvent, &vSolvent, &exclusionDistances_solvt, pbc);
+            removeSolventBoxOverlap(atomsSolvent, &xSolvent, &vSolvent, &exclusionDistances_solvt, pbc);
         }
     }
     if (atoms->nr > 0)
     {
         if (rshell > 0.0)
         {
-            removeSolventOutsideShell(atomsSolvent.get(), &xSolvent,  &vSolvent,
+            removeSolventOutsideShell(atomsSolvent, &xSolvent,  &vSolvent,
                                       &exclusionDistances_solvt, pbc, *x, rshell);
         }
-        removeSolventOverlappingWithSolute(atomsSolvent.get(), &xSolvent, &vSolvent,
+        removeSolventOverlappingWithSolute(atomsSolvent, &xSolvent, &vSolvent,
                                            &exclusionDistances_solvt, pbc, *x,
                                            exclusionDistances);
     }
@@ -715,12 +714,16 @@ static void add_solv(const char *filename,
     if (max_sol > 0 && atomsSolvent->nres > max_sol)
     {
         const int numberToRemove = atomsSolvent->nres - max_sol;
-        removeExtraSolventMolecules(atomsSolvent.get(), &xSolvent, &vSolvent, numberToRemove);
+        removeExtraSolventMolecules(atomsSolvent, &xSolvent, &vSolvent, numberToRemove);
     }
 
     /* Sort the solvent mixture, not the protein... */
-    t_atoms *newatoms           = nullptr;
-    t_atoms *sortedAtomsSolvent = atomsSolvent.get();
+    t_atoms *newatoms = nullptr;
+    // The sort_molecule function does something creative with the
+    // t_atoms pointers. We need to make sure we neither leak, nor
+    // double-free, so make a shallow pointer that is fine for it to
+    // change.
+    t_atoms *sortedAtomsSolvent = atomsSolvent;
     sort_molecule(&sortedAtomsSolvent, &newatoms, &xSolvent, &vSolvent);
 
     // Merge the two configurations.
@@ -730,17 +733,22 @@ static void add_solv(const char *filename,
         v->insert(v->end(), vSolvent.begin(), vSolvent.end());
     }
     {
-        gmx::AtomsBuilder builder(atoms, &topInfo.mtop()->symtab);
+        gmx::AtomsBuilder builder(atoms, symtab);
         builder.mergeAtoms(*sortedAtomsSolvent);
     }
     fprintf(stderr, "Generated solvent containing %d atoms in %d residues\n",
-            sortedAtomsSolvent->nr, sortedAtomsSolvent->nres);
+            atomsSolvent->nr, atomsSolvent->nres);
 
     if (newatoms)
     {
         done_atom(newatoms);
         sfree(newatoms);
     }
+    if (atomsSolvent)
+    {
+        done_atom(atomsSolvent);
+        sfree(atomsSolvent);
+    }
 }
 
 static void update_top(t_atoms        *atoms,
@@ -973,38 +981,46 @@ int gmx_solvate(int argc, char *argv[])
 
     AtomProperties           aps;
 
-    gmx::TopologyInformation topInfo;
-    std::vector<RVec>        x, v;
-    matrix                   box = {{ 0 }};
+    /* solute configuration data */
+    gmx_mtop_t        top;
+    std::vector<RVec> x, v;
+    matrix            box  = {{ 0 }};
+    int               ePBC = -1;
+    t_atoms          *atoms;
+    snew(atoms, 1);
     if (bProt)
     {
         /* Generate a solute configuration */
         conf_prot = opt2fn("-cp", NFILE, fnm);
-        topInfo.fillFromInputFile(conf_prot);
-        x = copyOf(topInfo.x());
-        if (bReadV)
-        {
-            v = copyOf(topInfo.v());
-        }
-        topInfo.getBox(box);
         fprintf(stderr, "Reading solute configuration%s\n",
                 bReadV ? " and velocities" : "");
-        if (bReadV && v.empty())
+        bool  bTprFileWasRead;
+        rvec *temporaryX = nullptr, *temporaryV = nullptr;
+        readConfAndTopology(conf_prot, &bTprFileWasRead, &top,
+                            &ePBC, &temporaryX, bReadV ? &temporaryV : nullptr, box);
+        *atoms = gmx_mtop_global_atoms(&top);
+        x.assign(temporaryX, temporaryX + top.natoms);
+        sfree(temporaryX);
+        if (temporaryV)
+        {
+            v.assign(temporaryV, temporaryV + top.natoms);
+            sfree(temporaryV);
+        }
+        else if (bReadV)
         {
             fprintf(stderr, "Note: no velocities found\n");
         }
-        if (topInfo.mtop()->natoms == 0)
+        if (atoms->nr == 0)
         {
             fprintf(stderr, "Note: no atoms in %s\n", conf_prot);
             bProt = FALSE;
         }
         else
         {
-            firstSolventResidueIndex = topInfo.atoms()->nres;
+            firstSolventResidueIndex = atoms->nres;
         }
     }
-    auto atoms         = topInfo.copyAtoms();
-    int  ePBCForOutput = topInfo.ePBC();
+    int ePBCForOutput = ePBC;
     if (bBox)
     {
         ePBCForOutput = epbcXYZ;
@@ -1019,20 +1035,23 @@ int gmx_solvate(int argc, char *argv[])
                   "or give explicit -box command line option");
     }
 
-    add_solv(solventFileName, topInfo, atoms.get(), &x, &v, box,
+    add_solv(solventFileName, atoms, &top.symtab, &x, &v, ePBCForOutput, box,
              &aps, defaultDistance, scaleFactor, r_shell, max_sol);
 
     /* write new configuration 1 to file confout */
     confout = ftp2fn(efSTO, NFILE, fnm);
     fprintf(stderr, "Writing generated configuration to %s\n", confout);
-    const char *outputTitle = (bProt ? *topInfo.mtop()->name : "Generated by gmx solvate");
-    write_sto_conf(confout, outputTitle, atoms.get(), as_rvec_array(x.data()),
+    const char *outputTitle = (bProt ? *top.name : "Generated by gmx solvate");
+    write_sto_conf(confout, outputTitle, atoms, as_rvec_array(x.data()),
                    !v.empty() ? as_rvec_array(v.data()) : nullptr, ePBCForOutput, box);
 
     /* print size of generated configuration */
     fprintf(stderr, "\nOutput configuration contains %d atoms in %d residues\n",
             atoms->nr, atoms->nres);
-    update_top(atoms.get(), firstSolventResidueIndex, box, NFILE, fnm, &aps);
+    update_top(atoms, firstSolventResidueIndex, box, NFILE, fnm, &aps);
+
+    done_atom(atoms);
+    sfree(atoms);
     output_env_done(oenv);
 
     return 0;
index cf66b046a7a6d6955a043bb0c4fd74329c9e4618..e75f429e782970b325c02bd160075f5c89dcc2a7 100644 (file)
@@ -189,6 +189,23 @@ int Constraints::numFlexibleConstraints() const
     return impl_->nflexcon;
 }
 
+bool Constraints::havePerturbedConstraints() const
+{
+    const gmx_ffparams_t &ffparams = impl_->mtop.ffparams;
+
+    for (size_t i = 0; i < ffparams.functype.size(); i++)
+    {
+        if ((ffparams.functype[i] == F_CONSTR ||
+             ffparams.functype[i] == F_CONSTRNC) &&
+            ffparams.iparams[i].constr.dA != ffparams.iparams[i].constr.dB)
+        {
+            return true;
+        }
+    }
+
+    return false;
+}
+
 //! Clears constraint quantities for atoms in nonlocal region.
 static void clear_constraint_quantity_nonlocal(gmx_domdec_t *dd, rvec *q)
 {
index a07560bde73c022d597c8c6d66914d9c72642eda..147ad445615f67e1a461b5adf9e3837c147b818b 100644 (file)
@@ -120,6 +120,9 @@ class Constraints
         /*! \brief Returns the total number of flexible constraints in the system. */
         int numFlexibleConstraints() const;
 
+        /*! \brief Returns whether the system contains perturbed constraints */
+        bool havePerturbedConstraints() const;
+
         /*! \brief Set up all the local constraints for the domain.
          *
          * \todo Make this a callback that is called automatically
index 0ed28de87e05c0c75cd7a2f78ca5fd8c301df6a2..1a7d648e801d74102a86dae217152757b2aa0335 100644 (file)
@@ -784,7 +784,7 @@ void sum_dhdl(gmx_enerdata_t *enerd, gmx::ArrayRef<const real> lambda, t_lambda
                 enerpart_lambda += dlam*enerd->term[F_DVDL_CONSTR];
             }
 
-            if (j == efptMASS)
+            if (j == efptMASS && !fepvals->separate_dvdl[j])
             {
                 enerpart_lambda += dlam*enerd->term[F_DKDL];
             }
index 6dedbb795b4a78c9bf5664e3dc175846d0ef0b43..3d5578a664b07f0849877da60a1a25f0b68985c1 100644 (file)
@@ -1202,7 +1202,7 @@ static void do_force_cutsVERLET(FILE *fplog,
         }
 
         /* launch local nonbonded work on GPU */
-        wallcycle_sub_start(wcycle, ewcsLAUNCH_GPU_NONBONDED);
+        wallcycle_sub_start_nocount(wcycle, ewcsLAUNCH_GPU_NONBONDED);
         do_nb_verlet(fr, ic, enerd, flags, Nbnxm::InteractionLocality::Local, enbvClearFNo,
                      step, nrnb, wcycle);
         wallcycle_sub_stop(wcycle, ewcsLAUNCH_GPU_NONBONDED);
@@ -1267,7 +1267,7 @@ static void do_force_cutsVERLET(FILE *fplog,
             wallcycle_start(wcycle, ewcLAUNCH_GPU);
 
             /* launch non-local nonbonded tasks on GPU */
-            wallcycle_sub_start(wcycle, ewcsLAUNCH_GPU_NONBONDED);
+            wallcycle_sub_start_nocount(wcycle, ewcsLAUNCH_GPU_NONBONDED);
             Nbnxm::gpu_copy_xq_to_gpu(nbv->gpu_nbv, nbv->nbat, Nbnxm::AtomLocality::NonLocal, ppForceWorkload->haveGpuBondedWork);
             wallcycle_sub_stop(wcycle, ewcsLAUNCH_GPU_NONBONDED);
 
index a6f30f0e748b6701af35879af75577e6e0c7905f..fc6d53e60c2759d20ad3bc842a33aa4521d80e4d 100644 (file)
@@ -230,6 +230,13 @@ void gmx::Integrator::do_rerun()
                    "be available in a different form in a future version of GROMACS, "
                    "e.g. gmx rerun -f.");
 
+    if (ir->efep != efepNO && (mdAtoms->mdatoms()->nMassPerturbed > 0 ||
+                               (constr && constr->havePerturbedConstraints())))
+    {
+        gmx_fatal(FARGS, "Perturbed masses or constraints are not supported by rerun. "
+                  "Either make a .tpr without mass and constraint perturbation, "
+                  "or use GROMACS 2018.4, 2018.5 or later 2018 version.");
+    }
     if (ir->bExpanded)
     {
         gmx_fatal(FARGS, "Expanded ensemble not supported by rerun.");
index 3ad53c99eb748531538f3fdc9a4a683e8d99136e..1ae70af026460cad75cb4bb39136d2f23013456b 100644 (file)
@@ -603,10 +603,9 @@ int Mdrunner::mdrunner()
                     inputrec->cutoff_scheme == ecutsVERLET,
                     gpuAccelerationOfNonbondedIsUseful(mdlog, inputrec, GMX_THREAD_MPI),
                     hw_opt.nthreads_tmpi);
-            auto canUseGpuForPme   = pme_gpu_supports_build(*hwinfo, nullptr) && pme_gpu_supports_input(*inputrec, mtop, nullptr);
             useGpuForPme = decideWhetherToUseGpusForPmeWithThreadMpi
                     (useGpuForNonbonded, pmeTarget, gpuIdsToUse, userGpuTaskAssignment,
-                    canUseGpuForPme, hw_opt.nthreads_tmpi, domdecOptions.numPmeRanks);
+                    *hwinfo, *inputrec, mtop, hw_opt.nthreads_tmpi, domdecOptions.numPmeRanks);
 
         }
         GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
@@ -674,9 +673,9 @@ int Mdrunner::mdrunner()
                                                                 usingVerletScheme,
                                                                 gpuAccelerationOfNonbondedIsUseful(mdlog, inputrec, !GMX_THREAD_MPI),
                                                                 gpusWereDetected);
-        auto canUseGpuForPme   = pme_gpu_supports_build(*hwinfo, nullptr) && pme_gpu_supports_input(*inputrec, mtop, nullptr);
         useGpuForPme = decideWhetherToUseGpusForPme(useGpuForNonbonded, pmeTarget, userGpuTaskAssignment,
-                                                    canUseGpuForPme, cr->nnodes, domdecOptions.numPmeRanks,
+                                                    *hwinfo, *inputrec, mtop,
+                                                    cr->nnodes, domdecOptions.numPmeRanks,
                                                     gpusWereDetected);
         auto canUseGpuForBonded = buildSupportsGpuBondeds(nullptr) && inputSupportsGpuBondeds(*inputrec, mtop, nullptr);
         useGpuForBonded =
index 34b932394b97f81c62fa1710c6529d8729c7902a..758e5ec55d16c6ea3799dda3c8844016c03e6e5f 100644 (file)
@@ -112,7 +112,7 @@ void calculate_force_switch_F(const  cu_nbparam_t nbparam,
 
     *F_invr  +=
         -c6*(disp_shift_V2 + disp_shift_V3*r_switch)*r_switch*r_switch*inv_r +
-        c12*(-repu_shift_V2 + repu_shift_V3*r_switch)*r_switch*r_switch*inv_r;
+        c12*(repu_shift_V2 + repu_shift_V3*r_switch)*r_switch*r_switch*inv_r;
 }
 
 /*! Apply force switch, force-only version. */
@@ -144,7 +144,7 @@ void calculate_force_switch_F_E(const  cu_nbparam_t nbparam,
 
     *F_invr  +=
         -c6*(disp_shift_V2 + disp_shift_V3*r_switch)*r_switch*r_switch*inv_r +
-        c12*(-repu_shift_V2 + repu_shift_V3*r_switch)*r_switch*r_switch*inv_r;
+        c12*(repu_shift_V2 + repu_shift_V3*r_switch)*r_switch*r_switch*inv_r;
     *E_lj    +=
         c6*(disp_shift_F2 + disp_shift_F3*r_switch)*r_switch*r_switch*r_switch -
         c12*(repu_shift_F2 + repu_shift_F3*r_switch)*r_switch*r_switch*r_switch;
index 74fcc398ac8080973c369dd0727da5c987ff5fbb..c63c10d9571919fe14c3f15d12c9990d4eb6f1a3 100644 (file)
@@ -331,7 +331,7 @@ void calculate_force_switch_F(const cl_nbparam_params_t *nbparam,
 
     *F_invr  +=
         -c6*(disp_shift_V2 + disp_shift_V3*r_switch)*r_switch*r_switch*inv_r +
-        c12*(-repu_shift_V2 + repu_shift_V3*r_switch)*r_switch*r_switch*inv_r;
+        c12*(repu_shift_V2 + repu_shift_V3*r_switch)*r_switch*r_switch*inv_r;
 }
 
 /*! Apply force switch, force-only version. */
@@ -363,7 +363,7 @@ void calculate_force_switch_F_E(const cl_nbparam_params_t *nbparam,
 
     *F_invr  +=
         -c6*(disp_shift_V2 + disp_shift_V3*r_switch)*r_switch*r_switch*inv_r +
-        c12*(-repu_shift_V2 + repu_shift_V3*r_switch)*r_switch*r_switch*inv_r;
+        c12*(repu_shift_V2 + repu_shift_V3*r_switch)*r_switch*r_switch*inv_r;
     *E_lj    +=
         c6*(disp_shift_F2 + disp_shift_F3*r_switch)*r_switch*r_switch*r_switch -
         c12*(repu_shift_F2 + repu_shift_F3*r_switch)*r_switch*r_switch*r_switch;
index 72912172a33f97575d5d9c98a71024aadc84006c..fe4eece00196dca4501327b4328aefdb1138fa3e 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2015,2017,2018, by the GROMACS development team, led by
+ * Copyright (c) 2015,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.
@@ -467,6 +467,9 @@ TEST_F(SimdFloatingpointUtilTest, transposeScatterDecrU3Overlapping)
         mem0_[j] = refmem[j] = (1000.0 + j) * (1.0 + 100*GMX_REAL_EPS);
     }
 
+#ifdef __INTEL_COMPILER  //Bug in (at least) 19u1 and 18u5 (03424712)
+    #pragma novector
+#endif
     for (std::size_t j = 0; j < GMX_SIMD_REAL_WIDTH; j++)
     {
         // Subtract values from _reference_ memory (we will then test with mem0_, and compare)
index 5e18aa79483706da3f697d17ad281ca5972a0b3e..09f4ebc27cf8e7f01587394f964da4be470f13c1 100644 (file)
@@ -51,6 +51,7 @@
 #include <algorithm>
 #include <string>
 
+#include "gromacs/ewald/pme.h"
 #include "gromacs/hardware/cpuinfo.h"
 #include "gromacs/hardware/detecthardware.h"
 #include "gromacs/hardware/hardwaretopology.h"
@@ -153,14 +154,18 @@ decideWhetherToUseGpusForPmeWithThreadMpi(const bool              useGpuForNonbo
                                           const TaskTarget        pmeTarget,
                                           const std::vector<int> &gpuIdsToUse,
                                           const std::vector<int> &userGpuTaskAssignment,
-                                          const bool              canUseGpuForPme,
+                                          const gmx_hw_info_t    &hardwareInfo,
+                                          const t_inputrec       &inputrec,
+                                          const gmx_mtop_t       &mtop,
                                           const int               numRanksPerSimulation,
                                           const int               numPmeRanksPerSimulation)
 {
     // First, exclude all cases where we can't run PME on GPUs.
     if ((pmeTarget == TaskTarget::Cpu) ||
         !useGpuForNonbonded ||
-        !canUseGpuForPme)
+        !pme_gpu_supports_build(nullptr) ||
+        !pme_gpu_supports_hardware(hardwareInfo, nullptr) ||
+        !pme_gpu_supports_input(inputrec, mtop, nullptr))
     {
         // PME can't run on a GPU. If the user required that, we issue
         // an error later.
@@ -335,7 +340,9 @@ bool decideWhetherToUseGpusForNonbonded(const TaskTarget           nonbondedTarg
 bool decideWhetherToUseGpusForPme(const bool              useGpuForNonbonded,
                                   const TaskTarget        pmeTarget,
                                   const std::vector<int> &userGpuTaskAssignment,
-                                  const bool              canUseGpuForPme,
+                                  const gmx_hw_info_t    &hardwareInfo,
+                                  const t_inputrec       &inputrec,
+                                  const gmx_mtop_t       &mtop,
                                   const int               numRanksPerSimulation,
                                   const int               numPmeRanksPerSimulation,
                                   const bool              gpusWereDetected)
@@ -350,18 +357,36 @@ bool decideWhetherToUseGpusForPme(const bool              useGpuForNonbonded,
         if (pmeTarget == TaskTarget::Gpu)
         {
             GMX_THROW(NotImplementedError
-                          ("The PME on the GPU is only supported when nonbonded interactions run on GPUs also."));
+                          ("PME on GPUs is only supported when nonbonded interactions run on GPUs also."));
         }
         return false;
     }
 
-    if (!canUseGpuForPme)
+    std::string message;
+    if (!pme_gpu_supports_build(&message))
     {
         if (pmeTarget == TaskTarget::Gpu)
         {
-            // TODO Pass in the inputrec so we can give more help here?
             GMX_THROW(NotImplementedError
-                          ("The input simulation did not use PME in a way that is supported on the GPU."));
+                          ("Cannot compute PME interactions on a GPU, because " + message));
+        }
+        return false;
+    }
+    if (!pme_gpu_supports_hardware(hardwareInfo, &message))
+    {
+        if (pmeTarget == TaskTarget::Gpu)
+        {
+            GMX_THROW(NotImplementedError
+                          ("Cannot compute PME interactions on a GPU, because " + message));
+        }
+        return false;
+    }
+    if (!pme_gpu_supports_input(inputrec, mtop, &message))
+    {
+        if (pmeTarget == TaskTarget::Gpu)
+        {
+            GMX_THROW(NotImplementedError
+                          ("Cannot compute PME interactions on a GPU, because " + message));
         }
         return false;
     }
@@ -383,7 +408,7 @@ bool decideWhetherToUseGpusForPme(const bool              useGpuForNonbonded,
         // Specifying -gputasks requires specifying everything.
         if (pmeTarget == TaskTarget::Auto)
         {
-            GMX_THROW(InconsistentInputError(formatString(g_specifyEverythingFormatString, "all of -nb, -pme, and -ntmpi")));
+            GMX_THROW(InconsistentInputError(formatString(g_specifyEverythingFormatString, "all of -nb, -pme, and -ntmpi"))); // TODO ntmpi?
         }
 
         return true;
index ac2fe27478218d17c854e43ad788fb9073f12e98..02dcac5512571f55d3b46188d015d8406d483e8d 100644 (file)
@@ -46,6 +46,8 @@
 #include <vector>
 
 struct gmx_hw_info_t;
+struct gmx_mtop_t;
+struct t_inputrec;
 
 enum class EmulateGpuNonbonded : bool;
 
@@ -102,7 +104,9 @@ bool decideWhetherToUseGpusForNonbondedWithThreadMpi(TaskTarget              non
  * \param[in]  pmeTarget                 The user's choice for mdrun -pme for where to assign long-ranged PME nonbonded interaction tasks.
  * \param[in]  gpuIdsToUse               The compatible GPUs that the user permitted us to use.
  * \param[in]  userGpuTaskAssignment     The user-specified assignment of GPU tasks to device IDs.
- * \param[in]  canUseGpuForPme           Whether the form of PME chosen can run on a GPU
+ * \param[in]  hardwareInfo              Hardware information
+ * \param[in]  inputrec                  The user input
+ * \param[in]  mtop                      Global system topology
  * \param[in]  numRanksPerSimulation     The number of ranks in each simulation.
  * \param[in]  numPmeRanksPerSimulation  The number of PME ranks in each simulation.
  *
@@ -114,7 +118,9 @@ bool decideWhetherToUseGpusForPmeWithThreadMpi(bool                    useGpuFor
                                                TaskTarget              pmeTarget,
                                                const std::vector<int> &gpuIdsToUse,
                                                const std::vector<int> &userGpuTaskAssignment,
-                                               bool                    canUseGpuForPme,
+                                               const gmx_hw_info_t    &hardwareInfo,
+                                               const t_inputrec       &inputrec,
+                                               const gmx_mtop_t       &mtop,
                                                int                     numRanksPerSimulation,
                                                int                     numPmeRanksPerSimulation);
 
@@ -173,7 +179,9 @@ bool decideWhetherToUseGpusForNonbonded(TaskTarget              nonbondedTarget,
  * \param[in]  useGpuForNonbonded        Whether GPUs will be used for nonbonded interactions.
  * \param[in]  pmeTarget                 The user's choice for mdrun -pme for where to assign long-ranged PME nonbonded interaction tasks.
  * \param[in]  userGpuTaskAssignment     The user-specified assignment of GPU tasks to device IDs.
- * \param[in]  canUseGpuForPme           Whether the form of PME chosen can run on a GPU
+ * \param[in]  hardwareInfo              Hardware information
+ * \param[in]  inputrec                  The user input
+ * \param[in]  mtop                      Global system topology
  * \param[in]  numRanksPerSimulation     The number of ranks in each simulation.
  * \param[in]  numPmeRanksPerSimulation  The number of PME ranks in each simulation.
  * \param[in]  gpusWereDetected          Whether compatible GPUs were detected on any node.
@@ -185,7 +193,9 @@ bool decideWhetherToUseGpusForNonbonded(TaskTarget              nonbondedTarget,
 bool decideWhetherToUseGpusForPme(bool                    useGpuForNonbonded,
                                   TaskTarget              pmeTarget,
                                   const std::vector<int> &userGpuTaskAssignment,
-                                  bool                    canUseGpuForPme,
+                                  const gmx_hw_info_t    &hardwareInfo,
+                                  const t_inputrec       &inputrec,
+                                  const gmx_mtop_t       &mtop,
                                   int                     numRanksPerSimulation,
                                   int                     numPmeRanksPerSimulation,
                                   bool                    gpusWereDetected);
index da85789f5f0ff21fb1dceb6299907481c77a525e..05e3912797ddb62d9bee0abfc3f9aa66e919faae 100644 (file)
@@ -356,7 +356,9 @@ int get_nthreads_mpi(const gmx_hw_info_t    *hwinfo,
     if (pmeOnGpu)
     {
         GMX_RELEASE_ASSERT((EEL_PME(inputrec->coulombtype) || EVDW_PME(inputrec->vdwtype)) &&
-                           pme_gpu_supports_build(*hwinfo, nullptr) && pme_gpu_supports_input(*inputrec, *mtop, nullptr),
+                           pme_gpu_supports_build(nullptr) &&
+                           pme_gpu_supports_hardware(*hwinfo, nullptr) &&
+                           pme_gpu_supports_input(*inputrec, *mtop, nullptr),
                            "PME can't be on GPUs unless we are using PME");
 
         // PME on GPUs supports a single PME rank with PP running on the same or few other ranks.
diff --git a/src/gromacs/trajectoryanalysis/tests/index.ndx b/src/gromacs/trajectoryanalysis/tests/index.ndx
new file mode 100644 (file)
index 0000000..134c789
--- /dev/null
@@ -0,0 +1,47 @@
+[ name_OW ]
+   1    4    7   10   13   16   19   22   25   28   31   34   37   40   43 
+  46   49   52   55   58   61   64   67   70   73   76   79   82   85   88 
+  91   94   97  100  103  106  109  112  115  118  121  124  127  130  133 
+ 136  139  142  145  148  151  154  157  160  163  166  169  172  175  178 
+ 181  184  187  190  193  196  199  202  205  208  211  214  217  220  223 
+ 226  229  232  235  238  241  244  247  250  253  256  259  262  265  268 
+ 271  274  277  280  283  286  289  292  295  298  301  304  307  310  313 
+ 316  319  322  325  328  331  334  337  340  343  346  349  352  355  358 
+ 361  364  367  370  373  376  379  382  385  388  391  394  397  400  403 
+ 406  409  412  415  418  421  424  427  430  433  436  439  442  445  448 
+ 451  454  457  460  463  466  469  472  475  478  481  484  487  490  493 
+ 496  499  502  505  508  511  514  517  520  523  526  529  532  535  538 
+ 541  544  547  550  553  556  559  562  565  568  571  574  577  580  583 
+ 586  589  592  595  598  601  604  607  610  613  616  619  622  625  628 
+ 631  634  637  640  643  646 
+
+[ not_name_OW ]
+   2    3    5    6    8    9   11   12   14   15   17   18   20   21   23 
+  24   26   27   29   30   32   33   35   36   38   39   41   42   44   45 
+  47   48   50   51   53   54   56   57   59   60   62   63   65   66   68 
+  69   71   72   74   75   77   78   80   81   83   84   86   87   89   90 
+  92   93   95   96   98   99  101  102  104  105  107  108  110  111  113 
+ 114  116  117  119  120  122  123  125  126  128  129  131  132  134  135 
+ 137  138  140  141  143  144  146  147  149  150  152  153  155  156  158 
+ 159  161  162  164  165  167  168  170  171  173  174  176  177  179  180 
+ 182  183  185  186  188  189  191  192  194  195  197  198  200  201  203 
+ 204  206  207  209  210  212  213  215  216  218  219  221  222  224  225 
+ 227  228  230  231  233  234  236  237  239  240  242  243  245  246  248 
+ 249  251  252  254  255  257  258  260  261  263  264  266  267  269  270 
+ 272  273  275  276  278  279  281  282  284  285  287  288  290  291  293 
+ 294  296  297  299  300  302  303  305  306  308  309  311  312  314  315 
+ 317  318  320  321  323  324  326  327  329  330  332  333  335  336  338 
+ 339  341  342  344  345  347  348  350  351  353  354  356  357  359  360 
+ 362  363  365  366  368  369  371  372  374  375  377  378  380  381  383 
+ 384  386  387  389  390  392  393  395  396  398  399  401  402  404  405 
+ 407  408  410  411  413  414  416  417  419  420  422  423  425  426  428 
+ 429  431  432  434  435  437  438  440  441  443  444  446  447  449  450 
+ 452  453  455  456  458  459  461  462  464  465  467  468  470  471  473 
+ 474  476  477  479  480  482  483  485  486  488  489  491  492  494  495 
+ 497  498  500  501  503  504  506  507  509  510  512  513  515  516  518 
+ 519  521  522  524  525  527  528  530  531  533  534  536  537  539  540 
+ 542  543  545  546  548  549  551  552  554  555  557  558  560  561  563 
+ 564  566  567  569  570  572  573  575  576  578  579  581  582  584  585 
+ 587  588  590  591  593  594  596  597  599  600  602  603  605  606  608 
+ 609  611  612  614  615  617  618  620  621  623  624  626  627  629  630 
+ 632  633  635  636  638  639  641  642  644  645  647  648 
index dae68d2481e32422c6ba3861821bf564ae14188c..e1fb5bd197b7dffeb24746eedccdf87868578d2c 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2014,2015, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015,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.
@@ -87,6 +87,42 @@ TEST_F(RdfModuleTest, BasicTest)
     runTest(CommandLine(cmdline));
 }
 
+TEST_F(RdfModuleTest, SelectionsSolelyFromIndexFileWork)
+{
+    const char *const cmdline[] = {
+        "rdf",
+        "-bin", "0.05",
+        // Use selection that names a group in the index file
+        "-ref", "name_OW",
+        // Use selections that name groups in the index file
+        "-sel", "name_OW", "not_name_OW"
+    };
+    // Note not supplying a topology file to -s
+    setTrajectory("spc216.gro");
+    setInputFile("-n", "index.ndx");
+    setOutputFile("-o", ".xvg", NoTextMatch());
+    excludeDataset("pairdist");
+    runTest(CommandLine(cmdline));
+}
+
+TEST_F(RdfModuleTest, SelectionsFromBothTopologyFileAndIndexFileWork)
+{
+    const char *const cmdline[] = {
+        "rdf",
+        "-bin", "0.05",
+        // Use selection whose parsing requires topology file
+        "-ref", "name OW",
+        // Use selections that name groups in the index file
+        "-sel", "name_OW", "not_name_OW"
+    };
+    // Note supplying a topology file to -s
+    setTopology("spc216.gro");
+    setInputFile("-n", "index.ndx");
+    setOutputFile("-o", ".xvg", NoTextMatch());
+    excludeDataset("pairdist");
+    runTest(CommandLine(cmdline));
+}
+
 TEST_F(RdfModuleTest, CalculatesSurf)
 {
     const char *const cmdline[] = {
diff --git a/src/gromacs/trajectoryanalysis/tests/refdata/RdfModuleTest_SelectionsFromBothTopologyFileAndIndexFileWork.xml b/src/gromacs/trajectoryanalysis/tests/refdata/RdfModuleTest_SelectionsFromBothTopologyFileAndIndexFileWork.xml
new file mode 100644 (file)
index 0000000..ab81965
--- /dev/null
@@ -0,0 +1,262 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+  <String Name="CommandLine">rdf -bin 0.05 -ref 'name OW' -sel name_OW not_name_OW</String>
+  <OutputData Name="Data">
+    <AnalysisData Name="norm">
+      <DataFrame Name="Frame0">
+        <Real Name="X">0</Real>
+        <DataValues>
+          <Int Name="Count">3</Int>
+          <DataValue>
+            <Real Name="Value">216</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">33.455901630929986</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">66.911803261859973</Real>
+          </DataValue>
+        </DataValues>
+      </DataFrame>
+    </AnalysisData>
+    <AnalysisData Name="paircount">
+      <DataFrame Name="Frame0">
+        <Real Name="X">0</Real>
+        <DataValues>
+          <Int Name="Count">37</Int>
+          <Int Name="DataSet">0</Int>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">274</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">360</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">226</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">234</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">270</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">332</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">420</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">456</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">548</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">588</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">546</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">632</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">660</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">696</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">822</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">922</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1060</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1084</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1276</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1260</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1260</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1416</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1468</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1560</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1668</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1774</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1578</Real>
+          </DataValue>
+        </DataValues>
+        <DataValues>
+          <Int Name="Count">37</Int>
+          <Int Name="DataSet">1</Int>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">215</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">217</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">114</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">163</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">87</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">52</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">103</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">266</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">618</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">751</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">703</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">722</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">772</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">821</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">946</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1065</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1229</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1281</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1402</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1518</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1640</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1844</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">2058</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">2137</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">2412</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">2451</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">2650</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">2886</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">2928</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">3101</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">3374</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">3623</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">3288</Real>
+          </DataValue>
+        </DataValues>
+      </DataFrame>
+    </AnalysisData>
+  </OutputData>
+  <OutputFiles Name="Files">
+    <File Name="-o"></File>
+  </OutputFiles>
+</ReferenceData>
diff --git a/src/gromacs/trajectoryanalysis/tests/refdata/RdfModuleTest_SelectionsSolelyFromIndexFileWork.xml b/src/gromacs/trajectoryanalysis/tests/refdata/RdfModuleTest_SelectionsSolelyFromIndexFileWork.xml
new file mode 100644 (file)
index 0000000..367568f
--- /dev/null
@@ -0,0 +1,262 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+  <String Name="CommandLine">rdf -bin 0.05 -ref name_OW -sel name_OW not_name_OW</String>
+  <OutputData Name="Data">
+    <AnalysisData Name="norm">
+      <DataFrame Name="Frame0">
+        <Real Name="X">0</Real>
+        <DataValues>
+          <Int Name="Count">3</Int>
+          <DataValue>
+            <Real Name="Value">216</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">33.455901630929986</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">66.911803261859973</Real>
+          </DataValue>
+        </DataValues>
+      </DataFrame>
+    </AnalysisData>
+    <AnalysisData Name="paircount">
+      <DataFrame Name="Frame0">
+        <Real Name="X">0</Real>
+        <DataValues>
+          <Int Name="Count">37</Int>
+          <Int Name="DataSet">0</Int>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">274</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">360</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">226</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">234</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">270</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">332</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">420</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">456</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">548</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">588</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">546</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">632</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">660</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">696</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">822</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">922</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1060</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1084</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1276</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1260</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1260</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1416</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1468</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1560</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1668</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1774</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1578</Real>
+          </DataValue>
+        </DataValues>
+        <DataValues>
+          <Int Name="Count">37</Int>
+          <Int Name="DataSet">1</Int>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">215</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">217</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">0</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">114</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">163</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">87</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">52</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">103</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">266</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">618</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">751</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">703</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">722</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">772</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">821</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">946</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1065</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1229</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1281</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1402</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1518</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1640</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">1844</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">2058</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">2137</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">2412</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">2451</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">2650</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">2886</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">2928</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">3101</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">3374</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">3623</Real>
+          </DataValue>
+          <DataValue>
+            <Real Name="Value">3288</Real>
+          </DataValue>
+        </DataValues>
+      </DataFrame>
+    </AnalysisData>
+  </OutputData>
+  <OutputFiles Name="Files">
+    <File Name="-o"></File>
+  </OutputFiles>
+</ReferenceData>
index 594f918d7425deb65e785bbd1486eefa44ef6d33..6d29b0e67033a92297f3989545018bed1df5a6b7 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2018, by the GROMACS development team, led by
+ * Copyright (c) 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.
@@ -69,9 +69,8 @@ TEST(TopologyInformation, CantWorkWithoutReadingAFile)
     TopologyInformation topInfo;
     EXPECT_FALSE(topInfo.hasTopology());
     EXPECT_FALSE(topInfo.hasFullTopology());
-    ASSERT_TRUE(topInfo.mtop());
-    EXPECT_EQ(0, topInfo.mtop()->natoms);
-    EXPECT_FALSE(topInfo.expandedTopology());
+    EXPECT_EQ(nullptr, topInfo.mtop());
+    EXPECT_EQ(nullptr, topInfo.expandedTopology());
     auto atoms1 = topInfo.copyAtoms();
     EXPECT_TRUE(atoms1);
     auto atoms2 = topInfo.copyAtoms();
index c2e8eb2dc39b239267ea78c79ab7dbfb749d2b5a..15f100aa9f11f87b357d07fd232c119b433b9d2c 100644 (file)
@@ -60,8 +60,7 @@ namespace gmx
 {
 
 TopologyInformation::TopologyInformation()
-    : mtop_(std::make_unique<gmx_mtop_t>()),
-      hasLoadedMtop_(false),
+    : hasLoadedMtop_(false),
       expandedTopology_(nullptr),
       atoms_ (nullptr),
       bTop_(false), ePBC_(-1)
index c2c734c53d049c2f4be81f49cb83dca96739eeab..960ccbf276b7cae493b6d6f9cab372dac221f9e0 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2016,2017,2018, by the GROMACS development team, led by
+ * Copyright (c) 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.
@@ -147,7 +147,9 @@ void PmeTest::runTest(const RunModesList &runModes)
             continue;
         }
         auto modeTargetsPmeOnGpus = (mode.first.find("PmeOnGpu") != std::string::npos);
-        if (modeTargetsPmeOnGpus && !pme_gpu_supports_build(*hardwareInfo_, nullptr))
+        if (modeTargetsPmeOnGpus &&
+            !(pme_gpu_supports_build(nullptr) &&
+              pme_gpu_supports_hardware(*hardwareInfo_, nullptr)))
         {
             // This run mode will cause a fatal error from mdrun when
             // it finds an unsuitable device, which is not something