From: Roland Schulz Date: Sat, 16 Aug 2014 04:30:10 +0000 (-0400) Subject: Merge release-5-0 into master X-Git-Url: http://biod.pnpi.spb.ru/gitweb/?a=commitdiff_plain;h=e3d1a2232511301142cebe889d5b10dc21d0d653;p=alexxy%2Fgromacs.git Merge release-5-0 into master Conflicts (trivial): src/gromacs/commandline/pargs.cpp src/gromacs/gmxlib/gmx_thread_affinity.c src/gromacs/options/filenameoption.cpp Manual changes required for ConstArrayRef: src/gromacs/commandline/pargs.cpp src/gromacs/options/filenameoption.cpp src/gromacs/selection/selection.cpp src/gromacs/selection/tests/nbsearch.cpp Manual moved REGRESSIONTEST_MD5SUM from CMakeLists.txt to cmake/gmxVersionInfo.cmake Change-Id: I1a2038f72c1e1cfed830de5c540ab278dbb39cfe --- e3d1a2232511301142cebe889d5b10dc21d0d653 diff --cc cmake/gmxVersionInfo.cmake index 3e6ed3fc63,0000000000..7b8d08402f mode 100644,000000..100644 --- a/cmake/gmxVersionInfo.cmake +++ b/cmake/gmxVersionInfo.cmake @@@ -1,408 -1,0 +1,412 @@@ +# +# This file is part of the GROMACS molecular simulation package. +# +# Copyright (c) 2014, 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. + +# Sets version information variables and provides CMake functions for +# generating files based on them +# +# This script provides the following basic version variables that need to be +# maintained manually: +# GMX_VERSION_MAJOR Major version number. +# GMX_VERSION_MINOR Minor version number. +# GMX_VERSION_PATCH Patch version number. +# Should always be defined: zero for, e.g., 5.0. +# GMX_VERSION_SUFFIX String suffix to add to numeric version string. +# "-dev" is automatically added when not building from a source package, +# and does not need to be kept here. +# LIBRARY_SOVERSION so version for the built libraries. +# Should be increased for each binary incompatible release (in GROMACS, +# the typical policy is to increase it for each major/minor version +# change, but not for patch releases, even if the latter may not always +# be fully binary compatible). +# LIBRARY_VERSION Full library version. +# REGRESSIONTEST_BRANCH For builds not from source packages, name of the +# regressiontests branch at gerrit.gromacs.org whose HEAD can test this +# code, *if* this code is recent enough (i.e., contains all changes from +# the corresponding code branch that affects the regression test +# results). ++# REGRESSIONTEST_MD5SUM ++# The MD5 checksum of the regressiontest tarball. Only used when building ++# from a source package. +# They are collected into a single section below. +# The following variables are set based on these: +# GMX_VERSION String composed from GMX_VERSION_* numeric variables +# above. Example: 4.6.1, 5.0 +# GMX_VERSION_STRING String with GMX_VERSION suffixed with the given +# suffix and possibly "-dev" for builds not from a source package. +# GMX_VERSION_NUMERIC Numeric version number (e.g., 40601 for 4.6.1). +# GMX_API_VERSION Numeric API version. +# This is currently set automatically to GMX_VERSION_NUMERIC, but may +# become manually maintained in the future if there will be releases +# where the API does not change, but programs/libraries do. +# In such a case, this should be the first version where the current API +# appeared. +# REGRESSIONTEST_VERSION For source packages, version number of the +# matching regressiontests tarball. Not used for builds not from source +# packages. +# The latter two are used to generate gromacs/version.h to allow software +# written against the GROMACS API to provide some #ifdef'ed code to support +# multiple GROMACS versions. +# +# The following variables are defined without manual intervention: +# SOURCE_IS_SOURCE_DISTRIBUTION The source tree is from a source tarball. +# SOURCE_IS_GIT_REPOSITORY The source tree is a git repository. +# Note that both can be false if the tree has been extracted, e.g., as a +# tarball directly from git. +# +# This script also declares machinery to generate and obtain version +# information from a git repository. This is enabled by default if the source +# tree is a git, but can be disabled with +# GMX_GIT_VERSION_INFO Advanced CMake variable to disable git +# version info generation. +# The main interface to this machinery is the gmx_configure_version_file() +# CMake function. The signature is +# gmx_configure_version_file( +# [REMOTE_HASH] [SOURCE_FILE] +# [TARGET ] +# [COMMENT ]) +# Specify the input and output files as for configure_file(). +# The configuration is done with configure_file(... @ONLY) with +# the following variables defined (as well as all the +# GMX_VERSION* variables from above): +# GMX_VERSION_STRING_FULL +# GMX_VERSION_FULL_HASH +# GMX_VERSION_CENTRAL_BASE_HASH +# The output file is created during build time, so any dependent +# targets should specify it as a dependency. +# REMOTE_HASH Currently, this has no effect, but it signifies that the +# file is using the CENTRAL_BASE_HASH variable. +# This variable is much more expensive to initialize than the +# others, so this allows local changes in this file to only +# compute that value when required if that becomes necessary. +# SOURCE_FILE Signals that will be used as a source file. +# The function will set properties for the source file +# appropriately to signify that it is generated. +# TARGET By default, this function uses add_custom_command() to +# generate the output file. If TARGET is specified, then +# add_custom_target() is used to create a target with the given +# name that runs this custom command. Use this if +# the same file will be used for multiple downstream targets, +# or if the explicit target for the file is otherwise +# necessary. +# COMMENT Set a custom comment to be shown when building the rule +# (see add_custom_command(... COMMENT )). +# As an alternative to using this script, also the following variables are +# provided (can be useful when generating more complex CMake scripts that do +# build-time tasks): +# VERSION_INFO_CMAKE_SCRIPT +# Absolute path to a CMake script that can be included using include() +# to declare the GMX_VERSION_* variables documented for +# gmx_configure_version_file(). +# VERSION_INFO_DEPS +# If a custom command depends on VERSION_INFO_CMAKE_SCRIPT, then it +# should add ${VERSION_INFO_DEPS} to its DEPENDS list to get the +# appropriate dependencies. +# TODO: If someone wants to add a custom target that depends on +# VERSION_INFO_CMAKE_SCRIPT, a separate variable may be needed for those +# dependencies. +# +# The version string printed by 'gmx -version' (and also printed in the startup +# header) can provide useful information for, e.g., diagnosing bug reports and +# identifying what exact version the user was using. The following formats are +# possible (with examples given for a particular version): +# 4.6.1 Plain version number without any suffix signifies a build from +# a released source tarball. +# 4.6.1-dev '-dev' suffix signifies all other builds. If there is no other +# information, either the user built the code outside any git +# repository, or disabled the version info generation. +# 4.6.1-dev-YYYYMMDD-1234abc +# The YYYYMMDD part shows the commit date (not author date) of +# the HEAD commit from which the code was built. The abbreviated +# hash is the hash of that commit (the full hash is available in +# 'gmx -version' output). +# If the HEAD hash is not identified as coming from branches in +# "authoritative" GROMACS repositories, 'gmx -version' will show +# the nearest ancestor commit that is identified as such (but see +# the '-local' and '-unknown' suffixes below). +# 4.6.1-dev-YYYYMMDD-1234abc-dirty +# As above, but there were local modifications in the source tree +# when the code was built. +# 4.6.1-dev-YYYYMMDD-1234abc-unknown +# As above, but there were no remotes in the repository that +# could be identified as "authoritative" GROMACS repositories. +# This happens if the code is not cloned from git.gromacs.org +# or gerrit.gromacs.org. +# 4.6.1-dev-YYYYMMDD-1234abc-local +# As above, but there were no commits in the recent history of +# the branch that could be identified as coming from +# "authoritative" GROMACS repositories. This should be +# relatively rare. +# +# Other variables set here are not intended for use outside this file. +# The scripts gmxGenerateVersionInfo.cmake and gmxConfigureVersionInfo.cmake +# are used internally by this machinery, as well as VersionInfo.cmake.cmakein. + +##################################################################### +# Basic nature of the source tree + +set(SOURCE_IS_GIT_REPOSITORY OFF) +set(SOURCE_IS_SOURCE_DISTRIBUTION OFF) +if (EXISTS "${PROJECT_SOURCE_DIR}/.git") + set(SOURCE_IS_GIT_REPOSITORY ON) +endif() +# This file is excluded from CPack source packages, but part of the repository, +# so it should get included everywhere else. +if (NOT EXISTS "${PROJECT_SOURCE_DIR}/admin/.isreposource") + set(SOURCE_IS_SOURCE_DISTRIBUTION ON) +endif() + +##################################################################### +# Manually maintained version info + +# 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 5) +set(GMX_VERSION_MINOR 1) +set(GMX_VERSION_PATCH 0) +# The suffix, on the other hand, is used mainly for betas and release +# candidates, where it signifies the last such release from this branch; +# it will be empty before the first such release, as well as after the +# final release is out. +set(GMX_VERSION_SUFFIX "") + +set(LIBRARY_SOVERSION 1) +set(LIBRARY_VERSION ${LIBRARY_SOVERSION}.0.0) + +set(REGRESSIONTEST_BRANCH "refs/heads/master") ++set(REGRESSIONTEST_MD5SUM "a07524afebca5013540d4f2f72df2dce") + +##################################################################### +# General version management based on manually set numbers + +if (GMX_VERSION_PATCH) + set(GMX_VERSION "${GMX_VERSION_MAJOR}.${GMX_VERSION_MINOR}.${GMX_VERSION_PATCH}") +else() + set(GMX_VERSION "${GMX_VERSION_MAJOR}.${GMX_VERSION_MINOR}") +endif() +set(GMX_VERSION_STRING "${GMX_VERSION}${GMX_VERSION_SUFFIX}") +if (NOT SOURCE_IS_SOURCE_DISTRIBUTION) + set(GMX_VERSION_STRING "${GMX_VERSION_STRING}-dev") +endif() + +set(REGRESSIONTEST_VERSION "${GMX_VERSION_STRING}") + +math(EXPR GMX_VERSION_NUMERIC + "${GMX_VERSION_MAJOR}*10000 + ${GMX_VERSION_MINOR}*100 + ${GMX_VERSION_PATCH}") +set(GMX_API_VERSION ${NUM_VERSION}) + +##################################################################### +# git version info management + +# There can be clusters where git and CMake can run on nodes where the other is +# not available, accessing the same source tree. +# Should be unlikely, but doesn't hurt to check. +set(_git_info_default OFF) +if (SOURCE_IS_GIT_REPOSITORY) + find_package(Git) + if (GIT_FOUND) + set(_git_info_default ON) + endif() +endif() +option(GMX_GIT_VERSION_INFO "Generate git version information" ${_git_info_default}) +mark_as_advanced(GMX_GIT_VERSION_INFO) +# Detect preconditions for version info generation if it is requested. +if (GMX_GIT_VERSION_INFO) + if (NOT SOURCE_IS_GIT_REPOSITORY) + message(FATAL_ERROR + "Cannot generate git version information from source tree not under git. " + "Set GMX_GIT_VERSION_INFO=OFF to proceed.") + endif() + # We need at least git v1.5.3 be able to parse git's date output. + if (NOT GIT_FOUND OR GIT_VERSION_STRING VERSION_LESS "1.5.3") + message(FATAL_ERROR + "No compatible git version found (>= 1.5.3 required). " + "Won't be able to generate development version information. " + "Set GMX_GIT_VERSION_INFO=OFF to proceed.") + endif() +endif() + +# The first two are also for use outside this file, encapsulating the details +# of how to use the generated VersionInfo.cmake. +set(VERSION_INFO_CMAKE_FILE ${PROJECT_BINARY_DIR}/VersionInfo.cmake) +set(VERSION_INFO_DEPS ${VERSION_INFO_CMAKE_FILE}) +# Capture the location of the necessary files in internal variables for use in +# the function below. +set(VERSION_INFO_CMAKEIN_FILE ${CMAKE_CURRENT_LIST_DIR}/VersionInfo.cmake.cmakein) +set(VERSION_INFO_CONFIGURE_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/gmxConfigureVersionInfo.cmake) + +# Rules to create the VersionInfo.cmake file. +# For git info, the sequence is: +# 1. (configure time) VersionInfo.cmake.cmakein -> VersionInfo-partial.cmake.cmakein +# - Set all variables that are known at configure time. +# 2. (build time) VersionInfo-partial.cmake.cmakein -> VersionInfo.cmake +# - Set variables that may change as result of repository state changes +# (i.e., everything that requires running git). +# - Runs every time as a git-version-info target, but the output file +# timestamp only changes if its contents actually change. +# - Depending on the native build system, this may run once per build +# or once per each time it is required for step 3. +# 3. (build time) VersionInfo.cmake -> other files +# - Set variables in files specified with gmx_configure_version_file() +# using the values generated in step 2. +# - Each file runs as a custom command that depends on the previous +# steps, and runs only if the VersionInfo.cmake file is newer than the +# output file. +# Without git info, the sequence is: +# 1. (configure time) VersionInfo.cmake.cmakein -> VersionInfo.cmake +# - Everything is known at configure time, so the output is generated +# immediately with all variables set (git info will be empty). +# 2. (build time) VersionInfo.cmake -> other files +# - As with git info, processes files from gmx_configure_version_file(). +# - These are again custom commands that depend on the output from +# step 1, so they get regenerated only when the static version info +# changes. +if (GMX_GIT_VERSION_INFO) + # Configure information known at this time into a partially filled + # version info file. + set(VERSION_INFO_CMAKEIN_FILE_PARTIAL + ${PROJECT_BINARY_DIR}/VersionInfo-partial.cmake.cmakein) + # Leave these to be substituted by the custom target below. + set(GMX_VERSION_STRING_FULL "\@GMX_VERSION_STRING_FULL\@") + set(GMX_VERSION_FULL_HASH "\@GMX_VERSION_FULL_HASH\@") + set(GMX_VERSION_CENTRAL_BASE_HASH "\@GMX_VERSION_CENTRAL_BASE_HASH\@") + configure_file(${VERSION_INFO_CMAKEIN_FILE} + ${VERSION_INFO_CMAKEIN_FILE_PARTIAL} + @ONLY) + # If generating the version info, create a target that runs on every build + # and does the actual git calls, storing the results into a CMake script. + # This needs to be run at build time to update the version information + # properly when the git hash changes, but the build system does not. + # All targets added by gmx_configure_version_file() use the information + # from this script to get their variables from, removing the need to run + # git multiple times and simplifying reuse for other purposes. + # + # Ninja requires all generated files mentioned in dependencies of custom + # commands (in gmx_configure_version_info()) to be actually mentioned in + # the build system, and luckily add_custom_command() makes that possible. + # But it seems impossible to create a robust custom command that would be + # always run, so other generators that do not have this constraint simply + # use an add_custom_target(). + if (CMAKE_GENERATOR STREQUAL "Ninja") + # The second, phony file is never created, so the rule is always + # triggered again. TODO: Figure out why this works, even though ninja + # very eagerly complains about missing files. + # This unfortunately does not work with the make generator, as + # the non-existent second file causes some part of the generated system + # erase the first file at the beginning of every build, causing a full + # rebuild of the dependencies. + add_custom_command(OUTPUT ${VERSION_INFO_CMAKE_FILE} git-version-phony + COMMAND ${CMAKE_COMMAND} + -D GIT_EXECUTABLE=${GIT_EXECUTABLE} + -D PROJECT_VERSION=${GMX_VERSION_STRING} + -D PROJECT_SOURCE_DIR=${PROJECT_SOURCE_DIR} + -D VERSION_CMAKEIN=${VERSION_INFO_CMAKEIN_FILE_PARTIAL} + -D VERSION_OUT=${VERSION_INFO_CMAKE_FILE} + -P ${CMAKE_CURRENT_LIST_DIR}/gmxGenerateVersionInfo.cmake + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + COMMENT "Generating git version information" + VERBATIM) + # The generated Ninja build system would probably work fine even + # without this target, but CMake requires all custom commands to belong + # to a target in the same CMakeLists.txt to generate anything for them. + add_custom_target(git-version-info DEPENDS ${VERSION_INFO_CMAKE_FILE}) + else() + # For other generators, a target-level dependency on git-version-info + # ensures that VERSION_INFO_CMAKE_FILE is created before the dependent + # target's dependencies are even evaluated. + add_custom_target(git-version-info + COMMAND ${CMAKE_COMMAND} + -D GIT_EXECUTABLE=${GIT_EXECUTABLE} + -D PROJECT_VERSION=${GMX_VERSION_STRING} + -D PROJECT_SOURCE_DIR=${PROJECT_SOURCE_DIR} + -D VERSION_CMAKEIN=${VERSION_INFO_CMAKEIN_FILE_PARTIAL} + -D VERSION_OUT=${VERSION_INFO_CMAKE_FILE} + -P ${CMAKE_CURRENT_LIST_DIR}/gmxGenerateVersionInfo.cmake + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + COMMENT "Generating git version information" + VERBATIM) + endif() + list(APPEND VERSION_INFO_DEPS git-version-info) +else() + # If the version info is static, just generate the CMake script with the + # version variables during the CMake run. + set(GMX_VERSION_STRING_FULL ${GMX_VERSION_STRING}) + set(GMX_VERSION_FULL_HASH "") + set(GMX_VERSION_CENTRAL_BASE_HASH "") + configure_file(${VERSION_INFO_CMAKEIN_FILE} ${VERSION_INFO_CMAKE_FILE}) +endif() +unset(GMX_VERSION_STRING_FULL) +unset(GMX_VERSION_FULL_HASH) +unset(GMX_VERSION_CENTRAL_BASE_HASH) + +# The main user-visible interface to the machinery. +# See documentation at the top of the script. +function (gmx_configure_version_file INFILE OUTFILE) + include(CMakeParseArguments) + set(_options REMOTE_HASH SOURCE_FILE) + set(_one_value_args COMMENT TARGET) + cmake_parse_arguments(ARG "${_options}" "${_one_value_args}" "" ${ARGN}) + if (ARG_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Unknown arguments: ${ARG_UNPARSED_ARGUMENTS}") + endif() + # Some callers may pass partial paths that do not really make sense, + # so create a default comment that only contains the actual file name. + get_filename_component(_basename ${OUTFILE} NAME) + set(_comment "Generating ${_basename}") + if (ARG_COMMENT) + set(_comment ${ARG_COMMENT}) + endif() + # Mimic configure_file() + if (NOT IS_ABSOLUTE ${INFILE}) + set(INFILE ${CMAKE_CURRENT_SOURCE_DIR}/${INFILE}) + endif() + # The touch command is necessary to ensure that after the target is run, + # the timestamp is newer than in the input files. + add_custom_command(OUTPUT ${OUTFILE} + COMMAND ${CMAKE_COMMAND} + -D VERSION_VARIABLES=${VERSION_INFO_CMAKE_FILE} + -D VERSION_CMAKEIN=${INFILE} + -D VERSION_OUT=${OUTFILE} + -P ${VERSION_INFO_CONFIGURE_SCRIPT} + COMMAND ${CMAKE_COMMAND} -E touch ${OUTFILE} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS ${INFILE} ${VERSION_INFO_DEPS} ${VERSION_INFO_CONFIGURE_SCRIPT} + COMMENT "${_comment}" + VERBATIM) + if (ARG_TARGET) + add_custom_target(${ARG_TARGET} DEPENDS ${OUTFILE} VERBATIM) + endif() + if (ARG_SOURCE_FILE) + set_source_files_properties(${OUTFILE} PROPERTIES GENERATED true) + endif() +endfunction() diff --cc src/gromacs/commandline/pargs.cpp index 8ddff6fb8c,944b3089b5..66c0f2abad --- a/src/gromacs/commandline/pargs.cpp +++ b/src/gromacs/commandline/pargs.cpp @@@ -482,130 -660,181 +482,130 @@@ gmx_bool parse_common_args(int *argc, c // The FF macro returns whether or not the bit is set #define FF(arg) ((Flags & arg) == arg) - /* Check for double arguments */ - for (i = 1; (i < *argc); i++) + try { - if (argv[i] && (strlen(argv[i]) > 1) && (!std::isdigit(argv[i][1]))) + int nicelevel = 0; + double tbegin = 0.0, tend = 0.0, tdelta = 0.0; + bool bView = false; + int xvgFormat = 0; + gmx::TimeUnitManager timeUnitManager; + gmx::OptionsAdapter adapter(*argc, argv); + gmx::Options options(NULL, NULL); + gmx::FileNameOptionManager fileOptManager; + + fileOptManager.disableInputOptionChecking( + FF(PCA_NOT_READ_NODE) || FF(PCA_DISABLE_INPUT_FILE_CHECKING)); + options.addManager(&fileOptManager); - options.setDescription(gmx::ConstArrayRef(desc, ndesc)); ++ options.setDescription(gmx::constArrayRefFromArray(desc, ndesc)); + + options.addOption( + gmx::IntegerOption("nice").store(&nicelevel) + .defaultValue(FF(PCA_BE_NICE) ? 19 : 0) + .description("Set the nicelevel")); + + if (FF(PCA_CAN_SET_DEFFNM)) { - for (j = i+1; (j < *argc); j++) - { - if ( (argv[i][0] == '-') && (argv[j][0] == '-') && - (strcmp(argv[i], argv[j]) == 0) ) - { - if (FF(PCA_NOEXIT_ON_ARGS)) - { - fprintf(stderr, "Double command line argument %s\n", - argv[i]); - } - else - { - gmx_fatal(FARGS, "Double command line argument %s\n", - argv[i]); - } - } - } + fileOptManager.addDefaultFileNameOption(&options, "deffnm"); } - } - debug_gmx(); - - /* Check ALL the flags ... */ - max_pa = NPCA_PA + EXTRA_PA + npargs+1; - snew(all_pa, max_pa); - - for (i = npall = 0; (i < static_cast(NPCA_PA)); i++) - { - npall = add_parg(npall, all_pa, &(pca_pa[i])); - } - - if (FF(PCA_BE_NICE)) - { - nicelevel = 19; - } - npall = add_parg(npall, all_pa, &nice_pa); - - if (FF(PCA_CAN_SET_DEFFNM)) - { - npall = add_parg(npall, all_pa, &deffnm_pa); - } - if (FF(PCA_CAN_BEGIN)) - { - npall = add_parg(npall, all_pa, &begin_pa); - } - if (FF(PCA_CAN_END)) - { - npall = add_parg(npall, all_pa, &end_pa); - } - if (FF(PCA_CAN_DT)) - { - npall = add_parg(npall, all_pa, &dt_pa); - } - if (FF(PCA_TIME_UNIT)) - { - npall = add_parg(npall, all_pa, &time_pa); - } - if (FF(PCA_CAN_VIEW)) - { - npall = add_parg(npall, all_pa, &view_pa); - } - - bXvgr = FALSE; - for (i = 0; (i < nfile); i++) - { - bXvgr = bXvgr || (fnm[i].ftp == efXVG); - } - if (bXvgr) - { - npall = add_parg(npall, all_pa, &xvg_pa); - } - - /* Now append the program specific arguments */ - for (i = 0; (i < npargs); i++) - { - npall = add_parg(npall, all_pa, &(pa[i])); - } - - /* set etENUM options to default */ - for (i = 0; (i < npall); i++) - { - if (all_pa[i].type == etENUM) + if (FF(PCA_CAN_BEGIN)) { - all_pa[i].u.c[0] = all_pa[i].u.c[1]; + options.addOption( + gmx::DoubleOption("b").store(&tbegin).timeValue() + .description("First frame (%t) to read from trajectory")); } - } - set_default_time_unit(time_units, FF(PCA_TIME_UNIT)); - set_default_xvg_format(xvg_format); - - /* Now parse all the command-line options */ - get_pargs(argc, argv, npall, all_pa); - - /* set program name, command line, and default values for output options */ - output_env_init(oenv, gmx::getProgramContext(), (time_unit_t)nenum(time_units), bView, - (xvg_format_t)nenum(xvg_format), 0, debug_level); - - /* Parse the file args */ - parse_file_args(argc, argv, nfile, fnm, deffnm, !FF(PCA_NOT_READ_NODE)); - - /* Open the debug file */ - if (debug_level > 0) - { - char buf[256]; - - if (gmx_mpi_initialized()) + if (FF(PCA_CAN_END)) { - sprintf(buf, "%s%d.debug", output_env_get_short_program_name(*oenv), - gmx_node_rank()); + options.addOption( + gmx::DoubleOption("e").store(&tend).timeValue() + .description("Last frame (%t) to read from trajectory")); } - else + if (FF(PCA_CAN_DT)) + { + options.addOption( + gmx::DoubleOption("dt").store(&tdelta).timeValue() + .description("Only use frame when t MOD dt = first time (%t)")); + } + if (FF(PCA_TIME_UNIT)) + { + timeUnitManager.setTimeUnitFromEnvironment(); + timeUnitManager.addTimeUnitOption(&options, "tu"); + } + if (FF(PCA_CAN_VIEW)) { - sprintf(buf, "%s.debug", output_env_get_short_program_name(*oenv)); + options.addOption( + gmx::BooleanOption("w").store(&bView) + .description("View output [TT].xvg[tt], [TT].xpm[tt], " + "[TT].eps[tt] and [TT].pdb[tt] files")); } - init_debug(debug_level, buf); - fprintf(stderr, "Opening debug file %s (src code file %s, line %d)\n", - buf, __FILE__, __LINE__); - } + bool bXvgr = false; + for (int i = 0; i < nfile; i++) + { + bXvgr = bXvgr || (fnm[i].ftp == efXVG); + } + xvgFormat = gmx::getDefaultXvgFormat(xvg_formats); + if (bXvgr) + { + options.addOption( + gmx::StringOption("xvg").enumValue(xvg_formats) + .storeEnumIndex(&xvgFormat) + .description("xvg plot formatting")); + } - /* Now copy the results back... */ - for (i = 0, k = npall-npargs; (i < npargs); i++, k++) - { - memcpy(&(pa[i]), &(all_pa[k]), (size_t)sizeof(pa[i])); - } + /* Now append the program specific arguments */ + for (int i = 0; i < nfile; i++) + { + adapter.filenmToOptions(&options, &fnm[i]); + } + for (int i = 0; i < npargs; i++) + { + adapter.pargsToOptions(&options, &pa[i]); + } - bool bExit = false; - try - { const gmx::CommandLineHelpContext *context = gmx::GlobalCommandLineHelpContext::get(); - bExit = (context != NULL); - if (context != NULL && !(FF(PCA_QUIET))) + if (context != NULL) { - gmx::Options options(NULL, NULL); - options.setDescription(gmx::constArrayRefFromArray(desc, ndesc)); - for (i = 0; i < nfile; i++) - { - gmx::filenmToOptions(&options, &fnm[i]); - } - for (i = 0; i < npall; i++) - { - gmx::pargsToOptions(&options, &all_pa[i]); - } + GMX_RELEASE_ASSERT(gmx_node_rank() == 0, + "Help output should be handled higher up and " + "only get called only on the master rank"); gmx::CommandLineHelpWriter(options) .setShowDescriptions(true) - .setTimeUnitString(output_env_get_time_unit(*oenv)) + .setTimeUnitString(timeUnitManager.timeUnitAsString()) - .setKnownIssues(gmx::ConstArrayRef(bugs, nbugs)) + .setKnownIssues(gmx::constArrayRefFromArray(bugs, nbugs)) .writeHelp(*context); + return FALSE; } - } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; - /* Set the nice level */ + /* Now parse all the command-line options */ + gmx::CommandLineParser(&options).skipUnknown(FF(PCA_NOEXIT_ON_ARGS)) + .parse(argc, argv); + options.finish(); + + /* set program name, command line, and default values for output options */ + output_env_init(oenv, gmx::getProgramContext(), + (time_unit_t)(timeUnitManager.timeUnit() + 1), bView, + (xvg_format_t)(xvgFormat + 1), 0); + + /* Set the nice level */ #ifdef HAVE_UNISTD_H #ifndef GMX_NO_NICE - /* The some system, e.g. the catamount kernel on cray xt3 do not have nice(2). */ - if (nicelevel != 0 && !bExit) - { - static gmx_bool nice_set = FALSE; /* only set it once */ - static tMPI_Thread_mutex_t init_mutex = TMPI_THREAD_MUTEX_INITIALIZER; - tMPI_Thread_mutex_lock(&init_mutex); - if (!nice_set) + /* The some system, e.g. the catamount kernel on cray xt3 do not have nice(2). */ + if (nicelevel != 0) { - if (nice(nicelevel) == -1) + static gmx_bool nice_set = FALSE; /* only set it once */ + static tMPI_Thread_mutex_t init_mutex = TMPI_THREAD_MUTEX_INITIALIZER; + tMPI_Thread_mutex_lock(&init_mutex); + if (!nice_set) { - /* Do nothing, but use the return value to avoid warnings. */ + if (nice(nicelevel) == -1) + { + /* Do nothing, but use the return value to avoid warnings. */ + } + nice_set = TRUE; } - nice_set = TRUE; + tMPI_Thread_mutex_unlock(&init_mutex); } - tMPI_Thread_mutex_unlock(&init_mutex); - } #endif #endif diff --cc src/gromacs/gmxlib/gmx_thread_affinity.c index 17aa65ec06,fb2064213e..52898a0ed8 --- a/src/gromacs/gmxlib/gmx_thread_affinity.c +++ b/src/gromacs/gmxlib/gmx_thread_affinity.c @@@ -32,11 -32,15 +32,13 @@@ * To help us fund GROMACS development, we humbly ask that you cite * the research papers on the package. Check out http://www.gromacs.org. */ -#ifdef HAVE_CONFIG_H -#include -#endif +#include "config.h" - #if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_GETAFFINITY) - #define _GNU_SOURCE - #include - #include + #if defined(HAVE_SCHED_H) + # ifndef _GNU_SOURCE + # define _GNU_SOURCE 1 + # endif + # include + # include #endif #include #include @@@ -370,13 -371,13 +372,13 @@@ gmx_set_thread_affinity(FIL * Note that this will only work on Linux as we use a GNU feature. */ void -gmx_check_thread_affinity_set(FILE gmx_unused *fplog, - const t_commrec gmx_unused *cr, - gmx_hw_opt_t gmx_unused *hw_opt, - int gmx_unused nthreads_hw_avail, - gmx_bool gmx_unused bAfterOpenmpInit) +gmx_check_thread_affinity_set(FILE *fplog, + const t_commrec *cr, + gmx_hw_opt_t *hw_opt, + int gmx_unused nthreads_hw_avail, + gmx_bool bAfterOpenmpInit) { - #ifdef HAVE_SCHED_GETAFFINITY + #ifdef HAVE_SCHED_AFFINITY cpu_set_t mask_current; int i, ret, cpu_count, cpu_set; gmx_bool bAllSet; diff --cc src/gromacs/options/filenameoption.cpp index a0a4a4023b,f5b58f0665..8c06ea6887 --- a/src/gromacs/options/filenameoption.cpp +++ b/src/gromacs/options/filenameoption.cpp @@@ -376,54 -363,15 +376,54 @@@ void FileNameOptionStorage::processAll( bool FileNameOptionStorage::isDirectoryOption() const { - return legacyType_ == efRND; + return fileType_ == efRND; +} + +bool FileNameOptionStorage::isTrajectoryOption() const +{ + return fileType_ == efTRX; } -ConstArrayRef FileNameOptionStorage::extensions() const +const char *FileNameOptionStorage::defaultExtension() const { - const FileTypeRegistry ®istry = FileTypeRegistry::instance(); - const FileTypeHandler &typeHandler = registry.handlerForType(filetype_, legacyType_); - const ExtensionList &extensions = typeHandler.extensions(); - return constArrayRefFromVector(extensions.begin(), extensions.end()); + FileTypeHandler typeHandler(fileType_); + if (typeHandler.extensionCount() == 0) + { + return ""; + } + return typeHandler.extension(0); +} + +std::vector FileNameOptionStorage::extensions() const +{ + FileTypeHandler typeHandler(fileType_); + std::vector result; + result.reserve(typeHandler.extensionCount()); + for (int i = 0; i < typeHandler.extensionCount(); ++i) + { + result.push_back(typeHandler.extension(i)); + } + return result; +} + +bool FileNameOptionStorage::isValidType(int fileType) const +{ + FileTypeHandler typeHandler(fileType_); + return typeHandler.isValidType(fileType); +} + +ConstArrayRef FileNameOptionStorage::fileTypes() const +{ + if (fileType_ < 0) + { + return ConstArrayRef(); + } + const int genericTypeCount = ftp2generic_count(fileType_); + if (genericTypeCount > 0) + { - return ConstArrayRef(ftp2generic_list(fileType_), genericTypeCount); ++ return constArrayRefFromArray(ftp2generic_list(fileType_), genericTypeCount); + } - return ConstArrayRef(&fileType_, 1); ++ return constArrayRefFromArray(&fileType_, 1); } /******************************************************************** diff --cc src/gromacs/selection/nbsearch.cpp index b50c4dbd53,24a66ddbda..1e8f1cfdad --- a/src/gromacs/selection/nbsearch.cpp +++ b/src/gromacs/selection/nbsearch.cpp @@@ -634,12 -604,9 +634,12 @@@ bool AnalysisNeighborhoodPairSearchImpl void AnalysisNeighborhoodPairSearchImpl::startSearch( const AnalysisNeighborhoodPositions &positions) { + testExclusionIds_ = positions.exclusionIds_; + GMX_RELEASE_ASSERT(search_.excls_ == NULL || testExclusionIds_ != NULL, + "Exclusion IDs must be set when exclusions are enabled"); if (positions.index_ < 0) { - testPositions_ = ConstArrayRef(positions.x_, positions.count_); + testPositions_ = constArrayRefFromArray(positions.x_, positions.count_); reset(0); } else diff --cc src/gromacs/selection/selection.cpp index 892496298a,786fb9912a..f317486fe2 --- a/src/gromacs/selection/selection.cpp +++ b/src/gromacs/selection/selection.cpp @@@ -352,15 -345,9 +352,15 @@@ Selection::printDebugInfo(FILE *fp, in SelectionPosition::operator AnalysisNeighborhoodPositions() const { - return AnalysisNeighborhoodPositions(sel_->rawPositions_.x, - sel_->rawPositions_.count()) - .selectSingleFromArray(i_); + AnalysisNeighborhoodPositions pos(sel_->rawPositions_.x, + sel_->rawPositions_.count()); + if (sel_->hasOnlyAtoms()) + { + // TODO: Move atomIndices() such that it can be reused here as well. - pos.exclusionIds(ConstArrayRef(sel_->rawPositions_.m.mapb.a, - sel_->rawPositions_.m.mapb.nra)); ++ pos.exclusionIds(constArrayRefFromArray(sel_->rawPositions_.m.mapb.a, ++ sel_->rawPositions_.m.mapb.nra)); + } + return pos.selectSingleFromArray(i_); } } // namespace gmx diff --cc src/gromacs/selection/tests/nbsearch.cpp index 370235bd31,0ecf04b6e1..0d7c0db1e8 --- a/src/gromacs/selection/tests/nbsearch.cpp +++ b/src/gromacs/selection/tests/nbsearch.cpp @@@ -286,105 -229,6 +286,105 @@@ void NeighborhoodSearchTestData::comput } } +/******************************************************************** + * ExclusionsHelper + */ + +class ExclusionsHelper +{ + public: + static void markExcludedPairs(RefPairList *refPairs, int testIndex, + const t_blocka *excls); + + ExclusionsHelper(int refPosCount, int testPosCount); + + void generateExclusions(); + + const t_blocka *exclusions() const { return &excls_; } + + gmx::ConstArrayRef refPosIds() const + { - return gmx::ConstArrayRef(exclusionIds_.begin(), - exclusionIds_.begin() + refPosCount_); ++ return gmx::constArrayRefFromVector(exclusionIds_.begin(), ++ exclusionIds_.begin() + refPosCount_); + } + gmx::ConstArrayRef testPosIds() const + { - return gmx::ConstArrayRef(exclusionIds_.begin(), - exclusionIds_.begin() + testPosCount_); ++ return gmx::constArrayRefFromVector(exclusionIds_.begin(), ++ exclusionIds_.begin() + testPosCount_); + } + + private: + int refPosCount_; + int testPosCount_; + std::vector exclusionIds_; + std::vector exclsIndex_; + std::vector exclsAtoms_; + t_blocka excls_; +}; + +// static +void ExclusionsHelper::markExcludedPairs(RefPairList *refPairs, int testIndex, + const t_blocka *excls) +{ + int count = 0; + for (int i = excls->index[testIndex]; i < excls->index[testIndex + 1]; ++i) + { + const int excludedIndex = excls->a[i]; + NeighborhoodSearchTestData::RefPair searchPair(excludedIndex, 0.0); + RefPairList::iterator excludedRefPair + = std::lower_bound(refPairs->begin(), refPairs->end(), searchPair); + if (excludedRefPair != refPairs->end() + && excludedRefPair->refIndex == excludedIndex) + { + excludedRefPair->bFound = true; + excludedRefPair->bExcluded = true; + ++count; + } + } +} + +ExclusionsHelper::ExclusionsHelper(int refPosCount, int testPosCount) + : refPosCount_(refPosCount), testPosCount_(testPosCount) +{ + // Generate an array of 0, 1, 2, ... + // TODO: Make the tests work also with non-trivial exclusion IDs, + // and test that. + exclusionIds_.resize(std::max(refPosCount, testPosCount), 1); + exclusionIds_[0] = 0; + std::partial_sum(exclusionIds_.begin(), exclusionIds_.end(), + exclusionIds_.begin()); + + excls_.nr = 0; + excls_.index = NULL; + excls_.nra = 0; + excls_.a = NULL; + excls_.nalloc_index = 0; + excls_.nalloc_a = 0; +} + +void ExclusionsHelper::generateExclusions() +{ + // TODO: Consider a better set of test data, where the density of the + // particles would be higher, or where the exclusions would not be random, + // to make a higher percentage of the exclusions to actually be within the + // cutoff. + exclsIndex_.reserve(testPosCount_ + 1); + exclsAtoms_.reserve(testPosCount_ * 20); + exclsIndex_.push_back(0); + for (int i = 0; i < testPosCount_; ++i) + { + for (int j = 0; j < 20; ++j) + { + exclsAtoms_.push_back(i + j*3); + } + exclsIndex_.push_back(exclsAtoms_.size()); + } + excls_.nr = exclsIndex_.size(); + excls_.index = &exclsIndex_[0]; + excls_.nra = exclsAtoms_.size(); + excls_.a = &exclsAtoms_[0]; +} + /******************************************************************** * NeighborhoodSearchTest */ diff --cc tests/CMakeLists.txt index bcf188a662,fb611ffd20..3bd404724f --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@@ -60,6 -60,12 +60,12 @@@ status_code: ${status_code status_string: ${status_string} log: ${log}") endif() - if(NOT "${PROJECT_VERSION}" MATCHES "-dev") ++ if (SOURCE_IS_SOURCE_DISTRIBUTION) + file(MD5 ${REGRESSIONTEST_FILE} COMPUTED_MD5SUM) + if(NOT ${REGRESSIONTEST_MD5SUM} STREQUAL ${COMPUTED_MD5SUM}) + message(FATAL_ERROR "Download of regressiontests failed. Expected MD5 of ${REGRESSIONTEST_MD5SUM} but download has ${COMPUTED_MD5SUM}") + endif() + endif() file(REMOVE_RECURSE "${REGRESSIONTEST_PATH}") #delete potential prior folder execute_process(COMMAND ${CMAKE_COMMAND} -E tar xf "${REGRESSIONTEST_FILE}"