Merge branch release-2018
authorMark Abraham <mark.j.abraham@gmail.com>
Thu, 4 Jan 2018 15:25:43 +0000 (16:25 +0100)
committerMark Abraham <mark.j.abraham@gmail.com>
Thu, 4 Jan 2018 15:28:08 +0000 (16:28 +0100)
Lots of copyright bumps, also

Change-Id: I0f9e8d81b265cc96cbcc84d30267932af2ab5b69

93 files changed:
1  2 
CMakeLists.txt
cmake/gmxManageFFTLibraries.cmake
cmake/gmxManageGPU.cmake
src/gromacs/commandline/pargs.cpp
src/gromacs/domdec/domdec_setup.cpp
src/gromacs/energyanalysis/tests/legacyenergy.cpp
src/gromacs/ewald/pme-gather.cpp
src/gromacs/ewald/pme-spline-work.cpp
src/gromacs/ewald/pme-spread.cpp
src/gromacs/gpu_utils/gpu_utils.cu
src/gromacs/gpu_utils/gpu_utils.h
src/gromacs/gpu_utils/tests/gputest.cpp
src/gromacs/gpu_utils/tests/hostallocator.cpp
src/gromacs/gpu_utils/tests/pinnedmemorychecker.cpp
src/gromacs/hardware/architecture.h
src/gromacs/hardware/cpuinfo.cpp
src/gromacs/hardware/detecthardware.cpp
src/gromacs/listed-forces/bonded.cpp
src/gromacs/listed-forces/pairs.cpp
src/gromacs/mdlib/clincs.cpp
src/gromacs/mdlib/csettle.cpp
src/gromacs/mdlib/gmx_omp_nthreads.cpp
src/gromacs/mdlib/md_support.cpp
src/gromacs/mdlib/md_support.h
src/gromacs/mdlib/nbnxn_kernels/simd_2xnn/nbnxn_kernel_simd_2xnn_inner.h
src/gromacs/mdlib/nbnxn_kernels/simd_2xnn/nbnxn_kernel_simd_2xnn_outer.h
src/gromacs/mdlib/nbnxn_kernels/simd_4xn/nbnxn_kernel_simd_4xn_inner.h
src/gromacs/mdlib/nbnxn_kernels/simd_4xn/nbnxn_kernel_simd_4xn_outer.h
src/gromacs/mdlib/sim_util.cpp
src/gromacs/simd/impl_arm_neon/impl_arm_neon_definitions.h
src/gromacs/simd/impl_arm_neon/impl_arm_neon_util_float.h
src/gromacs/simd/impl_arm_neon_asimd/impl_arm_neon_asimd_definitions.h
src/gromacs/simd/impl_arm_neon_asimd/impl_arm_neon_asimd_util_double.h
src/gromacs/simd/impl_ibm_qpx/impl_ibm_qpx_definitions.h
src/gromacs/simd/impl_ibm_qpx/impl_ibm_qpx_simd_double.h
src/gromacs/simd/impl_ibm_qpx/impl_ibm_qpx_simd_float.h
src/gromacs/simd/impl_ibm_qpx/impl_ibm_qpx_util_double.h
src/gromacs/simd/impl_ibm_qpx/impl_ibm_qpx_util_float.h
src/gromacs/simd/impl_ibm_vmx/impl_ibm_vmx_definitions.h
src/gromacs/simd/impl_ibm_vmx/impl_ibm_vmx_util_float.h
src/gromacs/simd/impl_ibm_vsx/impl_ibm_vsx.h
src/gromacs/simd/impl_ibm_vsx/impl_ibm_vsx_definitions.h
src/gromacs/simd/impl_ibm_vsx/impl_ibm_vsx_util_double.h
src/gromacs/simd/impl_ibm_vsx/impl_ibm_vsx_util_float.h
src/gromacs/simd/impl_none/impl_none.h
src/gromacs/simd/impl_reference/impl_reference_definitions.h
src/gromacs/simd/impl_x86_avx2_128/impl_x86_avx2_128_definitions.h
src/gromacs/simd/impl_x86_avx2_256/impl_x86_avx2_256_definitions.h
src/gromacs/simd/impl_x86_avx_128_fma/impl_x86_avx_128_fma_definitions.h
src/gromacs/simd/impl_x86_avx_256/impl_x86_avx_256_definitions.h
src/gromacs/simd/impl_x86_avx_256/impl_x86_avx_256_util_double.h
src/gromacs/simd/impl_x86_avx_256/impl_x86_avx_256_util_float.h
src/gromacs/simd/impl_x86_avx_512/impl_x86_avx_512_definitions.h
src/gromacs/simd/impl_x86_avx_512/impl_x86_avx_512_util_double.h
src/gromacs/simd/impl_x86_avx_512/impl_x86_avx_512_util_float.h
src/gromacs/simd/impl_x86_avx_512_knl/impl_x86_avx_512_knl_definitions.h
src/gromacs/simd/impl_x86_mic/impl_x86_mic_definitions.h
src/gromacs/simd/impl_x86_mic/impl_x86_mic_util_double.h
src/gromacs/simd/impl_x86_mic/impl_x86_mic_util_float.h
src/gromacs/simd/impl_x86_sse2/impl_x86_sse2_definitions.h
src/gromacs/simd/impl_x86_sse2/impl_x86_sse2_util_float.h
src/gromacs/simd/impl_x86_sse4_1/impl_x86_sse4_1_definitions.h
src/gromacs/simd/simd_math.h
src/gromacs/simd/tests/bootstrap_loadstore.cpp
src/gromacs/simd/tests/simd.cpp
src/gromacs/simd/tests/simd.h
src/gromacs/simd/tests/simd4.cpp
src/gromacs/simd/tests/simd4_floatingpoint.cpp
src/gromacs/simd/tests/simd_floatingpoint.cpp
src/gromacs/simd/tests/simd_floatingpoint_util.cpp
src/gromacs/simd/tests/simd_integer.cpp
src/gromacs/simd/tests/simd_math.cpp
src/gromacs/tables/cubicsplinetable.cpp
src/gromacs/tables/cubicsplinetable.h
src/gromacs/tables/quadraticsplinetable.cpp
src/gromacs/tables/splineutil.cpp
src/gromacs/tables/tests/splinetable.cpp
src/gromacs/taskassignment/resourcedivision.cpp
src/gromacs/taskassignment/resourcedivision.h
src/gromacs/tools/check.cpp
src/gromacs/utility/basedefinitions.h
src/gromacs/utility/coolstuff.cpp
src/gromacs/utility/tests/CMakeLists.txt
src/programs/mdrun/md.cpp
src/programs/mdrun/runner.cpp
src/programs/mdrun/tests/pmetest.cpp
src/testutils/cmdlinetest.cpp
src/testutils/cmdlinetest.h
src/testutils/testasserts.h
src/testutils/tests/testasserts_tests.cpp
tests/CMakeLists.txt
tests/CheckTarget.cmake
tests/CppCheck.cmake

diff --combined CMakeLists.txt
index 7745cd0012206cdba57ae1aaa6abfffed8455df0,73469b7703e21ce8d266813e7881150616603e8c..86b52f7bb2e74c18b6e740872cf516592eea21bc
@@@ -1,7 -1,7 +1,7 @@@
  #
  # This file is part of the GROMACS molecular simulation package.
  #
--# Copyright (c) 2009,2010,2011,2012,2013,2014,2015,2016,2017, by the GROMACS development team, led by
++# Copyright (c) 2009,2010,2011,2012,2013,2014,2015,2016,2017,2018, 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.
@@@ -857,13 -857,18 +857,18 @@@ else(
      # RPATHs), and makes the binaries in the build tree relocatable.
      if(GMX_LIB_INSTALL_DIR STREQUAL "lib")
          set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
+         if(POLICY CMP0068)
+             cmake_policy(SET CMP0068 NEW) # From CMake-3.9
+             set(CMAKE_BUILD_WITH_INSTALL_NAME_DIR TRUE)
+         endif()
      endif()
      # Set the RPATH as relative to the executable location to make the
      # binaries relocatable.
-     if(NOT CMAKE_SYSTEM_NAME STREQUAL "Darwin") #Assume OS X >=10.5
-         set(CMAKE_INSTALL_RPATH "\$ORIGIN/../${GMX_LIB_INSTALL_DIR}")
-     else()
+     if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") #Assume OS X >=10.5
          set(CMAKE_INSTALL_RPATH "@executable_path/../${GMX_LIB_INSTALL_DIR}")
+         set(CMAKE_INSTALL_NAME_DIR ${CMAKE_INSTALL_RPATH})
+     else()
+         set(CMAKE_INSTALL_RPATH "\$ORIGIN/../${GMX_LIB_INSTALL_DIR}")
      endif()
      set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
      set(CMAKE_MACOSX_RPATH 1)
index 224f03b684dd5a53da5b9e247a75d3815fce05df,2f72efcae7ba3b0a66d01bd169c690e3aa8a56e2..f496ddd9594dfa88fcf7af8f59ba2e404cbe066a
@@@ -1,7 -1,7 +1,7 @@@
  #
  # This file is part of the GROMACS molecular simulation package.
  #
--# Copyright (c) 2012,2013,2014,2015,2016,2017, by the GROMACS development team, led by
++# Copyright (c) 2012,2013,2014,2015,2016,2017,2018, 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.
@@@ -68,8 -68,11 +68,11 @@@ if(${GMX_FFT_LIBRARY} STREQUAL "FFTW3"
  
      if(GMX_BUILD_OWN_FFTW)
  
-         if(WIN32)
-             message(FATAL_ERROR "Cannot build FFTW3 automatically (GMX_BUILD_OWN_FFTW=ON) on Windows")
+         if(MSVC)
+             message(FATAL_ERROR "Cannot build FFTW3 automatically (GMX_BUILD_OWN_FFTW=ON) in Visual Studio")
+         endif()
+         if(CMAKE_GENERATOR STREQUAL "Ninja")
+             message(FATAL_ERROR "Cannot build FFTW3 automatically (GMX_BUILD_OWN_FFTW=ON) with ninja")
          endif()
  
          add_subdirectory(src/contrib/fftw)
diff --combined cmake/gmxManageGPU.cmake
index e05511239bf1fa3ba38b72ff4c8f6bd3d4940528,42a7a22e29824e9de7c21ab5f984511a89868102..b32df691083db65993eeeee09230966961ffce65
@@@ -1,7 -1,7 +1,7 @@@
  #
  # This file is part of the GROMACS molecular simulation package.
  #
--# Copyright (c) 2012,2013,2014,2015,2016,2017, by the GROMACS development team, led by
++# Copyright (c) 2012,2013,2014,2015,2016,2017,2018, 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.
@@@ -39,6 -39,8 +39,8 @@@
  # - if CUDA is not found but GPUs were detected issue a warning
  if (NOT DEFINED GMX_GPU)
      set(GMX_GPU_AUTO TRUE CACHE INTERNAL "GPU acceleration will be selected automatically")
+ else()
+     set(GMX_GPU_AUTO FALSE CACHE INTERNAL "GPU acceleration will be selected automatically")
  endif()
  option(GMX_GPU "Enable GPU acceleration" OFF)
  
index c4419f7f03e2f7b8e7feef5b7e171001cb7e3569,c0b321d7114a5539808b371b6a9c1523579f22f7..c35c3a1b35b1542b835c45890a81aa5edcf1e758
@@@ -3,7 -3,7 +3,7 @@@
   *
   * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
   * Copyright (c) 2001-2004, The GROMACS development team.
-- * Copyright (c) 2013,2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2013,2014,2015,2016,2017,2018, 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.
@@@ -512,21 -512,21 +512,21 @@@ gmx_bool parse_common_args(int *argc, c
              options.addOption(
                      gmx::DoubleOption("b")
                          .store(&tbegin).storeIsSet(&bBeginTimeSet).timeValue()
-                         .description("First frame (%t) to read from trajectory"));
+                         .description("Time of first frame to read from trajectory (default unit %t)"));
          }
          if (isFlagSet(PCA_CAN_END))
          {
              options.addOption(
                      gmx::DoubleOption("e")
                          .store(&tend).storeIsSet(&bEndTimeSet).timeValue()
-                         .description("Last frame (%t) to read from trajectory"));
+                         .description("Time of last frame to read from trajectory (default unit %t)"));
          }
          if (isFlagSet(PCA_CAN_DT))
          {
              options.addOption(
                      gmx::DoubleOption("dt")
                          .store(&tdelta).storeIsSet(&bDtSet).timeValue()
-                         .description("Only use frame when t MOD dt = first time (%t)"));
+                         .description("Only use frame when t MOD dt = first time (default unit %t)"));
          }
          gmx::TimeUnit  timeUnit = gmx::TimeUnit_Default;
          if (isFlagSet(PCA_TIME_UNIT))
index 4b4d4231b8dbd2b0321ca319c3eceaa05d70099d,dfa9c1418405853a3456c53a04ac9ca7e894e01a..69956c9a8395cfb2207b528737458997a939be7f
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2008,2009,2010,2011,2012,2013,2014,2015,2017, by the GROMACS development team, led by
++ * Copyright (c) 2008,2009,2010,2011,2012,2013,2014,2015,2017,2018, 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.
@@@ -811,7 -811,10 +811,10 @@@ real dd_choose_grid(FILE *fplog
                  cr->npmenodes = nPmeRanks;
                  if (fplog)
                  {
-                     fprintf(fplog, "Using %d separate PME ranks, per user request\n", cr->npmenodes);
+                     fprintf(fplog, "Using %d separate PME ranks\n", cr->npmenodes);
+                     // TODO: there was a ", per user request" note here, but it's not correct anymore,
+                     // as with GPUs decision about nPmeRanks can be made in runner() as well.
+                     // Consider a single spot for setting nPmeRanks.
                  }
              }
          }
index dc2d6217ce4e84d41f3872b974c158d2fed19df9,7162fc1b179d3a77fc0f44419c5be00d172879de..b8a4edf43db7ec48d9daa4c3150669193cc8262e
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2017, by the GROMACS development team, led by
++ * Copyright (c) 2017,2018, 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.
@@@ -133,6 -133,11 +133,11 @@@ class EnergyTest : public CommandLineTe
              stdioHelper.redirectStringToStdin(stringForStdin);
              ASSERT_EQ(0, gmx_energy(cmdline.argc(), cmdline.argv()));
  
+             // All the .edr files used in the tests contain only
+             // single-precision values, so even from a
+             // double-precision build they should conform to
+             // tolerances suitable for single-precision values.
+             setDefaultTolerance(defaultFloatTolerance());
              checkOutputFiles();
          }
  };
index 2c9e961feef8c5bf448aea7e351098463265cf21,edaf535b5c8c99bdd5194d0fb4b7be60912f58f0..e9c5c0d8935697f254c46f9c8a140e33ea0bb4bb
@@@ -3,7 -3,7 +3,7 @@@
   *
   * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
   * Copyright (c) 2001-2004, The GROMACS development team.
-- * Copyright (c) 2013,2014,2015,2017, by the GROMACS development team, led by
++ * Copyright (c) 2013,2014,2015,2017,2018, 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.
@@@ -197,7 -197,7 +197,7 @@@ struct do_fsplin
          *S0 = load4U(data-offset);
          *S1 = load4U(data-offset+4);
  #else
-         GMX_ALIGNED(real, GMX_SIMD4_WIDTH)  buf_aligned[GMX_SIMD4_WIDTH*2];
+         alignas(GMX_SIMD_ALIGNMENT) real  buf_aligned[GMX_SIMD4_WIDTH*2];
          /* Copy data to an aligned buffer */
          for (int i = 0; i < order; i++)
          {
index 5859a340455ffac1dfee4a854c89cf942181fe5b,cb4a625084853d7923d910030aaebeb988851e8f..37b8b07190f3a9ba31596aadd7cfe2ed9a78dfec
@@@ -3,7 -3,7 +3,7 @@@
   *
   * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
   * Copyright (c) 2001-2004, The GROMACS development team.
-- * Copyright (c) 2013,2014,2015,2017, by the GROMACS development team, led by
++ * Copyright (c) 2013,2014,2015,2017,2018, 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.
@@@ -54,7 -54,7 +54,7 @@@ pme_spline_work *make_pme_spline_work(i
      pme_spline_work *work;
  
  #ifdef PME_SIMD4_SPREAD_GATHER
-     GMX_ALIGNED(real, GMX_SIMD4_WIDTH)  tmp[GMX_SIMD4_WIDTH*2];
+     alignas(GMX_SIMD_ALIGNMENT) real  tmp[GMX_SIMD4_WIDTH*2];
      Simd4Real        zero_S;
      Simd4Real        real_mask_S0, real_mask_S1;
      int              of, i;
index b3db6c366bc141439eeed445822338021ed92c8c,f38efc81bca8695a3cd981db65fda8c53e40e60b..3f70f80ed57be8b637a80afbce222c5b2ddd71f5
@@@ -3,7 -3,7 +3,7 @@@
   *
   * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
   * Copyright (c) 2001-2004, The GROMACS development team.
-- * Copyright (c) 2013,2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2013,2014,2015,2016,2017,2018, 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.
@@@ -329,7 -329,7 +329,7 @@@ static void spread_coefficients_bspline
      int            offx, offy, offz;
  
  #if defined PME_SIMD4_SPREAD_GATHER && !defined PME_SIMD4_UNALIGNED
-     GMX_ALIGNED(real, GMX_SIMD4_WIDTH)  thz_aligned[GMX_SIMD4_WIDTH*2];
+     alignas(GMX_SIMD_ALIGNMENT) real  thz_aligned[GMX_SIMD4_WIDTH*2];
  #endif
  
      pnx = pmegrid->s[XX];
index 84e918fc01170c3e5262e9393e591df1eafab1a8,9ca379ee96366cf64016c78b09fdafd5891fcad5..2df4709ab4755440375242777b30326fe470cbaa
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by
   * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
   * and including many others, as listed in the AUTHORS file in the
   * top-level source directory and at http://www.gromacs.org.
@@@ -55,6 -55,7 +55,7 @@@
  #include "gromacs/hardware/gpu_hw_info.h"
  #include "gromacs/utility/basedefinitions.h"
  #include "gromacs/utility/cstringutil.h"
+ #include "gromacs/utility/exceptions.h"
  #include "gromacs/utility/fatalerror.h"
  #include "gromacs/utility/gmxassert.h"
  #include "gromacs/utility/logger.h"
@@@ -113,12 -114,12 +114,12 @@@ static void checkCompiledTargetCompatib
      if (cudaErrorInvalidDeviceFunction == stat)
      {
          gmx_fatal(FARGS,
-                   "The %s binary was not compiled for the selected GPU "
-                   "(device ID #%d, compute capability %d.%d).\n"
-                   "When selecting target GPU architectures with GMX_CUDA_TARGET_SM, "
-                   "make sure to pass the appropriate architecture(s) corresponding to the "
-                   "device(s) intended to be used (see in the GPU info listing) or alternatively "
-                   "pass in GMX_CUDA_TARGET_COMPUTE an appropriate virtual architecture. ",
+                   "The %s binary does not include support for the CUDA architecture "
+                   "of the selected GPU (device ID #%d, compute capability %d.%d). "
+                   "By default, GROMACS supports all common architectures, so your GPU "
+                   "might be rare, or some architectures were disabled in the build. ",
+                   "Consult the install guide for how to use the GMX_CUDA_TARGET_SM and ",
+                   "GMX_CUDA_TARGET_COMPUTE CMake variables to add this architecture.",
                    gmx::getProgramContext().displayName(), devInfo->id,
                    devInfo->prop.major, devInfo->prop.minor);
      }
@@@ -644,7 -645,7 +645,7 @@@ static int is_gmx_supported_gpu_id(int 
      }
  }
  
- bool canDetectGpus()
+ bool canDetectGpus(std::string *errorMessage)
  {
      cudaError_t        stat;
      int                driverVersion = -1;
                         gmx::formatString("An unexpected value was returned from cudaDriverGetVersion %s: %s",
                                           cudaGetErrorName(stat), cudaGetErrorString(stat)).c_str());
      bool foundDriver = (driverVersion > 0);
-     return foundDriver;
+     if (!foundDriver)
+     {
+         // Can't detect GPUs if there is no driver
+         if (errorMessage != nullptr)
+         {
+             errorMessage->assign("No valid CUDA driver found");
+         }
+         return false;
+     }
+     int numDevices;
+     stat = cudaGetDeviceCount(&numDevices);
+     if (stat != cudaSuccess)
+     {
+         if (errorMessage != nullptr)
+         {
+             /* cudaGetDeviceCount failed which means that there is
+              * something wrong with the machine: driver-runtime
+              * mismatch, all GPUs being busy in exclusive mode,
+              * invalid CUDA_VISIBLE_DEVICES, or some other condition
+              * which should result in GROMACS issuing a warning a
+              * falling back to CPUs. */
+             errorMessage->assign(cudaGetErrorString(stat));
+         }
+         // Consume the error now that we have prepared to handle
+         // it. This stops it reappearing next time we check for
+         // errors. Note that if CUDA_VISIBLE_DEVICES does not contain
+         // valid devices, then cudaGetLastError returns the
+         // (undocumented) cudaErrorNoDevice, but this should not be a
+         // problem as there should be no future CUDA API calls.
+         // NVIDIA bug report #2038718 has been filed.
+         cudaGetLastError();
+         // Can't detect GPUs
+         return false;
+     }
+     // We don't actually use numDevices here, that's not the job of
+     // this function.
+     return true;
  }
  
int detect_gpus(gmx_gpu_info_t *gpu_info, char *err_str)
void findGpus(gmx_gpu_info_t *gpu_info)
  {
-     int                i, ndev, checkres, retval;
+     int                i, ndev, checkres;
      cudaError_t        stat;
      cudaDeviceProp     prop;
      gmx_device_info_t *devs;
  
      assert(gpu_info);
-     assert(err_str);
  
      gpu_info->n_dev_compatible = 0;
  
      stat = cudaGetDeviceCount(&ndev);
      if (stat != cudaSuccess)
      {
-         const char *s;
-         /* cudaGetDeviceCount failed which means that there is something
-          * wrong with the machine: driver-runtime mismatch, all GPUs being
-          * busy in exclusive mode, or some other condition which should
-          * result in us issuing a warning a falling back to CPUs. */
-         retval = -1;
-         s      = cudaGetErrorString(stat);
-         strncpy(err_str, s, STRLEN*sizeof(err_str[0]));
-         // Consume the error now that we have prepared to handle
-         // it. This stops it reappearing next time we check for errors.
-         cudaGetLastError();
+         GMX_THROW(gmx::InternalError("Invalid call of findGpus() when CUDA API returned an error, perhaps "
+                                      "canDetectGpus() was not called appropriately beforehand."));
      }
-     else
+     snew(devs, ndev);
+     for (i = 0; i < ndev; i++)
      {
-         snew(devs, ndev);
-         for (i = 0; i < ndev; i++)
-         {
-             checkres = is_gmx_supported_gpu_id(i, &prop);
+         checkres = is_gmx_supported_gpu_id(i, &prop);
  
-             devs[i].id   = i;
-             devs[i].prop = prop;
-             devs[i].stat = checkres;
+         devs[i].id   = i;
+         devs[i].prop = prop;
+         devs[i].stat = checkres;
  
-             if (checkres == egpuCompatible)
-             {
-                 gpu_info->n_dev_compatible++;
-             }
+         if (checkres == egpuCompatible)
+         {
+             gpu_info->n_dev_compatible++;
          }
-         retval = 0;
      }
+     GMX_RELEASE_ASSERT(cudaSuccess == cudaPeekAtLastError(), "Should be cudaSuccess");
  
      gpu_info->n_dev   = ndev;
      gpu_info->gpu_dev = devs;
-     return retval;
  }
  
  std::vector<int> getCompatibleGpus(const gmx_gpu_info_t &gpu_info)
index d7e724aedf022b7e10d80b414201028bf3b19247,1a5ced2c0ba7640bebb8d1bccdd8f948edfb5367..c364363ed6efe173ec0ef518e192c61906a98ecd
@@@ -3,7 -3,7 +3,7 @@@
   *
   * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
   * Copyright (c) 2001-2010, The GROMACS development team.
-- * Copyright (c) 2012,2013,2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2012,2013,2014,2015,2016,2017,2018, 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.
@@@ -47,6 -47,7 +47,7 @@@
  
  #include <cstdio>
  
+ #include <string>
  #include <vector>
  
  #include "gromacs/gpu_utils/gpu_macros.h"
@@@ -77,32 -78,31 +78,31 @@@ enum class GpuTaskCompletio
  /*! \brief Return whether GPUs can be detected
   *
   * Returns true when this is a build of \Gromacs configured to support
-  * GPU usage, and a valid device driver or ICD was detected by the GPU
-  * runtime.
+  * GPU usage, and a valid device driver, ICD, and/or runtime was detected.
+  *
+  * \param[out] errorMessage  When returning false and non-nullptr was passed,
+  *                           the string contains a descriptive message about
+  *                           why GPUs cannot be detected.
   *
   * Does not throw. */
  GPU_FUNC_QUALIFIER
- bool canDetectGpus() GPU_FUNC_TERM_WITH_RETURN(false);
+ bool canDetectGpus(std::string *GPU_FUNC_ARGUMENT(errorMessage)) GPU_FUNC_TERM_WITH_RETURN(false);
  
- /*! \brief Detect all GPUs in the system.
+ /*! \brief Find all GPUs in the system.
   *
-  *  Will detect every GPU supported by the device driver in use. If
-  *  the device driver is missing or unsuitable, returns the same error
-  *  as for "no valid devices detected," so generally calling code
-  *  should have checked the return value from canDetectGpus() first,
-  *  in order to understand the behaviour of this routine. This routine
+  *  Will detect every GPU supported by the device driver in use. Must
+  *  only be called if canDetectGpus() has returned true. This routine
   *  also checks for the compatibility of each and fill the
   *  gpu_info->gpu_dev array with the required information on each the
   *  device: ID, device properties, status.
   *
   *  \param[in] gpu_info    pointer to structure holding GPU information.
-  *  \param[out] err_str    The error message of any GPU API error that caused
-  *                         the detection to fail (if there was any). The memory
-  *                         the pointer points to should be managed externally.
-  *  \returns               non-zero if the detection encountered a failure, zero otherwise.
+  *
+  *  \throws                InternalError if a GPU API returns an unexpected failure (because
+  *                         the call to canDetectGpus() should always prevent this occuring)
   */
  GPU_FUNC_QUALIFIER
- int detect_gpus(struct gmx_gpu_info_t *GPU_FUNC_ARGUMENT(gpu_info), char *GPU_FUNC_ARGUMENT(err_str)) GPU_FUNC_TERM_WITH_RETURN(-1)
+ void findGpus(struct gmx_gpu_info_t *GPU_FUNC_ARGUMENT(gpu_info)) GPU_FUNC_TERM
  
  /*! \brief Return a container of the detected GPUs that are compatible.
   *
index 2cd80e1609a5391c8adc87c2a9d0851e173bb02a,03abbf8784524e8d40ff89ca87a1e6831429568f..7d7a7536a00df99ab49c0d68d36e2fc59c38a023
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2017, by the GROMACS development team, led by
++ * Copyright (c) 2017,2018, 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.
@@@ -46,7 -46,6 +46,6 @@@
  
  #include "gromacs/gpu_utils/gpu_utils.h"
  #include "gromacs/hardware/gpu_hw_info.h"
- #include "gromacs/utility/cstringutil.h"
  #include "gromacs/utility/smalloc.h"
  
  namespace gmx
@@@ -57,8 -56,11 +56,11 @@@ namespace tes
  GpuTest::GpuTest()
  {
      snew(gpuInfo_, 1);
-     char errorString[STRLEN];
-     detect_gpus(gpuInfo_, errorString);
+     if (canDetectGpus(nullptr))
+     {
+         findGpus(gpuInfo_);
+     }
+     // Failing to find valid GPUs does not require further action
  }
  
  GpuTest::~GpuTest()
index 809cce2b5a593292c82126e9493dc83f9943de32,53daa9cb980a2edc47b358416296ebfaf0877574..5ea54eaecbd25fe9c371b8150c346037e3921ef4
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2017, by the GROMACS development team, led by
++ * Copyright (c) 2017,2018, 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.
@@@ -226,6 -226,11 +226,11 @@@ TYPED_TEST(HostAllocatorTest, FillInput
  
  TYPED_TEST(HostAllocatorTest, TransfersWithPinningWorkWithCuda)
  {
+     if (!this->haveValidGpus())
+     {
+         return;
+     }
      typename TestFixture::VectorType input;
      changePinningPolicy(&input, PinningPolicy::CanBePinned);
      this->fillInput(&input);
@@@ -246,6 -251,11 +251,11 @@@ bool isPinned(const VectorType &v
  
  TYPED_TEST(HostAllocatorTest, ManualPinningOperationsWorkWithCuda)
  {
+     if (!this->haveValidGpus())
+     {
+         return;
+     }
      typename TestFixture::VectorType input;
      changePinningPolicy(&input, PinningPolicy::CanBePinned);
      EXPECT_FALSE(isPinned(input));
index 0f34dab15fda23ba522351ee303e2feeaf8c298a,f6d1643a9e27b86a22cbe8099a5f66d1d5dbdf35..7366aaf344eb49f5da0db49c44d1275660536648
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2017, by the GROMACS development team, led by
++ * Copyright (c) 2017,2018, 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.
@@@ -66,12 -66,22 +66,22 @@@ using PinnedMemoryCheckerTest = GpuTest
  
  TEST_F(PinnedMemoryCheckerTest, DefaultContainerIsRecognized)
  {
+     if (!haveValidGpus())
+     {
+         return;
+     }
      std::vector<real> dummy(3, 1.5);
      EXPECT_FALSE(isHostMemoryPinned(dummy.data()));
  }
  
  TEST_F(PinnedMemoryCheckerTest, NonpinnedContainerIsRecognized)
  {
+     if (!haveValidGpus())
+     {
+         return;
+     }
      HostVector<real> dummy(3, 1.5);
      changePinningPolicy(&dummy, PinningPolicy::CannotBePinned);
      EXPECT_FALSE(isHostMemoryPinned(dummy.data()));
  
  TEST_F(PinnedMemoryCheckerTest, PinnedContainerIsRecognized)
  {
+     if (!haveValidGpus())
+     {
+         return;
+     }
      HostVector<real> dummy(3, 1.5);
      changePinningPolicy(&dummy, PinningPolicy::CanBePinned);
      EXPECT_TRUE(isHostMemoryPinned(dummy.data()));
  
  TEST_F(PinnedMemoryCheckerTest, DefaultCBufferIsRecognized)
  {
+     if (!haveValidGpus())
+     {
+         return;
+     }
      real *dummy;
      snew(dummy, 3);
      EXPECT_FALSE(isHostMemoryPinned(dummy));
  
  TEST_F(PinnedMemoryCheckerTest, PinnedCBufferIsRecognized)
  {
+     if (!haveValidGpus())
+     {
+         return;
+     }
      real *dummy = nullptr;
      pmalloc((void **)&dummy, 3 * sizeof(real));
      EXPECT_TRUE(isHostMemoryPinned(dummy));
index aeda6c3a91479c95b34e082c46f63dad939e019c,fc897a077cea4f5b6dba54c5d0edc28608f44a4a..34d5b082a18f06b30761f0bda77d3a8c2dfc653e
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2017, by the GROMACS development team, led by
++ * Copyright (c) 2017,2018, 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.
@@@ -71,7 -71,7 +71,7 @@@ enum class Architectur
  static constexpr Architecture c_architecture =
  #if GMX_IS_X86_32 || GMX_IS_X86_64
      Architecture::X86;
- #elif defined __arm__ || defined __arm || defined _M_ARM || defined __aarch64_
+ #elif defined __arm__ || defined __arm || defined _M_ARM || defined __aarch64__
      Architecture::Arm;
  #elif defined __powerpc__ || defined __ppc__ || defined __PPC__
      Architecture::PowerPC;
index 273d8d8e2c23fbb57560819d4d96b38d8bd44053,6f16a041c52b165ef2cddfd43e975f314a1f3fbe..917bdeda609701c188842aa4f38b74b23941defe
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2012,2013,2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2012,2013,2014,2015,2016,2017,2018, 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.
@@@ -778,6 -778,11 +778,11 @@@ detectProcCpuInfoArm(const std::map<std
      {
          *brand = cpuInfo.at("Processor");
      }
+     else if (cpuInfo.count("model name"))
+     {
+         *brand = cpuInfo.at("model name");
+     }
      if (cpuInfo.count("CPU architecture"))
      {
          *family = std::strtol(cpuInfo.at("CPU architecture").c_str(), nullptr, 10);
index 015f3003ad2165cb9bf4797dab51ac6844da4f0e,f72237eab67ebfe9328168d1a4505161528b5bb7..ea1737a5721404eb0752b44820fee5bb030f2fb6
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2012,2013,2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2012,2013,2014,2015,2016,2017,2018, 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.
@@@ -162,32 -162,25 +162,25 @@@ static void gmx_detect_gpus(const gmx::
      bool gpusCanBeDetected = false;
      if (isMasterRankOfNode || isOpenclPpRank)
      {
-         gpusCanBeDetected = canDetectGpus();
-         // No need to tell the user anything at this point, they get a
-         // hardware report later.
-     }
-     if (gpusCanBeDetected)
-     {
-         char detection_error[STRLEN] = "", sbuf[STRLEN];
-         if (detect_gpus(&hwinfo_g->gpu_info, detection_error) != 0)
+         std::string errorMessage;
+         gpusCanBeDetected = canDetectGpus(&errorMessage);
+         if (!gpusCanBeDetected)
          {
-             if (detection_error[0] != '\0')
-             {
-                 sprintf(sbuf, ":\n      %s\n", detection_error);
-             }
-             else
-             {
-                 sprintf(sbuf, ".");
-             }
              GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted(
-                     "NOTE: Error occurred during GPU detection%s"
+                     "NOTE: GPUs cannot be detected:\n"
+                     "      %s\n"
                      "      Can not use GPU acceleration, will fall back to CPU kernels.",
-                     sbuf);
+                     errorMessage.c_str());
          }
      }
  
+     if (gpusCanBeDetected)
+     {
+         findGpus(&hwinfo_g->gpu_info);
+         // No need to tell the user anything at this point, they get a
+         // hardware report later.
+     }
  #if GMX_LIB_MPI
      if (!isOpenclPpRank)
      {
index c9d7b45e02b9c97edd2c2b0183f0d07f7da4903f,425e74478709a85abaef535ab28ece7f3ee3ea18..ac12d4c8af7eafee846c3106f2f09a254852f40d
@@@ -3,7 -3,7 +3,7 @@@
   *
   * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
   * Copyright (c) 2001-2004, The GROMACS development team.
-- * Copyright (c) 2013,2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2013,2014,2015,2016,2017,2018, 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.
@@@ -982,10 -982,10 +982,10 @@@ angles_noener_simd(int nbonds
      const int            nfa1 = 4;
      int                  i, iu, s;
      int                  type;
-     GMX_ALIGNED(int, GMX_SIMD_REAL_WIDTH)    ai[GMX_SIMD_REAL_WIDTH];
-     GMX_ALIGNED(int, GMX_SIMD_REAL_WIDTH)    aj[GMX_SIMD_REAL_WIDTH];
-     GMX_ALIGNED(int, GMX_SIMD_REAL_WIDTH)    ak[GMX_SIMD_REAL_WIDTH];
-     GMX_ALIGNED(real, GMX_SIMD_REAL_WIDTH)   coeff[2*GMX_SIMD_REAL_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t    ai[GMX_SIMD_REAL_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t    aj[GMX_SIMD_REAL_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t    ak[GMX_SIMD_REAL_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) real            coeff[2*GMX_SIMD_REAL_WIDTH];
      SimdReal             deg2rad_S(DEG2RAD);
      SimdReal             xi_S, yi_S, zi_S;
      SimdReal             xj_S, yj_S, zj_S;
      SimdReal             cik_S, cii_S, ckk_S;
      SimdReal             f_ix_S, f_iy_S, f_iz_S;
      SimdReal             f_kx_S, f_ky_S, f_kz_S;
-     GMX_ALIGNED(real, GMX_SIMD_REAL_WIDTH)    pbc_simd[9*GMX_SIMD_REAL_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) real    pbc_simd[9*GMX_SIMD_REAL_WIDTH];
  
      set_pbc_simd(pbc, pbc_simd);
  
@@@ -1309,11 -1309,11 +1309,11 @@@ void urey_bradley_noener_simd(int nbond
                                int gmx_unused *global_atom_index)
  {
      constexpr int            nfa1 = 4;
-     GMX_ALIGNED(int, GMX_SIMD_REAL_WIDTH)    ai[GMX_SIMD_REAL_WIDTH];
-     GMX_ALIGNED(int, GMX_SIMD_REAL_WIDTH)    aj[GMX_SIMD_REAL_WIDTH];
-     GMX_ALIGNED(int, GMX_SIMD_REAL_WIDTH)    ak[GMX_SIMD_REAL_WIDTH];
-     GMX_ALIGNED(real, GMX_SIMD_REAL_WIDTH)   coeff[4*GMX_SIMD_REAL_WIDTH];
-     GMX_ALIGNED(real, GMX_SIMD_REAL_WIDTH)   pbc_simd[9*GMX_SIMD_REAL_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t    ai[GMX_SIMD_REAL_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t    aj[GMX_SIMD_REAL_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t    ak[GMX_SIMD_REAL_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) real            coeff[4*GMX_SIMD_REAL_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) real            pbc_simd[9*GMX_SIMD_REAL_WIDTH];
  
      set_pbc_simd(pbc, pbc_simd);
  
@@@ -1995,11 -1995,11 +1995,11 @@@ pdihs_noener_simd(int nbonds
      const int             nfa1 = 5;
      int                   i, iu, s;
      int                   type;
-     GMX_ALIGNED(int, GMX_SIMD_REAL_WIDTH)    ai[GMX_SIMD_REAL_WIDTH];
-     GMX_ALIGNED(int, GMX_SIMD_REAL_WIDTH)    aj[GMX_SIMD_REAL_WIDTH];
-     GMX_ALIGNED(int, GMX_SIMD_REAL_WIDTH)    ak[GMX_SIMD_REAL_WIDTH];
-     GMX_ALIGNED(int, GMX_SIMD_REAL_WIDTH)    al[GMX_SIMD_REAL_WIDTH];
-     GMX_ALIGNED(real, GMX_SIMD_REAL_WIDTH)  buf[3*GMX_SIMD_REAL_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t    ai[GMX_SIMD_REAL_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t    aj[GMX_SIMD_REAL_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t    ak[GMX_SIMD_REAL_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t    al[GMX_SIMD_REAL_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) real            buf[3*GMX_SIMD_REAL_WIDTH];
      real                 *cp, *phi0, *mult;
      SimdReal              deg2rad_S(DEG2RAD);
      SimdReal              p_S, q_S;
      SimdReal              sin_S, cos_S;
      SimdReal              mddphi_S;
      SimdReal              sf_i_S, msf_l_S;
-     GMX_ALIGNED(real, GMX_SIMD_REAL_WIDTH)    pbc_simd[9*GMX_SIMD_REAL_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) real            pbc_simd[9*GMX_SIMD_REAL_WIDTH];
  
      /* Extract aligned pointer for parameters and variables */
      cp    = buf + 0*GMX_SIMD_REAL_WIDTH;
@@@ -2110,11 -2110,11 +2110,11 @@@ rbdihs_noener_simd(int nbonds
      const int             nfa1 = 5;
      int                   i, iu, s, j;
      int                   type;
-     GMX_ALIGNED(int, GMX_SIMD_REAL_WIDTH)    ai[GMX_SIMD_REAL_WIDTH];
-     GMX_ALIGNED(int, GMX_SIMD_REAL_WIDTH)    aj[GMX_SIMD_REAL_WIDTH];
-     GMX_ALIGNED(int, GMX_SIMD_REAL_WIDTH)    ak[GMX_SIMD_REAL_WIDTH];
-     GMX_ALIGNED(int, GMX_SIMD_REAL_WIDTH)    al[GMX_SIMD_REAL_WIDTH];
-     GMX_ALIGNED(real, GMX_SIMD_REAL_WIDTH) parm[NR_RBDIHS*GMX_SIMD_REAL_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t  ai[GMX_SIMD_REAL_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t  aj[GMX_SIMD_REAL_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t  ak[GMX_SIMD_REAL_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t  al[GMX_SIMD_REAL_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) real          parm[NR_RBDIHS*GMX_SIMD_REAL_WIDTH];
  
      SimdReal              p_S, q_S;
      SimdReal              phi_S;
      SimdReal              parm_S, c_S;
      SimdReal              sin_S, cos_S;
      SimdReal              sf_i_S, msf_l_S;
-     GMX_ALIGNED(real, GMX_SIMD_REAL_WIDTH)    pbc_simd[9*GMX_SIMD_REAL_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) real          pbc_simd[9*GMX_SIMD_REAL_WIDTH];
  
      SimdReal              pi_S(M_PI);
      SimdReal              one_S(1.0);
index 6d0d1794de6fdb08f421e30662446194bc476d96,dd4b061a1f0e4ff3412db11a4a6f8a350e017480..fdc2279c20983c9a7eeae6f7195316ae3c190ac5
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2014,2015,2016,2017,2018, 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.
@@@ -550,11 -550,15 +550,15 @@@ do_pairs_simple(int nbonds
      T         twelve(12);
      T         ef(scale_factor);
  
-     const int align = 16;
-     GMX_ASSERT(pack_size <= align, "align should be increased");
-     GMX_ALIGNED(int,  align)  ai[pack_size];
-     GMX_ALIGNED(int,  align)  aj[pack_size];
-     GMX_ALIGNED(real, align)  coeff[3*pack_size];
+ #if GMX_SIMD_HAVE_REAL
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t  ai[pack_size];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t  aj[pack_size];
+     alignas(GMX_SIMD_ALIGNMENT) real          coeff[3*pack_size];
+ #else
+     std::int32_t   ai[pack_size];
+     std::int32_t   aj[pack_size];
+     real           coeff[3*pack_size];
+ #endif
  
      /* nbonds is #pairs*nfa1, here we step pack_size pairs */
      for (int i = 0; i < nbonds; i += pack_size*nfa1)
@@@ -658,7 -662,7 +662,7 @@@ do_pairs(int ftype, int nbonds
           * at once for the angles and dihedrals as well.
           */
  #if GMX_SIMD
-         GMX_ALIGNED(real, GMX_SIMD_REAL_WIDTH) pbc_simd[9*GMX_SIMD_REAL_WIDTH];
+         alignas(GMX_SIMD_ALIGNMENT) real pbc_simd[9*GMX_SIMD_REAL_WIDTH];
          set_pbc_simd(pbc, pbc_simd);
  
          do_pairs_simple<SimdReal, GMX_SIMD_REAL_WIDTH,
index 336e75b4aa9858105d64dc0828fd36bc2352dcfd,6b272513ac7ca69b5b825667eaca202d77b47c80..f254bea23f98241307e4cb95a2385d27d2e30856
@@@ -3,7 -3,7 +3,7 @@@
   *
   * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
   * Copyright (c) 2001-2004, The GROMACS development team.
-- * Copyright (c) 2013,2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2013,2014,2015,2016,2017,2018, 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.
@@@ -441,7 -441,7 +441,7 @@@ calc_dr_x_f_simd(in
  {
      assert(b0 % GMX_SIMD_REAL_WIDTH == 0);
  
-     GMX_ALIGNED(int, GMX_SIMD_REAL_WIDTH) offset2[GMX_SIMD_REAL_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t offset2[GMX_SIMD_REAL_WIDTH];
  
      for (int i = 0; i < GMX_SIMD_REAL_WIDTH; i++)
      {
          SimdReal x1_S, y1_S, z1_S;
          SimdReal rx_S, ry_S, rz_S, n2_S, il_S;
          SimdReal fx_S, fy_S, fz_S, ip_S, rhs_S;
-         GMX_ALIGNED(int, GMX_SIMD_REAL_WIDTH)      offset0[GMX_SIMD_REAL_WIDTH];
-         GMX_ALIGNED(int, GMX_SIMD_REAL_WIDTH)      offset1[GMX_SIMD_REAL_WIDTH];
+         alignas(GMX_SIMD_ALIGNMENT) std::int32_t      offset0[GMX_SIMD_REAL_WIDTH];
+         alignas(GMX_SIMD_ALIGNMENT) std::int32_t      offset1[GMX_SIMD_REAL_WIDTH];
  
          for (int i = 0; i < GMX_SIMD_REAL_WIDTH; i++)
          {
@@@ -537,7 -537,7 +537,7 @@@ static void do_lincsp(rvec *x, rvec *f
       * The only difference is that we always call pbc code, as with SIMD
       * the overhead of pbc computation (when not needed) is small.
       */
-     GMX_ALIGNED(real, GMX_SIMD_REAL_WIDTH)    pbc_simd[9*GMX_SIMD_REAL_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) real    pbc_simd[9*GMX_SIMD_REAL_WIDTH];
  
      /* Convert the pbc struct for SIMD */
      set_pbc_simd(pbc, pbc_simd);
@@@ -695,7 -695,7 +695,7 @@@ calc_dr_x_xp_simd(in
                    real * gmx_restrict       sol)
  {
      assert(b0 % GMX_SIMD_REAL_WIDTH == 0);
-     GMX_ALIGNED(int, GMX_SIMD_REAL_WIDTH) offset2[GMX_SIMD_REAL_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t offset2[GMX_SIMD_REAL_WIDTH];
  
      for (int i = 0; i < GMX_SIMD_REAL_WIDTH; i++)
      {
          SimdReal x1_S, y1_S, z1_S;
          SimdReal rx_S, ry_S, rz_S, n2_S, il_S;
          SimdReal rxp_S, ryp_S, rzp_S, ip_S, rhs_S;
-         GMX_ALIGNED(int, GMX_SIMD_REAL_WIDTH)      offset0[GMX_SIMD_REAL_WIDTH];
-         GMX_ALIGNED(int, GMX_SIMD_REAL_WIDTH)      offset1[GMX_SIMD_REAL_WIDTH];
+         alignas(GMX_SIMD_ALIGNMENT) std::int32_t      offset0[GMX_SIMD_REAL_WIDTH];
+         alignas(GMX_SIMD_ALIGNMENT) std::int32_t      offset1[GMX_SIMD_REAL_WIDTH];
  
          for (int i = 0; i < GMX_SIMD_REAL_WIDTH; i++)
          {
@@@ -835,8 -835,8 +835,8 @@@ calc_dist_iter_simd(in
          SimdReal x1_S, y1_S, z1_S;
          SimdReal rx_S, ry_S, rz_S, n2_S;
          SimdReal len_S, len2_S, dlen2_S, lc_S, blc_S;
-         GMX_ALIGNED(int, GMX_SIMD_REAL_WIDTH)      offset0[GMX_SIMD_REAL_WIDTH];
-         GMX_ALIGNED(int, GMX_SIMD_REAL_WIDTH)      offset1[GMX_SIMD_REAL_WIDTH];
+         alignas(GMX_SIMD_ALIGNMENT) std::int32_t      offset0[GMX_SIMD_REAL_WIDTH];
+         alignas(GMX_SIMD_ALIGNMENT) std::int32_t      offset1[GMX_SIMD_REAL_WIDTH];
  
          for (int i = 0; i < GMX_SIMD_REAL_WIDTH; i++)
          {
@@@ -923,7 -923,7 +923,7 @@@ static void do_lincs(rvec *x, rvec *xp
       * The only difference is that we always call pbc code, as with SIMD
       * the overhead of pbc computation (when not needed) is small.
       */
-     GMX_ALIGNED(real, GMX_SIMD_REAL_WIDTH)    pbc_simd[9*GMX_SIMD_REAL_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) real    pbc_simd[9*GMX_SIMD_REAL_WIDTH];
  
      /* Convert the pbc struct for SIMD */
      set_pbc_simd(pbc, pbc_simd);
index 34a011a0e32d208fe7a384ec242e668a0840146f,d65405c3a9942d52ca7d8b99c004b984470ec17f..0fa7e3c7221e6b2d56814b73954ac082c2221640
@@@ -3,7 -3,7 +3,7 @@@
   *
   * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
   * Copyright (c) 2001-2004, The GROMACS development team.
-- * Copyright (c) 2013,2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2013,2014,2015,2016,2017,2018, 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.
@@@ -850,7 -850,7 +850,7 @@@ void csettle(gmx_settledata_t settled
      if (settled->bUseSimd)
      {
          /* Convert the pbc struct for SIMD */
-         GMX_ALIGNED(real, GMX_SIMD_REAL_WIDTH) pbcSimd[9*GMX_SIMD_REAL_WIDTH];
+         alignas(GMX_SIMD_ALIGNMENT) real    pbcSimd[9*GMX_SIMD_REAL_WIDTH];
          set_pbc_simd(pbc, pbcSimd);
  
          settleTemplateWrapper<SimdReal, SimdBool, GMX_SIMD_REAL_WIDTH,
index 6c3b06b0992affb830af5c6d7c06184739cadbdd,4f04591d38e7ed7e76999682b397d4afe90cb742..d8df2950446a29187303b94c54f2f16ab88c3ed8
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2012,2013,2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2012,2013,2014,2015,2016,2017,2018, 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.
@@@ -465,50 -465,6 +465,6 @@@ reportOpenmpSettings(const gmx::MDLogge
      GMX_LOG(mdlog.warning);
  }
  
- /*! \brief Detect and warn about oversubscription of cores.
-  *
-  * \todo This could probably live elsewhere, since it is not specifc
-  * to OpenMP, and only needs modth.gnth.
-  *
-  * \todo Enable this for separate PME nodes as well! */
- static void
- issueOversubscriptionWarning(const gmx::MDLogger &mdlog,
-                              const t_commrec     *cr,
-                              int                  nthreads_hw_avail,
-                              int                  nppn,
-                              gmx_bool             bSepPME)
- {
-     char sbuf[STRLEN], sbuf1[STRLEN], sbuf2[STRLEN];
-     if (bSepPME || 0 != cr->rank_pp_intranode)
-     {
-         return;
-     }
-     if (modth.gnth*nppn > nthreads_hw_avail)
-     {
-         sprintf(sbuf, "threads");
-         sbuf1[0] = '\0';
-         sprintf(sbuf2, "O");
- #if GMX_MPI
-         if (modth.gnth == 1)
-         {
- #if GMX_THREAD_MPI
-             sprintf(sbuf, "thread-MPI threads");
- #else
-             sprintf(sbuf, "MPI processes");
-             sprintf(sbuf1, " per rank");
-             sprintf(sbuf2, "On rank %d: o", cr->sim_nodeid);
- #endif
-         }
- #endif
-         GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted(
-                 "WARNING: %sversubscribing the available %d logical CPU cores%s with %d %s.\n"
-                 "         This will cause considerable performance loss!",
-                 sbuf2, nthreads_hw_avail, sbuf1, nppn*modth.gnth, sbuf);
-     }
- }
  void gmx_omp_nthreads_init(const gmx::MDLogger &mdlog, t_commrec *cr,
                             int nthreads_hw_avail,
                             int omp_nthreads_req,
  #endif
  
      reportOpenmpSettings(mdlog, cr, bOMP, bFullOmpSupport, bSepPME);
-     issueOversubscriptionWarning(mdlog, cr, nthreads_hw_avail, nppn, bSepPME);
  }
  
  int gmx_omp_nthreads_get(int mod)
index 9115a942a5b510ab07ba0e23d021c469a54f5116,72d90484dbd69c3d0169f73a104ec29b4881fde6..b25a37cf3e95d5ebfdf5fb3a445b8b7a6f3bbb67
@@@ -3,7 -3,7 +3,7 @@@
   *
   * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
   * Copyright (c) 2001-2004, The GROMACS development team.
-- * Copyright (c) 2013,2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2013,2014,2015,2016,2017,2018, 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.
@@@ -247,12 -247,16 +247,16 @@@ void compute_globals(FILE *fplog, gmx_g
      if (bStopCM)
      {
          check_cm_grp(fplog, vcm, ir, 1);
-         /* Don't pass x with linear modes to avoid correction of the initial
-          * coordinates for the initial COM velocity.
+         /* At initialization, do not pass x with acceleration-correction mode
+          * to avoid (incorrect) correction of the initial coordinates.
           */
+         rvec *xPtr = nullptr;
+         if (vcm->mode == ecmANGULAR || (vcm->mode == ecmLINEAR_ACCELERATION_CORRECTION && !(flags & CGLO_INITIALIZATION)))
+         {
+             xPtr = as_rvec_array(state->x.data());
+         }
          do_stopcm_grp(mdatoms->homenr, mdatoms->cVCM,
-                       vcm->mode == ecmANGULAR ? as_rvec_array(state->x.data()) : nullptr,
-                       as_rvec_array(state->v.data()), *vcm);
+                       xPtr, as_rvec_array(state->v.data()), *vcm);
          inc_nrnb(nrnb, eNR_STOPCM, mdatoms->homenr);
      }
  
index 20bbcc8b0bbeff83e0b7203cde0d4fd2703b2dac,ddee3c679219a8ea3b25edd9c4d5511a46d48d56..e6b092da974e4384e2f71d782f4bbc5174fba0d3
@@@ -3,7 -3,7 +3,7 @@@
   *
   * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
   * Copyright (c) 2001-2004, The GROMACS development team.
-- * Copyright (c) 2013,2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by
   * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
   * and including many others, as listed in the AUTHORS file in the
   * top-level source directory and at http://www.gromacs.org.
@@@ -64,6 -64,8 +64,8 @@@ class SimulationSignaller
   * passed to compute_globals in md.c and global_stat.
   */
  
+ /* we are initializing and not yet in the actual MD loop */
+ #define CGLO_INITIALIZATION (1<<1)
  /* we are computing the kinetic energy from average velocities */
  #define CGLO_EKINAVEVEL     (1<<2)
  /* we are removing the center of mass momenta */
index 3dfc89b2ade33b763745af51d5c79accb7d4392e,ff968573b6636f9b42d54ab19238324a17446eb5..844f55d7f58ddc3860b640e30c7318ebee5bbd04
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2012,2013,2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2012,2013,2014,2015,2016,2017,2018, 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.
  #ifdef COUNT_PAIRS
      {
          int  i, j;
-         GMX_ALIGNED(real, GMX_SIMD_REAL_WIDTH)  tmp[GMX_SIMD_REAL_WIDTH];
+         alignas(GMX_SIMD_ALIGNMENT) real  tmp[GMX_SIMD_REAL_WIDTH];
  
          for (i = 0; i < UNROLLI; i += 2)
          {
index 2aa994455f01171c3eacf1a4e5e237ad728ae9f2,b2960bce4a2a2db7874ee1a736aacc2a6d7bcdc2..ae56ddbf3be5fe52547f4e42283473c9b05f9efa
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2012,2013,2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2012,2013,2014,2015,2016,2017,2018, 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.
      SimdReal          hsig_i_S2, seps_i_S2;
  #else
  #ifdef FIX_LJ_C
-     GMX_ALIGNED(real, GMX_SIMD_REAL_WIDTH)  pvdw_c6[2*UNROLLI*UNROLLJ];
+     alignas(GMX_SIMD_ALIGNMENT) real  pvdw_c6[2*UNROLLI*UNROLLJ];
      real  *pvdw_c12 = pvdw_c6 + UNROLLI*UNROLLJ;
  #endif
  
index f0b0b7a8bc66ecefd3207ce4db75377b391a0248,782a3fbb69294ead586db6b1f302a3c9b53215c1..a3169fe83b8fc5ec30499ac758f37cca30b115d5
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2012,2013,2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2012,2013,2014,2015,2016,2017,2018, 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.
  #ifdef COUNT_PAIRS
      {
          int  i, j;
-         GMX_ALIGNED(real, GMX_SIMD_REAL_WIDTH)  tmp[2*GMX_SIMD_REAL_WIDTH];
+         alignas(GMX_SIMD_ALIGNMENT) real  tmp[2*GMX_SIMD_REAL_WIDTH];
  
          for (i = 0; i < UNROLLI; i++)
          {
index 167379c455f1ca241dca3abcbed6bf492036a517,8ca51262935a17d90fd7f24df379a8a2ce719caf..696d53a7fac0c40363c73692559199a7d119cf05
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2012,2013,2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2012,2013,2014,2015,2016,2017,2018, 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.
      x                   = nbat->x;
  
  #ifdef FIX_LJ_C
-     GMX_ALIGNED(real, GMX_SIMD_REAL_WIDTH)  pvdw_c6[2*UNROLLI*UNROLLJ];
+     alignas(GMX_SIMD_ALIGNMENT) real  pvdw_c6[2*UNROLLI*UNROLLJ];
      real *pvdw_c12 = pvdw_c6 + UNROLLI*UNROLLJ;
  
      for (int jp = 0; jp < UNROLLJ; jp++)
index b746326ac9e4c8228240e6de43b15691610fece4,ee757e41813383d99063be53eb3a16f466be1a9e..c2c40c441470b1a3cef2106b587e2dfc277878e4
@@@ -3,7 -3,7 +3,7 @@@
   *
   * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
   * Copyright (c) 2001-2004, The GROMACS development team.
-- * Copyright (c) 2013,2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2013,2014,2015,2016,2017,2018, 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.
@@@ -2724,10 -2724,14 +2724,14 @@@ void finish_run(FILE *fplog, const gmx:
         communication deadlocks, we always do the communication for the
         report, even if we've decided not to write the report, because
         how long it takes to finish the run is not important when we've
-        decided not to report on the simulation performance. */
-     bool    printReport = SIMMASTER(cr);
+        decided not to report on the simulation performance.
  
-     if (!walltime_accounting_get_valid_finish(walltime_accounting))
+        Further, we only report performance for dynamical integrators,
+        because those are the only ones for which we plan to
+        consider doing any optimizations. */
+     bool printReport = EI_DYNAMICS(inputrec->eI) && SIMMASTER(cr);
+     if (printReport && !walltime_accounting_get_valid_finish(walltime_accounting))
      {
          GMX_LOG(mdlog.warning).asParagraph().appendText("Simulation ended prematurely, no performance report will be written.");
          printReport = false;
index 2800f1f8830489d350daa36c058fbdac0bb4f6f1,388c44654ed016942c5f760876c5d7fc1661e080..6e767c5aaabd35a1797e5f9445bedc6680ff7cee
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2014,2015,2017, by the GROMACS development team, led by
++ * Copyright (c) 2014,2015,2017,2018, by the GROMACS development team, led by
   * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
   * and including many others, as listed in the AUTHORS file in the
   * top-level source directory and at http://www.gromacs.org.
@@@ -75,6 -75,7 +75,7 @@@
  #define GMX_SIMD_FINT32_WIDTH                   4
  #undef  GMX_SIMD_DINT32_WIDTH
  #define GMX_SIMD4_WIDTH                         4
+ #define GMX_SIMD_ALIGNMENT                     16 // Bytes (4*single)
  #define GMX_SIMD_RSQRT_BITS                     8
  #define GMX_SIMD_RCP_BITS                       8
  
index d2919f4384947039ca276e341bd6f4da0b14997d,2648fef615562224fca6880ac25111d0c7025d68..93aaed2561fb24041eb3538f5ff12199da0894c4
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-  * Copyright (c) 2014,2015,2016, by the GROMACS development team, led by
 - * Copyright (c) 2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2014,2015,2016,2017,2018, 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.
@@@ -286,7 -286,7 +286,7 @@@ gatherLoadBySimdIntTranspose(const floa
                               SimdFloat *    v2,
                               SimdFloat *    v3)
  {
-     GMX_ALIGNED(int, GMX_SIMD_FINT32_WIDTH)  ioffset[GMX_SIMD_FINT32_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t  ioffset[GMX_SIMD_FINT32_WIDTH];
  
      assert(std::size_t(base) % 16 == 0);
      assert(align % 4 == 0);
@@@ -302,7 -302,7 +302,7 @@@ gatherLoadBySimdIntTranspose(const floa
                               SimdFloat *     v0,
                               SimdFloat *     v1)
  {
-     GMX_ALIGNED(int, GMX_SIMD_FINT32_WIDTH)  ioffset[GMX_SIMD_FINT32_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t  ioffset[GMX_SIMD_FINT32_WIDTH];
  
      store(ioffset, offset);
      gatherLoadTranspose<align>(base, ioffset, v0, v1);
@@@ -317,7 -317,7 +317,7 @@@ gatherLoadUBySimdIntTranspose(const flo
                                SimdFloat *    v0,
                                SimdFloat *    v1)
  {
-     GMX_ALIGNED(int, GMX_SIMD_FINT32_WIDTH)  ioffset[GMX_SIMD_FINT32_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t  ioffset[GMX_SIMD_FINT32_WIDTH];
  
      store(ioffset, offset);
      v0->simdInternal_ = vcombine_f32(vld1_f32( base + align * ioffset[0] ),
index ab1a7783af8787aab64d2d7caf72fa000539881e,c7b807d2d2fa5632979395414267559c2fbd2478..20ab5bceeabe25e8ff7479e9d209d0074121566f
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-  * Copyright (c) 2014,2015, by the GROMACS development team, led by
 - * Copyright (c) 2014,2015,2017, by the GROMACS development team, led by
++ * Copyright (c) 2014,2015,2017,2018, 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.
@@@ -77,6 -77,7 +77,7 @@@
  #define GMX_SIMD_FINT32_WIDTH                   4
  #define GMX_SIMD_DINT32_WIDTH                   2
  #define GMX_SIMD4_WIDTH                         4
+ #define GMX_SIMD_ALIGNMENT                     16 // Bytes (4*single or 2*double)
  #define GMX_SIMD_RSQRT_BITS                     8
  #define GMX_SIMD_RCP_BITS                       8
  
index 45abcbbe1667d9d4593a74ad96bdd8fa4404d2da,ec54d0ee6837779d75de9a2c8b53a90b8f8394fd..2dfb2480a83aaac37faf8f5db6e22eb5df0ae0fa
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-  * Copyright (c) 2014,2015, by the GROMACS development team, led by
 - * Copyright (c) 2014,2015,2017, by the GROMACS development team, led by
++ * Copyright (c) 2014,2015,2017,2018, 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.
@@@ -225,7 -225,7 +225,7 @@@ gatherLoadBySimdIntTranspose(const doub
                               SimdDouble *    v2,
                               SimdDouble *    v3)
  {
-     GMX_ALIGNED(int, GMX_SIMD_DINT32_WIDTH)  ioffset[GMX_SIMD_DINT32_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t     ioffset[GMX_SIMD_DINT32_WIDTH];
  
      assert(std::size_t(base) % 16 == 0);
      assert(align % 2 == 0);
@@@ -242,7 -242,7 +242,7 @@@ gatherLoadBySimdIntTranspose(const doub
                               SimdDouble *    v0,
                               SimdDouble *    v1)
  {
-     GMX_ALIGNED(int, GMX_SIMD_DINT32_WIDTH)  ioffset[GMX_SIMD_DINT32_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t     ioffset[GMX_SIMD_DINT32_WIDTH];
  
      assert(std::size_t(base) % 16 == 0);
      assert(align % 2 == 0);
@@@ -258,7 -258,7 +258,7 @@@ gatherLoadUBySimdIntTranspose(const dou
                                SimdDouble *    v0,
                                SimdDouble *    v1)
  {
-     GMX_ALIGNED(int, GMX_SIMD_DINT32_WIDTH)  ioffset[GMX_SIMD_DINT32_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t     ioffset[GMX_SIMD_DINT32_WIDTH];
  
      vst1_s32(ioffset, offset.simdInternal_);
  
index 1da37d2a2a6f6a85d5be23d1fe184a61173267fc,99128004b314cca18984f2b4eafe9a56a6d8c620..a2204b0c86ee2ae389fd558c5e72d17359129a40
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-  * Copyright (c) 2014,2015, by the GROMACS development team, led by
 - * Copyright (c) 2014,2015,2017, by the GROMACS development team, led by
++ * Copyright (c) 2014,2015,2017,2018, by the GROMACS development team, led by
   * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
   * and including many others, as listed in the AUTHORS file in the
   * top-level source directory and at http://www.gromacs.org.
@@@ -75,6 -75,7 +75,7 @@@
  #define GMX_SIMD_FINT32_WIDTH                   4
  #define GMX_SIMD_DINT32_WIDTH                   4
  #define GMX_SIMD4_WIDTH                         4
+ #define GMX_SIMD_ALIGNMENT                     32 // Bytes (4*double)
  #define GMX_SIMD_RSQRT_BITS                    14
  #define GMX_SIMD_RCP_BITS                      14
  
index dc20d78213a5e1ff134884a1dc51eeec10949afd,16a2f8ff343f4ecc586ec9bfcd4d4a80ff0c110e..497d45f321701f02db42db7e75452f0523f92d0e
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2014,2015,2016,2017,2018, by the GROMACS development team, led by
   * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
   * and including many others, as listed in the AUTHORS file in the
   * top-level source directory and at http://www.gromacs.org.
@@@ -75,7 -75,7 +75,7 @@@ class SimdDInt3
  
          SimdDInt32(std::int32_t i)
          {
-             GMX_ALIGNED(int, GMX_SIMD_DINT32_WIDTH) idata[GMX_SIMD_DINT32_WIDTH];
+             alignas(GMX_SIMD_ALIGNMENT) std::int32_t  idata[GMX_SIMD_DINT32_WIDTH];
              idata[0]      = i;
              simdInternal_ = vec_splat(vec_ldia(0, idata), 0);
          }
@@@ -332,8 -332,8 +332,8 @@@ trunc(SimdDouble x
  static inline SimdDouble
  frexp(SimdDouble value, SimdDInt32 * exponent)
  {
-     GMX_ALIGNED(double, GMX_SIMD_DOUBLE_WIDTH) rdata[GMX_SIMD_DOUBLE_WIDTH];
-     GMX_ALIGNED(int, GMX_SIMD_DOUBLE_WIDTH)    idata[GMX_SIMD_DOUBLE_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) double        rdata[GMX_SIMD_DOUBLE_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t  idata[GMX_SIMD_DOUBLE_WIDTH];
  
      vec_st(value.simdInternal_, 0, rdata);
  
@@@ -352,8 -352,8 +352,8 @@@ template <MathOptimization opt = MathOp
  static inline SimdDouble
  ldexp(SimdDouble value, SimdDInt32 exponent)
  {
-     GMX_ALIGNED(double, GMX_SIMD_DOUBLE_WIDTH) rdata[GMX_SIMD_DOUBLE_WIDTH];
-     GMX_ALIGNED(int, GMX_SIMD_DOUBLE_WIDTH)    idata[GMX_SIMD_DOUBLE_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) double        rdata[GMX_SIMD_DOUBLE_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t  idata[GMX_SIMD_DOUBLE_WIDTH];
  
      vec_st(value.simdInternal_,    0, rdata);
      vec_st(exponent.simdInternal_, 0, idata);
index 12ffdbd31c30fc8cbd85ae5138e2e8821ff3d664,83b74d1ad183bea3cca63797074801950c845d2e..322234b8f42d112214e865d429e92e4c7b441c5f
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2014,2015,2016,2017,2018, 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.
@@@ -72,7 -72,7 +72,7 @@@ class SimdFInt3
  
          SimdFInt32(std::int32_t i)
          {
-             GMX_ALIGNED(int, GMX_SIMD_FINT32_WIDTH) idata[GMX_SIMD_FINT32_WIDTH];
+             alignas(GMX_SIMD_ALIGNMENT) std::int32_t idata[GMX_SIMD_FINT32_WIDTH];
              idata[0]      = i;
              simdInternal_ = vec_splat(vec_ldia(0, idata), 0);
          }
@@@ -329,8 -329,8 +329,8 @@@ trunc(SimdFloat x
  static inline SimdFloat
  frexp(SimdFloat value, SimdFInt32 * exponent)
  {
-     GMX_ALIGNED(float, GMX_SIMD_FLOAT_WIDTH)  rdata[GMX_SIMD_FLOAT_WIDTH];
-     GMX_ALIGNED(int, GMX_SIMD_FLOAT_WIDTH)    idata[GMX_SIMD_FLOAT_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) float         rdata[GMX_SIMD_FLOAT_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t  idata[GMX_SIMD_FLOAT_WIDTH];
  
      vec_st(value.simdInternal_, 0, rdata);
  
@@@ -349,8 -349,8 +349,8 @@@ template <MathOptimization opt = MathOp
  static inline SimdFloat
  ldexp(SimdFloat value, SimdFInt32 exponent)
  {
-     GMX_ALIGNED(float, GMX_SIMD_FLOAT_WIDTH)  rdata[GMX_SIMD_FLOAT_WIDTH];
-     GMX_ALIGNED(int, GMX_SIMD_FLOAT_WIDTH)    idata[GMX_SIMD_FLOAT_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) float         rdata[GMX_SIMD_FLOAT_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t  idata[GMX_SIMD_FLOAT_WIDTH];
  
      vec_st(value.simdInternal_,    0, rdata);
      vec_st(exponent.simdInternal_, 0, idata);
index 5a220c412002b29e3b4a6b00dddeeb639ea54808,633327a660d35fbb643e382a6caf7d460e83ccf0..7c06ebcb3c9dd92bf2c8b5bd89daf9df8a9ea14d
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-  * Copyright (c) 2014,2015,2016, by the GROMACS development team, led by
 - * Copyright (c) 2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2014,2015,2016,2017,2018, 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.
@@@ -143,9 -143,9 +143,9 @@@ transposeScatterStoreU(double  
                         SimdDouble            v1,
                         SimdDouble            v2)
  {
-     GMX_ALIGNED(double, GMX_SIMD_DOUBLE_WIDTH)   m0[GMX_SIMD_DOUBLE_WIDTH];
-     GMX_ALIGNED(double, GMX_SIMD_DOUBLE_WIDTH)   m1[GMX_SIMD_DOUBLE_WIDTH];
-     GMX_ALIGNED(double, GMX_SIMD_DOUBLE_WIDTH)   m2[GMX_SIMD_DOUBLE_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) double   m0[GMX_SIMD_DOUBLE_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) double   m1[GMX_SIMD_DOUBLE_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) double   m2[GMX_SIMD_DOUBLE_WIDTH];
  
      store(m0, v0);
      store(m1, v1);
@@@ -193,9 -193,9 +193,9 @@@ transposeScatterIncrU(double  
      }
      else
      {
-         GMX_ALIGNED(double, GMX_SIMD_DOUBLE_WIDTH)   m0[GMX_SIMD_DOUBLE_WIDTH];
-         GMX_ALIGNED(double, GMX_SIMD_DOUBLE_WIDTH)   m1[GMX_SIMD_DOUBLE_WIDTH];
-         GMX_ALIGNED(double, GMX_SIMD_DOUBLE_WIDTH)   m2[GMX_SIMD_DOUBLE_WIDTH];
+         alignas(GMX_SIMD_ALIGNMENT) double   m0[GMX_SIMD_DOUBLE_WIDTH];
+         alignas(GMX_SIMD_ALIGNMENT) double   m1[GMX_SIMD_DOUBLE_WIDTH];
+         alignas(GMX_SIMD_ALIGNMENT) double   m2[GMX_SIMD_DOUBLE_WIDTH];
  
          store(m0, v0);
          store(m1, v1);
@@@ -244,9 -244,9 +244,9 @@@ transposeScatterDecrU(double  
      }
      else
      {
-         GMX_ALIGNED(double, GMX_SIMD_DOUBLE_WIDTH)   m0[GMX_SIMD_DOUBLE_WIDTH];
-         GMX_ALIGNED(double, GMX_SIMD_DOUBLE_WIDTH)   m1[GMX_SIMD_DOUBLE_WIDTH];
-         GMX_ALIGNED(double, GMX_SIMD_DOUBLE_WIDTH)   m2[GMX_SIMD_DOUBLE_WIDTH];
+         alignas(GMX_SIMD_ALIGNMENT) double   m0[GMX_SIMD_DOUBLE_WIDTH];
+         alignas(GMX_SIMD_ALIGNMENT) double   m1[GMX_SIMD_DOUBLE_WIDTH];
+         alignas(GMX_SIMD_ALIGNMENT) double   m2[GMX_SIMD_DOUBLE_WIDTH];
  
          store(m0, v0);
          store(m1, v1);
@@@ -287,7 -287,7 +287,7 @@@ gatherLoadBySimdIntTranspose(const doub
                               SimdDouble *     v2,
                               SimdDouble *     v3)
  {
-     GMX_ALIGNED(int, GMX_SIMD_DOUBLE_WIDTH)   ioffset[GMX_SIMD_DOUBLE_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t   ioffset[GMX_SIMD_DOUBLE_WIDTH];
  
      store(ioffset, simdoffset);
      gatherLoadTranspose<align>(base, ioffset, v0, v1, v2, v3);
@@@ -300,7 -300,7 +300,7 @@@ gatherLoadBySimdIntTranspose(const doub
                               SimdDouble *     v0,
                               SimdDouble *     v1)
  {
-     GMX_ALIGNED(int, GMX_SIMD_DOUBLE_WIDTH)   ioffset[GMX_SIMD_DOUBLE_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t   ioffset[GMX_SIMD_DOUBLE_WIDTH];
  
      store(ioffset, simdoffset);
      gatherLoadTranspose<align>(base, ioffset, v0, v1);
index 2e12fab5bcfe93a95c865a44412dc3d09e1a32bb,c3b3d9cadc8833eec4a07f09a3700a00c62a3d94..e63faa92507f78833f94be1d1b25f540645ac781
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-  * Copyright (c) 2014,2015,2016, by the GROMACS development team, led by
 - * Copyright (c) 2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2014,2015,2016,2017,2018, 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.
@@@ -143,9 -143,9 +143,9 @@@ transposeScatterStoreU(float 
                         SimdFloat            v1,
                         SimdFloat            v2)
  {
-     GMX_ALIGNED(float, GMX_SIMD_FLOAT_WIDTH)   m0[GMX_SIMD_FLOAT_WIDTH];
-     GMX_ALIGNED(float, GMX_SIMD_FLOAT_WIDTH)   m1[GMX_SIMD_FLOAT_WIDTH];
-     GMX_ALIGNED(float, GMX_SIMD_FLOAT_WIDTH)   m2[GMX_SIMD_FLOAT_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) float   m0[GMX_SIMD_FLOAT_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) float   m1[GMX_SIMD_FLOAT_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) float   m2[GMX_SIMD_FLOAT_WIDTH];
  
      store(m0, v0);
      store(m1, v1);
@@@ -193,9 -193,9 +193,9 @@@ transposeScatterIncrU(float 
      }
      else
      {
-         GMX_ALIGNED(float, GMX_SIMD_FLOAT_WIDTH)   m0[GMX_SIMD_FLOAT_WIDTH];
-         GMX_ALIGNED(float, GMX_SIMD_FLOAT_WIDTH)   m1[GMX_SIMD_FLOAT_WIDTH];
-         GMX_ALIGNED(float, GMX_SIMD_FLOAT_WIDTH)   m2[GMX_SIMD_FLOAT_WIDTH];
+         alignas(GMX_SIMD_ALIGNMENT) float   m0[GMX_SIMD_FLOAT_WIDTH];
+         alignas(GMX_SIMD_ALIGNMENT) float   m1[GMX_SIMD_FLOAT_WIDTH];
+         alignas(GMX_SIMD_ALIGNMENT) float   m2[GMX_SIMD_FLOAT_WIDTH];
  
          store(m0, v0);
          store(m1, v1);
@@@ -244,9 -244,9 +244,9 @@@ transposeScatterDecrU(float 
      }
      else
      {
-         GMX_ALIGNED(float, GMX_SIMD_FLOAT_WIDTH)   m0[GMX_SIMD_FLOAT_WIDTH];
-         GMX_ALIGNED(float, GMX_SIMD_FLOAT_WIDTH)   m1[GMX_SIMD_FLOAT_WIDTH];
-         GMX_ALIGNED(float, GMX_SIMD_FLOAT_WIDTH)   m2[GMX_SIMD_FLOAT_WIDTH];
+         alignas(GMX_SIMD_ALIGNMENT) float   m0[GMX_SIMD_FLOAT_WIDTH];
+         alignas(GMX_SIMD_ALIGNMENT) float   m1[GMX_SIMD_FLOAT_WIDTH];
+         alignas(GMX_SIMD_ALIGNMENT) float   m2[GMX_SIMD_FLOAT_WIDTH];
  
          store(m0, v0);
          store(m1, v1);
@@@ -287,7 -287,7 +287,7 @@@ gatherLoadBySimdIntTranspose(const floa
                               SimdFloat *    v2,
                               SimdFloat *    v3)
  {
-     GMX_ALIGNED(int, GMX_SIMD_FLOAT_WIDTH)   ioffset[GMX_SIMD_FLOAT_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) int     ioffset[GMX_SIMD_FLOAT_WIDTH];
  
      store(ioffset, simdoffset);
      gatherLoadTranspose<align>(base, ioffset, v0, v1, v2, v3);
@@@ -300,7 -300,7 +300,7 @@@ gatherLoadBySimdIntTranspose(const floa
                               SimdFloat *     v0,
                               SimdFloat *     v1)
  {
-     GMX_ALIGNED(int, GMX_SIMD_FLOAT_WIDTH)   ioffset[GMX_SIMD_FLOAT_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) int   ioffset[GMX_SIMD_FLOAT_WIDTH];
  
      store(ioffset, simdoffset);
      gatherLoadTranspose<align>(base, ioffset, v0, v1);
index e01f1bbf0220b067500466fc4207b20ae0249353,1878d2ac70752f70a8354425c4e6b2c5dbfea42c..3400c8097751ca7e07f5437a82c8865ef11fa3ae
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-  * Copyright (c) 2014,2015, by the GROMACS development team, led by
 - * Copyright (c) 2014,2015,2017, by the GROMACS development team, led by
++ * Copyright (c) 2014,2015,2017,2018, 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.
@@@ -89,6 -89,7 +89,7 @@@
  #define GMX_SIMD_FINT32_WIDTH                   4
  #undef  GMX_SIMD_DINT32_WIDTH
  #define GMX_SIMD4_WIDTH                         4
+ #define GMX_SIMD_ALIGNMENT                     16 // Bytes (4*single)
  #define GMX_SIMD_RSQRT_BITS                    14
  #define GMX_SIMD_RCP_BITS                      14
  
index 95690c36ff751801d546383abe8f0bc86355712f,e4edc8dc34a0975c28a1e83e991ce861dbba7d45..3fc3aaa11793788034fad448e698d22e2bb091b4
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-  * Copyright (c) 2014,2015,2016, by the GROMACS development team, led by
 - * Copyright (c) 2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2014,2015,2016,2017,2018, 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.
@@@ -273,9 -273,9 +273,9 @@@ transposeScatterIncrU(float 
      }
      else
      {
-         GMX_ALIGNED(float, GMX_SIMD_FLOAT_WIDTH) rdata0[GMX_SIMD_FLOAT_WIDTH];
-         GMX_ALIGNED(float, GMX_SIMD_FLOAT_WIDTH) rdata1[GMX_SIMD_FLOAT_WIDTH];
-         GMX_ALIGNED(float, GMX_SIMD_FLOAT_WIDTH) rdata2[GMX_SIMD_FLOAT_WIDTH];
+         alignas(GMX_SIMD_ALIGNMENT) float rdata0[GMX_SIMD_FLOAT_WIDTH];
+         alignas(GMX_SIMD_ALIGNMENT) float rdata1[GMX_SIMD_FLOAT_WIDTH];
+         alignas(GMX_SIMD_ALIGNMENT) float rdata2[GMX_SIMD_FLOAT_WIDTH];
  
          vec_st(v0.simdInternal_, 0, rdata0);
          vec_st(v1.simdInternal_, 0, rdata1);
@@@ -323,9 -323,9 +323,9 @@@ transposeScatterDecrU(float 
      }
      else
      {
-         GMX_ALIGNED(float, GMX_SIMD_FLOAT_WIDTH) rdata0[GMX_SIMD_FLOAT_WIDTH];
-         GMX_ALIGNED(float, GMX_SIMD_FLOAT_WIDTH) rdata1[GMX_SIMD_FLOAT_WIDTH];
-         GMX_ALIGNED(float, GMX_SIMD_FLOAT_WIDTH) rdata2[GMX_SIMD_FLOAT_WIDTH];
+         alignas(GMX_SIMD_ALIGNMENT) float rdata0[GMX_SIMD_FLOAT_WIDTH];
+         alignas(GMX_SIMD_ALIGNMENT) float rdata1[GMX_SIMD_FLOAT_WIDTH];
+         alignas(GMX_SIMD_ALIGNMENT) float rdata2[GMX_SIMD_FLOAT_WIDTH];
  
          vec_st(v0.simdInternal_, 0, rdata0);
          vec_st(v1.simdInternal_, 0, rdata1);
@@@ -371,7 -371,7 +371,7 @@@ gatherLoadBySimdIntTranspose(const floa
                               SimdFloat *    v2,
                               SimdFloat *    v3)
  {
-     GMX_ALIGNED(int, GMX_SIMD_FINT32_WIDTH) ioffset[GMX_SIMD_FINT32_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_FINT32_WIDTH];
  
      vec_st( offset.simdInternal_, 0, ioffset);
      gatherLoadTranspose<align>(base, ioffset, v0, v1, v2, v3);
@@@ -384,7 -384,7 +384,7 @@@ gatherLoadBySimdIntTranspose(const floa
                               SimdFloat *     v0,
                               SimdFloat *     v1)
  {
-     GMX_ALIGNED(int, GMX_SIMD_FINT32_WIDTH) ioffset[GMX_SIMD_FINT32_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_FINT32_WIDTH];
  
      vec_st( offset.simdInternal_, 0, ioffset);
      gatherLoadTranspose<align>(base, ioffset, v0, v1);
index 26a820876752d1eb5d6fdc04cb7fa58a638432d3,6f49d8a9c580f6ff09216c1c3c1c86e766e9ad15..e69fd33c3999c521c4361e4488d0a1a43b18f5f3
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-  * Copyright (c) 2014,2015, by the GROMACS development team, led by
 - * Copyright (c) 2014,2015,2017, by the GROMACS development team, led by
++ * Copyright (c) 2014,2015,2017,2018, 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.
  #ifndef GMX_SIMD_IMPLEMENTATION_IBM_VSX_H
  #define GMX_SIMD_IMPLEMENTATION_IBM_VSX_H
  
+ // At high optimization levels, gcc 7.2 gives false
+ // positives.
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wunused-but-set-parameter"
  // While we do our best to also test VSX with Power7, that depends on having
  // access to big-endian hardware, so for the long term our focus will be
  // little-endian Power8.
@@@ -48,4 -53,6 +53,6 @@@
  #include "impl_ibm_vsx_util_double.h"
  #include "impl_ibm_vsx_util_float.h"
  
+ #pragma GCC diagnostic pop
  #endif // GMX_SIMD_IMPLEMENTATION_IBM_VSX_H
index 3370727306244d5004d13610fd8a38b2e11d4d05,b55c2a63c45f3f4a2bc912d8be76b87e31891b2e..21fb93c7c735d9c98b24bcf6be9ce2bb1352937e
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-  * Copyright (c) 2014,2015, by the GROMACS development team, led by
 - * Copyright (c) 2014,2015,2017, by the GROMACS development team, led by
++ * Copyright (c) 2014,2015,2017,2018, 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.
  #define GMX_SIMD_FINT32_WIDTH                   4
  #define GMX_SIMD_DINT32_WIDTH                   2
  #define GMX_SIMD4_WIDTH                         4
+ #define GMX_SIMD_ALIGNMENT                     16 // Bytes (4*single or 2*sdouble)
  #define GMX_SIMD_RSQRT_BITS                    14
  #define GMX_SIMD_RCP_BITS                      14
  
index 868b40f2485ab031cc814b8af30cf6281838dadf,d5745bf631e2e955dd56632976236b0208c62035..d413a5c73321fe9f883cffb1676d6756200e9eee
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-  * Copyright (c) 2014,2015,2016, by the GROMACS development team, led by
 - * Copyright (c) 2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2014,2015,2016,2017,2018, 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.
@@@ -249,7 -249,7 +249,7 @@@ gatherLoadBySimdIntTranspose(const doub
                               SimdDouble *    v2,
                               SimdDouble *    v3)
  {
-     GMX_ALIGNED(std::int32_t, GMX_SIMD_DINT32_WIDTH) ioffset[GMX_SIMD_DINT32_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_DINT32_WIDTH];
  
      store(ioffset, offset );
      gatherLoadTranspose<align>(base, ioffset, v0, v1, v2, v3);
@@@ -262,7 -262,7 +262,7 @@@ gatherLoadBySimdIntTranspose(const doub
                               SimdDouble *      v0,
                               SimdDouble *      v1)
  {
-     GMX_ALIGNED(std::int32_t, GMX_SIMD_DINT32_WIDTH) ioffset[GMX_SIMD_DINT32_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_DINT32_WIDTH];
  
      store(ioffset, offset );
      gatherLoadTranspose<align>(base, ioffset, v0, v1);
@@@ -276,7 -276,7 +276,7 @@@ gatherLoadUBySimdIntTranspose(const dou
                                SimdDouble *    v0,
                                SimdDouble *    v1)
  {
-     GMX_ALIGNED(std::int32_t, GMX_SIMD_DINT32_WIDTH) ioffset[GMX_SIMD_DINT32_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_DINT32_WIDTH];
  
      store(ioffset, offset );
      gatherLoadTranspose<align>(base, ioffset, v0, v1);
index 8863765784e716b99bfc4bc734871bb4cd7e1cb4,d85b0ca5ae6e2973cafdacf98f1a8956d0b6bfc0..50e8ce8ad6aa763713e9fea9e04eb4120bf50e7e
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2014,2015,2016,2017,2018, 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.
@@@ -330,7 -330,7 +330,7 @@@ gatherLoadBySimdIntTranspose(const floa
                               SimdFloat *    v2,
                               SimdFloat *    v3)
  {
-     GMX_ALIGNED(std::int32_t, GMX_SIMD_FINT32_WIDTH) ioffset[GMX_SIMD_FINT32_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_FINT32_WIDTH];
  
      store(ioffset, offset );
      gatherLoadTranspose<align>(base, ioffset, v0, v1, v2, v3);
@@@ -343,7 -343,7 +343,7 @@@ gatherLoadBySimdIntTranspose(const floa
                               SimdFloat *     v0,
                               SimdFloat *     v1)
  {
-     GMX_ALIGNED(std::int32_t, GMX_SIMD_FINT32_WIDTH) ioffset[GMX_SIMD_FINT32_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_FINT32_WIDTH];
  
      store(ioffset, offset );
      gatherLoadTranspose<align>(base, ioffset, v0, v1);
@@@ -356,7 -356,7 +356,7 @@@ gatherLoadUBySimdIntTranspose(const flo
                                SimdFloat *    v0,
                                SimdFloat *    v1)
  {
-     GMX_ALIGNED(std::int32_t, GMX_SIMD_FINT32_WIDTH) ioffset[GMX_SIMD_FINT32_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_FINT32_WIDTH];
  
      store(ioffset, offset );
      gatherLoadTranspose<align>(base, ioffset, v0, v1);
index ceef6b47e6f1c08d9e6e61c85b2b3eec6640dd8d,7688e571d5defa9052c62ac57ff5f2ac37e38c7e..d457f6d428bbcb432cce8cab752fe423ab5caee1
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-  * Copyright (c) 2015, by the GROMACS development team, led by
 - * Copyright (c) 2015,2017, by the GROMACS development team, led by
++ * Copyright (c) 2015,2017,2018, 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.
@@@ -61,6 -61,7 +61,7 @@@
  #undef GMX_SIMD_FINT32_WIDTH
  #undef GMX_SIMD_DINT32_WIDTH
  #undef GMX_SIMD4_WIDTH
+ #define GMX_SIMD_ALIGNMENT                  8 // 1*double
  #undef GMX_SIMD_RSQRT_BITS
  #undef GMX_SIMD_RCP_BITS
  
index 1f9709f20cf6f1a31049fbe7bc34d3e7df727883,ac6f9120a49f8694cd59cfe8e7434fa5580fb856..f0f6e4e735f541801c7f966ad62b7397c5a60dc1
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2014,2015,2017, by the GROMACS development team, led by
++ * Copyright (c) 2014,2015,2017,2018, 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.
@@@ -232,6 -232,9 +232,9 @@@ namespace gm
  //! \brief The SIMD4 type is always four units wide, but this makes code more explicit
  #define GMX_SIMD4_WIDTH                                          4
  
+ //! \brief Required alignment in bytes for aligned load/store (always defined, even without SIMD)
+ #define GMX_SIMD_ALIGNMENT                                       8 // 8 (1*double)
  //! \brief Accuracy of SIMD 1/sqrt(x) lookup. Used to determine number of iterations.
  #define GMX_SIMD_RSQRT_BITS                                      23
  
index 49182e22f9683c6e8411fe1d5b96dcb81a3edaf9,86f30dab090056d595d898714cd00e2adb3f1bc6..b44204bddc61f23b54553cea6ae1c02108579364
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2014,2015,2017, by the GROMACS development team, led by
++ * Copyright (c) 2014,2015,2017,2018, 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.
@@@ -76,6 -76,7 +76,7 @@@
  #define GMX_SIMD_FINT32_WIDTH                   4
  #define GMX_SIMD_DINT32_WIDTH                   2
  #define GMX_SIMD4_WIDTH                         4
+ #define GMX_SIMD_ALIGNMENT                     32 // Bytes (4*double for SIMD4)
  #define GMX_SIMD_RSQRT_BITS                    11
  #define GMX_SIMD_RCP_BITS                      11
  
index d80cccc11275d65e1c1e1df36bb60b4105538d8f,a8ab2b4f308d7404e5afbf084240c5abccd82732..da2d146cda035895730b32132ea968a9c0c3a6a9
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2014,2015,2017, by the GROMACS development team, led by
++ * Copyright (c) 2014,2015,2017,2018, 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.
@@@ -77,6 -77,7 +77,7 @@@
  #define GMX_SIMD_FINT32_WIDTH                   8
  #define GMX_SIMD_DINT32_WIDTH                   4
  #define GMX_SIMD4_WIDTH                         4
+ #define GMX_SIMD_ALIGNMENT                     32 // Bytes (8*single or 4*double)
  #define GMX_SIMD_RSQRT_BITS                    11
  #define GMX_SIMD_RCP_BITS                      11
  
index f2b5a20d926d932e34e34071acc9c493f11fdbc2,ab8f533ce366e20d1f1de664775074c31ab99574..a3d53e64617bf4b71a808f42ce78821c2943974b
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-  * Copyright (c) 2014,2015,2016, by the GROMACS development team, led by
 - * Copyright (c) 2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2014,2015,2016,2017,2018, 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.
@@@ -77,6 -77,7 +77,7 @@@
  #define GMX_SIMD_FINT32_WIDTH                   4
  #define GMX_SIMD_DINT32_WIDTH                   2
  #define GMX_SIMD4_WIDTH                         4
+ #define GMX_SIMD_ALIGNMENT                     32 // Bytes (4*double for SIMD4)
  #define GMX_SIMD_RSQRT_BITS                    11
  #define GMX_SIMD_RCP_BITS                      11
  
index 4b2474c271232e0f7dfee7499ff54f0f4ed26533,72e7ce98784055b6ea5d2361ea51970572517e1a..106ba1c3e69c010ad7b9ed543110739c76837aa9
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2014,2015,2017, by the GROMACS development team, led by
++ * Copyright (c) 2014,2015,2017,2018, 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.
@@@ -77,6 -77,7 +77,7 @@@
  #define GMX_SIMD_FINT32_WIDTH                   8
  #define GMX_SIMD_DINT32_WIDTH                   4
  #define GMX_SIMD4_WIDTH                         4
+ #define GMX_SIMD_ALIGNMENT                     32 // Bytes (8*single or 4*double)
  #define GMX_SIMD_RSQRT_BITS                    11
  #define GMX_SIMD_RCP_BITS                      11
  
index a3cefcbbb01a85757965fe9251c03a573e1b041c,23f43c988ba7250a4e44c5dca48bf196e3b117ea..241c612e12205a60aca4f6adadee61907a0a9227
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-  * Copyright (c) 2014,2015, by the GROMACS development team, led by
 - * Copyright (c) 2014,2015,2017, by the GROMACS development team, led by
++ * Copyright (c) 2014,2015,2017,2018, 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.
@@@ -331,7 -331,7 +331,7 @@@ gatherLoadBySimdIntTranspose(const doub
      assert(std::size_t(base) % 32 == 0);
      assert(align % 4 == 0);
  
-     GMX_ALIGNED(int, GMX_SIMD_DINT32_WIDTH) ioffset[GMX_SIMD_DINT32_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_DINT32_WIDTH];
      _mm_store_si128( reinterpret_cast<__m128i *>(ioffset), offset.simdInternal_);
  
      v0->simdInternal_ = _mm256_load_pd(base + align * ioffset[0]);
@@@ -355,7 -355,7 +355,7 @@@ gatherLoadBySimdIntTranspose(const doub
      assert(std::size_t(base) % 16 == 0);
      assert(align % 2 == 0);
  
-     GMX_ALIGNED(int, GMX_SIMD_DINT32_WIDTH) ioffset[GMX_SIMD_DINT32_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t  ioffset[GMX_SIMD_DINT32_WIDTH];
      _mm_store_si128( reinterpret_cast<__m128i *>(ioffset), offset.simdInternal_);
  
      t1  = _mm_load_pd(base + align * ioffset[0]);
@@@ -379,7 -379,7 +379,7 @@@ gatherLoadUBySimdIntTranspose(const dou
      __m128d t1, t2, t3, t4;
      __m256d tA, tB;
  
-     GMX_ALIGNED(int, GMX_SIMD_DINT32_WIDTH) ioffset[GMX_SIMD_DINT32_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_DINT32_WIDTH];
      _mm_store_si128( reinterpret_cast<__m128i *>(ioffset), offset.simdInternal_);
  
      t1   = _mm_loadu_pd(base + align * ioffset[0]);
index 2eebda93e416b8e978c07effa36fde2e7364121d,2d19218593a1440328cb01cb852a2de73153d1b3..f96fe28ce12f964391bd9a0352af08fcda32d2f6
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2014,2015,2017, by the GROMACS development team, led by
++ * Copyright (c) 2014,2015,2017,2018, 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.
@@@ -484,7 -484,7 +484,7 @@@ gatherLoadBySimdIntTranspose(const floa
                               SimdFloat *    v2,
                               SimdFloat *    v3)
  {
-     GMX_ALIGNED(int, GMX_SIMD_FLOAT_WIDTH) offset[GMX_SIMD_FLOAT_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t    offset[GMX_SIMD_FLOAT_WIDTH];
      _mm256_store_si256( reinterpret_cast<__m256i *>(offset), simdoffset.simdInternal_);
      gatherLoadTranspose<align>(base, offset, v0, v1, v2, v3);
  }
@@@ -496,7 -496,7 +496,7 @@@ gatherLoadBySimdIntTranspose(const floa
                               SimdFloat *     v0,
                               SimdFloat *     v1)
  {
-     GMX_ALIGNED(int, GMX_SIMD_FLOAT_WIDTH) offset[GMX_SIMD_FLOAT_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t    offset[GMX_SIMD_FLOAT_WIDTH];
      _mm256_store_si256( reinterpret_cast<__m256i *>(offset), simdoffset.simdInternal_);
      gatherLoadTranspose<align>(base, offset, v0, v1);
  }
@@@ -512,7 -512,7 +512,7 @@@ gatherLoadUBySimdIntTranspose(const flo
      __m128 t1, t2, t3, t4, t5, t6, t7, t8;
      __m256 tA, tB, tC, tD;
  
-     GMX_ALIGNED(int, GMX_SIMD_FLOAT_WIDTH) offset[GMX_SIMD_FLOAT_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t     offset[GMX_SIMD_FLOAT_WIDTH];
      _mm256_store_si256( reinterpret_cast<__m256i *>(offset), simdoffset.simdInternal_);
  
      t1  = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast<const __m64 *>( base + align * offset[0] ) );
index 45acf123973f1853694ec18353ef0fd6c5295807,a27ea2c628b21e35626625bbb48d9be578639f5c..4e82a0fb8ff8fe8c998ad00b29a4a848997c1904
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2014,2015,2016,2017,2018, 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.
@@@ -96,6 -96,7 +96,7 @@@
  #define GMX_SIMD_FINT32_WIDTH                     16
  #define GMX_SIMD_DINT32_WIDTH                      8
  #define GMX_SIMD4_WIDTH                            4
+ #define GMX_SIMD_ALIGNMENT                        64 // Bytes (16*single or 8*double)
  #define GMX_SIMD_RSQRT_BITS                       14
  #define GMX_SIMD_RCP_BITS                         14
  
index 3ff77c61e07a99804ae932f85560671338e101c2,22b4ffaae29a1b49461a071e1a2c7cb04ee4ee10..8bb451d55064639519e87a55b48df63c0e2e62c9
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2014,2015,2016,2017,2018, 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.
@@@ -151,7 -151,7 +151,7 @@@ transposeScatterIncrU(double 
                        SimdDouble          v2)
  {
      __m512d t[4], t5, t6, t7, t8;
-     GMX_ALIGNED(std::int64_t, 8)    o[8];
+     alignas(GMX_SIMD_ALIGNMENT) std::int64_t    o[8];
      //TODO: should use fastMultiply
      _mm512_store_epi64(o, _mm512_cvtepi32_epi64(_mm256_mullo_epi32(_mm256_load_si256((const __m256i*)(offset  )), _mm256_set1_epi32(align))));
      t5   = _mm512_unpacklo_pd(v0.simdInternal_, v1.simdInternal_);
@@@ -206,7 -206,7 +206,7 @@@ transposeScatterDecrU(double 
                        SimdDouble          v2)
  {
      __m512d t[4], t5, t6, t7, t8;
-     GMX_ALIGNED(std::int64_t, 8)    o[8];
+     alignas(GMX_SIMD_ALIGNMENT) std::int64_t    o[8];
      //TODO: should use fastMultiply
      _mm512_store_epi64(o, _mm512_cvtepi32_epi64(_mm256_mullo_epi32(_mm256_load_si256((const __m256i*)(offset  )), _mm256_set1_epi32(align))));
      t5   = _mm512_unpacklo_pd(v0.simdInternal_, v1.simdInternal_);
index 61548bba13f889062424603a225e406c75a2dad4,6f94b981918492e80de572dd773eefd037283e2f..6f6bf175a419ee3cace07926f9e3238547b5124b
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2014,2015,2016,2017,2018, 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.
@@@ -154,7 -154,7 +154,7 @@@ transposeScatterIncrU(float 
  {
      __m512 t[4], t5, t6, t7, t8;
      int    i;
-     GMX_ALIGNED(std::int32_t, 16)    o[16];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t    o[16];
      store(o, fastMultiply<align>(simdLoad(offset, SimdFInt32Tag())));
      if (align < 4)
      {
@@@ -226,7 -226,7 +226,7 @@@ transposeScatterDecrU(float 
  {
      __m512 t[4], t5, t6, t7, t8;
      int    i;
-     GMX_ALIGNED(std::int32_t, 16)    o[16];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t    o[16];
      store(o, fastMultiply<align>(simdLoad(offset, SimdFInt32Tag())));
      if (align < 4)
      {
index d0698fa8bebe9c97df526781cdd56202609470cd,ada37e237c24fa739fbc80c0cd974c970d794d8c..6f988fed2f95df27581a7a9a0d74b5a9e746c723
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2014,2015,2016,2017,2018, 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.
@@@ -85,6 -85,7 +85,7 @@@
  #define GMX_SIMD_FINT32_WIDTH                     16
  #define GMX_SIMD_DINT32_WIDTH                      8
  #define GMX_SIMD4_WIDTH                            4
+ #define GMX_SIMD_ALIGNMENT                        64 // Bytes (16*single or 8*double)
  #define GMX_SIMD_RSQRT_BITS                       28
  #define GMX_SIMD_RCP_BITS                         28
  
index 61123eb1d9e56e243124c2affeb182a2016ca7f0,c6135c66aba0d7e915323f83db1daeb59ebb9bbf..fc9b71990f69af824837b36ed67f7be3b0620a79
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-  * Copyright (c) 2014,2015, by the GROMACS development team, led by
 - * Copyright (c) 2014,2015,2017, by the GROMACS development team, led by
++ * Copyright (c) 2014,2015,2017,2018, 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.
@@@ -78,6 -78,7 +78,7 @@@
  #define GMX_SIMD_FINT32_WIDTH                     16
  #define GMX_SIMD_DINT32_WIDTH                      8
  #define GMX_SIMD4_WIDTH                            4
+ #define GMX_SIMD_ALIGNMENT                        64 // Bytes (16*single or 8*double)
  #define GMX_SIMD_RSQRT_BITS                       23
  #define GMX_SIMD_RCP_BITS                         23
  
index 62e072071fb900490c85897708e019ecd40bd3ed,9904fc5fd932b8431543ffc4b00e209f7dcfd0a4..e6d6679818e952434830ec46f6314411eb624323
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2014,2015,2016,2017,2018, 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.
@@@ -235,9 -235,9 +235,9 @@@ transposeScatterIncrU(double 
                        SimdDouble          v1,
                        SimdDouble          v2)
  {
-     GMX_ALIGNED(double, GMX_SIMD_DOUBLE_WIDTH)  rdata0[GMX_SIMD_DOUBLE_WIDTH];
-     GMX_ALIGNED(double, GMX_SIMD_DOUBLE_WIDTH)  rdata1[GMX_SIMD_DOUBLE_WIDTH];
-     GMX_ALIGNED(double, GMX_SIMD_DOUBLE_WIDTH)  rdata2[GMX_SIMD_DOUBLE_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) double  rdata0[GMX_SIMD_DOUBLE_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) double  rdata1[GMX_SIMD_DOUBLE_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) double  rdata2[GMX_SIMD_DOUBLE_WIDTH];
  
      store(rdata0, v0);
      store(rdata1, v1);
@@@ -259,9 -259,9 +259,9 @@@ transposeScatterDecrU(double 
                        SimdDouble          v1,
                        SimdDouble          v2)
  {
-     GMX_ALIGNED(double, GMX_SIMD_DOUBLE_WIDTH)  rdata0[GMX_SIMD_DOUBLE_WIDTH];
-     GMX_ALIGNED(double, GMX_SIMD_DOUBLE_WIDTH)  rdata1[GMX_SIMD_DOUBLE_WIDTH];
-     GMX_ALIGNED(double, GMX_SIMD_DOUBLE_WIDTH)  rdata2[GMX_SIMD_DOUBLE_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) double  rdata0[GMX_SIMD_DOUBLE_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) double  rdata1[GMX_SIMD_DOUBLE_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) double  rdata2[GMX_SIMD_DOUBLE_WIDTH];
  
      store(rdata0, v0);
      store(rdata1, v1);
index 48b2a9f6638b73a9ca6ec0d8b47a42889bca1ee2,036ff2fb881edac474bb40ebdcf247f3f5365ab8..b766e1b444b5eee2936b93f7542fb3daf4ed4095
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2014,2015,2016,2017,2018, 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.
@@@ -239,9 -239,9 +239,9 @@@ transposeScatterIncrU(float 
                        SimdFloat            v1,
                        SimdFloat            v2)
  {
-     GMX_ALIGNED(float, GMX_SIMD_FLOAT_WIDTH)  rdata0[GMX_SIMD_FLOAT_WIDTH];
-     GMX_ALIGNED(float, GMX_SIMD_FLOAT_WIDTH)  rdata1[GMX_SIMD_FLOAT_WIDTH];
-     GMX_ALIGNED(float, GMX_SIMD_FLOAT_WIDTH)  rdata2[GMX_SIMD_FLOAT_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) float  rdata0[GMX_SIMD_FLOAT_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) float  rdata1[GMX_SIMD_FLOAT_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) float  rdata2[GMX_SIMD_FLOAT_WIDTH];
  
      store(rdata0, v0);
      store(rdata1, v1);
@@@ -263,9 -263,9 +263,9 @@@ transposeScatterDecrU(float 
                        SimdFloat            v1,
                        SimdFloat            v2)
  {
-     GMX_ALIGNED(float, GMX_SIMD_FLOAT_WIDTH)  rdata0[GMX_SIMD_FLOAT_WIDTH];
-     GMX_ALIGNED(float, GMX_SIMD_FLOAT_WIDTH)  rdata1[GMX_SIMD_FLOAT_WIDTH];
-     GMX_ALIGNED(float, GMX_SIMD_FLOAT_WIDTH)  rdata2[GMX_SIMD_FLOAT_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) float  rdata0[GMX_SIMD_FLOAT_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) float  rdata1[GMX_SIMD_FLOAT_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) float  rdata2[GMX_SIMD_FLOAT_WIDTH];
  
      store(rdata0, v0);
      store(rdata1, v1);
index 7b585d4e28dcaf37ff192a5ef3fa051309bcaab0,0cc62e9de15cb58df39e696d20064dd553a3dfa4..85128bb0dcd7ec6975cff1eb50473910482dc4f2
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-  * Copyright (c) 2014,2015, by the GROMACS development team, led by
 - * Copyright (c) 2014,2015,2017, by the GROMACS development team, led by
++ * Copyright (c) 2014,2015,2017,2018, 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.
@@@ -76,6 -76,7 +76,7 @@@
  #define GMX_SIMD_FINT32_WIDTH                   4
  #define GMX_SIMD_DINT32_WIDTH                   2
  #define GMX_SIMD4_WIDTH                         4
+ #define GMX_SIMD_ALIGNMENT                     16 // Bytes (4*single or 2*double)
  #define GMX_SIMD_RSQRT_BITS                    11
  #define GMX_SIMD_RCP_BITS                      11
  
index 67e3047a58f19a62e038a0cef755aebf4fbe64b5,4acf483065d8480e1a86c83c51e7a0dedd50405b..53bcaffc8a8762e5716ab4bdec9bc6d89cddd94a
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-  * Copyright (c) 2014,2015, by the GROMACS development team, led by
 - * Copyright (c) 2014,2015,2017, by the GROMACS development team, led by
++ * Copyright (c) 2014,2015,2017,2018, 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.
@@@ -334,7 -334,7 +334,7 @@@ gatherLoadBySimdIntTranspose(const floa
      // This is likely because (a) the extract function is expensive, and (b)
      // the alignment scaling can often be done as part of the load instruction
      // (which is even cheaper than doing it in SIMD registers).
-     GMX_ALIGNED(std::int32_t, GMX_SIMD_FINT32_WIDTH) ioffset[GMX_SIMD_FINT32_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_FINT32_WIDTH];
      _mm_store_si128( (__m128i *)ioffset, offset.simdInternal_);
      gatherLoadTranspose<align>(base, ioffset, v0, v1, v2, v3);
  }
@@@ -351,7 -351,7 +351,7 @@@ gatherLoadBySimdIntTranspose(const floa
      // This is likely because (a) the extract function is expensive, and (b)
      // the alignment scaling can often be done as part of the load instruction
      // (which is even cheaper than doing it in SIMD registers).
-     GMX_ALIGNED(std::int32_t, GMX_SIMD_FINT32_WIDTH) ioffset[GMX_SIMD_FINT32_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_FINT32_WIDTH];
      _mm_store_si128( (__m128i *)ioffset, offset.simdInternal_);
      gatherLoadTranspose<align>(base, ioffset, v0, v1);
  }
@@@ -370,7 -370,7 +370,7 @@@ gatherLoadUBySimdIntTranspose(const flo
      // This is likely because (a) the extract function is expensive, and (b)
      // the alignment scaling can often be done as part of the load instruction
      // (which is even cheaper than doing it in SIMD registers).
-     GMX_ALIGNED(std::int32_t, GMX_SIMD_FINT32_WIDTH) ioffset[GMX_SIMD_FINT32_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_FINT32_WIDTH];
      _mm_store_si128( (__m128i *)ioffset, offset.simdInternal_);
      gatherLoadTranspose<align>(base, ioffset, v0, v1);
  }
index 4d172273629d74f3fae6a3f8b1ab48c9e2d25f07,e9282ac57bfa38a2aa354e2377a407225a960a5b..0d5d3f48b95e7a6b55b9105e62ca1c594396dd1f
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-  * Copyright (c) 2014,2015, by the GROMACS development team, led by
 - * Copyright (c) 2014,2015,2017, by the GROMACS development team, led by
++ * Copyright (c) 2014,2015,2017,2018, 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.
@@@ -76,6 -76,7 +76,7 @@@
  #define GMX_SIMD_FINT32_WIDTH                   4
  #define GMX_SIMD_DINT32_WIDTH                   2
  #define GMX_SIMD4_WIDTH                         4
+ #define GMX_SIMD_ALIGNMENT                     16 // Bytes (4*single or 2*double)
  #define GMX_SIMD_RSQRT_BITS                    11
  #define GMX_SIMD_RCP_BITS                      11
  
index ad519574b1683cb8bd410d2ceece516f34bc64d0,207b1b784a2d6b5c5bc9df136ea138a206aed8dc..a45ba4b84d2bb092e676c5f6c4babe00747b8108
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2012,2013,2014,2015,2017, by the GROMACS development team, led by
++ * Copyright (c) 2012,2013,2014,2015,2017,2018, 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.
@@@ -742,7 -742,7 +742,7 @@@ erfc(SimdFloat x
      const SimdFloat         sieve(SimdFloat(-5.965323564e+29f) | SimdFloat(7.05044434e-30f));
  #else
      const int               isieve   = 0xFFFFF000;
-     GMX_ALIGNED(float, GMX_SIMD_FLOAT_WIDTH)  mem[GMX_SIMD_FLOAT_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) float  mem[GMX_SIMD_FLOAT_WIDTH];
  
      union {
          float f; int i;
index 5bbdb1d35f80ea3d75806e08c5add85c7d33891e,1ffe38a48c8d00d327706815526ffc8247fadae9..bb9307f3c7cf80e633e1d92fd4dbcb3ef9471db6
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2014,2015,2017, by the GROMACS development team, led by
++ * Copyright (c) 2014,2015,2017,2018, 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.
@@@ -91,13 -91,8 +91,8 @@@ loadStoreTester(TSimd gmx_simdcall load
       * simdWidth elements at the beginning and end
       * to test we are not polluting memory there either. Sum=4*simdWidth.
       */
- #if GMX_SIMD4_WIDTH > GMX_SIMD_REAL_WIDTH
-     GMX_ALIGNED(T, GMX_SIMD4_WIDTH)      src[simdWidth*4];
-     GMX_ALIGNED(T, GMX_SIMD4_WIDTH)      dst[simdWidth*4];
- #else
-     GMX_ALIGNED(T, GMX_SIMD_REAL_WIDTH)  src[simdWidth*4];
-     GMX_ALIGNED(T, GMX_SIMD_REAL_WIDTH)  dst[simdWidth*4];
- #endif
+     alignas(GMX_SIMD_ALIGNMENT) T        src[simdWidth*4];
+     alignas(GMX_SIMD_ALIGNMENT) T        dst[simdWidth*4];
  
      // Make sure we have memory to check both before and after the test pointers
      T *              pCopySrc = src + simdWidth + loadOffset;
index d07621baa1271f15b0c7e4c0f0baa0ce5ddfed4c,3de3c0e4b3e19a124558e0ff3e792d438c6382f0..8655f64dcd5c381adc22cc040e8d91ee007a68d8
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2014,2015,2016,2017,2018, 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.
@@@ -121,10 -121,42 +121,42 @@@ const SimdInt32 iSimd_0xCCCCCCCC = setS
  #endif
  
  #if GMX_SIMD_HAVE_REAL
+ TEST(SimdTest, GmxAligned)
+ {
+     // Test alignment with two variables that must be aligned, and one that
+     // doesn't have to be. The order of variables is up to the compiler, but
+     // if it ignores alignment it is highly unlikely that both r1/r3 still end
+     // up being aligned by mistake.
+     alignas(GMX_SIMD_ALIGNMENT) real        r1;
+     real                                    r2;
+     alignas(GMX_SIMD_ALIGNMENT) real        r3;
+     std::uint64_t addr1 = reinterpret_cast<std::uint64_t>(&r1);
+     std::uint64_t addr2 = reinterpret_cast<std::uint64_t>(&r2);
+     std::uint64_t addr3 = reinterpret_cast<std::uint64_t>(&r3);
+     EXPECT_EQ(0, addr1 % GMX_SIMD_ALIGNMENT);
+     EXPECT_NE(0, addr2); // Just so r2 is not optimized away
+     EXPECT_EQ(0, addr3 % GMX_SIMD_ALIGNMENT);
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t         i1;
+     std::int32_t                                     i2;
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t         i3;
+     addr1 = reinterpret_cast<std::uint64_t>(&i1);
+     addr2 = reinterpret_cast<std::uint64_t>(&i2);
+     addr3 = reinterpret_cast<std::uint64_t>(&i3);
+     EXPECT_EQ(0, addr1 % GMX_SIMD_ALIGNMENT);
+     EXPECT_NE(0, addr2); // Just so i2 is not optimized away
+     EXPECT_EQ(0, addr3 % GMX_SIMD_ALIGNMENT);
+ }
  ::std::vector<real>
  simdReal2Vector(const SimdReal simd)
  {
-     GMX_ALIGNED(real, GMX_SIMD_REAL_WIDTH)  mem[GMX_SIMD_REAL_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) real        mem[GMX_SIMD_REAL_WIDTH];
  
      store(mem, simd);
      std::vector<real>   v(mem, mem+GMX_SIMD_REAL_WIDTH);
  SimdReal
  vector2SimdReal(const std::vector<real> &v)
  {
-     GMX_ALIGNED(real, GMX_SIMD_REAL_WIDTH)  mem[GMX_SIMD_REAL_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) real        mem[GMX_SIMD_REAL_WIDTH];
  
      for (int i = 0; i < GMX_SIMD_REAL_WIDTH; i++)
      {
@@@ -179,21 -211,21 +211,21 @@@ SimdTest::compareSimdEq(const char * re
      return compareVectorEq(refExpr, tstExpr, simdReal2Vector(ref), simdReal2Vector(tst));
  }
  
- std::vector<int>
+ std::vector<std::int32_t>
  simdInt2Vector(const SimdInt32 simd)
  {
-     GMX_ALIGNED(int, GMX_SIMD_REAL_WIDTH)  mem[GMX_SIMD_REAL_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t  mem[GMX_SIMD_REAL_WIDTH];
  
      store(mem, simd);
-     std::vector<int>    v(mem, mem+GMX_SIMD_REAL_WIDTH);
+     std::vector<std::int32_t>    v(mem, mem+GMX_SIMD_REAL_WIDTH);
  
      return v;
  }
  
  SimdInt32
- vector2SimdInt(const std::vector<int> &v)
+ vector2SimdInt(const std::vector<std::int32_t> &v)
  {
-     GMX_ALIGNED(int, GMX_SIMD_REAL_WIDTH)  mem[GMX_SIMD_REAL_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t   mem[GMX_SIMD_REAL_WIDTH];
  
      for (int i = 0; i < GMX_SIMD_REAL_WIDTH; i++)
      {
index a32676bf7c0e83d9c4c6299e3de89e191ecdc182,efa57f3589ebee1bffd16aadc828111478151869..b4d08f4c5858ec6aa6895f301428957a8da2049a
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2014,2015,2016,2017,2018, 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.
@@@ -268,14 -268,14 +268,14 @@@ SimdReal   setSimdRealFrom1R(real value
   *
   * The returned vector will have the same length as the SIMD width.
   */
- std::vector<int>   simdInt2Vector(const SimdInt32 simd);
+ std::vector<std::int32_t>   simdInt2Vector(const SimdInt32 simd);
  
  /*! \brief Return 32-bit integer SIMD value from std::vector<int>.
   *
   * If the vector is longer than SIMD width, only the first elements will be used.
   * If it is shorter, the contents will be repeated to fill the SIMD register.
   */
- SimdInt32   vector2SimdInt(const std::vector<int> &v);
+ SimdInt32   vector2SimdInt(const std::vector<std::int32_t> &v);
  
  /*! \brief Set SIMD register contents from three int values.
   *
index edb66badf06bc5dceca67bfb37352965ee630b5d,ba915941009e7758239c44399f772efdd785ecef..86858d67b88f765da4752d8b21536e6dc1e1014e
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2014,2015,2017, by the GROMACS development team, led by
++ * Copyright (c) 2014,2015,2017,2018, by the GROMACS development team, led by
   * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
   * and including many others, as listed in the AUTHORS file in the
   * top-level source directory and at http://www.gromacs.org.
@@@ -86,7 -86,7 +86,7 @@@ const Simd4Real rSimd4_logicalResultO
  ::std::vector<real>
  simd4Real2Vector(const Simd4Real simd4)
  {
-     GMX_ALIGNED(real, GMX_SIMD4_WIDTH)  mem[GMX_SIMD4_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) real  mem[GMX_SIMD4_WIDTH];
  
      store4(mem, simd4);
      std::vector<real>   v(mem, mem+GMX_SIMD4_WIDTH);
@@@ -97,7 -97,7 +97,7 @@@
  Simd4Real
  vector2Simd4Real(const std::vector<real> &v)
  {
-     GMX_ALIGNED(real, GMX_SIMD4_WIDTH)  mem[GMX_SIMD4_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) real  mem[GMX_SIMD4_WIDTH];
  
      for (int i = 0; i < GMX_SIMD4_WIDTH; i++)
      {
index b2300ec8be733abe5c03a77103b17332224c47ad,50e8687fcdb38eccc2e61a1e9f60d195131c4107..451dadd7dcc90636370a8cfe6c0eefa55c500305
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2014,2015,2016,2017,2018, 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.
@@@ -312,7 -312,7 +312,7 @@@ TEST_F(Simd4FloatingpointTest, transpos
      Simd4Real        v0, v1, v2, v3;
      int              i;
      // aligned pointers
-     GMX_ALIGNED(real, GMX_SIMD4_WIDTH) p0[4*GMX_SIMD4_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) real p0[4*GMX_SIMD4_WIDTH];
      real          *  p1 = p0 + GMX_SIMD4_WIDTH;
      real          *  p2 = p0 + 2*GMX_SIMD4_WIDTH;
      real          *  p3 = p0 + 3*GMX_SIMD4_WIDTH;
index 14fbe0d366362ee330eb2dd9649294c95f45003b,2c57354c9bb70dcf969f173d910769422ceaa15a..825df83b6fdd07565eb5d5126a287b0681f6ae92
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2014,2015,2016,2017,2018, 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.
@@@ -453,8 -453,8 +453,8 @@@ TEST_F(SimdFloatingpointTest, reduce
  #if GMX_SIMD_HAVE_FLOAT && GMX_SIMD_HAVE_DOUBLE
  TEST_F(SimdFloatingpointTest, cvtFloat2Double)
  {
-     GMX_ALIGNED(float, GMX_SIMD_FLOAT_WIDTH)   f[GMX_SIMD_FLOAT_WIDTH];
-     GMX_ALIGNED(double, GMX_SIMD_DOUBLE_WIDTH) d[GMX_SIMD_FLOAT_WIDTH];  // Yes, double array length should be same as float
+     alignas(GMX_SIMD_ALIGNMENT) float   f[GMX_SIMD_FLOAT_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) double  d[GMX_SIMD_FLOAT_WIDTH];  // Yes, double array length should be same as float
  
      int                               i;
      SimdFloat                         vf;
  
  TEST_F(SimdFloatingpointTest, cvtDouble2Float)
  {
-     GMX_ALIGNED(float, GMX_SIMD_FLOAT_WIDTH)   f[GMX_SIMD_FLOAT_WIDTH];
-     GMX_ALIGNED(double, GMX_SIMD_DOUBLE_WIDTH) d[GMX_SIMD_FLOAT_WIDTH];  // Yes, double array length should be same as float
+     alignas(GMX_SIMD_ALIGNMENT) float     f[GMX_SIMD_FLOAT_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) double    d[GMX_SIMD_FLOAT_WIDTH];  // Yes, double array length should be same as float
      int                               i;
      SimdFloat                         vf;
      SimdDouble                        vd0;
index a43dfc5d7f9fb589181123025e65da4a069a988c,c229fb37c8696fe553e24763b219a3c8c1f62d5d..a957201707558482654eba9faa837c9bf9862b15
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2015,2017, by the GROMACS development team, led by
++ * Copyright (c) 2015,2017,2018, 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.
@@@ -929,7 -929,7 +929,7 @@@ TEST_F(SimdFloatingpointUtilTest, loadU
      real            data[GMX_SIMD_REAL_WIDTH/4];
      std::iota(data, data+GMX_SIMD_REAL_WIDTH/4, 1);
  
- #if defined _ICC && __ICC == 1800 || defined __ICL && __ICL == 1800
+ #if defined __ICC && __ICC == 1800 || defined __ICL && __ICL == 1800
  #pragma novector /* Work-around for incorrect vectorization for AVX_512(_KNL) */
  #endif
      for (i = 0; i < GMX_SIMD_REAL_WIDTH / 4; i++)
index c675f8b03490162c92e51077fb1d455855a47ae8,594827d84d4b943d2c44143a62f8534ac5f5e503..b2a99ecd780ab7853a74ac09aa1ac2ce9d29a7d1
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2014,2015,2016,2017,2018, 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.
@@@ -131,7 -131,7 +131,7 @@@ TEST_F(SimdIntegerTest, xor
  #if GMX_SIMD_HAVE_INT32_EXTRACT
  TEST_F(SimdIntegerTest, extract)
  {
-     GMX_ALIGNED(int, GMX_SIMD_REAL_WIDTH)  idata[GMX_SIMD_REAL_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) std::int32_t  idata[GMX_SIMD_REAL_WIDTH];
      SimdInt32 simd;
  
      for (int i = 0; i < GMX_SIMD_REAL_WIDTH; i++)
index de1e0d3a08f88b20a8f05ce1a269d2844a2b4e1e,5eddd563ab1bb2c855b299c2bc49ee63e47174db..e30c014c9d2cf0489816450208815a46b148643b
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2014,2015,2017, by the GROMACS development team, led by
++ * Copyright (c) 2014,2015,2017,2018, 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.
@@@ -422,10 -422,25 +422,25 @@@ TEST_F(SimdMathTest, exp
  
      // First test the range where we get normalized (non-denormal) results,
      // since we don't require denormal results to be reproduced correctly.
+     //
+     // For very small arguments that would produce results close to the
+     // smallest representable value, some of the intermediate values might
+     // trigger flush-to-zero denormals without FMA operations,
+     // e.g. for the icc compiler. Since we never use such values in Gromacs, we
+     // shrink the range a bit in that case instead of requiring the compiler to
+     // handle denormals (which might reduce performance).
  #if GMX_DOUBLE
+ #if GMX_SIMD_HAVE_FMA
      setRange(-708.3, 709.1);
  #else
+     setRange(-690, 709.1);
+ #endif
+ #else
+ #if GMX_SIMD_HAVE_FMA
      setRange(-87.3, 88.0);
+ #else
+     setRange(-80, 88.0);
+ #endif
  #endif
      GMX_EXPECT_SIMD_FUNC_NEAR(std::exp, exp);
  
      // Then multiply with ln(2) to get our limit for exp().
      // In this range we allow the value to be either correct (denormal) or 0.0
  #if GMX_DOUBLE
-     setRange(-746.0, -708.3);
+     setRange(-746.0, -708.4);
  #else
      setRange(-104.0, -87.3);
  #endif
  TEST_F(SimdMathTest, expUnsafe)
  {
  #if GMX_DOUBLE
+ #if GMX_SIMD_HAVE_FMA
      setRange(-708.3, 709.1);
  #else
+     setRange(-690, 709.1);
+ #endif
+ #else
+ #if GMX_SIMD_HAVE_FMA
      setRange(-87.3, 88.0);
+ #else
+     setRange(-80, 88.0);
+ #endif
  #endif
      GMX_EXPECT_SIMD_FUNC_NEAR(std::exp, exp<MathOptimization::Unsafe>);
  }
index 502b9bcb841de2806b5c52cd5d2b6810364c4473,8bcb4cf06bbf3a6ceb686a84af813734bda2cb50..da94daf08cd2e61cf329938a86f5569d6158b419
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2016,2017,2018, 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.
@@@ -340,10 -340,14 +340,14 @@@ CubicSplineTable::CubicSplineTable(std:
              ex.prependContext("Error generating cubic spline table for function '" + thisFuncInput.desc + "'");
              throw;
          }
-         // Calculate the required table spacing h. The error we make with linear interpolation
-         // of the derivative will be described by the third-derivative correction term.
-         // This means we can compute the required spacing as h = sqrt(12*tolerance*min(f'/f''')),
-         // where f'/f''' is the first and third derivative of the function, respectively.
+         // Calculate the required table spacing h. The error we make with a third order polynomial
+         // (second order for derivative) will be described by the fourth-derivative correction term.
+         //
+         // This means we can compute the required spacing as h = 0.5*cbrt(72*sqrt(3)*tolerance**min(f'/f'''')),
+         // where f'/f'''' is the first and fourth derivative of the function, respectively.
+         // Since we already have an analytical form of the derivative, we reduce the numerical
+         // errors by calculating the quotient of the function and third derivative of the
+         // input-derivative-analytical function instead.
  
          double thisMinQuotient = internal::findSmallestQuotientOfFunctionAndThirdDerivative(thisFuncInput.derivative, range_);
  
index c1122110bc39632d3a70d5a6cb31ab4360de88c4,02fbae5d69a654ddb005711423ec041f14266fe6..72e4c6399da3587e872627b21d9b2f9646ec7247
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-  * Copyright (c) 2016, by the GROMACS development team, led by
 - * Copyright (c) 2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2016,2017,2018, 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.
@@@ -113,7 -113,6 +113,6 @@@ namespace gm
   * \note There will be a small additional accuracy loss from the internal
   *       operation where we calculate the epsilon offset from the nearest table
   *       point, since the integer part we subtract can get large in those cases.
-  *
   *       While this is technically possible to solve with extended precision
   *       arithmetics, that would introduce extra instructions in some highly
   *       performance-sensitive code parts. For typical GROMACS interaction
index 7a85cda2353a6b952922d83c36cf57354f018334,fe69828cf84c799a6349673ec50219dc4d053701..de4487ad985b4522026bde5c1bfe06d8c58b4c86
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2016,2017,2018, 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.
@@@ -404,6 -404,9 +404,9 @@@ QuadraticSplineTable::QuadraticSplineTa
          // of the derivative will be described by the third-derivative correction term.
          // This means we can compute the required spacing as h = sqrt(12*tolerance*min(f'/f''')),
          // where f'/f''' is the first and third derivative of the function, respectively.
+         // Since we already have an analytical form of the derivative, we reduce the numerical
+         // errors by calculating the quotient of the function and second derivative of the
+         // input-derivative-analytical function instead.
  
          double thisMinQuotient = internal::findSmallestQuotientOfFunctionAndSecondDerivative(thisFuncInput.derivative, thisFuncInput.spacing, range_);
  
index 94c9228fe6f06e9c528175e3b306083ce827adf5,a023ec1fe111ef582221832c7e7f0bbf9b133d4e..1eb0001429c56e7ea9ffe63b49456d5097b01bac
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2016,2017,2018, by the GROMACS development team, led by
   * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
   * and including many others, as listed in the AUTHORS file in the
   * top-level source directory and at http://www.gromacs.org.
@@@ -147,7 -147,7 +147,7 @@@ throwUnlessDerivativeIsConsistentWithFu
  }
  
  
- /*! \brief Update minQuotient if the ratio of this function value and its second derivative is smaller
+ /*! \brief Calculate absolute quotient of function and its second derivative
   *
   * This is a utility function used in the functions to find the smallest quotient
   * in a range.
   * \param[in]    thisPoint     Value of function at x.
   * \param[in]    nextPoint     Value of function at x+h.
   * \param[in]    spacing       Value of h.
-  * \param[inout] minQuotient   Current minimum of such quotients, updated if this quotient is smaller.
+  *
+  * \return The absolute value of the quotient. If either the function or second
+  *         derivative is smaller than sqrt(GMX_REAL_MIN), they will be set to
+  *         that value.
   */
- static void
- updateMinQuotientOfFunctionAndSecondDerivative(double     previousPoint,
-                                                double     thisPoint,
-                                                double     nextPoint,
-                                                double     spacing,
-                                                double *   minQuotient)
+ static double
+ quotientOfFunctionAndSecondDerivative(double     previousPoint,
+                                       double     thisPoint,
+                                       double     nextPoint,
+                                       double     spacing)
  {
-     double value             = std::abs( thisPoint );
+     double lowerLimit        = static_cast<double>(std::sqrt(GMX_REAL_MIN));
+     double value             = std::max(std::abs( thisPoint ), lowerLimit );
      double secondDerivative  = std::abs( (previousPoint - 2.0 * thisPoint + nextPoint) / (spacing * spacing ) );
  
      // Make sure we do not divide by zero. This limit is arbitrary,
      // but it doesnt matter since this point will have a very large value,
      // and the whole routine is searching for the smallest value.
-     secondDerivative = std::max(secondDerivative, static_cast<double>(std::sqrt(GMX_REAL_MIN)));
+     secondDerivative = std::max(secondDerivative, lowerLimit);
  
-     *minQuotient = std::min(*minQuotient, value / secondDerivative);
+     return (value / secondDerivative);
  }
  
  
@@@ -186,14 -189,15 +189,15 @@@ findSmallestQuotientOfFunctionAndSecond
      // outside the range specified.
      double                     h           = std::pow( GMX_DOUBLE_EPS, 0.25 );
      std::pair<double, double>  newRange(range.first + h, range.second - h);
-     const int                  points      = 1000; // arbitrary
+     const int                  points      = 500; // arbitrary
      double                     dx          = (newRange.second - newRange.first) / points;
      double                     minQuotient = GMX_REAL_MAX;
  
      for (double x = newRange.first; x <= newRange.second; x += dx)
      {
-         updateMinQuotientOfFunctionAndSecondDerivative(f(x-h), f(x), f(x+h), h, &minQuotient);
+         minQuotient = std::min(minQuotient, quotientOfFunctionAndSecondDerivative(f(x-h), f(x), f(x+h), h));
      }
      return static_cast<real>(minQuotient);
  }
  
@@@ -214,14 -218,14 +218,14 @@@ findSmallestQuotientOfFunctionAndSecond
  
      for (std::size_t i = firstIndex + 1; (i + 1) < lastIndex; i++)
      {
-         updateMinQuotientOfFunctionAndSecondDerivative(function[i-1], function[i], function[i+1], inputSpacing, &minQuotient);
+         minQuotient = std::min(minQuotient, quotientOfFunctionAndSecondDerivative(function[i-1], function[i], function[i+1], inputSpacing));
      }
      return static_cast<real>(minQuotient);
  }
  
  
  
- /*! \brief Update minQuotient if the ratio of this function value and its third derivative is smaller
+ /*! \brief Calculate absolute quotient of function and its third derivative
   *
   * This is a utility function used in the functions to find the smallest quotient
   * in a range.
   * \param[in]    nextPoint             Value of function at x+h.
   * \param[in]    nextNextPoint         Value of function at x+2h.
   * \param[in]    spacing               Value of h.
-  * \param[inout] minQuotient   Current minimum of such quotients, updated if this quotient is smaller.
+  *
+  * \return The absolute value of the quotient. If either the function or third
+  *         derivative is smaller than sqrt(GMX_REAL_MIN), they will be set to
+  *         that value.
   */
- static void
- updateMinQuotientOfFunctionAndThirdDerivative(double     previousPreviousPoint,
-                                               double     previousPoint,
-                                               double     thisPoint,
-                                               double     nextPoint,
-                                               double     nextNextPoint,
-                                               double     spacing,
-                                               double *   minQuotient)
+ static double
+ quotientOfFunctionAndThirdDerivative(double     previousPreviousPoint,
+                                      double     previousPoint,
+                                      double     thisPoint,
+                                      double     nextPoint,
+                                      double     nextNextPoint,
+                                      double     spacing)
  {
-     double value            = std::abs( thisPoint );
+     double lowerLimit       = static_cast<double>(std::sqrt(GMX_REAL_MIN));
+     double value            = std::max(std::abs( thisPoint ), lowerLimit );
      double thirdDerivative  = std::abs((nextNextPoint - 2 * nextPoint + 2 * previousPoint - previousPreviousPoint) / (2 * spacing * spacing * spacing));
  
      // Make sure we do not divide by zero. This limit is arbitrary,
      // but it doesnt matter since this point will have a very large value,
      // and the whole routine is searching for the smallest value.
-     thirdDerivative = std::max(thirdDerivative, static_cast<double>(std::sqrt(GMX_REAL_MIN)));
+     thirdDerivative = std::max(thirdDerivative, lowerLimit);
  
-     *minQuotient = std::min(*minQuotient, value / thirdDerivative);
+     return (value / thirdDerivative);
  }
  
  
@@@ -264,13 -271,13 +271,13 @@@ findSmallestQuotientOfFunctionAndThirdD
      // outside the range specified.
      double                     h           = std::pow( GMX_DOUBLE_EPS, 0.2 ); // optimal spacing for 3rd derivative
      std::pair<double, double>  newRange(range.first + 2*h, range.second - 2*h);
-     const int                  points      = 1000;                            // arbitrary
+     const int                  points      = 500;                             // arbitrary
      double                     dx          = (newRange.second - newRange.first) / points;
      double                     minQuotient = GMX_REAL_MAX;
  
      for (double x = newRange.first; x <= newRange.second; x += dx)
      {
-         updateMinQuotientOfFunctionAndThirdDerivative(f(x-2*h), f(x-h), f(x), f(x+h), f(x+2*h), h, &minQuotient);
+         minQuotient = std::min(minQuotient, quotientOfFunctionAndThirdDerivative(f(x-2*h), f(x-h), f(x), f(x+h), f(x+2*h), h));
      }
      return static_cast<real>(minQuotient);
  }
@@@ -288,7 -295,7 +295,7 @@@ findSmallestQuotientOfFunctionAndThirdD
  
      for (std::size_t i = firstIndex + 2; (i + 2) < lastIndex; i++)
      {
-         updateMinQuotientOfFunctionAndThirdDerivative(function[i-2], function[i-1], function[i], function[i+1], function[i+2], inputSpacing, &minQuotient);
+         minQuotient = std::min(minQuotient, quotientOfFunctionAndThirdDerivative(function[i-2], function[i-1], function[i], function[i+1], function[i+2], inputSpacing));
      }
      return static_cast<real>(minQuotient);
  }
index e54a52d0d6971be7955ce295960926a85961b6f2,203a383ea55012458f48b5637900b84c8a0acb6e..afb40706b0188f445dfa14ee923658fa80043369
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2015,2016,2017,2018, by the GROMACS development team, led by
   * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
   * and including many others, as listed in the AUTHORS file in the
   * top-level source directory and at http://www.gromacs.org.
@@@ -152,7 -152,18 +152,18 @@@ SplineTableTest<T>::testSplineTableAgai
  
          table.template evaluateDerivative<numFuncInTable, funcIndex>(x, &tmpDer);
  
-         if (testFuncValue != tmpFunc)
+         // Before we even start to think about errors related to the table interpolation
+         // accuracy, we want to test that the interpolations are consistent whether we
+         // call the routine that evaluates both the function and derivative or only one
+         // of them.
+         // Note that for these tests the relevant tolerance is NOT the default one
+         // provided based on the requested accuracy of the table, but a tolerance related
+         // to the floating-point precision used. For now we only allow deviations up
+         // to 4 ulp (one for the FMA order, and then some margin).
+         FloatingPointTolerance  consistencyTolerance(ulpTolerance(4));
+         FloatingPointDifference evaluateFuncDiff(tmpFunc, testFuncValue);
+         if (!consistencyTolerance.isWithin(evaluateFuncDiff))
          {
              ADD_FAILURE()
              << "Interpolation inconsistency for table " << desc << std::endl
              << "Function value when evaluating only function:         " << tmpFunc << std::endl;
              return;
          }
-         if (testDerValue != tmpDer)
+         FloatingPointDifference evaluateDerDiff(tmpDer, testDerValue);
+         if (!consistencyTolerance.isWithin(evaluateDerDiff))
          {
              ADD_FAILURE()
              << "Interpolation inconsistency for table " << desc << std::endl
              return;
          }
  
+         // Next, we should examine that the table is exact enough relative
+         // to the requested accuracy in the interpolation.
+         //
          // There are two sources of errors that we need to account for when checking the values,
          // and we only fail the test if both of these tolerances are violated:
          //
              << "First failure at    x = " << x << std::endl
              << "Reference function    = " << refFuncValue << std::endl
              << "Test table function   = " << testFuncValue << std::endl
+             << "Allowed abs func err. = " << allowedAbsFuncErr << std::endl
              << "Reference derivative  = " << refDerValue << std::endl
-             << "Test table derivative = " << testDerValue << std::endl;
+             << "Test table derivative = " << testDerValue << std::endl
+             << "Allowed abs der. err. = " << allowedAbsDerErr << std::endl
+             << "Actual abs der. err.  = " << derDiff.asAbsolute() << std::endl;
              return;
          }
      }
@@@ -399,7 -418,11 +418,11 @@@ TYPED_TEST(SplineTableTest, CatchesOutO
  
  TYPED_TEST(SplineTableTest, Sinc)
  {
-     std::pair<real, real>  range(0.1, 10);
+     // Sinc hits some sensitive parts of the table construction code which means
+     // we will not have full relative accuracy close to the zeros in the
+     // derivative. Since this is intentially a pathological function we reduce
+     // the interval slightly for now.
+     std::pair<real, real>  range(0.1, 3.1);
  
      TypeParam              sincTable( {{"Sinc", sincFunction, sincDerivative}}, range);
  
@@@ -656,7 -679,7 +679,7 @@@ TYPED_TEST(SplineTableTest, Simd
      real     refDer  = lj12Derivative(x);
      SimdReal tstFunc, tstDer;
      real     funcErr, derErr;
-     GMX_ALIGNED(real, GMX_SIMD_REAL_WIDTH) alignedMem[GMX_SIMD_REAL_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) real alignedMem[GMX_SIMD_REAL_WIDTH];
  
      table.evaluateFunctionAndDerivative(SimdReal(x), &tstFunc, &tstDer);
  
@@@ -689,7 -712,7 +712,7 @@@ TYPED_TEST(SplineTableTest, SimdTwoFunc
      SimdReal tstFunc1, tstDer1;
      real     funcErr0, derErr0;
      real     funcErr1, derErr1;
-     GMX_ALIGNED(real, GMX_SIMD_REAL_WIDTH) alignedMem[GMX_SIMD_REAL_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) real alignedMem[GMX_SIMD_REAL_WIDTH];
  
      table.evaluateFunctionAndDerivative(SimdReal(x), &tstFunc0, &tstDer0, &tstFunc1, &tstDer1);
  
@@@ -742,7 -765,7 +765,7 @@@ TYPED_TEST(SplineTableTest, AcceptsInRa
      TypeParam              table( {{"LJ12", lj12Function, lj12Derivative}}, range);
      SimdReal               x, func, der;
  
-     GMX_ALIGNED(real, GMX_SIMD_REAL_WIDTH) alignedMem[GMX_SIMD_REAL_WIDTH];
+     alignas(GMX_SIMD_ALIGNMENT) real alignedMem[GMX_SIMD_REAL_WIDTH];
  
      // Test all values between 0 and range.second
      for (std::size_t i = 0; i < GMX_SIMD_REAL_WIDTH; i++)
index 6154d6712781d0022ef32984e2f349030e9cfdab,015c8b68575771e7f078ccbcaa897aef394b21c3..497123c8b7b68dccd3a587bb3ee7fdd800842a0a
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2015,2016,2017,2018, 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.
@@@ -216,6 -216,14 +216,14 @@@ gmx_unused static int get_tmpi_omp_thre
       */
      if (ngpu > 0)
      {
+         if (hw_opt.nthreads_omp > 0)
+         {
+             /* In this case it is unclear if we should use 1 rank per GPU
+              * or more or less, so we require also setting the number of ranks.
+              */
+             gmx_fatal(FARGS, "When using GPUs, setting the number of OpenMP threads without specifying the number of ranks can lead to conflicting demands. Please specify the number of thread-MPI ranks as well (option -ntmpi).");
+         }
          nrank = ngpu;
  
          /* When the user sets nthreads_omp, we can end up oversubscribing CPU cores
@@@ -866,3 -874,67 +874,67 @@@ void checkAndUpdateRequestedNumOpenmpTh
          print_hw_opt(debug, hw_opt);
      }
  }
+ void checkHardwareOversubscription(int                          numThreadsOnThisRank,
+                                    const gmx::HardwareTopology &hwTop,
+                                    const t_commrec             *cr,
+                                    const gmx::MDLogger         &mdlog)
+ {
+     if (hwTop.supportLevel() < gmx::HardwareTopology::SupportLevel::LogicalProcessorCount)
+     {
+         /* There is nothing we can check */
+         return;
+     }
+     int numRanksOnThisNode   = 1;
+     int numThreadsOnThisNode = numThreadsOnThisRank;
+ #if GMX_MPI
+     if (PAR(cr) || MULTISIM(cr))
+     {
+         /* Count the threads within this physical node */
+         MPI_Comm_size(cr->mpi_comm_physicalnode, &numRanksOnThisNode);
+         MPI_Allreduce(&numThreadsOnThisRank, &numThreadsOnThisNode, 1, MPI_INT, MPI_SUM, cr->mpi_comm_physicalnode);
+     }
+ #endif
+     if (numThreadsOnThisNode > hwTop.machine().logicalProcessorCount)
+     {
+         std::string mesg = "WARNING: ";
+         if (GMX_LIB_MPI)
+         {
+             mesg += gmx::formatString("On rank %d: o", cr->sim_nodeid);
+         }
+         else
+         {
+             mesg += "O";
+         }
+         mesg     += gmx::formatString("versubscribing the available %d logical CPU cores", hwTop.machine().logicalProcessorCount);
+         if (GMX_LIB_MPI)
+         {
+             mesg += " per node";
+         }
+         mesg     += gmx::formatString(" with %d ", numThreadsOnThisNode);
+         if (numRanksOnThisNode == numThreadsOnThisNode)
+         {
+             if (GMX_THREAD_MPI)
+             {
+                 mesg += "thread-MPI threads.";
+             }
+             else
+             {
+                 mesg += "MPI processes.";
+             }
+         }
+         else
+         {
+             mesg += "threads.";
+         }
+         mesg     += "\n         This will cause considerable performance loss.";
+         /* Note that only the master rank logs to stderr and only ranks
+          * with an open log file write to log.
+          * TODO: When we have a proper parallel logging framework,
+          *       the framework should add the rank and node numbers.
+          */
+         GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted(mesg.c_str());
+     }
+ }
index 411335c4929427c1068abd28c52cde73007d9073,a2ef70feb01f002e0135e99da4d3fd556eb62363..d972c559eeb1fcb671c9de746d1b061d79086248
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2015,2016,2017,2018, 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.
@@@ -59,6 -59,7 +59,7 @@@ struct t_inputrec
  
  namespace gmx
  {
+ class HardwareTopology;
  class MDLogger;
  }
  
@@@ -113,4 -114,11 +114,11 @@@ void checkAndUpdateRequestedNumOpenmpTh
                                               PmeRunMode           pmeRunMode,
                                               const gmx_mtop_t    &mtop);
  
+ /*! \brief Warns for oversubscribing the hardware threads, when that is the case
+  */
+ void checkHardwareOversubscription(int                          numThreadsOnThisRank,
+                                    const gmx::HardwareTopology &hwTop,
+                                    const t_commrec             *cr,
+                                    const gmx::MDLogger         &mdlog);
  #endif
index 691d0b136d8b829d94cdb3b4578891d7fbcba0d0,6605352eae5d2e3e5b3c41f1da8abff21b27a4ae..d7429f6a2c40228e69bdc6b0ffd073e3dbe000b7
@@@ -3,7 -3,7 +3,7 @@@
   *
   * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
   * Copyright (c) 2001-2013, The GROMACS development team.
-- * Copyright (c) 2013,2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2013,2014,2015,2016,2017,2018, 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.
@@@ -831,7 -831,11 +831,11 @@@ int gmx_check(int argc, char *argv[]
          "virtual sites. With these flags, [TT]gmx check[tt] provides a quick check for such problems.[PAR]",
          "The program can compare two run input ([REF].tpr[ref])",
          "files",
-         "when both [TT]-s1[tt] and [TT]-s2[tt] are supplied.",
+         "when both [TT]-s1[tt] and [TT]-s2[tt] are supplied. When comparing",
+         "run input files this way, the default relative tolerance is reduced",
+         "to 0.000001 and the absolute tolerance set to zero to find any differences",
+         "not due to minor compiler optimization differences, although you can",
+         "of course still set any other tolerances through the options."
          "Similarly a pair of trajectory files can be compared (using the [TT]-f2[tt]",
          "option), or a pair of energy files (using the [TT]-e2[tt] option).[PAR]",
          "For free energy simulations the A and B state topology from one",
              }
              fn2 = nullptr;
          }
+         fprintf(stderr, "Note: When comparing run input files, default tolerances are reduced.\n");
+         if (!opt2parg_bSet("-tol", asize(pa), pa))
+         {
+             ftol = 0.000001;
+         }
+         if (!opt2parg_bSet("-abstol", asize(pa), pa))
+         {
+             abstol = 0;
+         }
          comp_tpx(fn1, fn2, bRMSD, ftol, abstol);
      }
      else if (fn1 && tex)
index 1c3e36c5da895c601ec318309249d02dd08507b5,a1638ef69c5b83cde0725260d645c15e494864ff..a43a8d344665022e77fcd1863940d0581689658e
@@@ -3,7 -3,7 +3,7 @@@
   *
   * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
   * Copyright (c) 2001-2004, The GROMACS development team.
-- * Copyright (c) 2013,2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2013,2014,2015,2016,2017,2018, 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.
@@@ -226,24 -226,6 +226,6 @@@ typedef uint64_t gmx_uint64_t
  #endif
  #endif
  
- /*! \def GMX_ALIGNED(type, alignment)
-  * \brief
-  * Declare variable with data alignment
-  *
-  * \param[in] type       Type of variable
-  * \param[in] alignment  Alignment in multiples of type
-  *
-  * Typical usage:
-  * \code
-    GMX_ALIGNED(real, GMX_SIMD_REAL_WIDTH) buf[...];
-    \endcode
-  */
- // We rely on C++11. This will for instance work for MSVC2015 and later.
- // If you get an error here, find out what attribute to use to get your compiler to align
- // data properly and add it as a case.
- #define GMX_ALIGNED(type, alignment) alignas(alignment*sizeof(type)) type
  /*! \brief
   * Macro to explicitly ignore an unused value.
   *
index 8bcab77147bd0f26f4952f7558aaca0ac80aeb17,577e0a2de1aa75af4f86b8f6b059e7db8576b8ed..d95773c7d75298ad5416e0001a337cb1cae16db4
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2015,2016,2017,2018, 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.
@@@ -805,12 -805,11 +805,12 @@@ std::string getCoolQuote(
          { "An intellectual is someone who has found something more interesting than sex.", "Edgar Wallace" },
          { "Base eight is just like base ten really, if you’re missing two fingers.", "Tom Lehrer" },
          { "If 10 years from now, when you are doing something quick and dirty, you suddenly visualize that I am looking over your shoulders and say to yourself: â€˜Dijkstra would not have liked this’, well that would be enough immortality for me.", "Edsger Dijkstra" },
-         { "Memory is like an orgasm. It’s a lot better of you don’t have to fake it.", "Seymour Cray, on virtual memory" },
+         { "Memory is like an orgasm. It’s a lot better if you don’t have to fake it.", "Seymour Cray, on virtual memory" },
          { "A computer once beat me at chess, but it was no match for me at kick boxing.", "Emo Philips" },
          { "Home computers are being called upon to perform many new functions, including the consumption of homework formerly eaten by the dog.", "Doug Larson" },
          { "Forcefields are like dating; things go fine for a while and then sometimes it goes really bad.", "Alex MacKerell" },
 -        { "This type of advanced sampling techniques... which are not so advanced, really.", "Viveca Lindahl, on AWH, at her thesis defense." }
 +        { "This type of advanced sampling techniques... which are not so advanced, really.", "Viveca Lindahl, on AWH, at her thesis defense." },
 +        { "C++ is tricky. You can do everything. You can even make every mistake.", "Nicolai Josuttis, CppCon2017" },
      };
  
      if (beCool())
index 57cf2a19f199326019a87d5197a1f361855f8fa5,74ed8f471e943a65881c5554280c535bcb83fdea..0c67bc12ea798f3ee76c1eb00121bb71b630582b
@@@ -1,7 -1,7 +1,7 @@@
  #
  # This file is part of the GROMACS molecular simulation package.
  #
--# Copyright (c) 2012,2013,2014,2015,2016,2017, by the GROMACS development team, led by
++# Copyright (c) 2012,2013,2014,2015,2016,2017,2018, 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.
@@@ -35,7 -35,6 +35,6 @@@
  gmx_add_unit_test(UtilityUnitTests utility-test
                    alignedallocator.cpp
                    arrayref.cpp
-                   basedefinitions.cpp
                    bitmask32.cpp bitmask64.cpp bitmask128.cpp
                    keyvaluetreeserializer.cpp
                    keyvaluetreetransform.cpp
index 9604388c079c4816c219896a0d3b6edb17e2ee92,683460fa6b739be9d38c88b43337780aecf4dd2b..b874903548ee2c6e40851560ea1c3c19923c72b8
@@@ -3,7 -3,7 +3,7 @@@
   *
   * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
   * Copyright (c) 2001-2004, The GROMACS development team.
-- * Copyright (c) 2011,2012,2013,2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2011,2012,2013,2014,2015,2016,2017,2018, 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.
@@@ -704,7 -704,7 +704,7 @@@ double gmx::do_md(FILE *fplog, t_commre
          restore_ekinstate_from_state(cr, ekind, &state_global->ekinstate);
      }
  
-     cglo_flags = (CGLO_TEMPERATURE | CGLO_GSTAT
+     cglo_flags = (CGLO_INITIALIZATION | CGLO_TEMPERATURE | CGLO_GSTAT
                    | (EI_VV(ir->eI) ? CGLO_PRESSURE : 0)
                    | (EI_VV(ir->eI) ? CGLO_CONSTRAINT : 0)
                    | (continuationOptions.haveReadEkin ? CGLO_READEKIN : 0));
index 7928eeb6e83ea40561f84f8fc2b36ed0503f85ca,05d1eb0e4ae35a414dfe0cdd78e168d64349773e..162ead1fd36131f7b80eed27a5db54021dded758
@@@ -3,7 -3,7 +3,7 @@@
   *
   * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
   * Copyright (c) 2001-2004, The GROMACS development team.
-  * Copyright (c) 2011,2012,2013,2014,2015,2016,2017, by the GROMACS development team, led by
+  * Copyright (c) 2011,2012,2013,2014,2015,2016,2017,2018, 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.
@@@ -316,27 -316,29 +316,29 @@@ static void override_nsteps_cmdline(con
  namespace gmx
  {
  
- /*! \brief Return whether GPU acceleration of nonbondeds is useful with the given settings.
+ /*! \brief Return whether GPU acceleration of nonbondeds is supported with the given settings.
   *
-  * If not, logs a message about falling back to CPU code. */
+  * If not, and if a warning may be issued, logs a warning about
+  * falling back to CPU code. With thread-MPI, only the first
+  * call to this function should have \c issueWarning true. */
  static bool gpuAccelerationOfNonbondedIsUseful(const MDLogger   &mdlog,
                                                 const t_inputrec *ir,
-                                                bool              doRerun)
+                                                bool              issueWarning)
  {
-     if (doRerun && ir->opts.ngener > 1)
+     if (ir->opts.ngener > 1)
      {
-         /* Rerun execution time is dominated by I/O and pair search,
-          * so GPUs are not very useful, plus they do not support more
-          * than one energy group. If the user requested GPUs
-          * explicitly, a fatal error is given later.  With non-reruns,
-          * we fall back to a single whole-of system energy group
-          * (which runs much faster than a multiple-energy-groups
-          * implementation would), and issue a note in the .log
-          * file. Users can re-run if they want the information. */
-         GMX_LOG(mdlog.warning).asParagraph().appendText("Multiple energy groups is not implemented for GPUs, so is not useful for this rerun, so falling back to the CPU");
+         /* The GPU code does not support more than one energy group.
+          * If the user requested GPUs explicitly, a fatal error is given later.
+          */
+         if (issueWarning)
+         {
+             GMX_LOG(mdlog.warning).asParagraph()
+                 .appendText("Multiple energy groups is not implemented for GPUs, falling back to the CPU. "
+                             "For better performance, run on the GPU without energy groups and then do "
+                             "gmx mdrun -rerun option on the trajectory with an energy group .tpr file.");
+         }
          return false;
      }
      return true;
  }
  
@@@ -442,9 -444,9 +444,9 @@@ int Mdrunner::mdrunner(
  
      /* CAUTION: threads may be started later on in this function, so
         cr doesn't reflect the final parallel state right now */
 -    gmx::MDModules mdModules;
 -    t_inputrec     inputrecInstance;
 -    t_inputrec    *inputrec = &inputrecInstance;
 +    std::unique_ptr<gmx::MDModules> mdModules(new gmx::MDModules);
 +    t_inputrec                      inputrecInstance;
 +    t_inputrec                     *inputrec = &inputrecInstance;
      snew(mtop, 1);
  
      if (mdrunOptions.continuationOptions.appendFiles)
              useGpuForNonbonded = decideWhetherToUseGpusForNonbondedWithThreadMpi
                      (nonbondedTarget, gpuIdsToUse, userGpuTaskAssignment, emulateGpuNonbonded,
                      inputrec->cutoff_scheme == ecutsVERLET,
-                     gpuAccelerationOfNonbondedIsUseful(mdlog, inputrec, doRerun),
+                     gpuAccelerationOfNonbondedIsUseful(mdlog, inputrec, GMX_THREAD_MPI),
                      hw_opt.nthreads_tmpi);
              auto inputSystemHasPme = EEL_PME(inputrec->coulombtype) || EVDW_PME(inputrec->vdwtype);
              auto canUseGpuForPme   = inputSystemHasPme && pme_gpu_supports_input(inputrec, nullptr);
              useGpuForPme = decideWhetherToUseGpusForPmeWithThreadMpi
                      (useGpuForNonbonded, pmeTarget, gpuIdsToUse, userGpuTaskAssignment,
                      canUseGpuForPme, hw_opt.nthreads_tmpi, domdecOptions.numPmeRanks);
          }
          GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
          /* Determine how many thread-MPI ranks to start.
           *
           * TODO Over-writing the user-supplied value here does
          bool gpusWereDetected = hwinfo->ngpu_compatible_tot > 0;
          useGpuForNonbonded = decideWhetherToUseGpusForNonbonded(nonbondedTarget, userGpuTaskAssignment,
                                                                  emulateGpuNonbonded, inputrec->cutoff_scheme == ecutsVERLET,
-                                                                 gpuAccelerationOfNonbondedIsUseful(mdlog, inputrec, doRerun),
+                                                                 gpuAccelerationOfNonbondedIsUseful(mdlog, inputrec, !GMX_THREAD_MPI),
                                                                  gpusWereDetected);
          auto inputSystemHasPme = EEL_PME(inputrec->coulombtype) || EVDW_PME(inputrec->vdwtype);
          auto canUseGpuForPme   = inputSystemHasPme && pme_gpu_supports_input(inputrec, nullptr);
          useGpuForPme = decideWhetherToUseGpusForPme(useGpuForNonbonded, pmeTarget, userGpuTaskAssignment,
                                                      canUseGpuForPme, cr->nnodes, domdecOptions.numPmeRanks,
                                                      gpusWereDetected);
          pmeRunMode   = (useGpuForPme ? PmeRunMode::GPU : PmeRunMode::CPU);
          if (pmeRunMode == PmeRunMode::GPU)
          {
      GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
  
      // TODO: Error handling
 -    mdModules.assignOptionsToModules(*inputrec->params, nullptr);
 +    mdModules->assignOptionsToModules(*inputrec->params, nullptr);
  
      if (fplog != nullptr)
      {
       */
      nthreads_pme = gmx_omp_nthreads_get(emntPME);
  
+     int numThreadsOnThisRank;
+     /* threads on this MPI process or TMPI thread */
+     if (thisRankHasDuty(cr, DUTY_PP))
+     {
+         numThreadsOnThisRank = gmx_omp_nthreads_get(emntNonbonded);
+     }
+     else
+     {
+         numThreadsOnThisRank = nthreads_pme;
+     }
+     checkHardwareOversubscription(numThreadsOnThisRank,
+                                   *hwinfo->hardwareTopology,
+                                   cr, mdlog);
+     if (hw_opt.thread_affinity != threadaffOFF)
+     {
+         /* Before setting affinity, check whether the affinity has changed
+          * - which indicates that probably the OpenMP library has changed it
+          * since we first checked).
+          */
+         gmx_check_thread_affinity_set(mdlog, cr,
+                                       &hw_opt, hwinfo->nthreads_hw_avail, TRUE);
+         /* Set the CPU affinity */
+         gmx_set_thread_affinity(mdlog, cr, &hw_opt, *hwinfo->hardwareTopology,
+                                 numThreadsOnThisRank, nullptr);
+     }
      wcycle = wallcycle_init(fplog, mdrunOptions.timingOptions.resetStep, cr);
  
      if (PAR(cr))
      {
          /* Initiate forcerecord */
          fr                 = mk_forcerec();
 -        fr->forceProviders = mdModules.initForceProviders();
 +        fr->forceProviders = mdModules->initForceProviders();
          init_forcerec(fplog, mdlog, fr, fcd,
                        inputrec, mtop, cr, box,
                        opt2fn("-table", nfile, fnm),
      GMX_ASSERT(thisRankHasDuty(cr, DUTY_PP) == (fr != nullptr), "Double-checking that only PME-only ranks have no forcerec");
      gmx_pme_t * &pmedata = fr ? fr->pmedata : sepPmeData;
  
-     if (hw_opt.thread_affinity != threadaffOFF)
-     {
-         /* Before setting affinity, check whether the affinity has changed
-          * - which indicates that probably the OpenMP library has changed it
-          * since we first checked).
-          */
-         gmx_check_thread_affinity_set(mdlog, cr,
-                                       &hw_opt, hwinfo->nthreads_hw_avail, TRUE);
-         int nthread_local;
-         /* threads on this MPI process or TMPI thread */
-         if (thisRankHasDuty(cr, DUTY_PP))
-         {
-             nthread_local = gmx_omp_nthreads_get(emntNonbonded);
-         }
-         else
-         {
-             nthread_local = gmx_omp_nthreads_get(emntPME);
-         }
-         /* Set the CPU affinity */
-         gmx_set_thread_affinity(mdlog, cr, &hw_opt, *hwinfo->hardwareTopology,
-                                 nthread_local, nullptr);
-     }
      /* Initiate PME if necessary,
       * either on all nodes or on dedicated PME nodes only. */
      if (EEL_PME(inputrec->coulombtype) || EVDW_PME(inputrec->vdwtype))
                                       oenv,
                                       mdrunOptions,
                                       vsite, constr,
 -                                     mdModules.outputProvider(),
 +                                     mdModules->outputProvider(),
                                       inputrec, mtop,
                                       fcd,
                                       globalState.get(),
      // As soon as we destroy GPU contexts after mdrunner() exits, these lines should go.
      mdAtoms.reset(nullptr);
      globalState.reset(nullptr);
 +    mdModules.reset(nullptr);   // destruct force providers here as they might also use the GPU
  
      /* Free GPU memory and set a physical node tMPI barrier (which should eventually go away) */
      free_gpu_resources(fr, cr);
index 57ae23e152f422767b151c97c2ca13806a624c37,0c11b336b6df80b25ba03c11f83ee0dd5686de46..5a8cc48b38189c0a9bc01678327b392821001580
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2016,2017,2018, by the GROMACS development team, led by
   * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
   * and including many others, as listed in the AUTHORS file in the
   * top-level source directory and at http://www.gromacs.org.
@@@ -75,7 -75,9 +75,9 @@@ namespace tes
  namespace
  {
  
- //! A basic PME runner
+ /*! \brief A basic PME runner
+  *
+  * \todo Consider also using GpuTest class. */
  class PmeTest : public MdrunTestFixture
  {
      public:
@@@ -90,16 -92,16 +92,16 @@@ bool PmeTest::s_hasCompatibleCudaGpus 
  void PmeTest::SetUpTestCase()
  {
      gmx_gpu_info_t gpuInfo {};
-     char           detection_error[STRLEN];
-     GMX_UNUSED_VALUE(detection_error); //TODO
      // It would be nicer to do this detection once and have mdrun
      // re-use it, but this is OK. Note that this also caters for when
      // there is no GPU support in the build.
+     //
+     // TODO report any error messages gracefully.
      if (GMX_GPU == GMX_GPU_CUDA &&
-         (detect_gpus(&gpuInfo, detection_error) >= 0) &&
-         gpuInfo.n_dev_compatible > 0)
+         canDetectGpus(nullptr))
      {
-         s_hasCompatibleCudaGpus = true;
+         findGpus(&gpuInfo);
+         s_hasCompatibleCudaGpus = (gpuInfo.n_dev_compatible > 0);
      }
      free_gpu_info(&gpuInfo);
  }
index 5317d95b528505edf25368c722bc8ce9be3b09d4,2064b54c4efa65026e39593802677725c980e736..c95087a59bf0ed624b6ab27420a7029be4605644
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2012,2013,2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2012,2013,2014,2015,2016,2017,2018, 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.
@@@ -455,6 -455,11 +455,11 @@@ TestReferenceChecker CommandLineTestBas
      return impl_->data_.rootChecker();
  }
  
+ void CommandLineTestBase::setDefaultTolerance(const FloatingPointTolerance &tolerance)
+ {
+     impl_->data_.rootChecker().setDefaultTolerance(tolerance);
+ }
  void CommandLineTestBase::testWriteHelp(ICommandLineModule *module)
  {
      StringOutputStream     stream;
index fc3fd4afaf0fb6f42214a4fcd8049604b066d1ea,3954a321d8b0e8b10b4c560de3a4539381d14751..ccef7598d3f3fa8539c30f0057917bd4ddac29ab
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-- * Copyright (c) 2012,2013,2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2012,2013,2014,2015,2016,2017,2018, 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.
@@@ -63,6 -63,7 +63,7 @@@ class ICommandLineOptionsModule
  namespace test
  {
  
+ class FloatingPointTolerance;
  class IFileMatcherSettings;
  class ITextBlockMatcherSettings;
  class TestFileManager;
@@@ -443,7 -444,15 +444,15 @@@ class CommandLineTestBase : public ::te
           * file contents.
           */
          TestReferenceChecker rootChecker();
+         /*! \brief
+          * Sets the tolerance for floating-point comparisons.
+          *
+          * All following floating-point comparisons using the checker will use
+          * the new tolerance.
+          *
+          * Does not throw.
+          */
+         void setDefaultTolerance(const FloatingPointTolerance &tolerance);
          /*! \brief
           * Checks the output of writeHelp() against reference data.
           */
index c13c00ec569555c21931e3366ccb36a4bf300f82,c7ba7a4afe7589f5c35b396082bb9a537a736ea9..93fc616d6623ea9a1a2395c0520603a927c0122f
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * This file is part of the GROMACS molecular simulation package.
   *
-  * Copyright (c) 2013,2014,2015,2016, by the GROMACS development team, led by
 - * Copyright (c) 2013,2014,2015,2016,2017, by the GROMACS development team, led by
++ * Copyright (c) 2013,2014,2015,2016,2017,2018, 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.
@@@ -486,6 -486,12 +486,12 @@@ relativeToleranceAsUlp(double magnitude
      return relativeToleranceAsPrecisionDependentUlp(magnitude, ulpDiff, ulpDiff);
  }
  
+ namespace
+ {
+ //! Default tolerance in ULPs for two floating-point values to compare equal.
+ static gmx_uint64_t g_defaultUlpTolerance = 4;
+ }
  /*! \brief
   * Returns the default tolerance for comparing `real` numbers.
   *
   */
  static inline FloatingPointTolerance defaultRealTolerance()
  {
-     return relativeToleranceAsUlp(1.0, 4);
+     return relativeToleranceAsUlp(1.0, g_defaultUlpTolerance);
+ }
+ /*! \brief
+  * Returns the default tolerance for comparing single-precision numbers when
+  * compared by \Gromacs built in either precision mode.
+  *
+  * This permits a checker compiled with any \Gromacs precision to compare
+  * equal or not in the same way.
+  *
+  * \related FloatingPointTolerance
+  */
+ static inline FloatingPointTolerance defaultFloatTolerance()
+ {
+     return relativeToleranceAsPrecisionDependentUlp
+                (1.0, g_defaultUlpTolerance, g_defaultUlpTolerance * (GMX_FLOAT_EPS / GMX_DOUBLE_EPS));
  }
  
  /*! \name Assertions for floating-point comparison
index 01e9d6146da17abb74e72d9d68dc94605c583e89,d7175eae5270ca20843a7b6a4caf428d20235f31..4089f65d2b1b740a4e2191ab70c77ef3ab26b1af
@@@ -1,7 -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) 2014,2017, by the GROMACS development team, led by
++ * Copyright (c) 2014,2017,2018, 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.
@@@ -233,4 -233,38 +233,38 @@@ TEST(FloatingPointToleranceTest, Relati
      EXPECT_FALSE(relativeToleranceAsUlp(1.0, 4).isWithin(dsmall2));
  }
  
+ TEST(FloatingPointToleranceTest, DefaultFloatTolerance)
+ {
+     using gmx::test::defaultFloatTolerance;
+     // Differences within 4 single-precision ULPs are within the tolerance
+     FloatingPointDifference fequal(1.0f, 1.0f);
+     FloatingPointDifference fulp4(1.0f, addUlps(1.0f, 4));
+     FloatingPointDifference fulp8(1.0f, addUlps(1.0f, 8));
+     FloatingPointDifference fsmall(0.1f, addUlps(1.0f, 2) - 0.9f);
+     FloatingPointDifference fsmall2(0.1f, addUlps(1.0f, 6) - 0.9f);
+     EXPECT_TRUE(defaultFloatTolerance().isWithin(fequal));
+     EXPECT_TRUE(defaultFloatTolerance().isWithin(fulp4));
+     EXPECT_FALSE(defaultFloatTolerance().isWithin(fulp8));
+     EXPECT_TRUE(defaultFloatTolerance().isWithin(fsmall));
+     EXPECT_FALSE(defaultFloatTolerance().isWithin(fsmall2));
+     // Differences within 4 single-precision ULPs are still within the
+     // tolerance, even when expressed as double-precision values.
+     FloatingPointDifference dequal(1.0, 1.0);
+     FloatingPointDifference dulp4(1.0, addUlps(1.0, 4));
+     FloatingPointDifference dulp8(1.0, addUlps(1.0, 8));
+     FloatingPointDifference dulp4f(1.0, static_cast<double>(addUlps(1.0f, 4)));
+     FloatingPointDifference dulp8f(1.0, static_cast<double>(addUlps(1.0f, 8)));
+     FloatingPointDifference dsmallf(0.1, static_cast<double>(addUlps(1.0f, 2) - 0.9f));
+     FloatingPointDifference dsmall2f(0.1, static_cast<double>(addUlps(1.0f, 6) - 0.9f));
+     EXPECT_TRUE(defaultFloatTolerance().isWithin(dequal));
+     EXPECT_TRUE(defaultFloatTolerance().isWithin(dulp4));
+     EXPECT_TRUE(defaultFloatTolerance().isWithin(dulp8));
+     EXPECT_TRUE(defaultFloatTolerance().isWithin(dulp4f));
+     EXPECT_FALSE(defaultFloatTolerance().isWithin(dulp8f));
+     EXPECT_TRUE(defaultFloatTolerance().isWithin(dsmallf));
+     EXPECT_FALSE(defaultFloatTolerance().isWithin(dsmall2f));
+ }
  } // namespace
diff --combined tests/CMakeLists.txt
index 629d977dc48e644c89819d3ed3f471870d6fcb14,216652c8fb6dacf9df76f0a647a751443956a13a..7d0ea719bde159eaaf558d607679479ef8fb0af5
@@@ -1,7 -1,7 +1,7 @@@
  #
  # This file is part of the GROMACS molecular simulation package.
  #
--# Copyright (c) 2012,2013,2014,2015,2016,2017, by the GROMACS development team, led by
++# Copyright (c) 2012,2013,2014,2015,2016,2017,2018, 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.
@@@ -293,7 -293,7 +293,7 @@@ if(GMX_PHYSICAL_VALIDATION
                      GMX_PHYSCIAL_VALIDATION=OFF to disable the physical validation tests.")
          endif()
          #
-         foreach(module numpy scipy) # add further modules if necessary
+         foreach(module numpy scipy pymbar) # add further modules if necessary
              find_python_module(${module})
              string(TOUPPER ${module} module_upper)
              if(NOT PYTHONMODULE_${module_upper})
          # Hook in our own tests
          # Read them from json file to make every system a separate test
          #
-       if (GMX_DOUBLE)
-           set(PHYSVALTEST_JSON "${PHYSVALTEST_SOURCE_PATH}/systems_d.json")
-       else()
-           set(PHYSVALTEST_JSON "${PHYSVALTEST_SOURCE_PATH}/systems.json")
-       endif()
+         if (GMX_DOUBLE)
+             set(PHYSVALTEST_JSON "${PHYSVALTEST_SOURCE_PATH}/systems_d.json")
+         else()
+             set(PHYSVALTEST_JSON "${PHYSVALTEST_SOURCE_PATH}/systems.json")
+         endif()
          file(STRINGS "${PHYSVALTEST_JSON}" json)
          string(REPLACE "\"" "" json ${json})
          string(REPLACE "," "" json ${json})
          string(REPLACE "}" "" json ${json})
          string(REPLACE "<<>>" ";" json ${json})
          foreach(line ${json})
-             if("${line}" MATCHES "dir:")
-                 string(REPLACE "dir:" "" dirname ${line})
-                 add_test(NAME physicalvalidationtests/${dirname}
-                         COMMAND ${PYTHON_EXECUTABLE} "${PHYSVALTEST_SOURCE_PATH}/gmx_physicalvalidation.py" "${PHYSVALTEST_JSON}" -s ${dirname} -a ${PARGS})
-                 set_tests_properties(physicalvalidationtests/${dirname} PROPERTIES
+             if("${line}" MATCHES "name:")
+                 string(REPLACE "name:" "" testname ${line})
+                 add_test(NAME physicalvalidationtests/${testname}
+                         COMMAND ${PYTHON_EXECUTABLE} "${PHYSVALTEST_SOURCE_PATH}/gmx_physicalvalidation.py" "${PHYSVALTEST_JSON}" -s ${testname} -a ${PARGS})
+                 set_tests_properties(physicalvalidationtests/${testname} PROPERTIES
                          ENVIRONMENT "PATH=${PATH}"
                          LABELS "PhysicalValidationTest")
              endif()
          # Create prepare and run targets while all variables are set
          # Will be referenced in CheckTarget.cmake
          #
-         # "prepare-phys-tests" prepares the systems needed for physical validation for external running
-         add_custom_target(prepare-phys-tests
-                           COMMAND ${PYTHON_EXECUTABLE} "${PHYSVALTEST_SOURCE_PATH}/gmx_physicalvalidation.py" "${PHYSVALTEST_SOURCE_PATH}/systems.json" -p ${PARGS})
-         # "run-phys-tests" prepares and runs the systems needed for physical validation
-         add_custom_target(run-phys-tests
-                           COMMAND ${PYTHON_EXECUTABLE} "${PHYSVALTEST_SOURCE_PATH}/gmx_physicalvalidation.py" "${PHYSVALTEST_SOURCE_PATH}/systems.json" -r ${PARGS})
+         # "check-phys-prepare" prepares the systems needed for physical validation for external running
+         add_custom_target(check-phys-prepare
+                           COMMAND ${PYTHON_EXECUTABLE} "${PHYSVALTEST_SOURCE_PATH}/gmx_physicalvalidation.py" "${PHYSVALTEST_JSON}" -p ${PARGS}
+                           COMMENT "Preparing systems for physical validation"
+                           DEPENDS gmx)
+         # "run-physval-sims" prepares and runs the systems needed for physical validation
+         add_custom_target(run-physval-sims
+                           COMMAND ${PYTHON_EXECUTABLE} "${PHYSVALTEST_SOURCE_PATH}/gmx_physicalvalidation.py" "${PHYSVALTEST_JSON}" -r ${PARGS}
+                           COMMENT "Preparing and running systems for physical validation"
+                           DEPENDS gmx)
      endif()
  else()
      #
      # Create dummy prepare and run targets
      # Will be referenced in CheckTarget.cmake
      #
-     # "prepare-phys-tests" prepares the systems needed for physical validation for external running
-     add_custom_target(prepare-phys-tests
-                       COMMAND ${CMAKE_COMMAND} -E echo "NOTE: You called the target `prepare-phys-tests`, but ran cmake with\
+     # "check-phys-prepare" prepares the systems needed for physical validation for external running
+     add_custom_target(check-phys-prepare
+                       COMMAND ${CMAKE_COMMAND} -E echo "NOTE: You called the target `check-phys-prepare`, but ran cmake with\
   `-DGMX_PHYSICAL_VALIDATION=OFF`. The physical validation tests are therefore unavailable,\
   and this target is not doing anything."
                        COMMENT "No physical validation" VERBATIM)
-     # "run-phys-tests" prepares and runs the systems needed for physical validation
-     add_custom_target(run-phys-tests
-                       COMMAND ${CMAKE_COMMAND} -E echo "NOTE: You called the target `run-phys-tests`, but ran cmake with\
+     # "run-physval-sims" prepares and runs the systems needed for physical validation
+     add_custom_target(run-physval-sims
+                       COMMAND ${CMAKE_COMMAND} -E echo "NOTE: You called the target `run-physval-sims`, but ran cmake with\
   `-DGMX_PHYSICAL_VALIDATION=OFF`. The physical validation tests are therefore unavailable,\
   and this target is not doing anything."
                        COMMENT "No physical validation" VERBATIM)
diff --combined tests/CheckTarget.cmake
index 8c9fb49f69f3a5f520a4ec7f79b32858e35579ce,5e2f00eae3b6ca81d59b96308e8da5ffb2319aed..26eef1a18be306a830bdb770a3a746dceb9d5622
@@@ -1,7 -1,7 +1,7 @@@
  #
  # This file is part of the GROMACS molecular simulation package.
  #
--# Copyright (c) 2014,2016,2017, by the GROMACS development team, led by
++# Copyright (c) 2014,2016,2017,2018, 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.
@@@ -41,14 -41,13 +41,13 @@@ add_custom_target(tests
  add_custom_target(run-ctest
                    COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure
                    COMMENT "Running all tests"
-                   USES_TERMINAL VERBATIM)
+                   USES_TERMINAL VERBATIM
+                   DEPENDS run-physval-sims)
  add_dependencies(run-ctest tests)
- # "check-all" target builds and runs all tests.
+ # "check-all" target builds and runs all tests, simulating the physical validation systems first.
  add_custom_target(check-all DEPENDS run-ctest)
- # "check-all-run" target builds and runs all tests, simulating the physical validation systems first.
- add_custom_target(check-all-run DEPENDS run-phys-tests check-all)
  
- # "run-ctest-nophys" is an internal target that actually runs the tests in analogy to "run-ctest".
+ # "run-ctest-nophys" is an internal target that actually runs the tests analogously to "run-ctest".
  # It runs all tests except the physical validation tests.
  add_custom_target(run-ctest-nophys
                    COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -E physicalvalidationtests
@@@ -58,19 -57,23 +57,23 @@@ add_dependencies(run-ctest-nophys tests
  # "check" target builds and runs all tests except physical validation .
  add_custom_target(check DEPENDS run-ctest-nophys)
  
- # "run-ctest-phys" is an internal target that actually runs the tests in analogy to "run-ctest".
+ # "run-ctest-phys" is an internal target that actually runs the tests analogously to "run-ctest".
  # It only runs the physical validation tests.
  add_custom_target(run-ctest-phys
                    COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -R physicalvalidationtests
                    COMMENT "Running physical validation tests"
-                   USES_TERMINAL VERBATIM)
- # "check-phys" target runs only physical validation tests.
+                   USES_TERMINAL VERBATIM
+                   DEPENDS run-physval-sims)
+ # "run-ctest-phys-analyze" is the equivalent to "run-ctest-phys" not running the physical validation simulations.
+ add_custom_target(run-ctest-phys-analyze
+                   COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -R physicalvalidationtests
+                   COMMENT "Running physical validation tests"
+                   USES_TERMINAL VERBATIM
+                   DEPENDS gmx)
+ # "check-phys" target runs only physical validation tests, simulating the systems first.
  add_custom_target(check-phys DEPENDS run-ctest-phys)
- # "check-phys-run" target runs only physical validation tests, simulating the systems first
- add_custom_target(check-phys-run DEPENDS run-phys-tests check-phys)
- # "check-phys-prepare" target does only prepare physical validation runs, to be ran externally.
- add_custom_target(check-phys-prepare DEPENDS prepare-phys-tests)
+ # "check-phys-analyze" target runs only physical validation tests, without simulating the systems first.
+ add_custom_target(check-phys-analyze DEPENDS run-ctest-phys-analyze)
  
  # Calling targets "check-all" and "check-phys" does not make much sense if -DGMX_PHYSICAL_VALIDATION=OFF
  if(NOT GMX_PHYSICAL_VALIDATION)
              DEPENDS run-ctest-phys
              COMMENT "No physical validation" VERBATIM)
      add_dependencies(check-phys missing-phys-val-phys)
+     add_custom_target(missing-phys-val-phys-analyze
+             COMMAND ${CMAKE_COMMAND} -E echo "NOTE: You called the target `check-phys-analyze`, but ran cmake with\
+  `-DGMX_PHYSICAL_VALIDATION=OFF`. The physical validation tests are therefore unavailable,\
+  and this target is not testing anything."
+             DEPENDS run-ctest-phys-analyze
+             COMMENT "No physical validation" VERBATIM)
+     add_dependencies(check-phys-analyze missing-phys-val-phys)
      add_custom_target(missing-phys-val-all
              COMMAND ${CMAKE_COMMAND} -E echo "NOTE: You called the target `check-all`, but ran cmake with\
   `-DGMX_PHYSICAL_VALIDATION=OFF`. The physical validation tests are therefore unavailable,\
diff --combined tests/CppCheck.cmake
index 1cc97127d373749cd3f2180d0f7393fcc82f5684,2cd46d2bbd296d3096b6fa0c3a06e4ff531701cb..9f1d658e6b0beaa9f37330c2c02589de9e597ff9
@@@ -1,7 -1,7 +1,7 @@@
  #
  # This file is part of the GROMACS molecular simulation package.
  #
--# Copyright (c) 2013,2014,2015,2016,2017, by the GROMACS development team, led by
++# Copyright (c) 2013,2014,2015,2016,2017,2018, 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.
@@@ -60,6 -60,7 +60,7 @@@ if (CPPCHECK_EXECUTABLE AND UNIX
          ${CMAKE_SOURCE_DIR}/src/gromacs/selection/scanner.cpp
          ${CMAKE_SOURCE_DIR}/src/gromacs/selection/parser.cpp
          ${CMAKE_SOURCE_DIR}/src/gromacs/gpu_utils/ocl_compiler.cpp
+         ${CMAKE_SOURCE_DIR}/src/*\#* #ignore emacs lock files throwing of cmake
          )
      list(REMOVE_ITEM _inputfiles ${_files_to_ignore})