Merge release-5-0 into master
authorRoland Schulz <roland@utk.edu>
Sat, 16 Aug 2014 04:30:10 +0000 (00:30 -0400)
committerRoland Schulz <roland@utk.edu>
Sat, 16 Aug 2014 21:20:50 +0000 (17:20 -0400)
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

49 files changed:
CMakeLists.txt
cmake/CheckCCompilerFlag.cmake
cmake/CheckCXXCompilerFlag.cmake
cmake/TestInlineASM_gcc_x86.c
cmake/TestSchedAffinity.cmake [moved from cmake/gmxGetMsvcTupleWorkaround.cmake with 57% similarity]
cmake/gmxGetGmockTupleWorkaround.cmake [new file with mode: 0644]
cmake/gmxManageLinearAlgebraLibraries.cmake
cmake/gmxVersionInfo.cmake
install-guide/install-guide.md
src/config.h.cmakein
src/contrib/fftw/.gitattributes [new file with mode: 0644]
src/contrib/fftw/CMakeLists.txt
src/contrib/fftw/fftw-download.cmake.cmakein [new file with mode: 0644]
src/external/boost/README
src/external/boost/boost/config/compiler/generic.hpp [new file with mode: 0644]
src/external/boost/boost/config/select_compiler_config.hpp
src/external/gmock-1.7.0/CMakeLists.txt
src/external/gmock-1.7.0/README.Gromacs
src/external/gmock-1.7.0/gtest/src/gtest.cc
src/external/thread_mpi/include/thread_mpi/atomic.h
src/external/thread_mpi/include/thread_mpi/atomic/gcc_x86.h
src/gromacs/analysisdata/arraydata.cpp
src/gromacs/analysisdata/dataframe.cpp
src/gromacs/analysisdata/datastorage.cpp
src/gromacs/commandline/pargs.cpp
src/gromacs/gmxlib/gmx_cpuid.c
src/gromacs/gmxlib/gmx_thread_affinity.c
src/gromacs/gmxpreprocess/readir.c
src/gromacs/legacyheaders/pme.h
src/gromacs/mdlib/domdec.c
src/gromacs/mdlib/nbnxn_kernels/simd_2xnn/nbnxn_kernel_simd_2xnn_inner.h
src/gromacs/mdlib/nbnxn_kernels/simd_4xn/nbnxn_kernel_simd_4xn_inner.h
src/gromacs/mdlib/perf_est.c
src/gromacs/mdlib/pme.c
src/gromacs/mdlib/pme_pp.c
src/gromacs/mdlib/tpi.c
src/gromacs/onlinehelp/helpwritercontext.cpp
src/gromacs/options/filenameoption.cpp
src/gromacs/selection/nbsearch.cpp
src/gromacs/selection/selection.cpp
src/gromacs/selection/selection.h
src/gromacs/selection/tests/nbsearch.cpp
src/gromacs/simd/simd_math.h
src/gromacs/simd/tests/simd_math.cpp
src/gromacs/utility/arrayref.h
src/testutils/tests/CMakeLists.txt
src/testutils/tests/refdata_tests.cpp [moved from src/testutils/tests/refdata.cpp with 100% similarity]
src/testutils/tests/testasserts_tests.cpp [moved from src/testutils/tests/testasserts.cpp with 100% similarity]
tests/CMakeLists.txt

index 964612afad160d0b4c0863ce814048f85c594544..bc12271f47fabc2a150b4179f14c0ab3f835d90b 100644 (file)
@@ -270,14 +270,20 @@ include(gmxManageOpenMP)
 #####################################################################
 
 # The cmake/Check{C,CXX}CompilerFlag.cmake files in the GROMACS distribution
-# are used with permission from CMake v2.8.9 so that GROMACS can detect
-# invalid options with the Intel Compilers.
+# are used with permission from CMake v3.0.0 so that GROMACS can detect
+# invalid options with the Intel Compilers, and we have added a line
+# to detect warnings with the Fujitsu compilers on K computer.
+# CMake-3.0 also has a bug where the FAIL_REGEX pattern for AIX contains
+# a semicolon. Since this is also used as a separator in lists inside CMake,
+# that string ends up being split into two separate patterns, and the last
+# part is just a single word that also matches other messages. We solved this
+# by replacing the semicolon with a period that matches any character.
+#
 # These files should be removed from the source tree when a CMake version that
 # includes the features in question becomes required for building GROMACS.
 include(CheckCCompilerFlag)
 include(CheckCXXCompilerFlag)
 
-
 include(gmxCFlags)
 gmx_c_flags()
 
@@ -353,8 +359,6 @@ check_function_exists(fileno            HAVE_FILENO)
 check_function_exists(_commit           HAVE__COMMIT)
 check_function_exists(sigaction         HAVE_SIGACTION)
 check_function_exists(sysconf           HAVE_SYSCONF)
-check_function_exists(sched_setaffinity HAVE_SCHED_SETAFFINITY)
-check_function_exists(sched_getaffinity HAVE_SCHED_GETAFFINITY)
 check_function_exists(rsqrt             HAVE_RSQRT)
 check_function_exists(rsqrtf            HAVE_RSQRTF)
 check_function_exists(sqrtf             HAVE_SQRTF)
@@ -363,6 +367,9 @@ include(CheckLibraryExists)
 check_library_exists(m sqrt "" HAVE_LIBM)
 check_library_exists(rt clock_gettime "" HAVE_CLOCK_GETTIME)
 
+include(TestSchedAffinity)
+test_sched_affinity(HAVE_SCHED_AFFINITY)
+
 include(TestBigEndian)
 test_big_endian(GMX_INTEGER_BIG_ENDIAN)
 
index e65ba1b4a653bc4337240a478554c450743c3f97..48d8177e09feeb90ae526768cc7eb7cd8f8f5da2 100644 (file)
@@ -64,7 +64,13 @@ MACRO (CHECK_C_COMPILER_FLAG _FLAG _RESULT)
      FAIL_REGEX "[Uu]nknown option"                         # HP
      FAIL_REGEX "[Ww]arning: [Oo]ption"                     # SunPro
      FAIL_REGEX "command option .* is not recognized"       # XL
+     FAIL_REGEX "command option .* contains an incorrect subargument" # XL
+     FAIL_REGEX "not supported in this configuration. ignored" # AIX
+     FAIL_REGEX "File with unknown suffix passed to linker" # PGI
      FAIL_REGEX "WARNING: unknown flag:"                    # Open64
+     FAIL_REGEX "Incorrect command line option:"            # Borland
+     FAIL_REGEX "Warning: illegal option"                   # SunStudio 12
+     FAIL_REGEX "[Ww]arning: Invalid"                       # Fujitsu
      )
    SET (CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}")
 ENDMACRO (CHECK_C_COMPILER_FLAG)
index 660f5aaa62f591b46996e3f3c4afe66e5904f0ac..a11373eb3f06a2cd75cdfa8d2f7e16ea2b96cb41 100644 (file)
@@ -64,9 +64,13 @@ MACRO (CHECK_CXX_COMPILER_FLAG _FLAG _RESULT)
      FAIL_REGEX "[Uu]nknown option"                         # HP
      FAIL_REGEX "[Ww]arning: [Oo]ption"                     # SunPro
      FAIL_REGEX "command option .* is not recognized"       # XL
-     FAIL_REGEX "not supported in this configuration. ignored"       # AIX
+     FAIL_REGEX "command option .* contains an incorrect subargument" # XL
+     FAIL_REGEX "not supported in this configuration. ignored" # AIX
      FAIL_REGEX "File with unknown suffix passed to linker" # PGI
      FAIL_REGEX "WARNING: unknown flag:"                    # Open64
+     FAIL_REGEX "Incorrect command line option:"            # Borland
+     FAIL_REGEX "Warning: illegal option"                   # SunStudio 12
+     FAIL_REGEX "[Ww]arning: Invalid"                       # Fujitsu
      )
    SET (CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}")
 ENDMACRO (CHECK_CXX_COMPILER_FLAG)
index 27f7a07d56984760e5fe3b9de1029630dffa7e01..f5b184b7822e654dc225fce32145b06ada3b4f60 100644 (file)
@@ -4,19 +4,24 @@ main()
   unsigned int _eax,_ebx,_ecx,_edx;
   unsigned int level = 0;
 
-  /* Test gcc inline asm for x86 */
-#if defined (__LP64__) || defined (_M_X64)
+  /* Test gcc inline asm for x86. Note that we CANNOT plainly use __x86_64__
+   * to correspond to a 64-bit environment without also checking that __ILP32__
+   * is NOT set, since x32 uses __x86_64__.
+   */
+#if (defined(__x86_64__) && !defined(__ILP32__))
     __asm__("push %%rbx       \n\t"
             "cpuid            \n\t"
             "movl %%ebx, %1   \n\t"
             "pop %%rbx        \n\t"
             : "=a"(_eax), "=r"(_ebx), "=c"(_ecx), "=d"(_edx) : "0"(level));
-#else
+#elif (defined(__x86_64__) && defined(__ILP32__)) || defined(__i386__)
     __asm__("push %%ebx       \n\t"
             "cpuid            \n\t"
             "movl %%ebx, %1   \n\t"
             "pop %%ebx        \n\t"
             : "=a"(_eax), "=r"(_ebx), "=c"(_ecx), "=d"(_edx) : "0"(level));
+#else
+#    error Cannot detect whether this is a 32-bit or 64-bit x86 build.
 #endif
 
   return 0;
similarity index 57%
rename from cmake/gmxGetMsvcTupleWorkaround.cmake
rename to cmake/TestSchedAffinity.cmake
index 7096174d1529d6b6c750f78f06c9a0df604e417e..8fd23560735379bb308d25c4491f559247d2f908 100644 (file)
@@ -1,7 +1,7 @@
 #
 # This file is part of the GROMACS molecular simulation package.
 #
-# Copyright (c) 2014, by the GROMACS development team, led by
+# Copyright (c) 2012,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.
 # To help us fund GROMACS development, we humbly ask that you cite
 # the research papers on the package. Check out http://www.gromacs.org.
 
-# GMock uses tuples extensively, and MSVC bundles a tuple library that
-# is not compatible with the standard. r675 of googletest works around
-# this properly, but that's not in GMock 1.7.0. That logic is
-# duplicated here. See
-# https://code.google.com/p/googletest/source/detail?r=675#, but note
-# that its summary does not represent its code correctly.
-#
-# This function should be called to get the compile definitions
-# suitable for working around MSVC to compile GMock, if any.
-# Returns a string of options in VARIABLE
-function(GET_MSVC_TUPLE_WORKAROUND_DEFINITIONS VARIABLE)
-    set(${VARIABLE} "")
-    if(MSVC AND MSVC_VERSION VERSION_EQUAL 1700)
-        # Fixes Visual Studio 2012
-        set(${VARIABLE} "_VARIADIC_MAX=10")
-    endif()
-    set(${VARIABLE} ${${VARIABLE}} PARENT_SCOPE)
-endfunction()
+# - Define macro to check if all of the following work:
+# sched_getaffinity()
+# sched_setaffinity()
+# CPU_ZERO()
+# CPU_SET()
+# CPU_ISSET()
+# CPU_CLR()
+# CPU_COUNT()
+
+#  test_sched_affinity(VARIABLE)
+#
+#  VARIABLE will be set to true if all of the functions link fine.
+
+MACRO(test_sched_affinity VARIABLE)
+
+  if(NOT DEFINED sched_affinity_compile)
+    MESSAGE(STATUS "Checking for sched.h GNU affinity API")
+
+    check_c_source_compiles(
+      "#ifndef _GNU_SOURCE
+#define _GNU_SOURCE 1
+#endif
+#include <sched.h>
+int main(void) {
+  int i;
+  cpu_set_t mask;
+  CPU_ZERO(&mask);
+  sched_getaffinity(0, sizeof(cpu_set_t), &mask);
+  if(CPU_ISSET(0,&mask))
+  {
+    CPU_CLR(0,&mask);
+    CPU_SET(0,&mask);
+  }
+  sched_setaffinity(0, sizeof(cpu_set_t), &mask);
+  return CPU_COUNT(&mask);
+}" sched_affinity_compile)
+  endif(NOT DEFINED sched_affinity_compile)
+
+  if(sched_affinity_compile)
+    set(${VARIABLE} 1 CACHE INTERNAL "Result of test for sched.h GNU affinity API" FORCE)
+  else()
+    set(${VARIABLE} 0 CACHE INTERNAL "Result of test for sched.h GNU affinity API" FORCE)
+  endif()
+ENDMACRO(test_sched_affinity VARIABLE)
diff --git a/cmake/gmxGetGmockTupleWorkaround.cmake b/cmake/gmxGetGmockTupleWorkaround.cmake
new file mode 100644 (file)
index 0000000..d9456bb
--- /dev/null
@@ -0,0 +1,73 @@
+#
+# 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.
+
+# GMock uses tuples extensively, but since it is part of tr1 we cannot
+# assume it is present - the Fujitsu compilers on K computer is one
+# example of a system where it is not, and this is likely the case for many
+# embedded systems too.
+#
+# In general, we can ask gmock to use its own internal implementation by
+# defining GTEST_USE_OWN_TR1_TUPLE=1. This is safe for Gromacs, since we do
+# not use tr1/tuple.h elsewhere. However, this workaround itself will not
+# compile on MSVC - but this is the only architecture we know where it does
+# not work. To make things even worse, on MSVC even the standard tr1/tuple
+# implementation is not fully compatible, but we can make it work by setting
+# _VARIADIC_MAX=10. This is similar to r675 of googletest, which is still not
+# present in GMock 1.7.0. See
+# https://code.google.com/p/googletest/source/detail?r=675#, but note
+# that its summary does not represent its code correctly.
+#
+# To make all this work without user intervention, we first check what compiler
+# we have, and if it is not MSVC we simply use the internal version. If we are
+# using MSVC, we rely on the compiler's version, but set the variable necessary
+# to make it compatible.
+#
+# This function should be called to get the compile definitions
+# suitable for making sure we have a tuple implementation that works with gmock.
+#
+# Returns a string of options in VARIABLE
+function(GET_GMOCK_TUPLE_WORKAROUND VARIABLE)
+    set(${VARIABLE} "")
+    if(MSVC OR (WIN32 AND CMAKE_CXX_COMPILER_ID MATCHES "Intel"))
+        if(MSVC_VERSION VERSION_EQUAL 1700)
+            # Fixes Visual Studio 2012
+            set(${VARIABLE} "_VARIADIC_MAX=10")
+        endif()
+        # For MSVC different from 2012, or Intel on Windows, we reply on tr1/tuple working.
+    else()
+        # Use the built-in version on all other compilers.
+        set(${VARIABLE} "GTEST_USE_OWN_TR1_TUPLE=1")
+    endif()
+    set(${VARIABLE} ${${VARIABLE}} PARENT_SCOPE)
+endfunction()
index aa1df74a5dfee891972a37cddd48ca0826397a48..8c8562b9c75dc100154a1679ee369d26dc821284 100644 (file)
@@ -120,7 +120,7 @@ macro(manage_linear_algebra_library name function_in_library)
         endif()
 
         if (NOT _library_was_found AND NOT _find_quietly)
-            message("${_message_text}A ${name} library was not found by CMake in the paths available to it. Falling back on the GROMACS internal version of the ${name} library instead. This is fine for normal usage.")
+            message(STATUS "${_message_text}Using GROMACS built-in ${name}.")
         endif()
     endif()
 
index 3e6ed3fc6369af285ce2da7c868abe0ea1012589..7b8d08402f9374a98f8a63bb896650140d1b88fc 100644 (file)
@@ -55,6 +55,9 @@
 #       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
@@ -201,6 +204,7 @@ 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
index c8858a3bba62308c2707101af0a0e633eec8c16c..b914782c4bb4dada8c75be1dbe0af8f3ed2c6666 100644 (file)
@@ -223,11 +223,6 @@ recommends either
   `cmake -DGMX_BUILD_OWN_FFTW=ON`), or
 * that you build FFTW from the source code.
 
-Note that the GROMACS-managed download of the FFTW tarball has a
-slight chance of posing a security risk. If you use this option, you
-will see a warning that advises how you can eliminate this risk
-(before the opportunity has arisen).
-
 If you build FFTW from source yourself, get the most recent version
 and follow its [installation
 guide](http://www.fftw.org/doc/Installation-and-Customization.html#Installation-and-Customization).
index 2e208b36cdbef9f0046beb3a95ade0abdf641c28..b80401ff66eb3f9903b3f55bc415e7d256b55b2b 100644 (file)
 /* Define to 1 if you have the sysconf() function */
 #cmakedefine HAVE_SYSCONF
 
-/* Define to 1 if you have the sched_getaffinity() function */
-#cmakedefine HAVE_SCHED_GETAFFINITY
-
-/* Define to 1 if you have the sched_setaffinity() function */
-#cmakedefine HAVE_SCHED_SETAFFINITY
+/* Define to 1 if you have the all the affinity functions in sched.h */
+#cmakedefine HAVE_SCHED_AFFINITY
 
 /* Bytes in IEEE fp word are in big-endian order if set, little-endian if not.
    Only relevant when FLOAT_FORMAT_IEEE754 is defined. */
diff --git a/src/contrib/fftw/.gitattributes b/src/contrib/fftw/.gitattributes
new file mode 100644 (file)
index 0000000..9e8e962
--- /dev/null
@@ -0,0 +1 @@
+fftw-download.cmake.cmakein !filter
index b553c405899e650810ca23da118735b0d24a9bd4..c7d72989521fdc46130dbb3ae5e06bd1521b933f 100644 (file)
@@ -68,25 +68,54 @@ endif()
 # Machinery for running the external project
 set(EXTERNAL_FFTW_VERSION 3.3.3)
 # cmake make eats slashes //// -> //
-set(GMX_BUILD_OWN_FFTW_URL "http:////www.fftw.org/fftw-${EXTERNAL_FFTW_VERSION}.tar.gz" CACHE PATH "URL from where to download fftw, (use an absolute path when offline)")
-mark_as_advanced(GMX_BUILD_OWN_FFTW_URL)
-set(EXTERNAL_FFTW_MD5SUM 0a05ca9c7b3bfddc8278e7c40791a1c2)
-set (EXTERNAL_FFTW_BUILD_TARGET fftwBuild)
+set(GMX_BUILD_OWN_FFTW_URL
+    "http:////www.fftw.org/fftw-${EXTERNAL_FFTW_VERSION}.tar.gz" CACHE PATH
+    "URL from where to download fftw (use an absolute path when offline, adjust GMX_BUILD_OWN_FFTW_MD5 if downloading other version than ${EXTERNAL_FFTW_VERSION})")
+set(GMX_BUILD_OWN_FFTW_MD5 0a05ca9c7b3bfddc8278e7c40791a1c2 CACHE STRING
+    "Expected MD5 hash for the file at GMX_BUILD_OWN_FFTW_URL")
+mark_as_advanced(GMX_BUILD_OWN_FFTW_URL GMX_BUILD_OWN_FFTW_MD5)
+
+# ExternalProject at least up to CMake 3.0 prints a confusing error message if
+# download fails when MD5 verification is enabled.  So we manage the download
+# ourselves so that MD5 sum is not verified there, and then pass a local file
+# as the URL to ExternalProject.  This way, ExternalProject still verifies the
+# MD5 sum with a proper message if that fails.
+set(url "${GMX_BUILD_OWN_FFTW_URL}")
+# Determine whether we are actually downloading (this matches the conditions in
+# ExternalProject).  ExternalProject works as expected if passed a local file.
+set(is_download TRUE)
+if (IS_DIRECTORY "${url}" OR "${url}" MATCHES "^file://" OR NOT "${url}" MATCHES "^[a-z]+://")
+    set(is_download FALSE)
+endif()
+if (is_download)
+    # For simplicity, don't try to extract the file name from the URL, but use
+    # a hard-coded value.
+    set(remote_url "${GMX_BUILD_OWN_FFTW_URL}")
+    set(local_path "${CMAKE_CURRENT_BINARY_DIR}/fftw.tar.gz")
+    set(url ${local_path})
+    # Write a script to do our own download step (mimics what ExternalProject
+    # would do, but without MD5 sum verification at this step).
+    set(download_script ${CMAKE_CURRENT_BINARY_DIR}/fftw-download.cmake)
+    configure_file(fftw-download.cmake.cmakein ${download_script} @ONLY)
+endif()
+
+# The actual build target.
+set(EXTERNAL_FFTW_BUILD_TARGET fftwBuild)
 include(ExternalProject)
-# TODO in master branch - show this warning only on the first run
-# by using gmx_check_if_changed_result from I21b791ab8e4f3 when
-# that becomes available
-message(WARNING "The GROMACS build will download FFTW ${EXTERNAL_FFTW_VERSION} as requested, but it will not know the file it receives is correct. If you now use\nmake\n GROMACS will build and link to FFTW anyway, but there is a possible security risk if you execute a GROMACS tool that calls this library. Instead, you can use\nmake ${EXTERNAL_FFTW_BUILD_TARGET}\n to do just the download and build of FFTW, and then run\nmd5sum src/contrib/fftw/${EXTERNAL_FFTW_BUILD_TARGET}-prefix/src/fftw-${EXTERNAL_FFTW_VERSION}.tar.gz\nto see if it matches ${EXTERNAL_FFTW_MD5SUM}. If so, everything is OK and you should use \nmake\n to proceed with the rest of the GROMACS build. Alternatively, you could stop using GMX_BUILD_OWN_FFTW, and instead follow the GROMACS installation instructions to build FFTW yourself.")
-# TODO if/when CMake fixes http://www.cmake.org/Bug/view.php?id=14330
-# (ie. at least version > 2.8.11.2), consider reverting to using an
-# md5sum check to avoid needing the above warning
-    ExternalProject_add(${EXTERNAL_FFTW_BUILD_TARGET}
-        URL "${GMX_BUILD_OWN_FFTW_URL}"
+ExternalProject_add(${EXTERNAL_FFTW_BUILD_TARGET}
+        URL "${url}" URL_MD5 ${GMX_BUILD_OWN_FFTW_MD5}
         CONFIGURE_COMMAND <SOURCE_DIR>/configure --prefix=<INSTALL_DIR> --libdir=<INSTALL_DIR>/lib --disable-fortran
         ${GMX_BUILD_OWN_FFTW_SHARED_FLAG} ${GMX_BUILD_OWN_FFTW_OPTIMIZATION_CONFIGURATION}
         ${GMX_BUILD_OWN_FFTW_PREC}
         ${GMX_BUILD_OWN_FFTW_TARGET_HOST})
-externalproject_get_property(${EXTERNAL_FFTW_BUILD_TARGET} INSTALL_DIR)
+# Add a custom step to do our own download if that is necessary.
+if (is_download)
+    ExternalProject_add_step(${EXTERNAL_FFTW_BUILD_TARGET} pre-download
+            COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/fftw-download.cmake
+            DEPENDERS download)
+endif()
+
+ExternalProject_get_property(${EXTERNAL_FFTW_BUILD_TARGET} INSTALL_DIR)
 
 string(TOUPPER "${FFTW}" UPPERFFTW)
 string(TOLOWER "${FFTW}" LOWERFFTW)
diff --git a/src/contrib/fftw/fftw-download.cmake.cmakein b/src/contrib/fftw/fftw-download.cmake.cmakein
new file mode 100644 (file)
index 0000000..777fe3b
--- /dev/null
@@ -0,0 +1,19 @@
+# Custom download script for Gromacs external FFTW build.
+
+# Mimics a similar script generated by CMake ExternalProject package, but
+# does not verify the MD5 sum (which would give confusing error messages if the
+# download fails).
+message(STATUS "downloading...
+     src='@remote_url@'
+     dest='@local_path@'")
+file(DOWNLOAD "@remote_url@" "@local_path@"
+     SHOW_PROGRESS STATUS status LOG log)
+list(GET status 0 status_code)
+list(GET status 1 status_string)
+if (NOT status_code EQUAL 0)
+  message(FATAL_ERROR "error: downloading '@remote_url@' failed
+     status_code: ${status_code}
+     status_string: ${status_string}
+     log: ${log}")
+endif()
+message(STATUS "downloading... done")
index c63c724ab809fcc803a7eb8c2e0d635b8e79884a..a41bac446d5a98edc01163b884ed118f676425c3 100644 (file)
@@ -2,9 +2,14 @@ Steps to produce minimal version of BOOST:
 1) Download Boost (current minimal version is derived from 1.55.0)
 2) Extract
 3) Edit Boost files to uncomment unnessary includes (search for GMX in minimal version and copy all changes)
-4) run bcp with required files (currently exception/all.hpp, scoped_ptr.hpp)
-5) delete source files which are not required. Currently:
-       libs/smart_ptr/src/sp_collector.cpp
-       libs/smart_ptr/src/sp_debug_hooks.cpp
+4) Make sure our subset works even with compilers not listed
+   among the boost ones (in particular, Fujistu in native mode):
+   - Edit config/select_compiler_config.hpp to add the fallback
+     to a generic compiler capability file at the end.
+   - Add the generic compiler capability file config/compiler/generic.hpp
+5) run bcp with required files (currently exception/all.hpp, scoped_ptr.hpp)
+6) delete source files which are not required. Currently:
+   - libs/smart_ptr/src/sp_collector.cpp
+   - libs/smart_ptr/src/sp_debug_hooks.cpp
    Make sure that they are really not needed.If any source files are added make sure to add them to cmake.
 
diff --git a/src/external/boost/boost/config/compiler/generic.hpp b/src/external/boost/boost/config/compiler/generic.hpp
new file mode 100644 (file)
index 0000000..5822693
--- /dev/null
@@ -0,0 +1,71 @@
+//  File created by Erik Lindahl July 2014 by copying most of the pathscale.hpp
+//  compiler definition in Boost-1.55. 
+
+//  Use, modification and distribution are subject to the
+//  Boost Software License, Version 1.0. (See accompanying file
+//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+//  See http://www.boost.org for most recent version.
+
+//  Settings for a generic compiler. We assume that long long exists,
+//  remove all C++11 support, and assume threads work.
+
+#ifndef BOOST_COMPILER
+#  define BOOST_COMPILER "Generic compiler"
+#endif
+
+// It might seem stupid to assume a generic compiler to have threads, but it
+// appears some Boost reference counting might not be thread-safe without this.
+#define BOOST_HAS_THREADS
+#define BOOST_HAS_PTHREADS
+
+#define BOOST_HAS_LONG_LONG
+#define BOOST_NO_CXX11_VARIADIC_TEMPLATES
+#define BOOST_NO_CXX11_UNICODE_LITERALS
+#define BOOST_NO_CXX11_TEMPLATE_ALIASES
+#define BOOST_NO_CXX11_STATIC_ASSERT
+#define BOOST_NO_SFINAE_EXPR
+#define BOOST_NO_CXX11_SCOPED_ENUMS
+#define BOOST_NO_CXX11_RVALUE_REFERENCES
+#define BOOST_NO_CXX11_RANGE_BASED_FOR
+#define BOOST_NO_CXX11_RAW_LITERALS
+#define BOOST_NO_CXX11_NULLPTR
+#define BOOST_NO_CXX11_NUMERIC_LIMITS
+#define BOOST_NO_CXX11_NOEXCEPT
+#define BOOST_NO_CXX11_LAMBDAS
+#define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS
+#define BOOST_NO_MS_INT64_NUMERIC_LIMITS
+#define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS
+#define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
+#define BOOST_NO_CXX11_DELETED_FUNCTIONS
+#define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
+#define BOOST_NO_CXX11_DECLTYPE
+#define BOOST_NO_CXX11_DECLTYPE_N3276
+#define BOOST_NO_CXX11_CONSTEXPR
+#define BOOST_NO_COMPLETE_VALUE_INITIALIZATION
+#define BOOST_NO_CXX11_CHAR32_T
+#define BOOST_NO_CXX11_CHAR16_T
+#define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS
+#define BOOST_NO_CXX11_AUTO_DECLARATIONS
+#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
+#define BOOST_NO_CXX11_HDR_UNORDERED_SET
+#define BOOST_NO_CXX11_HDR_UNORDERED_MAP
+#define BOOST_NO_CXX11_HDR_TYPEINDEX
+#define BOOST_NO_CXX11_HDR_TUPLE
+#define BOOST_NO_CXX11_HDR_THREAD
+#define BOOST_NO_CXX11_HDR_SYSTEM_ERROR
+#define BOOST_NO_CXX11_HDR_REGEX
+#define BOOST_NO_CXX11_HDR_RATIO
+#define BOOST_NO_CXX11_HDR_RANDOM
+#define BOOST_NO_CXX11_HDR_MUTEX
+#define BOOST_NO_CXX11_HDR_INITIALIZER_LIST
+#define BOOST_NO_CXX11_HDR_FUTURE
+#define BOOST_NO_CXX11_HDR_FORWARD_LIST
+#define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE
+#define BOOST_NO_CXX11_HDR_CODECVT
+#define BOOST_NO_CXX11_HDR_CHRONO
+#define BOOST_NO_CXX11_USER_DEFINED_LITERALS
+#define BOOST_NO_CXX11_ALIGNAS
+#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES
+#define BOOST_NO_CXX11_INLINE_NAMESPACES
+
index 0eeb7ad3ee6fec7bc6c1c761f758072bf929240b..3b3541671205c8a65a5b534e0e509acf1ca362b8 100644 (file)
 //  example) also #define _MSC_VER
 #   define BOOST_COMPILER_CONFIG "boost/config/compiler/visualc.hpp"
 
-#elif defined (BOOST_ASSERT_CONFIG)
-// this must come last - generate an error if we don't
-// recognise the compiler:
-#  error "Unknown compiler - please configure (http://www.boost.org/libs/config/config.htm#configuring) and report the results to the main boost mailing list (http://www.boost.org/more/mailing_lists.htm#main)"
+#else
+
+#   warning Unknown boost compiler; using generic settings not tested for this compiler.
+#   define BOOST_COMPILER_CONFIG "boost/config/compiler/generic.hpp"
+
 
 #endif
index 3cb202bfd0ec27f7c3de5b58d0c84a95d330c74d..114e41834bb174a9da76637d49f3cb673427d62e 100644 (file)
@@ -35,8 +35,8 @@
 # As stated in README.Gromacs, this file is not part of GMock, but is written
 # specifically for the GROMACS build system from scratch.
 
-include(gmxGetMsvcTupleWorkaround)
-get_msvc_tuple_workaround_definitions(GMOCK_COMPILE_DEFINITIONS)
+include(gmxGetGmockTupleWorkaround)
+get_gmock_tuple_workaround(GMOCK_COMPILE_DEFINITIONS)
 set(GMOCK_COMPILE_DEFINITIONS ${GMOCK_COMPILE_DEFINITIONS} PARENT_SCOPE)
 
 # GTest/GMock suggest linking with pthreads when available for thread safety
index 6275ec1d12731c583ea943aa712cf7a2bc09ccb7..7560c11d5157083df1a45ff465c42583ddd9c27f 100644 (file)
@@ -14,3 +14,9 @@ gmock-1.7.0/gtest/src/
 
 The file CMakeLists.txt in this directory is part of the Gromacs build system
 and has been written from scratch.
+
+In the default version, gmock-1.7.0 assumes wcscasecmp() to be present on Linux.
+This is not the case on all platforms, so on line 1610 of gtest/src/gtest.cc
+we have added a define to only use this if GTEST_HAS_WCSCASECMP is set. Since
+we never set this define, we fall back on the alternative internal implementation
+which should be perfectly fine for now.
index 6de53dd0198c3a0bdb3857dbc4b9f7e5be26002a..e2b5c5b6f7a57c4138eabd2c2961a09dce0495fa 100644 (file)
@@ -1607,7 +1607,7 @@ bool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs,
 
 #if GTEST_OS_WINDOWS
   return _wcsicmp(lhs, rhs) == 0;
-#elif GTEST_OS_LINUX && !GTEST_OS_LINUX_ANDROID
+#elif GTEST_OS_LINUX && !GTEST_OS_LINUX_ANDROID && GTEST_HAS_WCSCASECMP
   return wcscasecmp(lhs, rhs) == 0;
 #else
   // Android, Mac OS X and Cygwin don't define wcscasecmp.
index 895db00ff43300d89488860a71b23d2ae9151643..5a183ab6b51bfff7d9834ff10ea08bc2fc6dc675 100644 (file)
@@ -169,7 +169,8 @@ extern "C"
 #elif defined(__FUJITSU) && defined(__sparc__)
 
 /* Fujitsu FX10 SPARC compiler requires gcc compatibility with -Xg */
-#error Atomics support for Fujitsu FX10 compiler requires -Xg (gcc compatibility)
+#warning Atomics support for Fujitsu FX10 compiler requires -Xg (gcc compatibility)
+#define TMPI_NO_ATOMICS
 
 #elif defined(_CRAYC)
 
index 559258e8d889a59eb95aa0d366ad14de13e0bd58..1dc5d995d87dc0b2173e3e0c7d6cc69a29af0b24 100644 (file)
@@ -162,16 +162,18 @@ static inline int tMPI_Atomic_ptr_cas(tMPI_Atomic_ptr_t *a,
                                       void              *newval)
 {
     void* prev;
-#ifndef __x86_64__
-    __asm__ __volatile__("lock ; cmpxchgl %1,%2"
+#if (defined(__x86_64__) && !defined(__ILP32__))
+    __asm__ __volatile__("lock ; cmpxchgq %1,%2"
                          : "=a" (prev)
                          : "q" (newval), "m" (a->value), "0" (oldval)
                          : "memory");
-#else
-    __asm__ __volatile__("lock ; cmpxchgq %1,%2"
+#elif (defined(__x86_64__) && defined(__ILP32__)) || defined(__i386__)
+    __asm__ __volatile__("lock ; cmpxchgl %1,%2"
                          : "=a" (prev)
                          : "q" (newval), "m" (a->value), "0" (oldval)
                          : "memory");
+#else
+#    error Cannot detect whether this is a 32-bit or 64-bit x86 build.
 #endif
     return prev == oldval;
 }
@@ -194,17 +196,18 @@ static inline int tMPI_Atomic_swap(tMPI_Atomic_t *a, int b)
 static inline void *tMPI_Atomic_ptr_swap(tMPI_Atomic_ptr_t *a, void *b)
 {
     void *volatile *ret = (void* volatile*)b;
-#ifndef __LP64__
-    __asm__ __volatile__("\txchgl %0, %1;"
+#if (defined(__x86_64__) && !defined(__ILP32__))
+    __asm__ __volatile__("\txchgq %0, %1;"
                          : "+r" (ret), "+m" (a->value)
                          :
                          : "memory");
-
-#else
-    __asm__ __volatile__("\txchgq %0, %1;"
+#elif (defined(__x86_64__) && defined(__ILP32__)) || defined(__i386__)
+    __asm__ __volatile__("\txchgl %0, %1;"
                          : "+r" (ret), "+m" (a->value)
                          :
                          : "memory");
+#else
+#    error Cannot detect whether this is a 32-bit or 64-bit x86 build.
 #endif
     return (void*)ret;
 }
index c14fece0aec9b2fb6f5f9cc898f377f83823d622..55dc204df5c45c4da35c4c85fc1452ed600fdf83 100644 (file)
@@ -74,8 +74,8 @@ AbstractAnalysisArrayData::tryGetDataFrameInternal(int index) const
         = value_.begin() + index * columnCount();
     return AnalysisDataFrameRef(
             AnalysisDataFrameHeader(index, xvalue(index), 0.0),
-            AnalysisDataValuesRef(begin, begin + columnCount()),
-            AnalysisDataPointSetInfosRef(&pointSetInfo_, 1));
+            constArrayRefFromVector<AnalysisDataValue>(begin, begin + columnCount()),
+            constArrayRefFromArray(&pointSetInfo_, 1));
 }
 
 
@@ -184,8 +184,8 @@ AbstractAnalysisArrayData::valuesReady()
         modules.notifyPointsAdd(
                 AnalysisDataPointSetRef(
                         header, pointSetInfo_,
-                        AnalysisDataValuesRef(valueIter,
-                                              valueIter + columnCount())));
+                        constArrayRefFromVector<AnalysisDataValue>(valueIter,
+                                                                   valueIter + columnCount())));
         modules.notifyFrameFinish(header);
     }
     modules.notifyDataFinish();
index 12ff2c03c7b9ad33f378c8e8a364def0047a8caf..cfa09e86a3811889cfe6adbabfe52bd4f235e492 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2012,2013, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,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.
@@ -74,8 +74,8 @@ AnalysisDataPointSetRef::AnalysisDataPointSetRef(
     : header_(header),
       dataSetIndex_(pointSetInfo.dataSetIndex()),
       firstColumn_(pointSetInfo.firstColumn()),
-      values_(&*values.begin() + pointSetInfo.valueOffset(),
-              pointSetInfo.valueCount())
+      values_(constArrayRefFromArray(&*values.begin() + pointSetInfo.valueOffset(),
+                                     pointSetInfo.valueCount()))
 {
     GMX_ASSERT(header_.isValid(),
                "Invalid point set reference should not be constructed");
@@ -86,7 +86,7 @@ AnalysisDataPointSetRef::AnalysisDataPointSetRef(
         const AnalysisDataFrameHeader        &header,
         const std::vector<AnalysisDataValue> &values)
     : header_(header), dataSetIndex_(0), firstColumn_(0),
-      values_(values.begin(), values.end())
+      values_(constArrayRefFromVector<AnalysisDataValue>(values.begin(), values.end()))
 {
     GMX_ASSERT(header_.isValid(),
                "Invalid point set reference should not be constructed");
@@ -166,8 +166,8 @@ AnalysisDataFrameRef::AnalysisDataFrameRef(
         const AnalysisDataFrameHeader               &header,
         const std::vector<AnalysisDataValue>        &values,
         const std::vector<AnalysisDataPointSetInfo> &pointSets)
-    : header_(header), values_(values.begin(), values.end()),
-      pointSets_(pointSets.begin(), pointSets.end())
+    : header_(header), values_(constArrayRefFromVector<AnalysisDataValue>(values.begin(), values.end())),
+      pointSets_(constArrayRefFromVector<AnalysisDataPointSetInfo>(pointSets.begin(), pointSets.end()))
 {
     GMX_ASSERT(!pointSets_.empty(), "There must always be a point set");
 }
@@ -176,7 +176,7 @@ AnalysisDataFrameRef::AnalysisDataFrameRef(
 AnalysisDataFrameRef::AnalysisDataFrameRef(
         const AnalysisDataFrameRef &frame, int firstColumn, int columnCount)
     : header_(frame.header()),
-      values_(&frame.values_[firstColumn], columnCount),
+      values_(constArrayRefFromArray(&frame.values_[firstColumn], columnCount)),
       pointSets_(frame.pointSets_)
 {
     // FIXME: This doesn't produce a valid internal state, although it does
index ec80d9b4c8c8552d1e94cb254ab32d23031f00a5..57dfea17c7bbd6564a1d5e11edaf3bfd52ed6415 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2012,2013, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,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.
@@ -635,7 +635,7 @@ AnalysisDataStorageFrameData::addPointSet(int dataSetIndex, int firstColumn,
     AnalysisDataPointSetInfo pointSetInfo(0, valueCount,
                                           dataSetIndex, firstColumn);
     AnalysisDataPointSetRef  pointSet(header(), pointSetInfo,
-                                      AnalysisDataValuesRef(begin, end));
+                                      constArrayRefFromVector<AnalysisDataValue>(begin, end));
     storageImpl().modules_->notifyParallelPointsAdd(pointSet);
     if (storageImpl().shouldNotifyImmediately())
     {
@@ -684,7 +684,7 @@ AnalysisDataStorageFrameData::pointSet(int index) const
                "Invalid point set index");
     return AnalysisDataPointSetRef(
             header_, pointSets_[index],
-            AnalysisDataValuesRef(values_.begin(), values_.end()));
+            constArrayRefFromVector<AnalysisDataValue>(values_.begin(), values_.end()));
 }
 
 }   // namespace internal
index 8ddff6fb8c395f21f3b4f5cc7216c9b6af5d833b..66c0f2abada26e0021ab6b58c3d363536ca6b665 100644 (file)
@@ -496,7 +496,7 @@ gmx_bool parse_common_args(int *argc, char *argv[], unsigned long Flags,
         fileOptManager.disableInputOptionChecking(
                 FF(PCA_NOT_READ_NODE) || FF(PCA_DISABLE_INPUT_FILE_CHECKING));
         options.addManager(&fileOptManager);
-        options.setDescription(gmx::ConstArrayRef<const char *>(desc, ndesc));
+        options.setDescription(gmx::constArrayRefFromArray<const char *>(desc, ndesc));
 
         options.addOption(
                 gmx::IntegerOption("nice").store(&nicelevel)
@@ -572,7 +572,7 @@ gmx_bool parse_common_args(int *argc, char *argv[], unsigned long Flags,
             gmx::CommandLineHelpWriter(options)
                 .setShowDescriptions(true)
                 .setTimeUnitString(timeUnitManager.timeUnitAsString())
-                .setKnownIssues(gmx::ConstArrayRef<const char *>(bugs, nbugs))
+                .setKnownIssues(gmx::constArrayRefFromArray(bugs, nbugs))
                 .writeHelp(*context);
             return FALSE;
         }
index 954139b6d09120fb059d4a363902c03de26581cf..039e36dcc06a76381c0d72f14169e73bb4885d33 100644 (file)
 #endif
 
 #ifdef HAVE_SCHED_H
-#define _GNU_SOURCE
-#include <sched.h>
+#  ifndef _GNU_SOURCE
+#    define _GNU_SOURCE 1
+#  endif
+#  include <sched.h>
 #endif
 
 #include <stdio.h>
@@ -556,7 +558,7 @@ cpuid_check_amd_x86(gmx_cpuid_t                cpuid)
     /* Query APIC information on AMD */
     if (max_extfn >= 0x80000008)
     {
-#if (defined HAVE_SCHED_H && defined HAVE_SCHED_SETAFFINITY && defined HAVE_SYSCONF && defined __linux__)
+#if (defined HAVE_SCHED_AFFINITY && defined HAVE_SYSCONF && defined __linux__)
         /* Linux */
         unsigned int   i;
         cpu_set_t      cpuset, save_cpuset;
@@ -670,7 +672,7 @@ cpuid_check_intel_x86(gmx_cpuid_t                cpuid)
     if (max_stdfn >= 0xB)
     {
         /* Query x2 APIC information from cores */
-#if (defined HAVE_SCHED_H && defined HAVE_SCHED_SETAFFINITY && defined HAVE_SYSCONF && defined __linux__)
+#if (defined HAVE_SCHED_AFFINITY && defined HAVE_SYSCONF && defined __linux__)
         /* Linux */
         unsigned int   i;
         cpu_set_t      cpuset, save_cpuset;
index 17aa65ec069909a32333ee58d8db22d125f0c6ec..52898a0ed88afb23ca556448939a465ff67aa5b2 100644 (file)
  * the research papers on the package. Check out http://www.gromacs.org.
  */
 #include "config.h"
-#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_GETAFFINITY)
-#define _GNU_SOURCE
-#include <sched.h>
-#include <sys/syscall.h>
+#if defined(HAVE_SCHED_H)
+#  ifndef _GNU_SOURCE
+#    define _GNU_SOURCE 1
+#  endif
+#  include <sched.h>
+#  include <sys/syscall.h>
 #endif
 #include <string.h>
 #include <errno.h>
@@ -376,7 +378,7 @@ gmx_check_thread_affinity_set(FILE            *fplog,
                               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;
@@ -495,5 +497,5 @@ gmx_check_thread_affinity_set(FILE            *fplog,
             fprintf(debug, "Default affinity mask found\n");
         }
     }
-#endif /* HAVE_SCHED_GETAFFINITY */
+#endif /* HAVE_SCHED_AFFINITY */
 }
index f58a75b0019e60fd00d62ae2bc6e69bf9b4f011b..322f0afed70aecc9533646e37d43e741e9d38097 100644 (file)
@@ -574,6 +574,8 @@ void check_ir(const char *mdparin, t_inputrec *ir, t_gromppopts *opts,
         CHECK(ir->nstlist <= 0);
         sprintf(err_buf, "TPI does not work with full electrostatics other than PME");
         CHECK(EEL_FULL(ir->coulombtype) && !EEL_PME(ir->coulombtype));
+        sprintf(err_buf, "TPI does not work (yet) with the Verlet cut-off scheme");
+        CHECK(ir->cutoff_scheme == ecutsVERLET);
     }
 
     /* SHAKE / LINCS */
index 88a8cd3aecaa5e91b49dacc481a0852cd15543f0..e2a26c73aa1d52a02d9e0f9b2c08bb1e744a808c 100644 (file)
@@ -153,6 +153,7 @@ gmx_pme_pp_t gmx_pme_pp_init(t_commrec *cr);
 /* Initialize the PME-only side of the PME <-> PP communication */
 
 void gmx_pme_send_parameters(t_commrec *cr,
+                             const interaction_const_t *ic,
                              gmx_bool bFreeEnergy_q, gmx_bool bFreeEnergy_lj,
                              real *chargeA, real *chargeB,
                              real *sqrt_c6A, real *sqrt_c6B,
index b94aa743fc697c28a79b2e435c8c39ca4d434123..09480a4be4b1b5017706b7c70cef6a6257c572a1 100644 (file)
@@ -9770,7 +9770,9 @@ void dd_partition_system(FILE                *fplog,
     if (!(cr->duty & DUTY_PME))
     {
         /* Send the charges and/or c6/sigmas to our PME only node */
-        gmx_pme_send_parameters(cr, mdatoms->nChargePerturbed, mdatoms->nTypePerturbed,
+        gmx_pme_send_parameters(cr,
+                                fr->ic,
+                                mdatoms->nChargePerturbed, mdatoms->nTypePerturbed,
                                 mdatoms->chargeA, mdatoms->chargeB,
                                 mdatoms->sqrt_c6A, mdatoms->sqrt_c6B,
                                 mdatoms->sigmaA, mdatoms->sigmaB,
index 99385ff3cac17b1fe9e1fc6cb3210b588c870f0f..c051d7e763696668fbdea0f26f390ae12752875e 100644 (file)
 #endif
 #endif
 
-        /* Mask for the cut-off to avoid overflow in gmx_simd_exp_r */
+        /* Mask for the cut-off to avoid overflow of cr2^2 */
         cr2_S0        = gmx_simd_mul_r(lje_c2_S, gmx_simd_blendzero_r(rsq_S0, wco_vdw_S0));
 #ifndef HALF_LJ
         cr2_S2        = gmx_simd_mul_r(lje_c2_S, gmx_simd_blendzero_r(rsq_S2, wco_vdw_S2));
index c567589ed5319c66148843e9195a12b913ef6fea..64467a121c95bca9f9a22629816ac9b27e03435a 100644 (file)
 #endif
 #endif
 
-        /* Mask for the cut-off to avoid overflow in gmx_simd_exp_r */
+        /* Mask for the cut-off to avoid overflow of cr2^2 */
         cr2_S0        = gmx_simd_mul_r(lje_c2_S, gmx_simd_blendzero_r(rsq_S0, wco_vdw_S0));
         cr2_S1        = gmx_simd_mul_r(lje_c2_S, gmx_simd_blendzero_r(rsq_S1, wco_vdw_S1));
 #ifndef HALF_LJ
index a22020a633a0f5ad3fe357d84497ebc01364822b..8069880ce220d14201c2550add48308fc8100d30 100644 (file)
@@ -99,6 +99,9 @@ int n_bonded_dx(gmx_mtop_t *mtop, gmx_bool bExcl)
      */
     ndx      = 0;
     ndx_excl = 0;
+#if __ICC == 1400 || __ICL == 1400
+#pragma novector /* Work-around for incorrect vectorization */
+#endif
     for (mb = 0; mb < mtop->nmolblock; mb++)
     {
         molt = &mtop->moltype[mtop->molblock[mb].type];
index 924420ce0f3ad61516c82b2b172f58b9612330f6..6e6a40e3b62bca21a158036c172f43c59a112334 100644 (file)
@@ -3988,7 +3988,8 @@ reduce_threadgrid_overlap(gmx_pme_t pme,
                     if (bCommY)
                     {
                         commbuf = commbuf_y;
-                        buf_my  = ty1 - offy;
+                        /* The y-size of the communication buffer is order-1 */
+                        buf_my  = pmegrid->order - 1;
                         if (bCommX)
                         {
                             /* We index commbuf modulo the local grid size */
index 9d9fa384572677207866cf1a269ab8945e6c3709..d245e92a30b1781a7da46ea98908c45525533962 100644 (file)
@@ -188,9 +188,11 @@ static void gmx_pme_send_coeffs_coords(t_commrec *cr, int flags,
 
     if (debug)
     {
-        fprintf(debug, "PP rank %d sending to PME rank %d: %d%s%s\n",
+        fprintf(debug, "PP rank %d sending to PME rank %d: %d%s%s%s%s\n",
                 cr->sim_nodeid, dd->pme_nodeid, n,
                 flags & PP_PME_CHARGE ? " charges" : "",
+                flags & PP_PME_SQRTC6 ? " sqrtC6" : "",
+                flags & PP_PME_SIGMA  ? " sigma" : "",
                 flags & PP_PME_COORD  ? " coordinates" : "");
     }
 
@@ -293,6 +295,7 @@ static void gmx_pme_send_coeffs_coords(t_commrec *cr, int flags,
 }
 
 void gmx_pme_send_parameters(t_commrec *cr,
+                             const interaction_const_t *ic,
                              gmx_bool bFreeEnergy_q, gmx_bool bFreeEnergy_lj,
                              real *chargeA, real *chargeB,
                              real *sqrt_c6A, real *sqrt_c6B,
@@ -301,15 +304,14 @@ void gmx_pme_send_parameters(t_commrec *cr,
 {
     int flags;
 
-    /* We always send the charges, even with only LJ- and no Coulomb-PME */
-    flags = PP_PME_CHARGE;
-    if (sqrt_c6A != NULL)
+    flags = 0;
+    if (EEL_PME(ic->eeltype))
     {
-        flags |= PP_PME_SQRTC6;
+        flags |= PP_PME_CHARGE;
     }
-    if (sigmaA != NULL)
+    if (EVDW_PME(ic->vdwtype))
     {
-        flags |= PP_PME_SIGMA;
+        flags |= (PP_PME_SQRTC6 | PP_PME_SIGMA);
     }
     if (bFreeEnergy_q || bFreeEnergy_lj)
     {
@@ -559,9 +561,10 @@ int gmx_pme_recv_coeffs_coords(struct gmx_pme_pp          *pme_pp,
                         nat += pme_pp->nat[sender];
                         if (debug)
                         {
-                            fprintf(debug, "Received from PP rank %d: %d "
-                                    "charges\n",
-                                    pme_pp->node[sender], pme_pp->nat[sender]);
+                            fprintf(debug, "Received from PP rank %d: %d %s\n",
+                                    pme_pp->node[sender], pme_pp->nat[sender],
+                                    (q == eCommType_ChargeA ||
+                                     q == eCommType_ChargeB) ? "charges" : "params");
                         }
                     }
                 }
index c19a5ef38c8ac71d13ab95d0af22291d0a2dc00a..d517174f1b353d40ca35673e8fc4269e3f7e170a 100644 (file)
@@ -166,6 +166,11 @@ double do_tpi(FILE *fplog, t_commrec *cr,
     real bU_bin_limit      = 50;
     real bU_logV_bin_limit = bU_bin_limit + 10;
 
+    if (inputrec->cutoff_scheme == ecutsVERLET)
+    {
+        gmx_fatal(FARGS, "TPI does not work (yet) with the Verlet cut-off scheme");
+    }
+
     nnodes = cr->nnodes;
 
     top = gmx_mtop_generate_local_top(top_global, inputrec);
index 00e7bd33a9a4a69b2a681b51445496b0717dce57..2eff412668fad91f94adff76cf904a1a45e2a6dd 100644 (file)
@@ -357,7 +357,7 @@ class WrapperToVector : public WrapperInterface
 std::string toUpperCase(const std::string &text)
 {
     std::string result(text);
-    transform(result.begin(), result.end(), result.begin(), toupper);
+    std::transform(result.begin(), result.end(), result.begin(), toupper);
     return result;
 }
 
index a0a4a4023ba0651d14eae89940e5cdcf6eb60450..8c06ea6887f20c904a2fc0fe292d9c883785ddcf 100644 (file)
@@ -421,9 +421,9 @@ ConstArrayRef<int> FileNameOptionStorage::fileTypes() const
     const int genericTypeCount = ftp2generic_count(fileType_);
     if (genericTypeCount > 0)
     {
-        return ConstArrayRef<int>(ftp2generic_list(fileType_), genericTypeCount);
+        return constArrayRefFromArray<int>(ftp2generic_list(fileType_), genericTypeCount);
     }
-    return ConstArrayRef<int>(&fileType_, 1);
+    return constArrayRefFromArray<int>(&fileType_, 1);
 }
 
 /********************************************************************
index b50c4dbd539c81fa63cc38077b496cf05976995f..1e8f1cfdadfe46617dab5a475ca22e327ef95578 100644 (file)
@@ -639,14 +639,14 @@ void AnalysisNeighborhoodPairSearchImpl::startSearch(
                        "Exclusion IDs must be set when exclusions are enabled");
     if (positions.index_ < 0)
     {
-        testPositions_ = ConstArrayRef<rvec>(positions.x_, positions.count_);
+        testPositions_ = constArrayRefFromArray<rvec>(positions.x_, positions.count_);
         reset(0);
     }
     else
     {
         // Somewhat of a hack: setup the array such that only the last position
         // will be used.
-        testPositions_ = ConstArrayRef<rvec>(positions.x_, positions.index_ + 1);
+        testPositions_ = constArrayRefFromArray<rvec>(positions.x_, positions.index_ + 1);
         reset(positions.index_);
     }
 }
index 892496298aebe0d090dd194163a0d8b602e9c4a7..f317486fe2e9e9a3a95611e251b8a541a3845d57 100644 (file)
@@ -357,8 +357,8 @@ SelectionPosition::operator AnalysisNeighborhoodPositions() const
     if (sel_->hasOnlyAtoms())
     {
         // TODO: Move atomIndices() such that it can be reused here as well.
-        pos.exclusionIds(ConstArrayRef<int>(sel_->rawPositions_.m.mapb.a,
-                                            sel_->rawPositions_.m.mapb.nra));
+        pos.exclusionIds(constArrayRefFromArray<int>(sel_->rawPositions_.m.mapb.a,
+                                                     sel_->rawPositions_.m.mapb.nra));
     }
     return pos.selectSingleFromArray(i_);
 }
index 23440078337dee86c918735cd2c9b5fe81fa56b8..30f060c5577ce72d813cd822faa0207d314d6885 100644 (file)
@@ -336,8 +336,8 @@ class Selection
         //! Returns atom indices of all atoms in the selection.
         ConstArrayRef<int> atomIndices() const
         {
-            return ConstArrayRef<int>(sel_->rawPositions_.m.mapb.a,
-                                      sel_->rawPositions_.m.mapb.nra);
+            return constArrayRefFromArray(sel_->rawPositions_.m.mapb.a,
+                                          sel_->rawPositions_.m.mapb.nra);
         }
         //! Number of positions in the selection.
         int posCount() const { return data().posCount(); }
@@ -346,7 +346,7 @@ class Selection
         //! Returns coordinates for this selection as a continuous array.
         ConstArrayRef<rvec> coordinates() const
         {
-            return ConstArrayRef<rvec>(data().rawPositions_.x, posCount());
+            return constArrayRefFromArray(data().rawPositions_.x, posCount());
         }
         //! Returns whether velocities are available for this selection.
         bool hasVelocities() const { return data().rawPositions_.v != NULL; }
@@ -358,7 +358,7 @@ class Selection
         ConstArrayRef<rvec> velocities() const
         {
             GMX_ASSERT(hasVelocities(), "Velocities accessed, but unavailable");
-            return ConstArrayRef<rvec>(data().rawPositions_.v, posCount());
+            return constArrayRefFromArray(data().rawPositions_.v, posCount());
         }
         //! Returns whether forces are available for this selection.
         bool hasForces() const { return sel_->rawPositions_.f != NULL; }
@@ -370,7 +370,7 @@ class Selection
         ConstArrayRef<rvec> forces() const
         {
             GMX_ASSERT(hasForces(), "Forces accessed, but unavailable");
-            return ConstArrayRef<rvec>(data().rawPositions_.f, posCount());
+            return constArrayRefFromArray(data().rawPositions_.f, posCount());
         }
         //! Returns masses for this selection as a continuous array.
         ConstArrayRef<real> masses() const
@@ -380,8 +380,8 @@ class Selection
             // (and thus the masses and charges are fixed).
             GMX_ASSERT(data().posMass_.size() >= static_cast<size_t>(posCount()),
                        "Internal inconsistency");
-            return ConstArrayRef<real>(data().posMass_.begin(),
-                                       data().posMass_.begin() + posCount());
+            return constArrayRefFromVector<real>(data().posMass_.begin(),
+                                                 data().posMass_.begin() + posCount());
         }
         //! Returns charges for this selection as a continuous array.
         ConstArrayRef<real> charges() const
@@ -391,8 +391,8 @@ class Selection
             // (and thus the masses and charges are fixed).
             GMX_ASSERT(data().posCharge_.size() >= static_cast<size_t>(posCount()),
                        "Internal inconsistency");
-            return ConstArrayRef<real>(data().posCharge_.begin(),
-                                       data().posCharge_.begin() + posCount());
+            return constArrayRefFromVector<real>(data().posCharge_.begin(),
+                                                 data().posCharge_.begin() + posCount());
         }
         /*! \brief
          * Returns reference IDs for this selection as a continuous array.
@@ -401,7 +401,7 @@ class Selection
          */
         ConstArrayRef<int> refIds() const
         {
-            return ConstArrayRef<int>(data().rawPositions_.m.refid, posCount());
+            return constArrayRefFromArray(data().rawPositions_.m.refid, posCount());
         }
         /*! \brief
          * Returns mapped IDs for this selection as a continuous array.
@@ -410,7 +410,7 @@ class Selection
          */
         ConstArrayRef<int> mappedIds() const
         {
-            return ConstArrayRef<int>(data().rawPositions_.m.mapid, posCount());
+            return constArrayRefFromArray(data().rawPositions_.m.mapid, posCount());
         }
 
         //! Returns whether the covered fraction can change between frames.
@@ -657,7 +657,7 @@ class SelectionPosition
                 return ConstArrayRef<int>();
             }
             const int first = sel_->rawPositions_.m.mapb.index[i_];
-            return ConstArrayRef<int>(&atoms[first], atomCount());
+            return constArrayRefFromArray(&atoms[first], atomCount());
         }
         /*! \brief
          * Returns whether this position is selected in the current frame.
index 370235bd3160a5a15b3eddc9ec952a7750f1b10e..0d7c0db1e86a7d03858c717af653ca727815b095 100644 (file)
@@ -304,13 +304,13 @@ class ExclusionsHelper
 
         gmx::ConstArrayRef<int> refPosIds() const
         {
-            return gmx::ConstArrayRef<int>(exclusionIds_.begin(),
-                                           exclusionIds_.begin() + refPosCount_);
+            return gmx::constArrayRefFromVector<int>(exclusionIds_.begin(),
+                                                     exclusionIds_.begin() + refPosCount_);
         }
         gmx::ConstArrayRef<int> testPosIds() const
         {
-            return gmx::ConstArrayRef<int>(exclusionIds_.begin(),
-                                           exclusionIds_.begin() + testPosCount_);
+            return gmx::constArrayRefFromVector<int>(exclusionIds_.begin(),
+                                                     exclusionIds_.begin() + testPosCount_);
         }
 
     private:
index 5013ab595ddc48a050640fea7c1dbb943d6c9409..4c03a250bf84fff2cb5f666ad7d9304aa75a9643 100644 (file)
@@ -345,7 +345,8 @@ gmx_simd_exp2_f(gmx_simd_float_t x)
  * extended precision arithmetics to improve accuracy.
  *
  * \param x Argument.
- * \result exp(x). Undefined if input argument caused overflow.
+ * \result exp(x). Undefined if input argument caused overflow,
+ * which can happen if abs(x) \> 7e13.
  */
 static gmx_inline gmx_simd_float_t
 gmx_simd_exp_f(gmx_simd_float_t x)
@@ -1125,9 +1126,9 @@ gmx_simd_atan2_f(gmx_simd_float_t y, gmx_simd_float_t x)
  * that we can leave out of this routine.
  *
  * For pme tolerances of 1e-3 to 1e-8 and cutoffs of 0.5nm to 1.8nm,
- * the argument \f$beta r\f$ will be in the range 0.15 to ~4. Use your
- * favorite plotting program to realize how well-behaved \f$\frac{\mbox{erf}(z)}{z}\f$ is
- * in this range!
+ * the argument \f$beta r\f$ will be in the range 0.15 to ~4, which is
+ * the range used for the minimax fit. Use your favorite plotting program
+ * to realize how well-behaved \f$\frac{\mbox{erf}(z)}{z}\f$ is in this range!
  *
  * We approximate \f$f(z)=\mbox{erf}(z)/z\f$ with a rational minimax polynomial.
  * However, it turns out it is more efficient to approximate \f$f(z)/z\f$ and
@@ -1171,8 +1172,11 @@ gmx_simd_atan2_f(gmx_simd_float_t y, gmx_simd_float_t x)
  *    with the vector connecting the two particles and you have your
  *    vectorial force to add to the particles.
  *
- * This approximation achieves an accuracy slightly lower than 1e-6; when
- * added to \f$1/r\f$ the error will be insignificant.
+ * This approximation achieves an error slightly lower than 1e-6
+ * in single precision and 1e-11 in double precision
+ * for arguments smaller than 16 (\f$\beta r \leq 4 \f$);
+ * when added to \f$1/r\f$ the error will be insignificant.
+ * For \f$\beta r \geq 7206\f$ the return value can be inf or NaN.
  *
  */
 static gmx_simd_float_t
@@ -1248,8 +1252,12 @@ gmx_simd_pmecorrF_f(gmx_simd_float_t z2)
  * 6. Subtract the result from \f$1/r\f$, multiply by the product of the charges,
  *    and you have your potential.
  *
- * This approximation achieves an accuracy slightly lower than 1e-6; when
- * added to \f$1/r\f$ the error will be insignificant.
+ * This approximation achieves an error slightly lower than 1e-6
+ * in single precision and 4e-11 in double precision
+ * for arguments smaller than 16 (\f$ 0.15 \leq \beta r \leq 4 \f$);
+ * for \f$ \beta r \leq 0.15\f$ the error can be twice as high;
+ * when added to \f$1/r\f$ the error will be insignificant.
+ * For \f$\beta r \geq 7142\f$ the return value can be inf or NaN.
  */
 static gmx_simd_float_t
 gmx_simd_pmecorrV_f(gmx_simd_float_t z2)
index b4959ceba7377e8397d245ea8210e4acb115438b..a3213c99a5397be9fefabeedb793ede8a4f807c9 100644 (file)
@@ -279,6 +279,23 @@ TEST_F(SimdMathTest, gmxSimdExp2R)
 {
     setRange(-100, 100);
     GMX_EXPECT_SIMD_FUNC_NEAR(ref_exp2, gmx_simd_exp2_r);
+
+    // We do not care about the SIMD implementation getting denormal values right,
+    // but they must be clamped to zero rather than producing garbage.
+    // Check by setting the absolute tolerance to machine precision.
+    setAbsTol(GMX_REAL_EPS);
+
+    // First two values will have denormal results in single, third value in double too.
+    GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(ref_exp2(-150.0), ref_exp2(-300.0), ref_exp2(-1050.0)),
+                              gmx_simd_exp2_r(setSimdRealFrom3R(-150.0, -300.0, -1050.0)));
+
+    // Reset absolute tolerance to enforce ULP checking
+    setAbsTol(0.0);
+
+    // Make sure that underflowing values are set to zero.
+    // First two values underflow in single, third value in double too.
+    GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(ref_exp2(-200.0), ref_exp2(-600.0), ref_exp2(-1500.0)),
+                              gmx_simd_exp2_r(setSimdRealFrom3R(-200.0, -600.0, -1500.0)));
 }
 #endif
 
@@ -292,6 +309,22 @@ TEST_F(SimdMathTest, gmxSimdExpR)
 {
     setRange(-75, 75);
     GMX_EXPECT_SIMD_FUNC_NEAR(ref_exp, gmx_simd_exp_r);
+
+    // We do not care about the SIMD implementation getting denormal values right,
+    // but they must be clamped to zero rather than producing garbage.
+    // Check by setting the absolute tolerance to machine precision.
+    setAbsTol(GMX_REAL_EPS);
+    // First two values will have denormal results in single, third value in double too.
+    GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(ref_exp(-90.0), ref_exp(-100.0), ref_exp(-725.0)),
+                              gmx_simd_exp_r(setSimdRealFrom3R(-90.0, -100.0, -725.0)));
+
+    // Reset absolute tolerance to enforce ULP checking
+    setAbsTol(0.0);
+
+    // Make sure that underflowing values are set to zero.
+    // First two values underflow in single, third value in double too.
+    GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(ref_exp(-150.0), ref_exp(-300.0), ref_exp(-800.0)),
+                              gmx_simd_exp_r(setSimdRealFrom3R(-150.0, -300.0, -800.0)));
 }
 
 /*! \brief Function wrapper for erf(x), with argument/return in default Gromacs precision.
index c02f120ab0570bb1c86deb033fd4dd3f72cae886..982c712b7d4128cdd72027290082d6d6e29fc467 100644 (file)
@@ -144,41 +144,15 @@ class ArrayRef
          * \param[in] end    Pointer to the end of a range.
          *
          * Passed pointers must remain valid for the lifetime of this object.
+         *
+         * \note For clarity, use the non-member function arrayRefFromPointers
+         * instead.
          */
         ArrayRef(pointer begin, pointer end)
             : begin_(begin), end_(end)
         {
             GMX_ASSERT(end >= begin, "Invalid range");
         }
-        /*! \brief
-         * Constructs a reference to a particular range in a std::vector.
-         *
-         * \param[in] begin  Iterator to the beginning of a range.
-         * \param[in] end    Iterator to the end of a range.
-         *
-         * The referenced vector must remain valid and not be reallocated for
-         * the lifetime of this object.
-         */
-        ArrayRef(typename std::vector<value_type>::iterator begin,
-                 typename std::vector<value_type>::iterator end)
-            : begin_((begin != end) ? &*begin : NULL),
-              end_(begin_+(end-begin))
-        {
-            GMX_ASSERT(end >= begin, "Invalid range");
-        }
-        /*! \brief
-         * Constructs a reference to an array.
-         *
-         * \param[in] begin  Pointer to the beginning of the array.
-         *      May be NULL if \p size is zero.
-         * \param[in] size   Number of elements in the array.
-         *
-         * Passed pointer must remain valid for the lifetime of this object.
-         */
-        ArrayRef(pointer begin, size_type size)
-            : begin_(begin), end_(begin + size)
-        {
-        }
         //! \cond
         // Doxygen 1.8.5 doesn't parse the declaration correctly...
         /*! \brief
@@ -281,6 +255,62 @@ class ArrayRef
         pointer           end_;
 };
 
+
+/*! \brief
+ * Constructs a reference to a particular range from two pointers.
+ *
+ * \param[in] begin  Pointer to the beginning of a range.
+ * \param[in] end    Pointer to the end of a range.
+ *
+ * Passed pointers must remain valid for the lifetime of this object.
+ *
+ * \related ArrayRef
+ */
+template <typename T>
+ArrayRef<T> arrayRefFromPointers(T * begin, T * end)
+{
+    return ArrayRef<T>(begin, end);
+}
+
+/*! \brief
+ * Constructs a reference to an array
+ *
+ * \param[in] begin  Pointer to the beginning of the array.
+ *                   May be NULL if \p size is zero.
+ * \param[in] size   Number of elements in the array.
+ *
+ * Passed pointer must remain valid for the lifetime of this object.
+ *
+ * \related ArrayRef
+ */
+template <typename T>
+ArrayRef<T> arrayRefFromArray(T * begin, size_t size)
+{
+    return arrayRefFromPointers<T>(begin, begin+size);
+}
+
+/*! \brief
+ * Constructs a reference to a particular range in a std::vector.
+ *
+ * \param[in] begin  Iterator to the beginning of a range.
+ * \param[in] end    Iterator to the end of a range.
+ *
+ * The referenced vector must remain valid and not be reallocated for
+ * the lifetime of this object.
+ *
+ * \related ArrayRef
+ */
+template <typename T>
+ArrayRef<T> arrayRefFromVector(typename std::vector<T>::iterator begin,
+                               typename std::vector<T>::iterator end)
+{
+    T * p_begin = (begin != end) ? &*begin : NULL;
+    T * p_end   = p_begin + (end-begin);
+    return arrayRefFromPointers<T>(p_begin, p_end);
+}
+
+
+
 /*! \brief
  * STL-like container for non-mutable interface to a C array (or part of a
  * std::vector).
@@ -354,41 +384,15 @@ class ConstArrayRef
          * \param[in] end    Pointer to the end of a range.
          *
          * Passed pointers must remain valid for the lifetime of this object.
+         *
+         * \note For clarity, use the non-member function constArrayRefFromPointers
+         * instead.
          */
         ConstArrayRef(const_pointer begin, const_pointer end)
             : begin_(begin), end_(end)
         {
             GMX_ASSERT(end >= begin, "Invalid range");
         }
-        /*! \brief
-         * Constructs a reference to a particular range in a std::vector.
-         *
-         * \param[in] begin  Iterator to the beginning of a range.
-         * \param[in] end    Iterator to the end of a range.
-         *
-         * The referenced vector must remain valid and not be reallocated for
-         * the lifetime of this object.
-         */
-        ConstArrayRef(typename std::vector<value_type>::const_iterator begin,
-                      typename std::vector<value_type>::const_iterator end)
-            : begin_((begin != end) ? &*begin : NULL),
-              end_(begin_+(end-begin))
-        {
-            GMX_ASSERT(end >= begin, "Invalid range");
-        }
-        /*! \brief
-         * Constructs a reference to an array.
-         *
-         * \param[in] begin  Pointer to the beginning of the array.
-         *      May be NULL if \p size is zero.
-         * \param[in] size   Number of elements in the array.
-         *
-         * Passed pointer must remain valid for the lifetime of this object.
-         */
-        ConstArrayRef(const_pointer begin, size_type size)
-            : begin_(begin), end_(begin + size)
-        {
-        }
         //! \cond
         // Doxygen 1.8.5 doesn't parse the declaration correctly...
         /*! \brief
@@ -465,6 +469,60 @@ class ConstArrayRef
         const_pointer           end_;
 };
 
+
+/*! \brief
+ * Constructs a reference to a particular range from two pointers.
+ *
+ * \param[in] begin  Pointer to the beginning of a range.
+ * \param[in] end    Pointer to the end of a range.
+ *
+ * Passed pointers must remain valid for the lifetime of this object.
+ *
+ * \related ConstArrayRef
+ */
+template <typename T>
+ConstArrayRef<T> constArrayRefFromPointers(const T * begin, const T * end)
+{
+    return ConstArrayRef<T>(begin, end);
+}
+
+/*! \brief
+ * Constructs a reference to an array.
+ *
+ * \param[in] begin  Pointer to the beginning of the array.
+ *                   May be NULL if \p size is zero.
+ * \param[in] size   Number of elements in the array.
+ *
+ * Passed pointer must remain valid for the lifetime of this object.
+ *
+ * \related ConstArrayRef
+ */
+template <typename T>
+ConstArrayRef<T> constArrayRefFromArray(const T * begin, size_t size)
+{
+    return constArrayRefFromPointers<T>(begin, begin+size);
+}
+
+/*! \brief
+ * Constructs a reference to a particular range in a std::vector.
+ *
+ * \param[in] begin  Iterator to the beginning of a range.
+ * \param[in] end    Iterator to the end of a range.
+ *
+ * The referenced vector must remain valid and not be reallocated for
+ * the lifetime of this object.
+ *
+ * \related ConstArrayRef
+ */
+template <typename T>
+ConstArrayRef<T> constArrayRefFromVector(typename std::vector<T>::const_iterator begin,
+                                         typename std::vector<T>::const_iterator end)
+{
+    const T * p_begin = (begin != end) ? &*begin : NULL;
+    const T * p_end   = p_begin + (end-begin);
+    return constArrayRefFromPointers<T>(p_begin, p_end);
+}
+
 /*! \brief
  * Simple swap method for ArrayRef objects.
  *
index 75008d6bfbafd867c7377689f96686baac08d4c7..045e7c5616b2e4ace992cdb142f168d2f0d3db8f 100644 (file)
@@ -33,5 +33,5 @@
 # the research papers on the package. Check out http://www.gromacs.org.
 
 gmx_add_unit_test(TestUtilsUnitTests testutils-test
-                  refdata.cpp
-                  testasserts.cpp)
+                  refdata_tests.cpp
+                  testasserts_tests.cpp)
index bcf188a6621a2b05ee543004c2bb995ae5eeead1..3bd404724f3ba8cd9b703fe6ef00fd71afbff6b1 100644 (file)
@@ -60,6 +60,12 @@ status_code: ${status_code}
 status_string: ${status_string}
 log: ${log}")
     endif()
+    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}"