diff --git a/CMakeLists.txt b/CMakeLists.txt index db12954d61..475be608ef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -274,8 +274,6 @@ gmx_dependent_cache_variable(GMX_SIMD_REF_DOUBLE_WIDTH "Reference SIMD double pr option(GMX_BROKEN_CALLOC "Work around broken calloc()" OFF) mark_as_advanced(GMX_BROKEN_CALLOC) -option(GMX_LOAD_PLUGINS "Compile with plugin support, needed to read VMD supported file formats" ON) -mark_as_advanced(GMX_LOAD_PLUGINS) option(GMX_OPENMP "Enable OpenMP-based multithreading" ON) @@ -505,8 +503,18 @@ if(DEFINED HWLOC_LIBRARIES) set(Hwloc_FIND_QUIETLY TRUE) endif() find_package(Hwloc 1.5) -if(HWLOC_FOUND) - set(GMX_HWLOC_DEFAULT ON) +if (HWLOC_FOUND) + if (HWLOC_LIBRARIES MATCHES ".a$") + set(_STATIC_HWLOC TRUE) + endif() + + gmx_check_if_changed(HWLOC_FOUND_CHANGED HWLOC_FOUND) + if (_STATIC_HWLOC AND HWLOC_FOUND_CHANGED) + message(STATUS "Static hwloc library found, will not attempt using it as it could lead to link-time errors. To use the detected library, manually set GMX_HWLOC=ON and you will likely have to pass appropriate linker flags too to satisfy the link-time dependencies of your hwloc library. Try \"pkg-config --libs --static hwloc\" for suggestions on what you will need.") + set(GMX_HWLOC_DEFAULT OFF) + else() + set(GMX_HWLOC_DEFAULT ON) + endif() else() set(GMX_HWLOC_DEFAULT OFF) endif() @@ -705,32 +713,13 @@ include(gmxManageFFTLibraries) include(gmxManageLinearAlgebraLibraries) -# Whether GROMACS will really try to compile support for VMD plugins -set(GMX_USE_PLUGINS OFF) +include(gmxManagePluginSupport) -if(GMX_LOAD_PLUGINS) - if(NOT WIN32) - # Native Windows does not have, nor need dlopen - include(gmxTestdlopen) - gmx_test_dlopen(HAVE_DLOPEN) - endif() - - # so, should we use plug-ins? - if(WIN32 OR (HAVE_DLOPEN AND BUILD_SHARED_LIBS)) - if(NOT VMD_QUIETLY) - MESSAGE(STATUS "Using dynamic plugins (e.g VMD-supported file formats)") - endif() +if (GMX_USE_PLUGINS) if(NOT GMX_VMD_PLUGIN_PATH) - find_package(VMD) + find_package(VMD) endif() - set(GMX_USE_PLUGINS ON) - list(APPEND GMX_EXTRA_LIBRARIES ${CMAKE_DL_LIBS}) # magic cross-platform pre-set variable for dlopen library - set(PKG_DL_LIBS "-l${CMAKE_DL_LIBS}") - else() - set(PKG_DL_LIBS) - endif() endif() -set(VMD_QUIETLY TRUE CACHE INTERNAL "") # Link real-time library for POSIX timers. The check for clock_gettime # confirms the linkability of rt. diff --git a/admin/builds/get-version-info.py b/admin/builds/get-version-info.py new file mode 100644 index 0000000000..29af7691b3 --- /dev/null +++ b/admin/builds/get-version-info.py @@ -0,0 +1,41 @@ +# +# This file is part of the GROMACS molecular simulation package. +# +# Copyright (c) 2016, by the GROMACS development team, led by +# Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, +# and including many others, as listed in the AUTHORS file in the +# top-level source directory and at http://www.gromacs.org. +# +# GROMACS is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public License +# as published by the Free Software Foundation; either version 2.1 +# of the License, or (at your option) any later version. +# +# GROMACS is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with GROMACS; if not, see +# http://www.gnu.org/licenses, or write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# If you want to redistribute modifications to GROMACS, please +# consider that scientific software is very special. Version +# control is crucial - bugs must be traceable. We will be happy to +# consider code for inclusion in the official distribution, but +# derived work must not be called official GROMACS. Details are found +# in the README & COPYING files - if they are missing, get the +# official version at http://www.gromacs.org. +# +# To help us fund GROMACS development, we humbly ask that you cite +# the research papers on the package. Check out http://www.gromacs.org. + +import json + +def do_build(context): + cmd = [context.env.cmake_command, '-P', 'cmake/gmxVersionInfo.cmake'] + info_json = context.run_cmd(cmd, use_output=True) + values = json.loads(info_json) + context.set_version_info(values['version'], values['regressiontest-md5sum']) diff --git a/admin/builds/gromacs.py b/admin/builds/gromacs.py index dd0182e900..2ef5be3327 100644 --- a/admin/builds/gromacs.py +++ b/admin/builds/gromacs.py @@ -113,11 +113,6 @@ def do_build(context): regressiontests_path = context.workspace.get_project_dir(Project.REGRESSIONTESTS) if context.job_type == JobType.RELEASE: - # TODO: Consider using REGRESSIONTEST_DOWNLOAD here, after refactoring - # it to make that possible. Or use some other mechanism to check the - # MD5 of the regressiontests tarball (also taking into account the -dev - # builds where the hardcoded value in gmxVersionInfo.cmake is not - # accurate). cmake_opts['REGRESSIONTEST_PATH'] = regressiontests_path else: if context.opts.mdrun_only: diff --git a/admin/builds/update-regtest-hash.py b/admin/builds/update-regtest-hash.py new file mode 100644 index 0000000000..ee73d0e2da --- /dev/null +++ b/admin/builds/update-regtest-hash.py @@ -0,0 +1,57 @@ +# +# This file is part of the GROMACS molecular simulation package. +# +# Copyright (c) 2016, by the GROMACS development team, led by +# Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, +# and including many others, as listed in the AUTHORS file in the +# top-level source directory and at http://www.gromacs.org. +# +# GROMACS is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public License +# as published by the Free Software Foundation; either version 2.1 +# of the License, or (at your option) any later version. +# +# GROMACS is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with GROMACS; if not, see +# http://www.gnu.org/licenses, or write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# If you want to redistribute modifications to GROMACS, please +# consider that scientific software is very special. Version +# control is crucial - bugs must be traceable. We will be happy to +# consider code for inclusion in the official distribution, but +# derived work must not be called official GROMACS. Details are found +# in the README & COPYING files - if they are missing, get the +# official version at http://www.gromacs.org. +# +# To help us fund GROMACS development, we humbly ask that you cite +# the research papers on the package. Check out http://www.gromacs.org. + +import json + +extra_options = { + 'md5sum': Option.string +} + +def do_build(context): + info_path = 'cmake/gmxVersionInfo.cmake' + cmd = [context.env.cmake_command, '-P', info_path] + info_json = context.run_cmd(cmd, use_output=True) + values = json.loads(info_json) + old_md5sum = values['regressiontest-md5sum'] + new_md5sum = context.opts.md5sum + if new_md5sum != old_md5sum: + context.replace_in_file(info_path, r'set\(REGRESSIONTEST_MD5SUM "(\w*)"', + lambda x: do_replacement(x, new_md5sum)) + context.workspace.upload_revision(project=Project.GROMACS, file_glob=info_path) + +def do_replacement(match, new_md5sum): + result = match.group(0) + start = match.start(1) - match.start(0) + end = match.end(1) - match.end(0) + return result[:start] + new_md5sum + result[end:] diff --git a/cmake/FindFFTW.cmake b/cmake/FindFFTW.cmake index c6058a7561..6781ad0e8c 100644 --- a/cmake/FindFFTW.cmake +++ b/cmake/FindFFTW.cmake @@ -1,7 +1,7 @@ # # This file is part of the GROMACS molecular simulation package. # -# Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by +# Copyright (c) 2012,2013,2014,2015,2016, 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. @@ -152,7 +152,7 @@ if (${FFTW}_FOUND) endif() #Verify FFTW is compiled with fPIC (necessary for shared libraries) - if (CMAKE_OBJDUMP AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND BUILD_SHARED_LIBS AND NOT CYGWIN) + if (CMAKE_OBJDUMP AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND BUILD_SHARED_LIBS AND NOT CYGWIN AND NOT APPLE) execute_process(COMMAND ${CMAKE_OBJDUMP} --reloc ${${FFTW}_LIBRARY} OUTPUT_VARIABLE ${FFTW}_OBJDUMP) if (${${FFTW}_OBJDUMP} MATCHES "R_X86_64" #Should always be true for static libraries. Checks that objdump works properly and that the library isn't dynamic AND NOT ${${FFTW}_OBJDUMP} MATCHES "R_X86_64_PLT32") diff --git a/cmake/gmxCFlags.cmake b/cmake/gmxCFlags.cmake index 69bc7956f2..2a86ced5fc 100644 --- a/cmake/gmxCFlags.cmake +++ b/cmake/gmxCFlags.cmake @@ -1,7 +1,7 @@ # # This file is part of the GROMACS molecular simulation package. # -# Copyright (c) 2009,2010,2011,2012,2013,2014,2015,2016, by the GROMACS development team, led by +# Copyright (c) 2009,2010,2011,2012,2013,2014,2015,2016,2017, 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. @@ -240,7 +240,8 @@ macro (gmx_c_flags) if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 15.00.00) GMX_TEST_CXXFLAG(CXXFLAGS_WARN_OLD /wd193 GMXC_CXXFLAGS) endif() - GMX_TEST_CXXFLAG(CXXFLAGS_WARN "/W3 /wd177 /wd271 /wd304 /wd383 /wd424 /wd444 /wd522 /wd593 /wd869 /wd981 /wd1418 /wd1419 /wd1572 /wd1599 /wd2259 /wd2415 /wd2547 /wd2557 /wd3280 /wd3346 /wd1782 /wd2282" GMXC_CXXFLAGS) +#809: exception specification for virtual function X is incompatible with that of overridden function + GMX_TEST_CXXFLAG(CXXFLAGS_WARN "/W3 /wd177 /wd271 /wd304 /wd383 /wd424 /wd444 /wd522 /wd593 /wd809 /wd869 /wd981 /wd1418 /wd1419 /wd1572 /wd1599 /wd2259 /wd2415 /wd2547 /wd2557 /wd3280 /wd3346 /wd1782 /wd2282" GMXC_CXXFLAGS) endif() GMX_TEST_CXXFLAG(CXXFLAGS_OPT "/Qip" GMXC_CXXFLAGS_RELEASE) endif() diff --git a/cmake/gmxDetectSimd.cmake b/cmake/gmxDetectSimd.cmake index 2d70f20e4d..fdf64df5f8 100644 --- a/cmake/gmxDetectSimd.cmake +++ b/cmake/gmxDetectSimd.cmake @@ -72,10 +72,12 @@ function(gmx_suggest_simd _suggested_simd) message(STATUS "Detecting best SIMD instructions for this CPU") # Get CPU SIMD properties information - set(_compile_definitions "${GCC_INLINE_ASM_DEFINE} -I${CMAKE_SOURCE_DIR}/src -DGMX_CPUINFO_STANDALONE ${GMX_STDLIB_CXX_FLAGS}") if(GMX_TARGET_X86) - set(_compile_definitions "${_compile_definitions} -DGMX_TARGET_X86") + set(GMX_TARGET_X86_VALUE 1) + else() + set(GMX_TARGET_X86_VALUE 0) endif() + set(_compile_definitions "${GCC_INLINE_ASM_DEFINE} -I${CMAKE_SOURCE_DIR}/src -DGMX_CPUINFO_STANDALONE ${GMX_STDLIB_CXX_FLAGS} -DGMX_TARGET_X86=${GMX_TARGET_X86_VALUE}") # Prepare a default suggestion set(OUTPUT_SIMD "None") diff --git a/cmake/gmxManagePluginSupport.cmake b/cmake/gmxManagePluginSupport.cmake new file mode 100644 index 0000000000..69c1e4c55a --- /dev/null +++ b/cmake/gmxManagePluginSupport.cmake @@ -0,0 +1,98 @@ +# +# This file is part of the GROMACS molecular simulation package. +# +# Copyright (c) 2016, by the GROMACS development team, led by +# Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, +# and including many others, as listed in the AUTHORS file in the +# top-level source directory and at http://www.gromacs.org. +# +# GROMACS is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public License +# as published by the Free Software Foundation; either version 2.1 +# of the License, or (at your option) any later version. +# +# GROMACS is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with GROMACS; if not, see +# http://www.gnu.org/licenses, or write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# If you want to redistribute modifications to GROMACS, please +# consider that scientific software is very special. Version +# control is crucial - bugs must be traceable. We will be happy to +# consider code for inclusion in the official distribution, but +# derived work must not be called official GROMACS. Details are found +# in the README & COPYING files - if they are missing, get the +# official version at http://www.gromacs.org. +# +# To help us fund GROMACS development, we humbly ask that you cite +# the research papers on the package. Check out http://www.gromacs.org. + +include(gmxOptionUtilities) + +# Sets GMX_USE_PLUGINS=ON in the parent scope if the toolchain and +# user selections permit the build to support plugin loading. +function(gmx_manage_plugin_support) + gmx_option_trivalue(GMX_LOAD_PLUGINS "Compile with plugin support, needed to read VMD supported file formats" AUTO) + mark_as_advanced(GMX_LOAD_PLUGINS) + + # Find out if non-Windows builds can support plugins. Native Windows + # neither needs nor has library support. + if (NOT WIN32) + # TODO Make a proper find_package for dlopen to find + # dlfcn.h. The CMake variable CMAKE_DL_LIBS works magically + # for the library, however. + include(gmxTestdlopen) + gmx_test_dlopen(HAVE_DLOPEN) + endif() + + # Keep the status line quiet unless something relevant has + # changed. + gmx_check_if_changed(EMIT_STATUS_MESSAGES GMX_LOAD_PLUGINS BUILD_SHARED_LIBS HAVE_DLOPEN) + + # Whether GROMACS will really try to compile support for VMD + # plugins. + set(GMX_USE_PLUGINS OFF) + + # Plugins are supported natively on Windows + if (WIN32 OR (BUILD_SHARED_LIBS AND HAVE_DLOPEN)) + set(GMX_USE_PLUGINS ${GMX_LOAD_PLUGINS}) + elseif(GMX_LOAD_PLUGINS) + # Can't support plugins for some reason. If the user required + # plugins, emit fatal errors. Otherwise, emit status messages + # for AUTO and be silent for OFF. + set(message "") + if (NOT HAVE_DLOPEN) + set(message "${message}dlopen() support for using dynamic plugins for VMD-supported file formats is missing. ") + endif() + if(NOT BUILD_SHARED_LIBS) + set(message "${message}GROMACS only supports plugins in a build that uses shared libraries, which can be disabled for various reasons. BUILD_SHARED_LIBS=on and a toolchain that supports dynamic linking is required. (Hint: GMX_PREFER_STATIC_LIBS and GMX_BUILD_MDRUN_ONLY can influence the default BUILD_SHARED_LIBS, so if you need plugins, reconsider those choices.) ") + endif() + if (GMX_LOAD_PLUGINS_FORCE) + message(FATAL_ERROR "${message}Cannot build with GMX_LOAD_PLUGINS=${GMX_LOAD_PLUGINS}.") + endif() + if (GMX_LOAD_PLUGINS_AUTO AND EMIT_STATUS_MESSAGES) + message(STATUS "${message}") + endif() + endif() + + if(EMIT_STATUS_MESSAGES) + if(GMX_USE_PLUGINS) + MESSAGE(STATUS "Using dynamic plugins (e.g VMD-supported file formats)") + else() + MESSAGE(STATUS "Not using dynamic plugins (e.g VMD-supported file formats)") + endif() + endif() + set(GMX_USE_PLUGINS ${GMX_USE_PLUGINS} PARENT_SCOPE) +endfunction() + +gmx_manage_plugin_support() + +if(GMX_USE_PLUGINS) + list(APPEND GMX_EXTRA_LIBRARIES ${CMAKE_DL_LIBS}) # magic cross-platform pre-set variable for dlopen library + set(PKG_DL_LIBS "-l${CMAKE_DL_LIBS}") +endif() diff --git a/cmake/gmxSetBuildInformation.cmake b/cmake/gmxSetBuildInformation.cmake index f064ba419f..52b60c3ea0 100644 --- a/cmake/gmxSetBuildInformation.cmake +++ b/cmake/gmxSetBuildInformation.cmake @@ -95,10 +95,12 @@ macro(gmx_set_build_information) if(NOT CMAKE_CROSSCOMPILING) # Get CPU information, e.g. for deciding what SIMD support probably exists - set(_compile_definitions "${GCC_INLINE_ASM_DEFINE} -I${CMAKE_SOURCE_DIR}/src -DGMX_CPUINFO_STANDALONE ${GMX_STDLIB_CXX_FLAGS}") if(GMX_TARGET_X86) - set(_compile_definitions "${_compile_definitions} -DGMX_TARGET_X86") + set(GMX_TARGET_X86_VALUE 1) + else() + set(GMX_TARGET_X86_VALUE 0) endif() + set(_compile_definitions "${GCC_INLINE_ASM_DEFINE} -I${CMAKE_SOURCE_DIR}/src -DGMX_CPUINFO_STANDALONE ${GMX_STDLIB_CXX_FLAGS} -DGMX_TARGET_X86=${GMX_TARGET_X86_VALUE}") set(GMX_BUILDINFORMATION_BINARY "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/GmxBuildInformation${CMAKE_EXECUTABLE_SUFFIX}") set(LINK_LIBRARIES "${GMX_STDLIB_LIBRARIES}") diff --git a/cmake/gmxTestCXX11.cmake b/cmake/gmxTestCXX11.cmake index 65a1598463..f289f811db 100644 --- a/cmake/gmxTestCXX11.cmake +++ b/cmake/gmxTestCXX11.cmake @@ -1,7 +1,7 @@ # # This file is part of the GROMACS molecular simulation package. # -# Copyright (c) 2012,2013,2014,2015,2016, by the GROMACS development team, led by +# Copyright (c) 2012,2013,2014,2015,2016,2017, 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. @@ -102,6 +102,7 @@ extern template void someFunction(); int main() { // Test nullptr double *x = nullptr; + (void)x; // Suppressing unused variable warning // Test range-based for loops int array[5] = { 1, 2, 3, 4, 5 }; for (int& x : array) diff --git a/cmake/gmxVersionInfo.cmake b/cmake/gmxVersionInfo.cmake index 585eee9580..3b72cf08ba 100644 --- a/cmake/gmxVersionInfo.cmake +++ b/cmake/gmxVersionInfo.cmake @@ -1,7 +1,7 @@ # # This file is part of the GROMACS molecular simulation package. # -# Copyright (c) 2014,2015,2016, by the GROMACS development team, led by +# Copyright (c) 2014,2015,2016,2017, 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. @@ -188,7 +188,7 @@ # The GROMACS convention is that these are the version number of the next # release that is going to be made from this branch. set(GMX_VERSION_MAJOR 2016) -set(GMX_VERSION_PATCH 1) +set(GMX_VERSION_PATCH 2) # The suffix, on the other hand, is used mainly for betas and release # candidates, where it signifies the most recent such release from # this branch; it will be empty before the first such release, as well @@ -205,7 +205,7 @@ set(GMX_VERSION_SUFFIX "") # code being able to dynamically link with a version of libgromacs # that might not work. set(LIBRARY_SOVERSION_MAJOR 2) -set(LIBRARY_SOVERSION_MINOR 1) +set(LIBRARY_SOVERSION_MINOR 2) set(LIBRARY_VERSION ${LIBRARY_SOVERSION_MAJOR}.${LIBRARY_SOVERSION_MINOR}.0) ##################################################################### @@ -219,22 +219,28 @@ endif() set(GMX_VERSION_STRING "${GMX_VERSION}${GMX_VERSION_SUFFIX}") option(GMX_BUILD_TARBALL "Build tarball without -dev version suffix" OFF) mark_as_advanced(GMX_BUILD_TARBALL) -if (NOT SOURCE_IS_SOURCE_DISTRIBUTION AND NOT GMX_BUILD_TARBALL) +# If run with cmake -P, the -dev suffix is managed elsewhere. +if (NOT SOURCE_IS_SOURCE_DISTRIBUTION AND + NOT GMX_BUILD_TARBALL AND + NOT CMAKE_SCRIPT_MODE_FILE) set(GMX_VERSION_STRING "${GMX_VERSION_STRING}-dev") endif() set(REGRESSIONTEST_VERSION "${GMX_VERSION_STRING}") set(REGRESSIONTEST_BRANCH "refs/heads/release-2016") -# TODO Find some way of ensuring that this is bumped appropriately for -# each release. It's hard to test because it is only used for -# REGRESSIONTEST_DOWNLOAD, which doesn't work until that tarball has -# been placed on the server. -set(REGRESSIONTEST_MD5SUM "366438549270d005fa6def6e56ca0256" CACHE INTERNAL "MD5 sum of the regressiontests tarball") +set(REGRESSIONTEST_MD5SUM "e4d24e3c5f28602c2429b3a389121de8" CACHE INTERNAL "MD5 sum of the regressiontests tarball") math(EXPR GMX_VERSION_NUMERIC "${GMX_VERSION_MAJOR}*10000 + ${GMX_VERSION_PATCH}") set(GMX_API_VERSION ${GMX_VERSION_NUMERIC}) +# If run with cmake -P from releng scripts, print out necessary version info +# as JSON. +if (CMAKE_SCRIPT_MODE_FILE) + message("{ \"version\": \"${GMX_VERSION_STRING}\", \"regressiontest-md5sum\": \"${REGRESSIONTEST_MD5SUM}\" }") + return() +endif() + ##################################################################### # git version info management diff --git a/docs/dev-manual/jenkins.rst b/docs/dev-manual/jenkins.rst index e76bffa217..40308988ee 100644 --- a/docs/dev-manual/jenkins.rst +++ b/docs/dev-manual/jenkins.rst @@ -113,7 +113,8 @@ On-demand builds ---------------- These builds can be triggered on request for certain changes in Gerrit, or -manually from Jenkins. +manually from Jenkins. See :ref:`releng-triggering-builds` for details on +how to trigger these. Coverage ^^^^^^^^ @@ -151,3 +152,9 @@ The exact build sequence is desribed in :ref:`releng-workflow-release`. The build uses the source tarball build as a subbuild, and parts of the build are executed using :file:`admin/builds/gromacs.py` and :file:`admin/builds/documentation.py`. + +:file:`admin/builds/get-version-info.py` is used for getting the version +information from the source tree as part of this workflow. + +:file:`admin/builds/update-regtest-hash.py` has logic to update the +regressiontests tarball MD5 sum for the released tarball automatically. diff --git a/docs/doxygen/includesorter.py b/docs/doxygen/includesorter.py index f3f8b77a7b..f2236d4cf5 100755 --- a/docs/doxygen/includesorter.py +++ b/docs/doxygen/includesorter.py @@ -373,6 +373,12 @@ def main(): if not options.quiet: sys.stderr.write('Scanning source tree...\n') + if not options.source_root: + sys.stderr.write('Source root required not specified.\n') + sys.exit(2) + if not options.build_root: + sys.stderr.write('Build root required not specified.\n') + sys.exit(2) tree = GromacsTree(options.source_root, options.build_root, reporter) tree.load_installed_file_list() files = [] diff --git a/docs/user-guide/mdp-options.rst b/docs/user-guide/mdp-options.rst index d0c44d28cd..54d7e19b64 100644 --- a/docs/user-guide/mdp-options.rst +++ b/docs/user-guide/mdp-options.rst @@ -1108,19 +1108,23 @@ Pressure coupling .. mdp:: pcoupltype + Specifies the kind of isotropy of the pressure coupling used. Each + kind takes one or more values for :mdp:`compressibility` and + :mdp:`ref-p`. Only a single value is permitted for :mdp:`tau-p`. + .. mdp-value:: isotropic Isotropic pressure coupling with time constant - :mdp:`tau-p`. The compressibility and reference pressure are - set with :mdp:`compressibility` and :mdp:`ref-p`, one value is - needed. + :mdp:`tau-p`. One value each for :mdp:`compressibility` and + :mdp:`ref-p` is required. .. mdp-value:: semiisotropic Pressure coupling which is isotropic in the ``x`` and ``y`` direction, but different in the ``z`` direction. This can be - useful for membrane simulations. 2 values are needed for ``x/y`` - and ``z`` directions respectively. + useful for membrane simulations. Two values each for + :mdp:`compressibility` and :mdp:`ref-p` are required, for + ``x/y`` and ``z`` directions respectively. .. mdp-value:: anisotropic @@ -1156,18 +1160,21 @@ Pressure coupling .. mdp:: tau-p (1) \[ps\] - time constant for coupling + The time constant for pressure coupling (one value for all + directions). .. mdp:: compressibility \[bar^-1\] - compressibility (NOTE: this is now really in bar-1) For water at 1 - atm and 300 K the compressibility is 4.5e-5 bar^-1. + The compressibility (NOTE: this is now really in bar^-1) For water at 1 + atm and 300 K the compressibility is 4.5e-5 bar^-1. The number of + required values is implied by :mdp:`pcoupltype`. .. mdp:: ref-p \[bar\] - reference pressure for coupling + The reference pressure for coupling. The number of required values + is implied by :mdp:`pcoupltype`. .. mdp:: refcoord-scaling diff --git a/src/gromacs/CMakeLists.txt b/src/gromacs/CMakeLists.txt index b7a6545ce3..b38c25f07a 100644 --- a/src/gromacs/CMakeLists.txt +++ b/src/gromacs/CMakeLists.txt @@ -124,7 +124,9 @@ list(APPEND LIBGROMACS_SOURCES ${THREAD_MPI_SOURCES}) if(GMX_USE_TNG) list(APPEND LIBGROMACS_SOURCES ${TNG_SOURCES}) - tng_set_source_properties(WITH_ZLIB ${HAVE_ZLIB}) + if (NOT GMX_EXTERNAL_TNG) + tng_set_source_properties(WITH_ZLIB ${HAVE_ZLIB}) + endif() endif() get_lmfit_properties(LMFIT_SOURCES LMFIT_LIBRARIES_TO_LINK LMFIT_INCLUDE_DIRECTORY LMFIT_INCLUDE_DIR_ORDER) @@ -169,15 +171,6 @@ check_cxx_compiler_flag(-Wno-unused-parameter HAS_NO_UNUSED_PARAMETER) if (HAS_NO_UNUSED_PARAMETER) set(_scanner_cpp_compiler_flags "${_scanner_cpp_compiler_flags} -Wno-unused-parameter") endif() -check_cxx_compiler_flag(-Wno-deprecated-register HAS_NO_DEPRECATED_REGISTER) -if (HAS_NO_DEPRECATED_REGISTER) - set(_scanner_cpp_compiler_flags "${_scanner_cpp_compiler_flags} -Wno-deprecated-register") -else() - check_cxx_compiler_flag(-Wno-deprecated HAS_NO_DEPRECATED) - if (HAS_NO_DEPRECATED) - set(_scanner_cpp_compiler_flags "${_scanner_cpp_compiler_flags} -Wno-deprecated") - endif() -endif() set_source_files_properties(selection/scanner.cpp PROPERTIES COMPILE_FLAGS "${_scanner_cpp_compiler_flags}") target_link_libraries(libgromacs diff --git a/src/gromacs/correlationfunctions/crosscorr.cpp b/src/gromacs/correlationfunctions/crosscorr.cpp index 37998b5f75..22291ee132 100644 --- a/src/gromacs/correlationfunctions/crosscorr.cpp +++ b/src/gromacs/correlationfunctions/crosscorr.cpp @@ -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,2017, 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. @@ -65,13 +65,13 @@ static int zeroPaddingSize(int n) * \param[in] in1 first complex number * \param[in] in2 second complex number */ -static void complexConjugatMult(double in1[], double in2[]) +static void complexConjugatMult(t_complex *in1, t_complex *in2) { - double res[2]; - res[0] = in1[0] * in2[0] + in1[1] * in2[1]; - res[1] = in1[0] * -in2[1] + in1[1] * in2[0]; - in1[0] = res[0]; - in1[1] = res[1]; + t_complex res; + res.re = in1->re * in2->re + in1->im * in2->im; + res.im = in1->re * -in2->im + in1->im * in2->re; + in1->re = res.re; + in1->im = res.im; } /*! \brief @@ -87,51 +87,38 @@ static void cross_corr_low(int n, real f[], real g[], real corr[], gmx_fft_t fft { int i; const int size = zeroPaddingSize(n); - double ** in1, ** in2; + t_complex * in1, * in2; + snew(in1, size); snew(in2, size); - for (i = 0; i < size; i++) - { - snew(in1[i], 2); - snew(in2[i], 2); - } - for (i = 0; i < n; i++) { - in1[i][0] = (double)f[i]; - in1[i][1] = 0; - in2[i][0] = (double)g[i]; - in2[i][1] = 0; + in1[i].re = f[i]; + in1[i].im = 0; + in2[i].re = g[i]; + in2[i].im = 0; } for (; i < size; i++) { - in1[i][0] = 0; - in1[i][1] = 0; - in2[i][0] = 0; - in2[i][1] = 0; + in1[i].re = 0; + in1[i].im = 0; + in2[i].re = 0; + in2[i].im = 0; } - - gmx_fft_1d(fft, GMX_FFT_FORWARD, in1, in1); gmx_fft_1d(fft, GMX_FFT_FORWARD, in2, in2); for (i = 0; i < size; i++) { - complexConjugatMult(in1[i], in2[i]); - in1[i][0] /= size; + complexConjugatMult(&in1[i], &in2[i]); + in1[i].re /= size; } gmx_fft_1d(fft, GMX_FFT_BACKWARD, in1, in1); for (i = 0; i < n; i++) { - corr[i] = (real)(in1[i][0]); - } - - for (i = 0; i < size; i++) - { - sfree(in1[i]); - sfree(in2[i]); + corr[i] = in1[i].re; } sfree(in1); diff --git a/src/gromacs/domdec/domdec_topology.cpp b/src/gromacs/domdec/domdec_topology.cpp index 46b05ddd71..6ef54dca4c 100644 --- a/src/gromacs/domdec/domdec_topology.cpp +++ b/src/gromacs/domdec/domdec_topology.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017, 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. @@ -1262,40 +1262,33 @@ static void combine_idef(t_idef *dest, const thread_work_t *src, int nsrc, /* Position restraints need an additional treatment */ if (ftype == F_POSRES || ftype == F_FBPOSRES) { - int nposres = dest->il[ftype].nr/2; - if (nposres > dest->iparams_posres_nalloc) + int nposres = dest->il[ftype].nr/2; + // TODO: Simplify this code using std::vector + t_iparams * &iparams_dest = (ftype == F_POSRES ? dest->iparams_posres : dest->iparams_fbposres); + int &posres_nalloc = (ftype == F_POSRES ? dest->iparams_posres_nalloc : dest->iparams_fbposres_nalloc); + if (nposres > posres_nalloc) { - dest->iparams_posres_nalloc = over_alloc_large(nposres); - srenew(dest->iparams_posres, dest->iparams_posres_nalloc); + posres_nalloc = over_alloc_large(nposres); + srenew(iparams_dest, posres_nalloc); } + /* Set nposres to the number of original position restraints in dest */ for (int s = 1; s < nsrc; s++) { nposres -= src[s].idef.il[ftype].nr/2; } + for (int s = 1; s < nsrc; s++) { - if (ftype == F_POSRES) - { - for (int i = 0; i < src[s].idef.il[ftype].nr/2; i++) - { - /* Correct the index into iparams_posres */ - dest->il[ftype].iatoms[nposres*2] = nposres; - /* Copy the position restraint force parameters */ - dest->iparams_posres[nposres] = src[s].idef.iparams_posres[i]; - nposres++; - } - } - else + const t_iparams *iparams_src = (ftype == F_POSRES ? src[s].idef.iparams_posres : src[s].idef.iparams_fbposres); + + for (int i = 0; i < src[s].idef.il[ftype].nr/2; i++) { - for (int i = 0; i < src[s].idef.il[ftype].nr/2; i++) - { - /* Correct the index into iparams_fbposres */ - dest->il[ftype].iatoms[nposres*2] = nposres; - /* Copy the position restraint force parameters */ - dest->iparams_fbposres[nposres] = src[s].idef.iparams_fbposres[i]; - nposres++; - } + /* Correct the index into iparams_posres */ + dest->il[ftype].iatoms[nposres*2] = nposres; + /* Copy the position restraint force parameters */ + iparams_dest[nposres] = iparams_src[i]; + nposres++; } } } diff --git a/src/gromacs/ewald/pme-spread.cpp b/src/gromacs/ewald/pme-spread.cpp index 94cf25a97d..2a1e8efc6b 100644 --- a/src/gromacs/ewald/pme-spread.cpp +++ b/src/gromacs/ewald/pme-spread.cpp @@ -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, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017, 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. @@ -271,7 +271,7 @@ static void make_bsplines(splinevec theta, splinevec dtheta, int order, if (bDoSplines || coefficient[ii] != 0.0) { xptr = fractx[ii]; - assert(order >= 4 && order <= PME_ORDER_MAX); + assert(order >= 3 && order <= PME_ORDER_MAX); switch (order) { case 4: CALC_SPLINE(4); break; diff --git a/src/gromacs/fileio/tngio_for_tools.cpp b/src/gromacs/fileio/tngio_for_tools.cpp index e351aed613..51839aa06d 100644 --- a/src/gromacs/fileio/tngio_for_tools.cpp +++ b/src/gromacs/fileio/tngio_for_tools.cpp @@ -616,7 +616,7 @@ gmx_bool gmx_read_next_tng_frame(tng_trajectory_t input, * be reallocated if it is not NULL. */ } - fr->step = static_cast(frameNumber); + fr->step = frameNumber; fr->bStep = TRUE; // Convert the time to ps fr->time = frameTime / PICO; @@ -840,7 +840,7 @@ gmx_bool gmx_get_tng_data_next_frame_of_block_type(tng_trajectory_t input, { gmx_file("Cannot read next frame of TNG file"); } - snew(*values, sizeof(real) * *nValuesPerFrame * *nAtoms); + srenew(*values, sizeof(real) * *nValuesPerFrame * *nAtoms); convert_array_to_real_array(data, *values, getDistanceScaleFactor(input), diff --git a/src/gromacs/fileio/trrio.cpp b/src/gromacs/fileio/trrio.cpp index 2890557224..87cddfdd52 100644 --- a/src/gromacs/fileio/trrio.cpp +++ b/src/gromacs/fileio/trrio.cpp @@ -82,6 +82,14 @@ static int nFloatSize(gmx_trr_header_t *sh) return nflsize; } +/* Returns whether a valid frame header was read. Upon exit, *bOK is + TRUE if a normal outcome resulted. Usually that is the same thing, + but encountering the end of the file before reading the magic + integer is a normal outcome for TRR reading, and it does not + produce a valid frame header, so the values differ in that case. + That does not exclude the possibility of a reading error between + frames, but the trajectory-handling infrastructure needs an + overhaul before we can handle that. */ static gmx_bool do_trr_frame_header(t_fileio *fio, bool bRead, gmx_trr_header_t *sh, gmx_bool *bOK) { @@ -94,9 +102,11 @@ do_trr_frame_header(t_fileio *fio, bool bRead, gmx_trr_header_t *sh, gmx_bool *b if (!gmx_fio_do_int(fio, magic)) { - // Failed to read an integer, which should be the magic number - *bOK = FALSE; - return *bOK; + /* Failed to read an integer, which should be the magic + number, which usually means we've reached the end + of the file (but could be an I/O error that we now + might mishandle). */ + return FALSE; } if (magic != magicValue) { diff --git a/src/gromacs/gmxana/gmx_anaeig.cpp b/src/gromacs/gmxana/gmx_anaeig.cpp index 15fbfb13f4..702d6f208e 100644 --- a/src/gromacs/gmxana/gmx_anaeig.cpp +++ b/src/gromacs/gmxana/gmx_anaeig.cpp @@ -1024,9 +1024,11 @@ int gmx_anaeig(int argc, char *argv[]) "of both files will be used unless [TT]-first[tt] and [TT]-last[tt]", "have been set explicitly.[PAR]", - "When [TT]-v[tt], [TT]-eig[tt], [TT]-v2[tt] and [TT]-eig2[tt] are given,", - "a single number for the overlap between the covariance matrices is", - "generated. The formulas are::", + "When [TT]-v[tt] and [TT]-v2[tt] are given, a single number for the", + "overlap between the covariance matrices is generated. Note that the", + "eigenvalues are by default read from the timestamp field in the", + "eigenvector input files, but when [TT]-eig[tt], or [TT]-eig2[tt] are", + "given, the corresponding eigenvalues are used instead. The formulas are::", "", " difference = sqrt(tr((sqrt(M1) - sqrt(M2))^2))", " normalized overlap = 1 - difference/sqrt(tr(M1) + tr(M2))", diff --git a/src/gromacs/gmxana/gmx_covar.cpp b/src/gromacs/gmxana/gmx_covar.cpp index b7ee514a56..34a5e03c31 100644 --- a/src/gromacs/gmxana/gmx_covar.cpp +++ b/src/gromacs/gmxana/gmx_covar.cpp @@ -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, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016, 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. @@ -75,7 +75,8 @@ int gmx_covar(int argc, char *argv[]) "the reference structure for the fit is written first with t=-1.", "The average (or reference when [TT]-ref[tt] is used) structure is", "written with t=0, the eigenvectors", - "are written as frames with the eigenvector number as timestamp.", + "are written as frames with the eigenvector number and eigenvalue", + "as step number and timestamp, respectively.", "[PAR]", "The eigenvectors can be analyzed with [gmx-anaeig].", "[PAR]", diff --git a/src/gromacs/gmxana/gmx_editconf.cpp b/src/gromacs/gmxana/gmx_editconf.cpp index 87fa1bc700..74405013a3 100644 --- a/src/gromacs/gmxana/gmx_editconf.cpp +++ b/src/gromacs/gmxana/gmx_editconf.cpp @@ -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, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017, 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. @@ -223,14 +223,15 @@ void set_pdb_conf_bfac(int natoms, int nres, t_atoms *atoms, int n_bfac, int i, n; gmx_bool found; + if (n_bfac > atoms->nres) + { + peratom = TRUE; + } + bfac_max = -1e10; bfac_min = 1e10; for (i = 0; (i < n_bfac); i++) { - if (bfac_nr[i] - 1 >= atoms->nres) - { - peratom = TRUE; - } /* if ((bfac_nr[i]-1<0) || (bfac_nr[i]-1>=atoms->nr)) gmx_fatal(FARGS,"Index of B-Factor %d is out of range: %d (%g)", i+1,bfac_nr[i],bfac[i]); */ @@ -564,7 +565,7 @@ int gmx_editconf(int argc, char *argv[]) "from a file with with following format: first line states number of", "entries in the file, next lines state an index", "followed by a B-factor. The B-factors will be attached per residue", - "unless an index is larger than the number of residues or unless the", + "unless the number of B-factors is larger than the number of the residues or unless the", "[TT]-atom[tt] option is set. Obviously, any type of numeric data can", "be added instead of B-factors. [TT]-legend[tt] will produce", "a row of CA atoms with B-factors ranging from the minimum to the", diff --git a/src/gromacs/gmxana/gmx_nmeig.cpp b/src/gromacs/gmxana/gmx_nmeig.cpp index 0c363ed7c1..531c004308 100644 --- a/src/gromacs/gmxana/gmx_nmeig.cpp +++ b/src/gromacs/gmxana/gmx_nmeig.cpp @@ -302,7 +302,8 @@ int gmx_nmeig(int argc, char *argv[]) "which can be calculated with [gmx-mdrun].", "The eigenvectors are written to a trajectory file ([TT]-v[tt]).", "The structure is written first with t=0. The eigenvectors", - "are written as frames with the eigenvector number as timestamp.", + "are written as frames with the eigenvector number and eigenvalue", + "written as step number and timestamp, respectively.", "The eigenvectors can be analyzed with [gmx-anaeig].", "An ensemble of structures can be generated from the eigenvectors with", "[gmx-nmens]. When mass weighting is used, the generated eigenvectors", diff --git a/src/gromacs/gmxana/gmx_order.cpp b/src/gromacs/gmxana/gmx_order.cpp index d48e5d4f90..1f1bad24f5 100644 --- a/src/gromacs/gmxana/gmx_order.cpp +++ b/src/gromacs/gmxana/gmx_order.cpp @@ -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, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017, 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. @@ -637,16 +637,13 @@ void calc_order(const char *fn, int *index, int *a, rvec **order, z1 = x1[a[index[i-1]+j]][axis]; z2 = x1[a[index[i+1]+j]][axis]; z_ave = 0.5 * (z1 + z2); - if (z_ave < 0) + slice = (int)((nslices*z_ave)/box[axis][axis]); + while (slice < 0) { - z_ave += box[axis][axis]; - } - if (z_ave > box[axis][axis]) - { - z_ave -= box[axis][axis]; + slice += nslices; } + slice = slice % nslices; - slice = static_cast((0.5 + (z_ave / (*slWidth))) - 1); slCount[slice]++; /* determine slice, increase count */ slFrameorder[slice] += 0.5 * (3 * cossum[axis] - 1); diff --git a/src/gromacs/gmxana/gmx_rmsf.cpp b/src/gromacs/gmxana/gmx_rmsf.cpp index 0cdbd1a2fc..8b5118003e 100644 --- a/src/gromacs/gmxana/gmx_rmsf.cpp +++ b/src/gromacs/gmxana/gmx_rmsf.cpp @@ -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, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017, 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. @@ -320,6 +320,8 @@ int gmx_rmsf(int argc, char *argv[]) snew(pdbatoms, 1); *pdbatoms = top_pdb->atoms; read_tps_conf(opt2fn("-q", NFILE, fnm), top_pdb, NULL, &pdbx, NULL, pdbbox, FALSE); + /* TODO Should this assert that top_pdb->atoms.nr == top.atoms.nr? + * See discussion at https://gerrit.gromacs.org/#/c/6430/1 */ title = *top_pdb->name; snew(refatoms, 1); *refatoms = top_pdb->atoms; @@ -548,24 +550,26 @@ int gmx_rmsf(int argc, char *argv[]) /* Write a .pdb file with B-factors and optionally anisou records */ for (i = 0; i < isize; i++) { - rvec_inc(xref[index[i]], xcm); + rvec_inc(pdbx[index[i]], xcm); } write_sto_conf_indexed(opt2fn("-oq", NFILE, fnm), title, pdbatoms, pdbx, NULL, ePBC, pdbbox, isize, index); } if (opt2bSet("-ox", NFILE, fnm)) { - /* Misuse xref as a temporary array */ + rvec *bFactorX; + snew(bFactorX, top.atoms.nr); for (i = 0; i < isize; i++) { for (d = 0; d < DIM; d++) { - xref[index[i]][d] = xcm[d] + xav[i*DIM + d]; + bFactorX[index[i]][d] = xcm[d] + xav[i*DIM + d]; } } /* Write a .pdb file with B-factors and optionally anisou records */ - write_sto_conf_indexed(opt2fn("-ox", NFILE, fnm), title, pdbatoms, xref, NULL, + write_sto_conf_indexed(opt2fn("-ox", NFILE, fnm), title, pdbatoms, bFactorX, NULL, ePBC, pdbbox, isize, index); + sfree(bFactorX); } if (bAniso) { diff --git a/src/gromacs/gmxana/gmx_trjconv.cpp b/src/gromacs/gmxana/gmx_trjconv.cpp index d7769a8633..aa00fe498f 100644 --- a/src/gromacs/gmxana/gmx_trjconv.cpp +++ b/src/gromacs/gmxana/gmx_trjconv.cpp @@ -861,7 +861,7 @@ int gmx_trjconv(int argc, char *argv[]) FILE *out = NULL; t_trxstatus *trxout = NULL; t_trxstatus *trxin; - int ftp, ftpin = 0, file_nr; + int file_nr; t_trxframe fr, frout; int flags; rvec *xmem = NULL, *vmem = NULL, *fmem = NULL; @@ -1015,13 +1015,13 @@ int gmx_trjconv(int argc, char *argv[]) /* Determine output type */ out_file = opt2fn("-o", NFILE, fnm); - ftp = fn2ftp(out_file); + int ftp = fn2ftp(out_file); fprintf(stderr, "Will write %s: %s\n", ftp2ext(ftp), ftp2desc(ftp)); bNeedPrec = (ftp == efXTC || ftp == efGRO); + int ftpin = fn2ftp(in_file); if (bVels) { /* check if velocities are possible in input and output files */ - ftpin = fn2ftp(in_file); bVels = (ftp == efTRR || ftp == efGRO || ftp == efG96 || ftp == efTNG) && (ftpin == efTRR || ftpin == efGRO || diff --git a/src/gromacs/gmxana/gmx_tune_pme.cpp b/src/gromacs/gmxana/gmx_tune_pme.cpp index adf950b835..90dc653b1a 100644 --- a/src/gromacs/gmxana/gmx_tune_pme.cpp +++ b/src/gromacs/gmxana/gmx_tune_pme.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2009,2010,2011,2012,2013,2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2009,2010,2011,2012,2013,2014,2015,2016,2017, 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. @@ -2201,9 +2201,9 @@ int gmx_tune_pme(int argc, char *argv[]) real rcoulomb = -1.0; /* Coulomb radius as set in .tpr file */ gmx_bool bScaleRvdw = TRUE; gmx_int64_t bench_nsteps = BENCHSTEPS; - gmx_int64_t new_sim_nsteps = -1; /* -1 indicates: not set by the user */ - gmx_int64_t cpt_steps = 0; /* Step counter in .cpt input file */ - int presteps = 100; /* Do a full cycle reset after presteps steps */ + gmx_int64_t new_sim_nsteps = -1; /* -1 indicates: not set by the user */ + gmx_int64_t cpt_steps = 0; /* Step counter in .cpt input file */ + int presteps = 1500; /* Do a full cycle reset after presteps steps */ gmx_bool bOverwrite = FALSE, bKeepTPR; gmx_bool bLaunch = FALSE; char *ExtraArgs = NULL; diff --git a/src/gromacs/gmxana/gmx_vanhove.cpp b/src/gromacs/gmxana/gmx_vanhove.cpp index db3da07cff..0c660cc4b3 100644 --- a/src/gromacs/gmxana/gmx_vanhove.cpp +++ b/src/gromacs/gmxana/gmx_vanhove.cpp @@ -229,7 +229,7 @@ int gmx_vanhove(int argc, char *argv[]) dt = (time[nfr-1] - time[0])/(nfr - 1); /* Some ugly rounding to get nice nice times in the output */ - dt = static_cast((10000.0*dt + 0.5)/10000.0); + dt = std::round(10000.0*dt)/10000.0; invbin = 1.0/rbin; diff --git a/src/gromacs/gmxana/gmx_wham.cpp b/src/gromacs/gmxana/gmx_wham.cpp index a375cb4364..e3769e0823 100644 --- a/src/gromacs/gmxana/gmx_wham.cpp +++ b/src/gromacs/gmxana/gmx_wham.cpp @@ -3334,7 +3334,8 @@ int gmx_wham(int argc, char *argv[]) "Parallelization", "^^^^^^^^^^^^^^^", "", - "If available, the number of OpenMP threads used by gmx wham is controlled with [TT]-nt[tt].", + "If available, the number of OpenMP threads used by gmx wham can be controlled by setting", + "the [TT]OMP_NUM_THREADS[tt] environment variable.", "", "Autocorrelations", "^^^^^^^^^^^^^^^^", diff --git a/src/gromacs/gmxana/gmx_xpm2ps.cpp b/src/gromacs/gmxana/gmx_xpm2ps.cpp index 4eb173d1d7..49c46ba775 100644 --- a/src/gromacs/gmxana/gmx_xpm2ps.cpp +++ b/src/gromacs/gmxana/gmx_xpm2ps.cpp @@ -172,6 +172,8 @@ void get_params(const char *mpin, const char *mpout, t_psrec *psr) RTYPE("y-tickfontsize", psr->Y.tickfontsize, psr->X.tickfontsize); STYPE("y-tickfont", psr->Y.tickfont, psr->Y.font); + check_warning_error(wi, FARGS); + if (mpout != NULL) { write_inpfile(mpout, ninp, inp, TRUE, wi); diff --git a/src/gromacs/gmxpreprocess/grompp.cpp b/src/gromacs/gmxpreprocess/grompp.cpp index cd4ee3af4b..be33e421c5 100644 --- a/src/gromacs/gmxpreprocess/grompp.cpp +++ b/src/gromacs/gmxpreprocess/grompp.cpp @@ -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, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017, 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. @@ -73,6 +73,7 @@ #include "gromacs/math/vec.h" #include "gromacs/mdlib/calc_verletbuf.h" #include "gromacs/mdlib/compute_io.h" +#include "gromacs/mdlib/constr.h" #include "gromacs/mdlib/genborn.h" #include "gromacs/mdlib/perf_est.h" #include "gromacs/mdtypes/inputrec.h" @@ -1421,6 +1422,174 @@ static void checkForUnboundAtoms(const gmx_mtop_t *mtop, } } +/*! \brief Checks if there are decoupled modes in moleculetype \p molt. + * + * The specific decoupled modes this routine check for are angle modes + * where the two bonds are constrained and the atoms a both ends are only + * involved in a single constraint; the mass of the two atoms needs to + * differ by more than \p massFactorThreshold. + */ +static bool haveDecoupledModeInMol(const gmx_moltype_t *molt, + const t_iparams *iparams, + real massFactorThreshold) +{ + if (molt->ilist[F_CONSTR].nr == 0 && molt->ilist[F_CONSTRNC].nr == 0) + { + return false; + } + + const t_atom * atom = molt->atoms.atom; + + int numFlexibleConstraints; + t_blocka atomToConstraints = make_at2con(0, molt->atoms.nr, + molt->ilist, iparams, + FALSE, + &numFlexibleConstraints); + + bool haveDecoupledMode = false; + for (int ftype = 0; ftype < F_NRE; ftype++) + { + if (interaction_function[ftype].flags & IF_ATYPE) + { + const int nral = NRAL(ftype); + const t_ilist *il = &molt->ilist[ftype]; + for (int i = 0; i < il->nr; i += 1 + nral) + { + /* Here we check for the mass difference between the atoms + * at both ends of the angle, that the atoms at the ends have + * 1 contraint and the atom in the middle at least 3; we check + * that the 3 atoms are linked by constraints below. + * We check for at least three constraints for the middle atom, + * since with only the two bonds in the angle, we have 3-atom + * molecule, which has much more thermal exhange in this single + * angle mode than molecules with more atoms. + * Note that this check also catches molecules where more atoms + * are connected to one or more atoms in the angle, but by + * bond potentials instead of angles. But such cases will not + * occur in "normal" molecules and it doesn't hurt running + * those with higher accuracy settings as well. + */ + int a0 = il->iatoms[1 + i]; + int a1 = il->iatoms[1 + i + 1]; + int a2 = il->iatoms[1 + i + 2]; + if ((atom[a0].m > atom[a2].m*massFactorThreshold || + atom[a2].m > atom[a0].m*massFactorThreshold) && + atomToConstraints.index[a0 + 1] - atomToConstraints.index[a0] == 1 && + atomToConstraints.index[a2 + 1] - atomToConstraints.index[a2] == 1 && + atomToConstraints.index[a1 + 1] - atomToConstraints.index[a1] >= 3) + { + int constraint0 = atomToConstraints.a[atomToConstraints.index[a0]]; + int constraint2 = atomToConstraints.a[atomToConstraints.index[a2]]; + + bool foundAtom0 = false; + bool foundAtom2 = false; + for (int conIndex = atomToConstraints.index[a1]; conIndex < atomToConstraints.index[a1 + 1]; conIndex++) + { + if (atomToConstraints.a[conIndex] == constraint0) + { + foundAtom0 = true; + } + if (atomToConstraints.a[conIndex] == constraint2) + { + foundAtom2 = true; + } + } + if (foundAtom0 && foundAtom2) + { + haveDecoupledMode = true; + } + } + } + } + } + + done_blocka(&atomToConstraints); + + return haveDecoupledMode; +} + +/*! \brief Checks if the Verlet buffer and constraint accuracy is sufficient for decoupled dynamic modes. + * + * When decoupled modes are present and the accuray in insufficient, + * this routine issues a warning if the accuracy is insufficient. + */ +static void checkDecoupledModeAccuracy(const gmx_mtop_t *mtop, + const t_inputrec *ir, + warninp_t wi) +{ + /* We only have issues with decoupled modes with normal MD. + * With stochastic dynamics equipartitioning is enforced strongly. + */ + if (!EI_MD(ir->eI)) + { + return; + } + + /* When atoms of very different mass are involved in an angle potential + * and both bonds in the angle are constrained, the dynamic modes in such + * angles have very different periods and significant energy exchange + * takes several nanoseconds. Thus even a small amount of error in + * different algorithms can lead to violation of equipartitioning. + * The parameters below are mainly based on an all-atom chloroform model + * with all bonds constrained. Equipartitioning is off by more than 1% + * (need to run 5-10 ns) when the difference in mass between H and Cl + * is more than a factor 13 and the accuracy is less than the thresholds + * given below. This has been verified on some other molecules. + * + * Note that the buffer and shake parameters have unit length and + * energy/time, respectively, so they will "only" work correctly + * for atomistic force fields using MD units. + */ + const real massFactorThreshold = 13.0; + const real bufferToleranceThreshold = 1e-4; + const int lincsIterationThreshold = 2; + const int lincsOrderThreshold = 4; + const real shakeToleranceThreshold = 0.005*ir->delta_t; + + bool lincsWithSufficientTolerance = (ir->eConstrAlg == econtLINCS && ir->nLincsIter >= lincsIterationThreshold && ir->nProjOrder >= lincsOrderThreshold); + bool shakeWithSufficientTolerance = (ir->eConstrAlg == econtSHAKE && ir->shake_tol <= 1.1*shakeToleranceThreshold); + if (ir->cutoff_scheme == ecutsVERLET && + ir->verletbuf_tol <= 1.1*bufferToleranceThreshold && + (lincsWithSufficientTolerance || shakeWithSufficientTolerance)) + { + return; + } + + bool haveDecoupledMode = false; + for (int mt = 0; mt < mtop->nmoltype; mt++) + { + if (haveDecoupledModeInMol(&mtop->moltype[mt], mtop->ffparams.iparams, + massFactorThreshold)) + { + haveDecoupledMode = true; + } + } + + if (haveDecoupledMode) + { + char modeMessage[STRLEN]; + sprintf(modeMessage, "There are atoms at both ends of an angle, connected by constraints and with masses that differ by more than a factor of %g. This means that there are likely dynamic modes that are only very weakly coupled.", + massFactorThreshold); + char buf[STRLEN]; + if (ir->cutoff_scheme == ecutsVERLET) + { + sprintf(buf, "%s To ensure good equipartitioning, you need to either not use constraints on all bonds (but, if possible, only on bonds involving hydrogens) or use integrator = %s or decrease one or more tolerances: verlet-buffer-tolerance <= %g, LINCS iterations >= %d, LINCS order >= %d or SHAKE tolerance <= %g", + modeMessage, + ei_names[eiSD1], + bufferToleranceThreshold, + lincsIterationThreshold, lincsOrderThreshold, + shakeToleranceThreshold); + } + else + { + sprintf(buf, "%s To ensure good equipartitioning, we suggest to switch to the %s cutoff-scheme, since that allows for better control over the Verlet buffer size and thus over the energy drift.", + modeMessage, + ecutscheme_names[ecutsVERLET]); + } + warning(wi, buf); + } +} + static void set_verlet_buffer(const gmx_mtop_t *mtop, t_inputrec *ir, real buffer_temp, @@ -1889,6 +2058,8 @@ int gmx_grompp(int argc, char *argv[]) check_bonds_timestep(sys, ir->delta_t, wi); } + checkDecoupledModeAccuracy(sys, ir, wi); + if (EI_ENERGY_MINIMIZATION(ir->eI) && 0 == ir->nsteps) { warning_note(wi, "Zero-step energy minimization will alter the coordinates before calculating the energy. If you just want the energy of a single point, try zero-step MD (with unconstrained_start = yes). To do multiple single-point energy evaluations of different configurations of the same topology, use mdrun -rerun."); diff --git a/src/gromacs/gmxpreprocess/toppush.cpp b/src/gromacs/gmxpreprocess/toppush.cpp index a711e49c59..ddf0bc79f2 100644 --- a/src/gromacs/gmxpreprocess/toppush.cpp +++ b/src/gromacs/gmxpreprocess/toppush.cpp @@ -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, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017, 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. @@ -55,6 +55,7 @@ #include "gromacs/mdtypes/md_enums.h" #include "gromacs/topology/ifunc.h" #include "gromacs/topology/symtab.h" +#include "gromacs/utility/arrayref.h" #include "gromacs/utility/cstringutil.h" #include "gromacs/utility/fatalerror.h" #include "gromacs/utility/gmxassert.h" @@ -537,16 +538,22 @@ void push_at (t_symtab *symtab, gpp_atomtype_t at, t_bond_atomtype bat, sfree(param); } +//! Return whether the contents of \c a and \c b are the same, considering also reversed order. +template +static bool equalEitherForwardOrBackward(gmx::ConstArrayRef a, gmx::ConstArrayRef b) +{ + return (std::equal(a.begin(), a.end(), b.begin()) || + std::equal(a.begin(), a.end(), b.rbegin())); +} + static void push_bondtype(t_params * bt, - t_param * b, + const t_param * b, int nral, int ftype, gmx_bool bAllowRepeat, - char * line, + const char * line, warninp_t wi) { - int i, j; - gmx_bool bTest, bFound, bCont, bId; int nr = bt->nr; int nrfp = NRFP(ftype); char errbuf[STRLEN]; @@ -561,73 +568,93 @@ static void push_bondtype(t_params * bt, in this group. */ - bFound = FALSE; - bCont = FALSE; - + bool isContinuationOfBlock = false; if (bAllowRepeat && nr > 1) { - for (j = 0, bCont = TRUE; (j < nral); j++) + isContinuationOfBlock = true; + for (int j = 0; j < nral; j++) { - bCont = bCont && (b->a[j] == bt->param[nr-2].a[j]); + if (b->a[j] != bt->param[nr - 2].a[j]) + { + isContinuationOfBlock = false; + } } } /* Search for earlier duplicates if this entry was not a continuation from the previous line. */ - if (!bCont) - { - bFound = FALSE; - for (i = 0; (i < nr); i++) - { - bTest = TRUE; - for (j = 0; (j < nral); j++) + bool addBondType = true; + bool haveWarned = false; + bool haveErrored = false; + for (int i = 0; (i < nr); i++) + { + gmx::ConstArrayRef bParams(b->a, b->a + nral); + gmx::ConstArrayRef testParams(bt->param[i].a, bt->param[i].a + nral); + if (equalEitherForwardOrBackward(bParams, testParams)) + { + GMX_ASSERT(nrfp <= MAXFORCEPARAM, "This is ensured in other places, but we need this assert to keep the clang analyzer happy"); + // TODO consider improving the following code by using: + // bool identicalParameters = std::equal(bt->param[i].c, bt->param[i].c + nrfp, b->c); + bool identicalParameters = true; + for (int j = 0; (j < nrfp); j++) { - bTest = (bTest && (b->a[j] == bt->param[i].a[j])); + identicalParameters = identicalParameters && (bt->param[i].c[j] == b->c[j]); } - if (!bTest) + + if (!bAllowRepeat || identicalParameters) { - bTest = TRUE; - for (j = 0; (j < nral); j++) - { - bTest = (bTest && (b->a[nral-1-j] == bt->param[i].a[j])); - } + addBondType = false; } - if (bTest) + + if (!identicalParameters) { - if (!bFound) + if (bAllowRepeat) { - bId = TRUE; - for (j = 0; (j < nrfp); j++) + /* With dihedral type 9 we only allow for repeating + * of the same parameters with blocks with 1 entry. + * Allowing overriding is too complex to check. + */ + if (!isContinuationOfBlock && !haveErrored) { - bId = bId && (bt->param[i].c[j] == b->c[j]); + warning_error(wi, "Encountered a second block of parameters for dihedral type 9 for the same atoms, with either different parameters and/or the first block has multiple lines. This is not supported."); + haveErrored = true; } - if (!bId) + } + else if (!haveWarned) + { + sprintf(errbuf, "Overriding %s parameters.%s", + interaction_function[ftype].longname, + (ftype == F_PDIHS) ? + "\nUse dihedraltype 9 to allow several multiplicity terms. Only consecutive lines are combined. Non-consective lines overwrite each other." + : ""); + warning(wi, errbuf); + + fprintf(stderr, " old: "); + for (int j = 0; (j < nrfp); j++) { - sprintf(errbuf, "Overriding %s parameters.%s", - interaction_function[ftype].longname, - (ftype == F_PDIHS) ? - "\nUse dihedraltype 9 to allow several multiplicity terms. Only consecutive lines are combined. Non-consective lines overwrite each other." - : ""); - warning(wi, errbuf); - fprintf(stderr, " old: "); - for (j = 0; (j < nrfp); j++) - { - fprintf(stderr, " %g", bt->param[i].c[j]); - } - fprintf(stderr, " \n new: %s\n\n", line); + fprintf(stderr, " %g", bt->param[i].c[j]); } + fprintf(stderr, " \n new: %s\n\n", line); + + haveWarned = true; } - /* Overwrite it! */ - for (j = 0; (j < nrfp); j++) + } + + if (!identicalParameters && !bAllowRepeat) + { + /* Overwrite the parameters with the latest ones */ + // TODO considering improving the following code by replacing with: + // std::copy(b->c, b->c + nrfp, bt->param[i].c); + for (int j = 0; (j < nrfp); j++) { bt->param[i].c[j] = b->c[j]; } - bFound = TRUE; } } } - if (!bFound) + + if (addBondType) { /* alloc */ pr_alloc (2, bt); @@ -647,7 +674,7 @@ static void push_bondtype(t_params * bt, bt->param[bt->nr+1].c[2] = 1-bt->param[bt->nr+1].c[2]; } - for (j = 0; (j < nral); j++) + for (int j = 0; (j < nral); j++) { bt->param[bt->nr+1].a[j] = b->a[nral-1-j]; } diff --git a/src/gromacs/hardware/tests/cpuinfo.cpp b/src/gromacs/hardware/tests/cpuinfo.cpp index f7bc5d32ca..e90d83606b 100644 --- a/src/gromacs/hardware/tests/cpuinfo.cpp +++ b/src/gromacs/hardware/tests/cpuinfo.cpp @@ -68,7 +68,7 @@ TEST(CpuInfoTest, SupportLevel) EXPECT_GT(c.supportLevel(), gmx::CpuInfo::SupportLevel::None) << "No CPU information at all could be detected. " << commonMsg << std::endl; -#ifdef GMX_TARGET_X86 +#if GMX_TARGET_X86 EXPECT_GE(c.supportLevel(), gmx::CpuInfo::SupportLevel::Features) << "No CPU features could be detected. " << commonMsg << std::endl; #endif diff --git a/src/gromacs/listed-forces/listed-forces.cpp b/src/gromacs/listed-forces/listed-forces.cpp index d982384c84..e09f9e8ee7 100644 --- a/src/gromacs/listed-forces/listed-forces.cpp +++ b/src/gromacs/listed-forces/listed-forces.cpp @@ -91,6 +91,11 @@ isPairInteraction(int ftype) static void zero_thread_output(struct bonded_threading_t *bt, int thread) { + if (!bt->haveBondeds) + { + return; + } + f_thread_t *f_t = &bt->f_t[thread]; const int nelem_fa = sizeof(*f_t->f)/sizeof(real); @@ -198,6 +203,11 @@ reduce_thread_output(int n, rvec *f, rvec *fshift, gmx_bool bCalcEnerVir, gmx_bool bDHDL) { + if (!bt->haveBondeds) + { + return; + } + if (bt->nblock_used > 0) { /* Reduce the bonded force buffer */ @@ -482,6 +492,7 @@ void calc_listed(const t_commrec *cr, wallcycle_sub_stop(wcycle, ewcsRESTRAINTS); } + /* TODO: Skip this whole loop with a system/domain without listeds */ wallcycle_sub_start(wcycle, ewcsLISTED); #pragma omp parallel for num_threads(bt->nthreads) schedule(static) for (thread = 0; thread < bt->nthreads; thread++) diff --git a/src/gromacs/listed-forces/listed-internal.h b/src/gromacs/listed-forces/listed-internal.h index 7bd21c6949..dbf706d28b 100644 --- a/src/gromacs/listed-forces/listed-internal.h +++ b/src/gromacs/listed-forces/listed-internal.h @@ -84,6 +84,8 @@ struct bonded_threading_t gmx_bitmask_t *mask; /**< Mask array, one element corresponds to a block of reduction_block_size atoms of the force array, bit corresponding to thread indices set if a thread writes to that block */ int block_nalloc; /**< Allocation size of block_index and mask */ + bool haveBondeds; /**< true if we have and thus need to reduce bonded forces */ + /* There are two different ways to distribute the bonded force calculation * over the threads. We dedice which to use based on the number of threads. */ diff --git a/src/gromacs/listed-forces/manage-threading.cpp b/src/gromacs/listed-forces/manage-threading.cpp index 4e3642c14b..afc7e84c73 100644 --- a/src/gromacs/listed-forces/manage-threading.cpp +++ b/src/gromacs/listed-forces/manage-threading.cpp @@ -45,6 +45,8 @@ #include "manage-threading.h" +#include "config.h" + #include #include #include @@ -188,7 +190,8 @@ static void divide_bondeds_by_locality(int ntype, //! Divides bonded interactions over threads static void divide_bondeds_over_threads(t_idef *idef, int nthread, - int max_nthread_uniform) + int max_nthread_uniform, + bool *haveBondeds) { ilist_data_t ild[F_NRE]; int ntype; @@ -204,7 +207,8 @@ static void divide_bondeds_over_threads(t_idef *idef, snew(idef->il_thread_division, idef->il_thread_division_nalloc); } - ntype = 0; + *haveBondeds = false; + ntype = 0; for (f = 0; f < F_NRE; f++) { if (!ftype_is_bonded_potential(f)) @@ -212,6 +216,11 @@ static void divide_bondeds_over_threads(t_idef *idef, continue; } + if (idef->il[f].nr > 0) + { + *haveBondeds = true; + } + if (idef->il[f].nr == 0) { /* No interactions, avoid all the integer math below */ @@ -308,7 +317,16 @@ calc_bonded_reduction_mask(int natoms, const t_idef *idef, int thread, int nthread) { - assert(nthread <= BITMASK_SIZE); + static_assert(BITMASK_SIZE == GMX_OPENMP_MAX_THREADS, "For the error message below we assume these two are equal."); + + if (nthread > BITMASK_SIZE) + { +#pragma omp master + gmx_fatal(FARGS, "You are using %d OpenMP threads, which is larger than GMX_OPENMP_MAX_THREADS (%d). Decrease the number of OpenMP threads or rebuild GROMACS with a larger value for GMX_OPENMP_MAX_THREADS.", + nthread, GMX_OPENMP_MAX_THREADS); +#pragma omp barrier + } + GMX_ASSERT(nthread <= BITMASK_SIZE, "We need at least nthread bits in the mask"); int nblock = (natoms + reduction_block_size - 1) >> reduction_block_bits; @@ -374,7 +392,14 @@ void setup_bonded_threading(t_forcerec *fr, t_idef *idef) /* Divide the bonded interaction over the threads */ divide_bondeds_over_threads(idef, bt->nthreads, - bt->bonded_max_nthread_uniform); + bt->bonded_max_nthread_uniform, + &bt->haveBondeds); + + if (!bt->haveBondeds) + { + /* We don't have bondeds, so there is nothing to reduce */ + return; + } /* Determine to which blocks each thread's bonded force calculation * contributes. Store this as a mask for each thread. diff --git a/src/gromacs/mdlib/md_support.cpp b/src/gromacs/mdlib/md_support.cpp index 4ad4c7732b..2663e635d1 100644 --- a/src/gromacs/mdlib/md_support.cpp +++ b/src/gromacs/mdlib/md_support.cpp @@ -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, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017, 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. @@ -626,11 +626,11 @@ int check_nstglobalcomm(FILE *fplog, t_commrec *cr, } void rerun_parallel_comm(t_commrec *cr, t_trxframe *fr, - gmx_bool *bNotLastFrame) + gmx_bool *bLastStep) { rvec *xp, *vp; - if (MASTER(cr) && !*bNotLastFrame) + if (MASTER(cr) && *bLastStep) { fr->natoms = -1; } @@ -640,7 +640,7 @@ void rerun_parallel_comm(t_commrec *cr, t_trxframe *fr, fr->x = xp; fr->v = vp; - *bNotLastFrame = (fr->natoms >= 0); + *bLastStep = (fr->natoms < 0); } diff --git a/src/gromacs/mdlib/md_support.h b/src/gromacs/mdlib/md_support.h index ce594fc874..b2b8b25b8c 100644 --- a/src/gromacs/mdlib/md_support.h +++ b/src/gromacs/mdlib/md_support.h @@ -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, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017, 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. @@ -110,7 +110,7 @@ bool multisim_int_all_are_equal(const gmx_multisim_t *ms, gmx_int64_t value); void rerun_parallel_comm(t_commrec *cr, t_trxframe *fr, - gmx_bool *bNotLastFrame); + gmx_bool *bLastStep); /* get the conserved energy associated with the ensemble type*/ real compute_conserved_from_auxiliary(t_inputrec *ir, t_state *state, diff --git a/src/gromacs/mdlib/minimize.cpp b/src/gromacs/mdlib/minimize.cpp index 2d5290d4b9..dd00b95f1b 100644 --- a/src/gromacs/mdlib/minimize.cpp +++ b/src/gromacs/mdlib/minimize.cpp @@ -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, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017, 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. @@ -413,7 +413,6 @@ void init_em(FILE *fplog, const char *title, } atoms2md(top_global, ir, 0, NULL, top_global->natoms, mdatoms); - update_mdatoms(mdatoms, state_global->lambda[efptFEP]); if (vsite) { @@ -421,6 +420,8 @@ void init_em(FILE *fplog, const char *title, } } + update_mdatoms(mdatoms, state_global->lambda[efptMASS]); + if (constr) { if (ir->eConstrAlg == econtSHAKE && diff --git a/src/gromacs/mdlib/sim_util.cpp b/src/gromacs/mdlib/sim_util.cpp index 53e8c17dc0..cff9f1d14d 100644 --- a/src/gromacs/mdlib/sim_util.cpp +++ b/src/gromacs/mdlib/sim_util.cpp @@ -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, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017, 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. @@ -52,6 +52,7 @@ #include "gromacs/essentialdynamics/edsam.h" #include "gromacs/ewald/pme.h" #include "gromacs/gmxlib/chargegroup.h" +#include "gromacs/gmxlib/md_logging.h" #include "gromacs/gmxlib/network.h" #include "gromacs/gmxlib/nrnb.h" #include "gromacs/gmxlib/nonbonded/nb_free_energy.h" @@ -2577,6 +2578,13 @@ void finish_run(FILE *fplog, t_commrec *cr, elapsed_time_over_all_threads, elapsed_time_over_all_threads_over_all_ranks; + if (!walltime_accounting_get_valid_finish(walltime_accounting)) + { + md_print_warn(cr, fplog, + "Simulation ended prematurely, no performance report will be written."); + return; + } + if (cr->nnodes > 1) { snew(nrnb_tot, 1); diff --git a/src/gromacs/selection/compiler.cpp b/src/gromacs/selection/compiler.cpp index 2027a495fd..a5f9239677 100644 --- a/src/gromacs/selection/compiler.cpp +++ b/src/gromacs/selection/compiler.cpp @@ -2281,6 +2281,7 @@ analyze_static(gmx_sel_evaluate_t *data, if (sel->v.type == POS_VALUE) { alloc_selection_pos_data(sel); + gmx_ana_pos_copy(sel->v.u.p, sel->child->v.u.p, true); } else { diff --git a/src/gromacs/selection/scanner.cpp b/src/gromacs/selection/scanner.cpp index 3cdfb93e73..c16a479a67 100644 --- a/src/gromacs/selection/scanner.cpp +++ b/src/gromacs/selection/scanner.cpp @@ -19,8 +19,8 @@ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 37 +#define YY_FLEX_MINOR_VERSION 6 +#define YY_FLEX_SUBMINOR_VERSION 0 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif @@ -170,7 +170,15 @@ typedef void* yyscan_t; /* Size of default input buffer. */ #ifndef YY_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k. + * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. + * Ditto for the __ia64__ case accordingly. + */ +#define YY_BUF_SIZE 32768 +#else #define YY_BUF_SIZE 16384 +#endif /* __ia64__ */ #endif /* The state buf must be large enough to hold one state per character in the main buffer. @@ -192,6 +200,7 @@ typedef size_t yy_size_t; #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) + #define YY_LINENO_REWIND_TO(ptr) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ @@ -347,6 +356,9 @@ typedef int yy_state_type; static yy_state_type yy_get_previous_state (yyscan_t yyscanner ); static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner); static int yy_get_next_buffer (yyscan_t yyscanner ); +#if defined(__GNUC__) && __GNUC__ >= 3 +__attribute__((__noreturn__)) +#endif static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); /* Done after the current pattern has been matched and before the @@ -380,7 +392,7 @@ static yyconst flex_int16_t yy_accept[76] = 3, 3, 17, 9, 0 } ; -static yyconst flex_int32_t yy_ec[256] = +static yyconst YY_CHAR yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, @@ -412,7 +424,7 @@ static yyconst flex_int32_t yy_ec[256] = 1, 1, 1, 1, 1 } ; -static yyconst flex_int32_t yy_meta[33] = +static yyconst YY_CHAR yy_meta[33] = { 0, 1, 1, 2, 1, 1, 1, 1, 1, 3, 4, 1, 1, 1, 4, 4, 1, 4, 4, 4, 4, @@ -420,7 +432,7 @@ static yyconst flex_int32_t yy_meta[33] = 4, 1 } ; -static yyconst flex_int16_t yy_base[80] = +static yyconst flex_uint16_t yy_base[80] = { 0, 0, 0, 93, 92, 10, 12, 0, 0, 115, 118, 35, 37, 101, 37, 0, 106, 102, 35, 118, 98, @@ -444,7 +456,7 @@ static yyconst flex_int16_t yy_def[80] = 75, 75, 79, 79, 0, 75, 75, 75, 75 } ; -static yyconst flex_int16_t yy_nxt[151] = +static yyconst flex_uint16_t yy_nxt[151] = { 0, 10, 11, 12, 13, 14, 15, 16, 10, 17, 18, 19, 20, 21, 22, 22, 23, 24, 25, 22, 22, @@ -495,7 +507,7 @@ static yyconst flex_int16_t yy_chk[151] = /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2009,2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by + * Copyright (c) 2009,2010,2011,2012,2013,2014,2015,2016, 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. @@ -543,6 +555,7 @@ static yyconst flex_int16_t yy_chk[151] = #line 60 "scanner.l" #include "gromacs/utility/cstringutil.h" +#include "gromacs/utility/stringutil.h" #include "parser.h" #include "scanner.h" @@ -560,7 +573,7 @@ static yyconst flex_int16_t yy_chk[151] = -#line 564 "scanner.cpp" +#line 577 "scanner.cpp" #define INITIAL 0 #define matchof 1 @@ -634,11 +647,11 @@ void _gmx_sel_yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner ); FILE *_gmx_sel_yyget_in (yyscan_t yyscanner ); -void _gmx_sel_yyset_in (FILE * in_str ,yyscan_t yyscanner ); +void _gmx_sel_yyset_in (FILE * _in_str ,yyscan_t yyscanner ); FILE *_gmx_sel_yyget_out (yyscan_t yyscanner ); -void _gmx_sel_yyset_out (FILE * out_str ,yyscan_t yyscanner ); +void _gmx_sel_yyset_out (FILE * _out_str ,yyscan_t yyscanner ); yy_size_t _gmx_sel_yyget_leng (yyscan_t yyscanner ); @@ -646,11 +659,11 @@ char *_gmx_sel_yyget_text (yyscan_t yyscanner ); int _gmx_sel_yyget_lineno (yyscan_t yyscanner ); -void _gmx_sel_yyset_lineno (int line_number ,yyscan_t yyscanner ); +void _gmx_sel_yyset_lineno (int _line_number ,yyscan_t yyscanner ); int _gmx_sel_yyget_column (yyscan_t yyscanner ); -void _gmx_sel_yyset_column (int column_no ,yyscan_t yyscanner ); +void _gmx_sel_yyset_column (int _column_no ,yyscan_t yyscanner ); /* Macros after this point can all be overridden by user definitions in * section 1. @@ -664,8 +677,12 @@ extern int _gmx_sel_yywrap (yyscan_t yyscanner ); #endif #endif +#ifndef YY_NO_UNPUT + static void yyunput (int c,char *buf_ptr ,yyscan_t yyscanner); +#endif + #ifndef yytext_ptr static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner); #endif @@ -686,7 +703,12 @@ static int input (yyscan_t yyscanner ); /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k */ +#define YY_READ_BUF_SIZE 16384 +#else #define YY_READ_BUF_SIZE 8192 +#endif /* __ia64__ */ #endif /* Copy whatever the last rule matched to the standard output. */ @@ -773,7 +795,7 @@ extern int _gmx_sel_yylex (yyscan_t yyscanner); /* Code executed at the end of each rule. */ #ifndef YY_BREAK -#define YY_BREAK break; +#define YY_BREAK /*LINTED*/break; #endif #define YY_RULE_SETUP \ @@ -783,12 +805,39 @@ extern int _gmx_sel_yylex (yyscan_t yyscanner); */ YY_DECL { - register yy_state_type yy_current_state; - register char *yy_cp, *yy_bp; - register int yy_act; + yy_state_type yy_current_state; + char *yy_cp, *yy_bp; + int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; -#line 98 "scanner.l" + if ( !yyg->yy_init ) + { + yyg->yy_init = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! yyg->yy_start ) + yyg->yy_start = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + _gmx_sel_yyensure_buffer_stack (yyscanner); + YY_CURRENT_BUFFER_LVALUE = + _gmx_sel_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); + } + + _gmx_sel_yy_load_buffer_state(yyscanner ); + } + + { +#line 99 "scanner.l" @@ -822,35 +871,9 @@ YY_DECL } -#line 826 "scanner.cpp" +#line 875 "scanner.cpp" - if ( !yyg->yy_init ) - { - yyg->yy_init = 1; - -#ifdef YY_USER_INIT - YY_USER_INIT; -#endif - - if ( ! yyg->yy_start ) - yyg->yy_start = 1; /* first start state */ - - if ( ! yyin ) - yyin = stdin; - - if ( ! yyout ) - yyout = stdout; - - if ( ! YY_CURRENT_BUFFER ) { - _gmx_sel_yyensure_buffer_stack (yyscanner); - YY_CURRENT_BUFFER_LVALUE = - _gmx_sel_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); - } - - _gmx_sel_yy_load_buffer_state(yyscanner ); - } - - while ( 1 ) /* loops until end-of-file is reached */ + while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ { yy_cp = yyg->yy_c_buf_p; @@ -866,7 +889,7 @@ YY_DECL yy_match: do { - register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; @@ -903,38 +926,38 @@ YY_DECL case 1: YY_RULE_SETUP -#line 131 "scanner.l" +#line 132 "scanner.l" break; YY_BREAK case 2: YY_RULE_SETUP -#line 132 "scanner.l" +#line 133 "scanner.l" { yylval->i = strtol(yytext, NULL, 10); ADD_TOKEN; return TOK_INT; } YY_BREAK case 3: YY_RULE_SETUP -#line 133 "scanner.l" +#line 134 "scanner.l" { yylval->r = strtod(yytext, NULL); ADD_TOKEN; return TOK_REAL; } YY_BREAK case 4: YY_RULE_SETUP -#line 134 "scanner.l" +#line 135 "scanner.l" { yylval->str = gmx_strndup(yytext+1, yyleng-2); ADD_TOKEN; return STR; } YY_BREAK case 5: /* rule 5 can match eol */ YY_RULE_SETUP -#line 136 "scanner.l" +#line 137 "scanner.l" { _gmx_sel_lexer_add_token(yylloc, " ", 1, state); break; } YY_BREAK case 6: /* rule 6 can match eol */ YY_RULE_SETUP -#line 137 "scanner.l" +#line 138 "scanner.l" { if (yytext[0] == ';' || state->statusWriter != NULL) { - rtrim(state->pselstr); + state->pselstr = gmx::stripString(state->pselstr); state->bCmdStart = true; return CMD_SEP; } @@ -946,94 +969,94 @@ YY_RULE_SETUP } YY_BREAK case YY_STATE_EOF(cmdstart): -#line 151 "scanner.l" +#line 152 "scanner.l" { state->bCmdStart = true; yyterminate(); } YY_BREAK case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(matchof): case YY_STATE_EOF(matchbool): -#line 152 "scanner.l" +#line 153 "scanner.l" { state->bCmdStart = true; return CMD_SEP; } YY_BREAK case 7: YY_RULE_SETUP -#line 155 "scanner.l" +#line 156 "scanner.l" { ADD_TOKEN; yylval->i = 1; return TOK_INT; } YY_BREAK case 8: YY_RULE_SETUP -#line 156 "scanner.l" +#line 157 "scanner.l" { ADD_TOKEN; yylval->i = 0; return TOK_INT; } YY_BREAK case 9: YY_RULE_SETUP -#line 158 "scanner.l" +#line 159 "scanner.l" { ADD_TOKEN; return GROUP; } YY_BREAK case 10: YY_RULE_SETUP -#line 159 "scanner.l" +#line 160 "scanner.l" { ADD_TOKEN; return TO; } YY_BREAK case 11: YY_RULE_SETUP -#line 160 "scanner.l" +#line 161 "scanner.l" { ADD_TOKEN; BEGIN(0); return OF; } YY_BREAK case 12: YY_RULE_SETUP -#line 161 "scanner.l" +#line 162 "scanner.l" { ADD_TOKEN; return AND; } YY_BREAK case 13: YY_RULE_SETUP -#line 162 "scanner.l" +#line 163 "scanner.l" { ADD_TOKEN; return OR; } YY_BREAK case 14: YY_RULE_SETUP -#line 163 "scanner.l" +#line 164 "scanner.l" { ADD_TOKEN; return XOR; } YY_BREAK case 15: YY_RULE_SETUP -#line 164 "scanner.l" +#line 165 "scanner.l" { ADD_TOKEN; return NOT; } YY_BREAK case 16: YY_RULE_SETUP -#line 165 "scanner.l" +#line 166 "scanner.l" { yylval->str = gmx_strndup(yytext, yyleng); ADD_TOKEN; return CMP_OP; } YY_BREAK case 17: YY_RULE_SETUP -#line 167 "scanner.l" +#line 168 "scanner.l" { return _gmx_sel_lexer_process_identifier(yylval, yylloc, yytext, yyleng, state); } YY_BREAK case 18: /* rule 18 can match eol */ YY_RULE_SETUP -#line 169 "scanner.l" +#line 170 "scanner.l" { _gmx_sel_lexer_add_token(yylloc, " ", 1, state); break; } YY_BREAK case 19: YY_RULE_SETUP -#line 170 "scanner.l" +#line 171 "scanner.l" { yylval->str = gmx_strndup(yytext, yyleng); ADD_TOKEN; return STR; } YY_BREAK case 20: YY_RULE_SETUP -#line 171 "scanner.l" +#line 172 "scanner.l" { ADD_TOKEN; return yytext[0]; } YY_BREAK case 21: YY_RULE_SETUP -#line 172 "scanner.l" +#line 173 "scanner.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK -#line 1037 "scanner.cpp" +#line 1060 "scanner.cpp" case YY_END_OF_BUFFER: { @@ -1163,6 +1186,7 @@ YY_FATAL_ERROR( "flex scanner jammed" ); "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ + } /* end of user's declarations */ } /* end of _gmx_sel_yylex */ /* yy_get_next_buffer - try to read in a new buffer @@ -1175,9 +1199,9 @@ YY_FATAL_ERROR( "flex scanner jammed" ); static int yy_get_next_buffer (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; - register char *source = yyg->yytext_ptr; - register int number_to_move, i; + char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + char *source = yyg->yytext_ptr; + yy_size_t number_to_move, i; int ret_val; if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) @@ -1206,7 +1230,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) /* Try to read more data. */ /* First move last chars to start of buffer. */ - number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1; + number_to_move = (yy_size_t) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1; for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); @@ -1309,15 +1333,15 @@ static int yy_get_next_buffer (yyscan_t yyscanner) static yy_state_type yy_get_previous_state (yyscan_t yyscanner) { - register yy_state_type yy_current_state; - register char *yy_cp; + yy_state_type yy_current_state; + char *yy_cp; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_current_state = yyg->yy_start; for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp ) { - register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; @@ -1342,11 +1366,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner) */ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) { - register int yy_is_jam; + int yy_is_jam; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ - register char *yy_cp = yyg->yy_c_buf_p; + char *yy_cp = yyg->yy_c_buf_p; - register YY_CHAR yy_c = 1; + YY_CHAR yy_c = 1; if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; @@ -1365,9 +1389,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner) return yy_is_jam ? 0 : yy_current_state; } - static void yyunput (int c, register char * yy_bp , yyscan_t yyscanner) +#ifndef YY_NO_UNPUT + + static void yyunput (int c, char * yy_bp , yyscan_t yyscanner) { - register char *yy_cp; + char *yy_cp; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_cp = yyg->yy_c_buf_p; @@ -1378,10 +1404,10 @@ static int yy_get_next_buffer (yyscan_t yyscanner) if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ - register yy_size_t number_to_move = yyg->yy_n_chars + 2; - register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ + yy_size_t number_to_move = yyg->yy_n_chars + 2; + char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; - register char *source = + char *source = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) @@ -1403,6 +1429,8 @@ static int yy_get_next_buffer (yyscan_t yyscanner) yyg->yy_c_buf_p = yy_cp; } +#endif + #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (yyscan_t yyscanner) @@ -1556,7 +1584,7 @@ static void _gmx_sel_yy_load_buffer_state (yyscan_t yyscanner) if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in _gmx_sel_yy_create_buffer()" ); - b->yy_buf_size = size; + b->yy_buf_size = (yy_size_t)size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. @@ -1717,7 +1745,7 @@ static void _gmx_sel_yyensure_buffer_stack (yyscan_t yyscanner) * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ - num_to_alloc = 1; + num_to_alloc = 1; // After all that talk, this was set to 1 anyways... yyg->yy_buffer_stack = (struct yy_buffer_state**)_gmx_sel_yyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) , yyscanner); @@ -1734,7 +1762,7 @@ static void _gmx_sel_yyensure_buffer_stack (yyscan_t yyscanner) if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){ /* Increase the buffer to prepare for a possible push. */ - int grow_size = 8 /* arbitrary grow size */; + yy_size_t grow_size = 8 /* arbitrary grow size */; num_to_alloc = yyg->yy_buffer_stack_max + grow_size; yyg->yy_buffer_stack = (struct yy_buffer_state**)_gmx_sel_yyrealloc @@ -1842,7 +1870,9 @@ YY_BUFFER_STATE _gmx_sel_yy_scan_bytes (yyconst char * yybytes, yy_size_t _yyb static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner) { - (void) fprintf( stderr, "%s\n", msg ); + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + (void)yyg; + (void) fprintf( stderr, "%s\n", msg ); exit( YY_EXIT_FAILURE ); } @@ -1948,10 +1978,10 @@ void _gmx_sel_yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) } /** Set the current line number. - * @param line_number + * @param _line_number line number * @param yyscanner The scanner object. */ -void _gmx_sel_yyset_lineno (int line_number , yyscan_t yyscanner) +void _gmx_sel_yyset_lineno (int _line_number , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; @@ -1959,14 +1989,14 @@ void _gmx_sel_yyset_lineno (int line_number , yyscan_t yyscanner) if (! YY_CURRENT_BUFFER ) YY_FATAL_ERROR( "_gmx_sel_yyset_lineno called with no buffer" ); - yylineno = line_number; + yylineno = _line_number; } /** Set the current column. - * @param line_number + * @param _column_no column number * @param yyscanner The scanner object. */ -void _gmx_sel_yyset_column (int column_no , yyscan_t yyscanner) +void _gmx_sel_yyset_column (int _column_no , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; @@ -1974,25 +2004,25 @@ void _gmx_sel_yyset_column (int column_no , yyscan_t yyscanner) if (! YY_CURRENT_BUFFER ) YY_FATAL_ERROR( "_gmx_sel_yyset_column called with no buffer" ); - yycolumn = column_no; + yycolumn = _column_no; } /** Set the input stream. This does not discard the current * input buffer. - * @param in_str A readable stream. + * @param _in_str A readable stream. * @param yyscanner The scanner object. * @see _gmx_sel_yy_switch_to_buffer */ -void _gmx_sel_yyset_in (FILE * in_str , yyscan_t yyscanner) +void _gmx_sel_yyset_in (FILE * _in_str , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyin = in_str ; + yyin = _in_str ; } -void _gmx_sel_yyset_out (FILE * out_str , yyscan_t yyscanner) +void _gmx_sel_yyset_out (FILE * _out_str , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyout = out_str ; + yyout = _out_str ; } int _gmx_sel_yyget_debug (yyscan_t yyscanner) @@ -2001,10 +2031,10 @@ int _gmx_sel_yyget_debug (yyscan_t yyscanner) return yy_flex_debug; } -void _gmx_sel_yyset_debug (int bdebug , yyscan_t yyscanner) +void _gmx_sel_yyset_debug (int _bdebug , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yy_flex_debug = bdebug ; + yy_flex_debug = _bdebug ; } /* Accessor methods for yylval and yylloc */ @@ -2143,7 +2173,10 @@ int _gmx_sel_yylex_destroy (yyscan_t yyscanner) #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner) { - register int i; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + (void)yyg; + + int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } @@ -2152,7 +2185,7 @@ static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yysca #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) { - register int n; + int n; for ( n = 0; s[n]; ++n ) ; @@ -2162,11 +2195,16 @@ static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) void *_gmx_sel_yyalloc (yy_size_t size , yyscan_t yyscanner) { + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + (void)yyg; return (void *) malloc( size ); } void *_gmx_sel_yyrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner) { + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + (void)yyg; + /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter @@ -2179,9 +2217,11 @@ void *_gmx_sel_yyrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner) void _gmx_sel_yyfree (void * ptr , yyscan_t yyscanner) { + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + (void)yyg; free( (char *) ptr ); /* see _gmx_sel_yyrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" -#line 172 "scanner.l" +#line 173 "scanner.l" diff --git a/src/gromacs/selection/scanner.l b/src/gromacs/selection/scanner.l index d2d2fd97ec..2c03a33e42 100644 --- a/src/gromacs/selection/scanner.l +++ b/src/gromacs/selection/scanner.l @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2009,2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by + * Copyright (c) 2009,2010,2011,2012,2013,2014,2015,2016, 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. @@ -58,6 +58,7 @@ } %{ #include "gromacs/utility/cstringutil.h" +#include "gromacs/utility/stringutil.h" #include "parser.h" #include "scanner.h" @@ -137,7 +138,7 @@ COMMENT (#.*) ";"|\n { if (yytext[0] == ';' || state->statusWriter != NULL) { - rtrim(state->pselstr); + state->pselstr = gmx::stripString(state->pselstr); state->bCmdStart = true; return CMD_SEP; } diff --git a/src/gromacs/selection/scanner.patch b/src/gromacs/selection/scanner.patch index 8bf42639c2..50b6185de3 100644 --- a/src/gromacs/selection/scanner.patch +++ b/src/gromacs/selection/scanner.patch @@ -4,17 +4,8 @@ #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) --#define _gmx_sel_yywrap(yyscanner) 1 +-#define _gmx_sel_yywrap(yyscanner) (/*CONSTCOND*/1) +static inline int _gmx_sel_yywrap(yyscan_t yyscanner) { return 1; } #define YY_SKIP_YYWRAP typedef unsigned char YY_CHAR; -@@ -1807,7 +1807,7 @@ - YY_BUFFER_STATE b; - char *buf; - yy_size_t n; -- int i; -+ yy_size_t i; - - /* Get memory for full buffer, including space for trailing EOB's. */ - n = _yybytes_len + 2; diff --git a/src/gromacs/selection/scanner_flex.h b/src/gromacs/selection/scanner_flex.h index abad91858e..0e23931895 100644 --- a/src/gromacs/selection/scanner_flex.h +++ b/src/gromacs/selection/scanner_flex.h @@ -23,8 +23,8 @@ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 37 +#define YY_FLEX_MINOR_VERSION 6 +#define YY_FLEX_SUBMINOR_VERSION 0 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif @@ -143,7 +143,15 @@ typedef void* yyscan_t; /* Size of default input buffer. */ #ifndef YY_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k. + * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. + * Ditto for the __ia64__ case accordingly. + */ +#define YY_BUF_SIZE 32768 +#else #define YY_BUF_SIZE 16384 +#endif /* __ia64__ */ #endif #ifndef YY_TYPEDEF_YY_BUFFER_STATE @@ -223,7 +231,7 @@ void *_gmx_sel_yyalloc (yy_size_t ,yyscan_t yyscanner ); void *_gmx_sel_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner ); void _gmx_sel_yyfree (void * ,yyscan_t yyscanner ); -#define _gmx_sel_yywrap(yyscanner) 1 +#define _gmx_sel_yywrap(yyscanner) (/*CONSTCOND*/1) #define YY_SKIP_YYWRAP #define yytext_ptr yytext_r @@ -267,11 +275,11 @@ void _gmx_sel_yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner ); FILE *_gmx_sel_yyget_in (yyscan_t yyscanner ); -void _gmx_sel_yyset_in (FILE * in_str ,yyscan_t yyscanner ); +void _gmx_sel_yyset_in (FILE * _in_str ,yyscan_t yyscanner ); FILE *_gmx_sel_yyget_out (yyscan_t yyscanner ); -void _gmx_sel_yyset_out (FILE * out_str ,yyscan_t yyscanner ); +void _gmx_sel_yyset_out (FILE * _out_str ,yyscan_t yyscanner ); yy_size_t _gmx_sel_yyget_leng (yyscan_t yyscanner ); @@ -279,11 +287,11 @@ char *_gmx_sel_yyget_text (yyscan_t yyscanner ); int _gmx_sel_yyget_lineno (yyscan_t yyscanner ); -void _gmx_sel_yyset_lineno (int line_number ,yyscan_t yyscanner ); +void _gmx_sel_yyset_lineno (int _line_number ,yyscan_t yyscanner ); int _gmx_sel_yyget_column (yyscan_t yyscanner ); -void _gmx_sel_yyset_column (int column_no ,yyscan_t yyscanner ); +void _gmx_sel_yyset_column (int _column_no ,yyscan_t yyscanner ); /* Macros after this point can all be overridden by user definitions in * section 1. @@ -311,7 +319,12 @@ static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner); /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k */ +#define YY_READ_BUF_SIZE 16384 +#else #define YY_READ_BUF_SIZE 8192 +#endif /* __ia64__ */ #endif /* Number of entries by which start-condition stack grows. */ @@ -344,8 +357,8 @@ extern int _gmx_sel_yylex (yyscan_t yyscanner); #undef YY_DECL #endif -#line 172 "scanner.l" +#line 173 "scanner.l" -#line 350 "scanner_flex.h" +#line 363 "scanner_flex.h" #undef _gmx_sel_yyIN_HEADER #endif /* _gmx_sel_yyHEADER_H */ diff --git a/src/gromacs/selection/scanner_internal.cpp b/src/gromacs/selection/scanner_internal.cpp index 79d915f586..da23df0453 100644 --- a/src/gromacs/selection/scanner_internal.cpp +++ b/src/gromacs/selection/scanner_internal.cpp @@ -74,11 +74,6 @@ #include "selmethod.h" #include "symrec.h" -/*! \brief - * Step in which the allocated memory for pretty-printed input is incremented. - */ -#define STRSTORE_ALLOCSTEP 1000 - /* These are defined as macros in the generated scanner_flex.h. * We undefine them here to have them as variable names in the subroutines. * There are other ways of doing this, but this is probably the easiest. */ @@ -355,12 +350,12 @@ void _gmx_sel_lexer_add_token(YYLTYPE *yylloc, const char *str, int len, gmx_sel_lexer_t *state) { - yylloc->startIndex = yylloc->endIndex = state->pslen; + yylloc->startIndex = yylloc->endIndex = state->pselstr.size(); /* Do nothing if the string is empty, or if it is a space and there is * no other text yet, or if there already is a space. */ if (!str || len == 0 || strlen(str) == 0 || (str[0] == ' ' && str[1] == 0 - && (state->pslen == 0 || state->pselstr[state->pslen - 1] == ' '))) + && (state->pselstr.empty() || state->pselstr.back() == ' '))) { return; } @@ -368,18 +363,9 @@ _gmx_sel_lexer_add_token(YYLTYPE *yylloc, const char *str, int len, { len = strlen(str); } - /* Allocate more memory if necessary */ - if (state->nalloc_psel - state->pslen < len) - { - int incr = STRSTORE_ALLOCSTEP < len ? len : STRSTORE_ALLOCSTEP; - state->nalloc_psel += incr; - srenew(state->pselstr, state->nalloc_psel); - } /* Append the token to the stored string */ - strncpy(state->pselstr + state->pslen, str, len); - state->pslen += len; - state->pselstr[state->pslen] = 0; - yylloc->endIndex = state->pslen; + state->pselstr.append(str, len); + yylloc->endIndex = state->pselstr.size(); } void @@ -407,10 +393,6 @@ _gmx_sel_init_lexer(yyscan_t *scannerp, struct gmx_ana_selcollection_t *sc, state->statusWriter = statusWriter; - snew(state->pselstr, STRSTORE_ALLOCSTEP); - state->pselstr[0] = 0; - state->pslen = 0; - state->nalloc_psel = STRSTORE_ALLOCSTEP; state->currentLocation.startIndex = 0; state->currentLocation.endIndex = 0; @@ -435,7 +417,6 @@ _gmx_sel_free_lexer(yyscan_t scanner) { gmx_sel_lexer_t *state = _gmx_sel_yyget_extra(scanner); - sfree(state->pselstr); sfree(state->mstack); if (state->bBuffer) { @@ -504,7 +485,7 @@ const char * _gmx_sel_lexer_pselstr(yyscan_t scanner) { gmx_sel_lexer_t *state = _gmx_sel_yyget_extra(scanner); - return state->pselstr; + return state->pselstr.c_str(); } void @@ -540,15 +521,14 @@ _gmx_sel_lexer_get_text(yyscan_t scanner, { return std::string(); } - return std::string(&state->pselstr[startIndex], endIndex - startIndex); + return state->pselstr.substr(startIndex, endIndex - startIndex); } void _gmx_sel_lexer_clear_pselstr(yyscan_t scanner) { gmx_sel_lexer_t *state = _gmx_sel_yyget_extra(scanner); - state->pselstr[0] = 0; - state->pslen = 0; + state->pselstr.clear(); } void diff --git a/src/gromacs/selection/scanner_internal.h b/src/gromacs/selection/scanner_internal.h index 70173aeb8c..3a182f3fd5 100644 --- a/src/gromacs/selection/scanner_internal.h +++ b/src/gromacs/selection/scanner_internal.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2009,2010,2011,2012,2014,2015, by the GROMACS development team, led by + * Copyright (c) 2009,2010,2011,2012,2014,2015,2016, 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. @@ -42,6 +42,7 @@ #define SELECTION_SCANNER_INTERNAL_H #include +#include #include "parser.h" @@ -86,11 +87,7 @@ typedef struct gmx_sel_lexer_t gmx::TextWriter *statusWriter; //! Pretty-printed version of the string parsed since last clear. - char *pselstr; - //! Length of the string in \a pselstr. - int pslen; - //! Number of bytes allocated for \a pselstr. - int nalloc_psel; + std::string pselstr; /*! \brief * Position of the result of the current Bison action. * diff --git a/src/gromacs/selection/selhelp.cpp b/src/gromacs/selection/selhelp.cpp index 57887d8865..14220e28c2 100644 --- a/src/gromacs/selection/selhelp.cpp +++ b/src/gromacs/selection/selhelp.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2009,2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by + * Copyright (c) 2009,2010,2011,2012,2013,2014,2015,2016, 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. @@ -163,6 +163,23 @@ const char *const CmdLineHelpText::text[] = { " positions used in selecting atoms by coordinates.", "", "See the \"positions\" subtopic for more information on these options.", + "", + "Tools that take selections apply them to a structure/topology and/or", + "a trajectory file. If the tool takes both (typically as [TT]-s[tt]", + "for structure/topology and [TT]-f[tt] for trajectory), then the", + "trajectory file is only used for coordinate information, and all other", + "information, such as atom names and residue information, is read from", + "the structure/topology file. If the tool only takes a structure file,", + "or if only that input parameter is provided, then also the coordinates", + "are taken from that file.", + "For example, to select atoms from a [TT].pdb[tt]/[TT].gro[tt] file in", + "a tool that provides both options, pass it as [TT]-s[tt] (only).", + "There is no warning if the trajectory file specifies, e.g., different", + "atom names than the structure file. Only the number of atoms is checked.", + "Many selection-enabled tools also provide an [TT]-fgroup[tt] option", + "to specify the atom indices that are present in the trajectory for cases", + "where the trajectory only has a subset of atoms from the", + "topology/structure file." }; struct EvaluationHelpText diff --git a/src/gromacs/selection/sm_simple.cpp b/src/gromacs/selection/sm_simple.cpp index 8f7af415a9..ca384efd81 100644 --- a/src/gromacs/selection/sm_simple.cpp +++ b/src/gromacs/selection/sm_simple.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2009,2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by + * Copyright (c) 2009,2010,2011,2012,2013,2014,2015,2016, 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. @@ -196,6 +196,28 @@ static const char *const help_atomname[] = { "keywords." }; +//! Help title for residue index selection keywords. +static const char helptitle_resindex[] = "Selecting atoms by residue number"; +//! Help text for residue index selection keywords. +static const char *const help_resindex[] = { + "::", + "", + " resnr", + " resid", + " resindex", + " residue", + "", + "[TT]resnr[tt] selects atoms using the residue numbering in the input", + "file. [TT]resid[tt] is synonym for this keyword for VMD compatibility.", + "", + "[TT]resindex N[tt] selects the [TT]N[tt]th residue starting from the", + "beginning of the input file. This is useful for uniquely identifying", + "residues if there are duplicate numbers in the input file (e.g., in", + "multiple chains).", + "[TT]residue[tt] is a synonym for [TT]resindex[tt]. This allows", + "[TT]same residue as[tt] to work as expected." +}; + /** Selection method data for \p all selection keyword. */ gmx_ana_selmethod_t sm_all = { "all", GROUP_VALUE, 0, @@ -250,6 +272,7 @@ gmx_ana_selmethod_t sm_resnr = { NULL, &evaluate_resnr, NULL, + {NULL, helptitle_resindex, asize(help_resindex), help_resindex} }; /** Selection method data for \p resindex selection keyword. */ @@ -264,6 +287,7 @@ gmx_ana_selmethod_t sm_resindex = { NULL, &evaluate_resindex, NULL, + {NULL, helptitle_resindex, asize(help_resindex), help_resindex} }; /** Selection method data for \p molindex selection keyword. */ diff --git a/src/gromacs/selection/tests/refdata/SelectionCollectionDataTest_HandlesPositionVariableInModifier.xml b/src/gromacs/selection/tests/refdata/SelectionCollectionDataTest_HandlesPositionVariableInModifier.xml new file mode 100644 index 0000000000..6381ff5e07 --- /dev/null +++ b/src/gromacs/selection/tests/refdata/SelectionCollectionDataTest_HandlesPositionVariableInModifier.xml @@ -0,0 +1,101 @@ + + + + + + foo = cog of resnr 1 + + + cog of resnr 2 plus foo + cog of resnr 2 plus foo + false + + + cog of resnr 3 plus foo + cog of resnr 3 plus foo + false + + + + + + 6 + 3 + 4 + 5 + 0 + 1 + 2 + + + + + 6 + 6 + 7 + 8 + 0 + 1 + 2 + + + + + + + 6 + 3 + 4 + 5 + 0 + 1 + 2 + + + 2 + + + 1.6666666666666665 + 2.333333333333333 + 0 + + + + + 1 + 2 + 0 + + + + + + + 6 + 6 + 7 + 8 + 0 + 1 + 2 + + + 2 + + + 2.333333333333333 + 2.6666666666666665 + 0 + + + + + 1 + 2 + 0 + + + + + + diff --git a/src/gromacs/selection/tests/selectioncollection.cpp b/src/gromacs/selection/tests/selectioncollection.cpp index aca01954c5..34f59aabcd 100644 --- a/src/gromacs/selection/tests/selectioncollection.cpp +++ b/src/gromacs/selection/tests/selectioncollection.cpp @@ -1486,6 +1486,18 @@ TEST_F(SelectionCollectionDataTest, HandlesPositionVariables) } +TEST_F(SelectionCollectionDataTest, HandlesPositionVariableInModifier) +{ + static const char * const selections[] = { + "foo = cog of resnr 1", + "cog of resnr 2 plus foo", + "cog of resnr 3 plus foo" + }; + setFlags(TestFlags() | efTestEvaluation | efTestPositionCoordinates); + runTest("simple.gro", selections); +} + + TEST_F(SelectionCollectionDataTest, HandlesConstantPositionInVariable) { static const char * const selections[] = { diff --git a/src/gromacs/timing/walltime_accounting.cpp b/src/gromacs/timing/walltime_accounting.cpp index bfcbf1d294..eeb199eded 100644 --- a/src/gromacs/timing/walltime_accounting.cpp +++ b/src/gromacs/timing/walltime_accounting.cpp @@ -2,7 +2,7 @@ * This file is part of the GROMACS molecular simulation package. * * Copyright (c) 2013, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017, 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. @@ -86,6 +86,8 @@ typedef struct gmx_walltime_accounting { int numOpenMPThreads; //! Set by integrators to report the amount of work they did gmx_int64_t nsteps_done; + //! Whether the simulation has finished in a way valid for walltime reporting. + bool isValidFinish; } t_gmx_walltime_accounting; /*! \brief Calls system timing routines (e.g. clock_gettime) to get @@ -116,6 +118,7 @@ walltime_accounting_init(int numOpenMPThreads) walltime_accounting->elapsed_time = 0; walltime_accounting->nsteps_done = 0; walltime_accounting->numOpenMPThreads = numOpenMPThreads; + walltime_accounting->isValidFinish = false; return walltime_accounting; } @@ -229,6 +232,19 @@ gmx_gettime() #endif } +void +walltime_accounting_set_valid_finish(gmx_walltime_accounting_t walltime_accounting) +{ + walltime_accounting->isValidFinish = true; +} + +//! Return whether the simulation finished in a way valid for reporting walltime. +bool +walltime_accounting_get_valid_finish(const gmx_walltime_accounting_t walltime_accounting) +{ + return walltime_accounting->isValidFinish; +} + static double gmx_gettime_per_thread() { diff --git a/src/gromacs/timing/walltime_accounting.h b/src/gromacs/timing/walltime_accounting.h index fe1767fe2c..41f4df888a 100644 --- a/src/gromacs/timing/walltime_accounting.h +++ b/src/gromacs/timing/walltime_accounting.h @@ -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, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2017, 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. @@ -102,6 +102,14 @@ void walltime_accounting_set_nsteps_done(gmx_walltime_accounting_t walltime_accounting, gmx_int64_t nsteps_done); +//! Record that the simulation finished in a way valid for reporting walltime. +void +walltime_accounting_set_valid_finish(gmx_walltime_accounting_t walltime_accounting); + +//! Return whether the simulation finished in a way valid for reporting walltime. +bool +walltime_accounting_get_valid_finish(const gmx_walltime_accounting_t walltime_accounting); + /*! \brief * Calls system timing routines (e.g. clock_gettime) to get the (fractional) * number of seconds elapsed since the epoch. diff --git a/src/gromacs/tools/dump.cpp b/src/gromacs/tools/dump.cpp index 432127302e..9ddd8ec035 100644 --- a/src/gromacs/tools/dump.cpp +++ b/src/gromacs/tools/dump.cpp @@ -346,6 +346,7 @@ static void list_tng(const char gmx_unused *fn) gmx_int64_t nframe = 0; gmx_int64_t i, *block_ids = NULL, step, ndatablocks; gmx_bool bOK; + real *values = NULL; gmx_tng_open(fn, 'r', &tng); gmx_print_tng_molecule_system(tng, stdout); @@ -360,7 +361,7 @@ static void list_tng(const char gmx_unused *fn) for (i = 0; i < ndatablocks; i++) { double frame_time; - real prec, *values = NULL; + real prec; gmx_int64_t n_values_per_frame, n_atoms; char block_name[STRLEN]; @@ -394,7 +395,7 @@ static void list_tng(const char gmx_unused *fn) { sfree(block_ids); } - + sfree(values); gmx_tng_close(&tng); #endif } diff --git a/src/gromacs/utility/arrayref.h b/src/gromacs/utility/arrayref.h index ccf6e5e9d0..5522d34556 100644 --- a/src/gromacs/utility/arrayref.h +++ b/src/gromacs/utility/arrayref.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2017, 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. @@ -253,13 +253,13 @@ class ArrayRef //! Returns an iterator to the end of the container. const_iterator end() const { return end_; } //! Returns an iterator to the reverse beginning of the container. - iterator rbegin() { return reverse_iterator(end()); } + reverse_iterator rbegin() { return reverse_iterator(end()); } //! Returns an iterator to the reverse beginning of the container. - const_iterator rbegin() const { return reverse_iterator(end()); } + const_reverse_iterator rbegin() const { return reverse_iterator(end()); } //! Returns an iterator to the reverse end of the container. - iterator rend() { return reverse_iterator(begin()); } + reverse_iterator rend() { return reverse_iterator(begin()); } //! Returns an iterator to the reverse end of the container. - const_iterator rend() const { return reverse_iterator(begin()); } + const_reverse_iterator rend() const { return reverse_iterator(begin()); } //! Returns the size of the container. size_type size() const { return end_ - begin_; } @@ -478,9 +478,9 @@ class ConstArrayRef //! Returns an iterator to the end of the container. const_iterator end() const { return end_; } //! Returns an iterator to the reverse beginning of the container. - const_iterator rbegin() const { return reverse_iterator(end()); } + const_reverse_iterator rbegin() const { return reverse_iterator(end()); } //! Returns an iterator to the reverse end of the container. - const_iterator rend() const { return reverse_iterator(begin()); } + const_reverse_iterator rend() const { return reverse_iterator(begin()); } //! Returns the size of the container. size_type size() const { return end_ - begin_; } diff --git a/src/programs/mdrun/md.cpp b/src/programs/mdrun/md.cpp index 0d8ee9b9e2..34bbd5e2b9 100644 --- a/src/programs/mdrun/md.cpp +++ b/src/programs/mdrun/md.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2011,2012,2013,2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2011,2012,2013,2014,2015,2016,2017, 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. @@ -1848,6 +1848,12 @@ double gmx::do_md(FILE *fplog, t_commrec *cr, int nfile, const t_filenm fnm[], IMD_finalize(ir->bIMD, ir->imd); walltime_accounting_set_nsteps_done(walltime_accounting, step_rel); + if (step_rel >= wcycle_get_reset_counters(wcycle) && + signals[eglsRESETCOUNTERS].set == 0 && + !bResetCountersHalfMaxH) + { + walltime_accounting_set_valid_finish(walltime_accounting); + } return 0; } diff --git a/src/programs/mdrun/membed.cpp b/src/programs/mdrun/membed.cpp index f7f47d9b93..cab4835715 100644 --- a/src/programs/mdrun/membed.cpp +++ b/src/programs/mdrun/membed.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by + * Copyright (c) 2010,2011,2012,2013,2014,2015,2016, 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. @@ -234,8 +234,9 @@ static void get_input(const char *membed_input, real *xy_fac, real *xy_max, real ITYPE ("maxwarn", *maxwarn, 0); ITYPE ("pieces", *pieces, 1); EETYPE("asymmetry", *bALLOW_ASYMMETRY, yesno_names); - + check_warning_error(wi, FARGS); write_inpfile(membed_input, ninp, inp, FALSE, wi); + done_warning(wi, FARGS); } /* Obtain the maximum and minimum coordinates of the group to be embedded */ @@ -1113,7 +1114,7 @@ gmx_membed_t *init_membed(FILE *fplog, int nfile, const t_filenm fnm[], gmx_mtop if (xy_fac < min_xy_init) { warn++; - fprintf(stderr, "\nWarning %d:\nThe initial size of %s is probably too smal.\n\n", warn, ins); + fprintf(stderr, "\nWarning %d:\nThe initial size of %s is probably too small.\n\n", warn, ins); } if (it_xy < min_it_xy)