#
# 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.
# 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)
#
# 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.
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)
#
# 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.
# - 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)
*
* 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.
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))
/*
* 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.
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.
}
}
}
/*
* 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.
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();
}
};
*
* 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.
*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++)
{
*
* 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.
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;
*
* 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.
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];
/*
* 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.
#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"
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);
}
}
}
- 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)
*
* 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.
#include <cstdio>
+ #include <string>
#include <vector>
#include "gromacs/gpu_utils/gpu_macros.h"
/*! \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.
*
/*
* 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.
#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
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()
/*
* 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.
TYPED_TEST(HostAllocatorTest, TransfersWithPinningWorkWithCuda)
{
+ if (!this->haveValidGpus())
+ {
+ return;
+ }
+
typename TestFixture::VectorType input;
changePinningPolicy(&input, PinningPolicy::CanBePinned);
this->fillInput(&input);
TYPED_TEST(HostAllocatorTest, ManualPinningOperationsWorkWithCuda)
{
+ if (!this->haveValidGpus())
+ {
+ return;
+ }
+
typename TestFixture::VectorType input;
changePinningPolicy(&input, PinningPolicy::CanBePinned);
EXPECT_FALSE(isPinned(input));
/*
* 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.
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));
/*
* 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.
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;
/*
* 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.
{
*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);
/*
* 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.
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)
{
*
* 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.
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);
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);
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;
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);
/*
* 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.
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)
* 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,
*
* 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.
{
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++)
{
* 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);
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++)
{
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++)
{
* 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);
*
* 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.
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,
/*
* 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.
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)
*
* 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.
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);
}
*
* 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.
* 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 */
/*
* 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)
{
/*
* 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
/*
* 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++)
{
/*
* 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++)
*
* 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.
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;
/*
* 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.
#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
/*
* 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.
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);
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);
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] ),
/*
* 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*double)
#define GMX_SIMD_RSQRT_BITS 8
#define GMX_SIMD_RCP_BITS 8
/*
* 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.
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);
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);
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_);
/*
* 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 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
/*
* 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.
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);
}
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);
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);
/*
* 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.
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);
}
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);
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);
/*
* 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.
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);
}
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);
}
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);
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);
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);
/*
* 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.
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);
}
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);
}
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);
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);
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);
/*
* 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
#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
/*
* 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.
}
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);
}
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);
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);
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);
/*
* 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.
#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
/*
* 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
/*
* 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.
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);
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);
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);
/*
* 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.
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);
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);
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);
/*
* 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.
#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
/*
* 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.
//! \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
/*
* 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.
#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
/*
* 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.
#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
/*
* 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.
#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
/*
* 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.
#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
/*
* 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.
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]);
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]);
__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]);
/*
* 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.
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);
}
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);
}
__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] ) );
/*
* 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.
#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
/*
* 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.
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_);
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_);
/*
* 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.
{
__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)
{
{
__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)
{
/*
* 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.
#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
/*
* 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 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
/*
* 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.
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);
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);
/*
* 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.
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);
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);
/*
* 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*double)
#define GMX_SIMD_RSQRT_BITS 11
#define GMX_SIMD_RCP_BITS 11
/*
* 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.
// 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);
}
// 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);
}
// 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);
}
/*
* 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*double)
#define GMX_SIMD_RSQRT_BITS 11
#define GMX_SIMD_RCP_BITS 11
/*
* 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.
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;
/*
* 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.
* 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;
/*
* 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.
#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++)
{
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++)
{
/*
* 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.
*
* 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.
*
/*
* 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.
::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);
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++)
{
/*
* 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.
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;
/*
* 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.
#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;
/*
* 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.
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++)
/*
* 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.
#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++)
/*
* 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.
// 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>);
}
/*
* 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.
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_);
/*
* 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.
* \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
/*
* 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.
// 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_);
/*
* 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.
}
- /*! \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);
}
// 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);
}
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);
}
// 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);
}
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);
}
/*
* 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.
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;
}
}
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);
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);
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);
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++)
/*
* 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.
*/
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
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());
+ }
+ }
/*
* 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.
namespace gmx
{
+ class HardwareTopology;
class MDLogger;
}
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
*
* 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.
"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)
*
* 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.
#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.
*
/*
* 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.
{ "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())
#
# 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.
gmx_add_unit_test(UtilityUnitTests utility-test
alignedallocator.cpp
arrayref.cpp
- basedefinitions.cpp
bitmask32.cpp bitmask64.cpp bitmask128.cpp
keyvaluetreeserializer.cpp
keyvaluetreetransform.cpp
*
* 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.
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));
*
* 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.
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;
}
/* 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);
/*
* 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.
namespace
{
- //! A basic PME runner
+ /*! \brief A basic PME runner
+ *
+ * \todo Consider also using GpuTest class. */
class PmeTest : public MdrunTestFixture
{
public:
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);
}
/*
* 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.
return impl_->data_.rootChecker();
}
+ void CommandLineTestBase::setDefaultTolerance(const FloatingPointTolerance &tolerance)
+ {
+ impl_->data_.rootChecker().setDefaultTolerance(tolerance);
+ }
+
void CommandLineTestBase::testWriteHelp(ICommandLineModule *module)
{
StringOutputStream stream;
/*
* 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.
namespace test
{
+ class FloatingPointTolerance;
class IFileMatcherSettings;
class ITextBlockMatcherSettings;
class TestFileManager;
* 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.
*/
/*
* 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.
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
/*
* 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.
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
#
# 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.
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)
#
# 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.
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
# "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,\
#
# 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.
${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})