# See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49002
endif()
-
+# Implement double-precision option. This is complicated because we
+# need installed headers to use the precision mode of the build that
+# produced the library, but cannot use config.h in that case. We also
+# want such variables to always have a definition, because #if is more
+# robust than #ifdef. So, we put this value on the compiler command
+# line in all cases.
+#
+# GMX_RELAXED_DOUBLE_PRECISION does not need to be handled here,
+# because no installed header needs it
if(GMX_DOUBLE)
- add_definitions(-DGMX_DOUBLE)
- list(APPEND INSTALLED_HEADER_DEFINITIONS "-DGMX_DOUBLE")
- if(GMX_RELAXED_DOUBLE_PRECISION)
- add_definitions(-DGMX_RELAXED_DOUBLE_PRECISION)
- endif()
+ set(GMX_DOUBLE_VALUE 1)
+else()
+ set(GMX_DOUBLE_VALUE 0)
endif()
+add_definitions(-DGMX_DOUBLE=${GMX_DOUBLE_VALUE})
+list(APPEND INSTALLED_HEADER_DEFINITIONS "-DGMX_DOUBLE=${GMX_DOUBLE_VALUE}")
if(WIN32)
list(APPEND GMX_EXTRA_LIBRARIES "wsock32")
.. cmake:: GMX_DOUBLE
+ Many part of GROMACS are implemented in terms of "real" precision,
+ which is actually either a single- or double-precision type,
+ according to the value of this flag. Some parts of the code
+ deliberately use single- or double-precision types, and these are
+ unaffected by this setting. See reference manual for further
+ information.
+
+.. cmake:: GMX_RELAXED_DOUBLE_PRECISION
+
+ Permit a double-precision configuration to compute some quantities
+ to single-precision accuracy. Particularly on architectures where
+ only double-precision SIMD is available (e.g. Sparc machines such
+ as the K computer), it is faster to default to ``GMX_DOUBLE=ON``
+ and use SIMD than to use ``GMX_DOUBLE=OFF`` and use no
+ SIMD. However, if the user does not need full double precision,
+ then some optimizations can achieve the equivalent of
+ single-precision results (e.g. fewer Newton-Raphson iterations for
+ a reciprocal square root computation).
+
.. cmake:: GMX_EXTRAE
.. cmake:: GMX_EXTERNAL_BLAS
# This module name doesn't really fall into any currently used pattern; needs some thought
: error: no matching directory for module: module_mdrun_integration_tests
-# These would be nice to fix, but can wait for later
+# These would be nice to fix, but can wait for later / deletion / rewrites
src/gromacs/gmxlib/nonbonded/nb_kernel_*/*: warning: includes "config.h" unnecessarily
+src/gromacs/gmxlib/nonbonded/nb_kernel_sparc64_hpc_ace_double/kernelutil_sparc64_hpc_ace_double.h: warning: should include "config.h"
src/gromacs/mdlib/nbnxn_kernels/nbnxn_kernel_gpu_ref.cpp: warning: includes "config.h" unnecessarily
src/gromacs/mdlib/nbnxn_kernels/nbnxn_kernel_ref.cpp: warning: includes "config.h" unnecessarily
src/gromacs/mdlib/nbnxn_kernels/simd_2xnn/nbnxn_kernel_simd_2xnn.cpp: warning: includes "config.h" unnecessarily
/* Target mantissa accuracy for SIMD double precision math */
#define GMX_SIMD_ACCURACY_BITS_DOUBLE @GMX_SIMD_ACCURACY_BITS_DOUBLE@
+/* Whether a double-precision configuration may target accuracy equivalent to single precision */
+#cmakedefine01 GMX_RELAXED_DOUBLE_PRECISION
+
/* Integer byte order is big endian. */
#cmakedefine01 GMX_INTEGER_BIG_ENDIAN
void testfft(FILE *fp,t_complex ***grid,int nx,int ny,int nz,gmx_bool bFirst)
{
#ifdef USE_SGI_FFT
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
static zomplex *coeff;
#else
static complex *coeff;
#ifdef USE_SGI_FFT
if (bFirst) {
fprintf(fp,"Going to use SGI optimized FFT routines.\n");
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
coeff = zfft3di(nx,ny,nz,NULL);
#else
coeff = cfft3di(nx,ny,nz,NULL);
}
la1 = nx;
la2 = ny;
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
zfft3d(1,nx,ny,nz,(zomplex *)cptr,la1,la2,coeff);
#else
cfft3d(1,nx,ny,nz,(complex *)cptr,la1,la2,coeff);
#endif
#ifdef USE_SGI_FFT
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
zfft3d(-1,nx,ny,nz,(zomplex *)cptr,la1,la2,coeff);
#else
cfft3d(-1,nx,ny,nz,(complex *)cptr,la1,la2,coeff);
void testrft(FILE *fp,real ***grid,int nx,int ny,int nz,gmx_bool bFirst)
{
#ifdef USE_SGI_FFT
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
static double *coeff;
#else
static float *coeff;
#ifdef USE_SGI_FFT
if (bFirst) {
fprintf(fp,"Going to use SGI optimized FFT routines.\n");
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
coeff = dfft3di(nx,ny,nz,NULL);
#else
coeff = sfft3di(nx,ny,nz,NULL);
job = 1;
la1 = nx+2;
la2 = ny;
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
dzfft3d(job,nx,ny,nz,cptr,la1,la2,coeff);
#else
scfft3d(job,nx,ny,nz,cptr,la1,la2,coeff);
job = -1;
#ifdef USE_SGI_FFT
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
zdfft3d(job,nx,ny,nz,cptr,la1,la2,coeff);
#else
csfft3d(job,nx,ny,nz,cptr,la1,la2,coeff);
AutocorrTest( )
: checker_(refData_.rootChecker())
{
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
checker_.setDefaultTolerance(test::relativeToleranceAsFloatingPoint(1, 1e-6));
#else
checker_.setDefaultTolerance(test::relativeToleranceAsFloatingPoint(1, 1e-3));
ewcdr = ewc_q*dr;
vc = qqA*std::erf(ewcdr)*rinv;
Vexcl_q += vc;
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
/* Relative accuracy at R_ERF_R_INACC of 3e-10 */
#define R_ERF_R_INACC 0.006
#else
#include <fftw3.h>
#endif
-#ifndef GMX_DOUBLE
+#if !GMX_DOUBLE
#define FFTW(x) fftwf_ ## x
#else
#define FFTW(x) fftw_ ## x
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/mutex.h"
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
#define FFTWPREFIX(name) fftw_ ## name
#else
#define FFTWPREFIX(name) fftwf_ ## name
#endif
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
#define GMX_DFTI_PREC DFTI_DOUBLE
#else
#define GMX_DFTI_PREC DFTI_SINGLE
#define CPT_MAGIC2 171819
#define CPTSTRLEN 1024
-#ifdef GMX_DOUBLE
-#define GMX_CPT_BUILD_DP 1
-#else
-#define GMX_CPT_BUILD_DP 0
-#endif
-
/* cpt_version should normally only be changed
* when the header of footer format changes.
* The state data format itself is backward and forward compatible.
static void do_cpt_real_err(XDR *xd, real *f)
{
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
bool_t res = xdr_double(xd, f);
#else
bool_t res = xdr_float(xd, f);
FILE *list, int erealtype)
{
bool_t res = 0;
-#ifndef GMX_DOUBLE
+#if !GMX_DOUBLE
int dtc = xdr_datatype_float;
#else
int dtc = xdr_datatype_double;
buser = gmx_strdup(BUILD_USER);
bhost = gmx_strdup(BUILD_HOST);
- double_prec = GMX_CPT_BUILD_DP;
+ double_prec = GMX_DOUBLE;
fprog = gmx_strdup(gmx::getProgramContext().fullBinaryPath());
ftime = &(timebuf[0]);
check_string(fplog, "Build time", BUILD_TIME, btime, &mm);
check_string(fplog, "Build user", BUILD_USER, buser, &mm);
check_string(fplog, "Build host", BUILD_HOST, bhost, &mm);
- check_int (fplog, "Double prec.", GMX_CPT_BUILD_DP, double_prec, &mm);
+ check_int (fplog, "Double prec.", GMX_DOUBLE, double_prec, &mm);
check_string(fplog, "Program name", gmx::getProgramContext().fullBinaryPath(), fprog, &mm);
check_int (fplog, "#ranks", cr->nnodes, npp_f+npme_f, &mm);
&state->edsamstate.nED, &state->swapstate.eSwapCoords, NULL);
if (bAppendOutputFiles &&
- file_version >= 13 && double_prec != GMX_CPT_BUILD_DP)
+ file_version >= 13 && double_prec != GMX_DOUBLE)
{
gmx_fatal(FARGS, "Output file appending requested, but the code and checkpoint file precision (single/double) don't match");
}
static void enxsubblock_init(t_enxsubblock *sb)
{
sb->nr = 0;
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
sb->type = xdr_datatype_double;
#else
sb->type = xdr_datatype_float;
gmx_bool bRead = gmx_fio_getread(ef->fio);
int ndisre = 0;
int startb = 0;
-#ifndef GMX_DOUBLE
+#if !GMX_DOUBLE
xdr_datatype dtreal = xdr_datatype_float;
#else
xdr_datatype dtreal = xdr_datatype_double;
char programInfo[256];
const char *precisionString = "";
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
precisionString = " (double precision)";
#endif
sprintf(programInfo, "%.100s %.128s%.24s",
const char*,
const char,
const char);
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
set_writing_interval_func_pointer set_writing_interval = tng_util_generic_write_interval_double_set;
#else
set_writing_interval_func_pointer set_writing_interval = tng_util_generic_write_interval_set;
const char*,
const char,
const char);
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
static write_data_func_pointer write_data = tng_util_generic_with_time_double_write;
#else
static write_data_func_pointer write_data = tng_util_generic_with_time_write;
const char*,
const char,
const char);
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
set_writing_interval_func_pointer set_writing_interval = tng_util_generic_write_interval_double_set;
#else
set_writing_interval_func_pointer set_writing_interval = tng_util_generic_write_interval_set;
{
int r;
-#ifndef GMX_DOUBLE
+#if !GMX_DOUBLE
/* since t is float, we can not use double precision for bRmod */
bDouble = FALSE;
#endif
* larger than the float/double precision.
*/
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
#define bRmod(a, b, c) bRmod_fd(a, b, c, TRUE)
#else
#define bRmod(a, b, c) bRmod_fd(a, b, c, FALSE)
fr->bV = fr->vmdplugin->bV;
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
snew(ts.coords, fr->natoms*3);
if (fr->bV)
{
return 0;
}
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
for (i = 0; i < fr->natoms; i++)
{
fr->x[i][0] = .1*ts.coords[i*3];
int xdr_real(XDR *xdrs, real *r)
{
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
float f;
int ret;
int xdr3drcoord(XDR *xdrs, real *fp, int *size, real *precision)
{
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
float *ffp;
float fprec;
int i, ret, isize;
static int xdr_r2f(XDR *xdrs, real *r, gmx_bool gmx_unused bRead)
{
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
float f;
int ret;
static int xtc_coord(XDR *xd, int *natoms, matrix box, rvec *x, real *prec, gmx_bool bRead)
{
int i, j, result;
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
float *ftmp;
float fprec;
#endif
return result;
}
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
/* allocate temp. single-precision array */
snew(ftmp, (*natoms)*DIM);
if (ndisre > 0)
{
GMX_RELEASE_ASSERT(blk_disre != NULL, "Trying to dereference NULL blk_disre pointer");
- #ifndef GMX_DOUBLE
+ #if !GMX_DOUBLE
float *disre_rt = blk_disre->sub[0].fval;
float *disre_rm3tav = blk_disre->sub[1].fval;
#else
blk = find_block_id_enxframe(fr, enx_i, NULL);
if (bORIRE && blk)
{
-#ifndef GMX_DOUBLE
+#if !GMX_DOUBLE
xdr_datatype dt = xdr_datatype_float;
#else
xdr_datatype dt = xdr_datatype_double;
{
gmx_fatal(FARGS, "Orientational restraints read in incorrectly");
}
-#ifndef GMX_DOUBLE
+#if !GMX_DOUBLE
vals = blk->sub[0].fval;
#else
vals = blk->sub[0].dval;
blk = find_block_id_enxframe(fr, enxORT, NULL);
if (bOTEN && blk)
{
-#ifndef GMX_DOUBLE
+#if !GMX_DOUBLE
xdr_datatype dt = xdr_datatype_float;
#else
xdr_datatype dt = xdr_datatype_double;
{
gmx_fatal(FARGS, "Orientational restraints read in incorrectly");
}
-#ifndef GMX_DOUBLE
+#if !GMX_DOUBLE
vals = blk->sub[0].fval;
#else
vals = blk->sub[0].dval;
void gmx_sumd_sim(int nr, double r[], const struct gmx_multisim_t *ms);
/* Calculate the sum over the simulations of an array of doubles */
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
#define gmx_sum gmx_sumd
#define gmx_sum_sim gmx_sumd_sim
#else
/* Different default (c) and SIMD instructions interaction-specific kernels */
#include "gromacs/gmxlib/nonbonded/nb_kernel_c/nb_kernel_c.h"
-#if GMX_SIMD_X86_SSE2 && !(defined GMX_DOUBLE)
+#if GMX_SIMD_X86_SSE2 && !GMX_DOUBLE
# include "gromacs/gmxlib/nonbonded/nb_kernel_sse2_single/nb_kernel_sse2_single.h"
#endif
-#if GMX_SIMD_X86_SSE4_1 && !(defined GMX_DOUBLE)
+#if GMX_SIMD_X86_SSE4_1 && !GMX_DOUBLE
# include "gromacs/gmxlib/nonbonded/nb_kernel_sse4_1_single/nb_kernel_sse4_1_single.h"
#endif
-#if GMX_SIMD_X86_AVX_128_FMA && !(defined GMX_DOUBLE)
+#if GMX_SIMD_X86_AVX_128_FMA && !GMX_DOUBLE
# include "gromacs/gmxlib/nonbonded/nb_kernel_avx_128_fma_single/nb_kernel_avx_128_fma_single.h"
#endif
-#if (GMX_SIMD_X86_AVX_256 || GMX_SIMD_X86_AVX2_256) && !(defined GMX_DOUBLE)
+#if (GMX_SIMD_X86_AVX_256 || GMX_SIMD_X86_AVX2_256) && !GMX_DOUBLE
# include "gromacs/gmxlib/nonbonded/nb_kernel_avx_256_single/nb_kernel_avx_256_single.h"
#endif
-#if GMX_SIMD_X86_SSE2 && defined GMX_DOUBLE
+#if GMX_SIMD_X86_SSE2 && GMX_DOUBLE
# include "gromacs/gmxlib/nonbonded/nb_kernel_sse2_double/nb_kernel_sse2_double.h"
#endif
-#if GMX_SIMD_X86_SSE4_1 && defined GMX_DOUBLE
+#if GMX_SIMD_X86_SSE4_1 && GMX_DOUBLE
# include "gromacs/gmxlib/nonbonded/nb_kernel_sse4_1_double/nb_kernel_sse4_1_double.h"
#endif
-#if GMX_SIMD_X86_AVX_128_FMA && defined GMX_DOUBLE
+#if GMX_SIMD_X86_AVX_128_FMA && GMX_DOUBLE
# include "gromacs/gmxlib/nonbonded/nb_kernel_avx_128_fma_double/nb_kernel_avx_128_fma_double.h"
#endif
-#if (GMX_SIMD_X86_AVX_256 || GMX_SIMD_X86_AVX2_256) && defined GMX_DOUBLE
+#if (GMX_SIMD_X86_AVX_256 || GMX_SIMD_X86_AVX2_256) && GMX_DOUBLE
# include "gromacs/gmxlib/nonbonded/nb_kernel_avx_256_double/nb_kernel_avx_256_double.h"
#endif
-#if GMX_SIMD_SPARC64_HPC_ACE && defined GMX_DOUBLE
+#if GMX_SIMD_SPARC64_HPC_ACE && GMX_DOUBLE
# include "gromacs/gmxlib/nonbonded/nb_kernel_sparc64_hpc_ace_double/nb_kernel_sparc64_hpc_ace_double.h"
#endif
{
/* Add interaction-specific kernels for different architectures */
/* Single precision */
-#if GMX_SIMD_X86_SSE2 && !(defined GMX_DOUBLE)
+#if GMX_SIMD_X86_SSE2 && !GMX_DOUBLE
nb_kernel_list_add_kernels(kernellist_sse2_single, kernellist_sse2_single_size);
#endif
-#if GMX_SIMD_X86_SSE4_1 && !(defined GMX_DOUBLE)
+#if GMX_SIMD_X86_SSE4_1 && !GMX_DOUBLE
nb_kernel_list_add_kernels(kernellist_sse4_1_single, kernellist_sse4_1_single_size);
#endif
-#if GMX_SIMD_X86_AVX_128_FMA && !(defined GMX_DOUBLE)
+#if GMX_SIMD_X86_AVX_128_FMA && !GMX_DOUBLE
nb_kernel_list_add_kernels(kernellist_avx_128_fma_single, kernellist_avx_128_fma_single_size);
#endif
-#if (GMX_SIMD_X86_AVX_256 || GMX_SIMD_X86_AVX2_256) && !(defined GMX_DOUBLE)
+#if (GMX_SIMD_X86_AVX_256 || GMX_SIMD_X86_AVX2_256) && !GMX_DOUBLE
nb_kernel_list_add_kernels(kernellist_avx_256_single, kernellist_avx_256_single_size);
#endif
/* Double precision */
-#if GMX_SIMD_X86_SSE2 && defined GMX_DOUBLE
+#if GMX_SIMD_X86_SSE2 && GMX_DOUBLE
nb_kernel_list_add_kernels(kernellist_sse2_double, kernellist_sse2_double_size);
#endif
-#if GMX_SIMD_X86_SSE4_1 && defined GMX_DOUBLE
+#if GMX_SIMD_X86_SSE4_1 && GMX_DOUBLE
nb_kernel_list_add_kernels(kernellist_sse4_1_double, kernellist_sse4_1_double_size);
#endif
-#if GMX_SIMD_X86_AVX_128_FMA && defined GMX_DOUBLE
+#if GMX_SIMD_X86_AVX_128_FMA && GMX_DOUBLE
nb_kernel_list_add_kernels(kernellist_avx_128_fma_double, kernellist_avx_128_fma_double_size);
#endif
-#if (GMX_SIMD_X86_AVX_256 || GMX_SIMD_X86_AVX2_256) && defined GMX_DOUBLE
+#if (GMX_SIMD_X86_AVX_256 || GMX_SIMD_X86_AVX2_256) && GMX_DOUBLE
nb_kernel_list_add_kernels(kernellist_avx_256_double, kernellist_avx_256_double_size);
#endif
-#if GMX_SIMD_SPARC64_HPC_ACE && defined GMX_DOUBLE
+#if GMX_SIMD_SPARC64_HPC_ACE && GMX_DOUBLE
nb_kernel_list_add_kernels(kernellist_sparc64_hpc_ace_double, kernellist_sparc64_hpc_ace_double_size);
#endif
; /* empty statement to avoid a completely empty block */
arch_and_padding[] =
{
/* Single precision */
-#if (GMX_SIMD_X86_AVX_256 || GMX_SIMD_X86_AVX2_256) && !(defined GMX_DOUBLE)
+#if (GMX_SIMD_X86_AVX_256 || GMX_SIMD_X86_AVX2_256) && !GMX_DOUBLE
{ "avx_256_single", 8 },
#endif
-#if GMX_SIMD_X86_AVX_128_FMA && !(defined GMX_DOUBLE)
+#if GMX_SIMD_X86_AVX_128_FMA && !GMX_DOUBLE
{ "avx_128_fma_single", 4 },
#endif
-#if GMX_SIMD_X86_SSE4_1 && !(defined GMX_DOUBLE)
+#if GMX_SIMD_X86_SSE4_1 && !GMX_DOUBLE
{ "sse4_1_single", 4 },
#endif
-#if GMX_SIMD_X86_SSE2 && !(defined GMX_DOUBLE)
+#if GMX_SIMD_X86_SSE2 && !GMX_DOUBLE
{ "sse2_single", 4 },
#endif
/* Double precision */
-#if (GMX_SIMD_X86_AVX_256 || GMX_SIMD_X86_AVX2_256) && defined GMX_DOUBLE
+#if (GMX_SIMD_X86_AVX_256 || GMX_SIMD_X86_AVX2_256) && GMX_DOUBLE
{ "avx_256_double", 4 },
#endif
-#if GMX_SIMD_X86_AVX_128_FMA && defined GMX_DOUBLE
+#if GMX_SIMD_X86_AVX_128_FMA && GMX_DOUBLE
/* Sic. Double precision 2-way SIMD does not require neighbor list padding,
* since the kernels execute a loop unrolled a factor 2, followed by
* a possible single odd-element epilogue.
*/
{ "avx_128_fma_double", 1 },
#endif
-#if GMX_SIMD_X86_SSE2 && defined GMX_DOUBLE
+#if GMX_SIMD_X86_SSE2 && GMX_DOUBLE
/* No padding - see comment above */
{ "sse2_double", 1 },
#endif
-#if GMX_SIMD_X86_SSE4_1 && defined GMX_DOUBLE
+#if GMX_SIMD_X86_SSE4_1 && GMX_DOUBLE
/* No padding - see comment above */
{ "sse4_1_double", 1 },
#endif
-#if GMX_SIMD_SPARC64_HPC_ACE && defined GMX_DOUBLE
+#if GMX_SIMD_SPARC64_HPC_ACE && GMX_DOUBLE
/* No padding - see comment above */
{ "sparc64_hpc_ace_double", 1 },
#endif
/* Call LAPACK routine using fortran interface. Note that we use upper storage,
* but this corresponds to lower storage ("L") in Fortran.
*/
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
F77_FUNC(dsyevr, DSYEVR) (jobz, "I", "L", &n, a, &n, &vl, &vu, &index_lower, &index_upper,
&abstol, &m, eigenvalues, eigenvectors, &n,
isuppz, &w0, &lwork, &iw0, &liwork, &info);
abstol = 0;
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
F77_FUNC(dsyevr, DSYEVR) (jobz, "I", "L", &n, a, &n, &vl, &vu, &index_lower, &index_upper,
&abstol, &m, eigenvalues, eigenvectors, &n,
isuppz, work, &lwork, iwork, &liwork, &info);
iter = 1;
do
{
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
F77_FUNC(pdsaupd, PDSAUPD) (&ido, "I", &n, "SA", &neig, &abstol,
resid, &ncv, v, &n, iparam, ipntr,
workd, iwork, workl, &lworkl, &info);
/* Extract eigenvalues and vectors from data */
fprintf(stderr, "Calculating eigenvalues and eigenvectors...\n");
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
F77_FUNC(pdseupd, PDSEUPD) (&dovec, "A", select, eigenvalues, eigenvectors,
&n, NULL, "I", &n, "SA", &neig, &abstol,
resid, &ncv, v, &n, iparam, ipntr,
iter = 1;
do
{
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
F77_FUNC(dsaupd, DSAUPD) (&ido, "I", &n, "SA", &neig, &abstol,
resid, &ncv, v, &n, iparam, ipntr,
workd, iwork, workl, &lworkl, &info);
/* Extract eigenvalues and vectors from data */
fprintf(stderr, "Calculating eigenvalues and eigenvectors...\n");
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
F77_FUNC(dseupd, DSEUPD) (&dovec, "A", select, eigenvalues, eigenvectors,
&n, NULL, "I", &n, "SA", &neig, &abstol,
resid, &ncv, v, &n, iparam, ipntr,
* In single precision, this is faster on Bulldozer.
*/
#if GMX_SIMD_REAL_WIDTH >= 8 || \
- (GMX_SIMD_REAL_WIDTH >= 4 && GMX_SIMD_HAVE_FMA && !defined GMX_DOUBLE) || GMX_SIMD_IBM_QPX
+ (GMX_SIMD_REAL_WIDTH >= 4 && GMX_SIMD_HAVE_FMA && !GMX_DOUBLE) || GMX_SIMD_IBM_QPX
*ewald_excl = ewaldexclAnalytical;
#endif
if (getenv("GMX_NBNXN_EWALD_TABLE") != NULL)
/* Generate the GB table if needed */
if (fr->bGB)
{
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
fr->gbtabscale = 2000;
#else
fr->gbtabscale = 500;
}
/* Switch for determining which algorithm to use for Born radii calculation */
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
switch (ir->gb_algorithm)
{
add_subblocks_enxblock(&(fr.block[b]), 1);
fr.block[b].id = id[b];
fr.block[b].sub[0].nr = nr[b];
-#ifndef GMX_DOUBLE
+#if !GMX_DOUBLE
fr.block[b].sub[0].type = xdr_datatype_float;
fr.block[b].sub[0].fval = block[b];
#else
fr.block[db].id = enxDISRE;
fr.block[db].sub[0].nr = ndisre;
fr.block[db].sub[1].nr = ndisre;
-#ifndef GMX_DOUBLE
+#if !GMX_DOUBLE
fr.block[db].sub[0].type = xdr_datatype_float;
fr.block[db].sub[1].type = xdr_datatype_float;
fr.block[db].sub[0].fval = disre_rt;
unsigned int i;
blk->sub[2].nr = dh->ndh;
-/* For F@H for now. */
-#undef GMX_DOUBLE
-#ifndef GMX_DOUBLE
+ /* Michael commented in 2012 that this use of explicit
+ xdr_datatype_float was good for F@H for now.
+ Apparently it's still good enough. */
blk->sub[2].type = xdr_datatype_float;
for (i = 0; i < dh->ndh; i++)
{
dh->dhf[i] = (float)dh->dh[i];
}
blk->sub[2].fval = dh->dhf;
-#else
- blk->sub[2].type = xdr_datatype_double;
- blk->sub[2].dval = dh->dh;
-#endif
- dh->written = TRUE;
+ dh->written = TRUE;
}
else
{
- blk->sub[2].nr = 0;
-#ifndef GMX_DOUBLE
+ blk->sub[2].nr = 0;
blk->sub[2].type = xdr_datatype_float;
blk->sub[2].fval = NULL;
-#else
- blk->sub[2].type = xdr_datatype_double;
- blk->sub[2].dval = NULL;
-#endif
}
}
else
alg, ftol, gmx_step_str(count, buf));
}
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
fprintf(fp, "Potential Energy = %21.14e\n", epot);
fprintf(fp, "Maximum force = %21.14e on atom %d\n", fmax, nfmax+1);
fprintf(fp, "Norm of force = %21.14e\n", fnorm);
stepsize = ustep/s_min->fmax;
/* Check if stepsize is too small, with 1 nm as a characteristic length */
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
if (count == nsteps || ustep < 1e-12)
#else
if (count == nsteps || ustep < 1e-6)
snew(fneg, natoms);
snew(dfdx, natoms);
-#ifndef GMX_DOUBLE
+#if !GMX_DOUBLE
if (bIsMaster)
{
fprintf(stderr,
if (!bIsMaster)
{
#ifdef GMX_MPI
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
#define mpi_type MPI_DOUBLE
#else
#define mpi_type MPI_FLOAT
* are of equal size.
*/
simd_excl_size = NBNXN_CPU_CLUSTER_I_SIZE*simd_width;
-#if defined GMX_DOUBLE && !GMX_SIMD_HAVE_INT32_LOGICAL
+#if GMX_DOUBLE && !GMX_SIMD_HAVE_INT32_LOGICAL
snew_aligned(nbat->simd_exclusion_filter64, simd_excl_size, NBNXN_MEM_ALIGN);
#else
snew_aligned(nbat->simd_exclusion_filter, simd_excl_size, NBNXN_MEM_ALIGN);
for (int j = 0; j < simd_excl_size; j++)
{
/* Set the consecutive bits for masking pair exclusions */
-#if defined GMX_DOUBLE && !GMX_SIMD_HAVE_INT32_LOGICAL
+#if GMX_DOUBLE && !GMX_SIMD_HAVE_INT32_LOGICAL
nbat->simd_exclusion_filter64[j] = (1U << j);
#else
nbat->simd_exclusion_filter[j] = (1U << j);
/* To avoid NaN when excluded atoms are at zero distance, we add a small
* number to r^2. NBNXN_AVOID_SING_R2_INC^-3 should fit in real.
*/
-#ifndef GMX_DOUBLE
+#if !GMX_DOUBLE
#define NBNXN_AVOID_SING_R2_INC 1.0e-12f
#else
/* The double prec. x86 SIMD kernels use a single prec. invsqrt, so > 1e-38 */
}
}
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
#define R2F_D(x) ((float)((x) >= 0 ? ((1-GMX_FLOAT_EPS)*(x)) : ((1+GMX_FLOAT_EPS)*(x))))
#define R2F_U(x) ((float)((x) >= 0 ? ((1+GMX_FLOAT_EPS)*(x)) : ((1-GMX_FLOAT_EPS)*(x))))
#else
#ifdef NBNXN_SEARCH_BB_SIMD4
/* Always use 4-wide SIMD for bounding box calculations */
-# ifndef GMX_DOUBLE
+# if !GMX_DOUBLE
/* Single precision BBs + coordinates, we can also load coordinates with SIMD */
# define NBNXN_SEARCH_SIMD4_FLOAT_X_BB
# endif
rinvsix_nm = rinvsix;
#endif
cr2 = lje_coeff2*rsq;
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
expmcr2 = exp(-cr2);
#else
expmcr2 = expf(-cr2);
rs = rsq*rinv*ic->tabq_scale;
ri = (int)rs;
frac = rs - ri;
-#ifndef GMX_DOUBLE
+#if !GMX_DOUBLE
/* fexcl = F_i + frac * (F_(i+1)-F_i) */
fexcl = tab_coul_FDV0[ri*4] + frac*tab_coul_FDV0[ri*4+1];
#else
fcoul = interact*rinvsq - fexcl;
/* 7 flops for float 1/r-table force */
#ifdef CALC_ENERGIES
-#ifndef GMX_DOUBLE
+#if !GMX_DOUBLE
vcoul = qq*(interact*(rinv - ic->sh_ewald)
-(tab_coul_FDV0[ri*4+2]
-halfsp*frac*(tab_coul_FDV0[ri*4] + fexcl)));
#ifdef CALC_ENERGIES
real halfsp;
#endif
-#ifndef GMX_DOUBLE
+#if !GMX_DOUBLE
const real *tab_coul_FDV0;
#else
const real *tab_coul_F;
halfsp = 0.5/ic->tabq_scale;
#endif
-#ifndef GMX_DOUBLE
+#if !GMX_DOUBLE
tab_coul_FDV0 = ic->tabq_coul_FDV0;
#else
tab_coul_F = ic->tabq_coul_F;
Vc_sub_self = 0.5*c_rf;
#endif
#ifdef CALC_COUL_TAB
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
Vc_sub_self = 0.5*tab_coul_V[0];
#else
Vc_sub_self = 0.5*tab_coul_FDV0[2];
#elif GMX_SIMD_HAVE_LOGICAL
union
{
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
std::int64_t i;
#else
std::int32_t i;
/* Load masks for topology exclusion masking. filter_stride is
static const, so the conditional will be optimized away. */
-#if defined GMX_DOUBLE && !GMX_SIMD_HAVE_INT32_LOGICAL
+#if GMX_DOUBLE && !GMX_SIMD_HAVE_INT32_LOGICAL
exclusion_filter = nbat->simd_exclusion_filter64;
#else
exclusion_filter = nbat->simd_exclusion_filter;
#elif GMX_SIMD_HAVE_LOGICAL
union
{
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
std::int64_t i;
#else
std::int32_t i;
#endif
/* Calculate 1/r */
-#ifndef GMX_DOUBLE
+#if !GMX_DOUBLE
rinv_S0 = invsqrt(rsq_S0);
rinv_S1 = invsqrt(rsq_S1);
rinv_S2 = invsqrt(rsq_S2);
SimdBool diagonal_mask1_S0, diagonal_mask1_S1, diagonal_mask1_S2, diagonal_mask1_S3;
#endif
-#if defined GMX_DOUBLE && !GMX_SIMD_HAVE_INT32_LOGICAL
+#if GMX_DOUBLE && !GMX_SIMD_HAVE_INT32_LOGICAL
std::uint64_t *exclusion_filter;
#else
std::uint32_t *exclusion_filter;
#endif
#endif
-#if defined GMX_DOUBLE && !GMX_SIMD_HAVE_INT32_LOGICAL
+#if GMX_DOUBLE && !GMX_SIMD_HAVE_INT32_LOGICAL
exclusion_filter = nbat->simd_exclusion_filter64;
#else
exclusion_filter = nbat->simd_exclusion_filter;
* but too small will result in overhead.
* Currently the block size is NBNXN_BUFFERFLAG_SIZE*3*sizeof(real)=192 bytes.
*/
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
#define NBNXN_BUFFERFLAG_SIZE 8
#else
#define NBNXN_BUFFERFLAG_SIZE 16
rbb2 = std::max(0.0, rlist - 0.5*std::sqrt(bbx*bbx + bby*bby));
rbb2 = rbb2 * rbb2;
-#ifndef GMX_DOUBLE
+#if !GMX_DOUBLE
return rbb2;
#else
return (float)((1+GMX_FLOAT_EPS)*rbb2);
/* Conversion factor for reference vs SIMD kernel performance.
* The factor is about right for SSE2/4, but should be 2 higher for AVX256.
*/
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
const real nbnxn_refkernel_fac = 4.0;
#else
const real nbnxn_refkernel_fac = 8.0;
out = fopen("LJ.dat", "w");
for (i = 0; i < qm->nrQMatoms; i++)
{
-
-#ifdef GMX_DOUBLE
- fprintf(out, "%3d %10.7lf %10.7lf\n",
- qm->atomicnumberQM[i], qm->c6[i], qm->c12[i]);
-#else
fprintf(out, "%3d %10.7f %10.7f\n",
qm->atomicnumberQM[i], qm->c6[i], qm->c12[i]);
-#endif
}
fclose(out);
}
fprintf(out, "%2d%2d\n", qm->QMcharge, qm->multiplicity);
for (i = 0; i < qm->nrQMatoms; i++)
{
-#ifdef GMX_DOUBLE
- fprintf(out, "%3d %10.7lf %10.7lf %10.7lf\n",
- qm->atomicnumberQM[i],
- qm->xQM[i][XX]/BOHR2NM,
- qm->xQM[i][YY]/BOHR2NM,
- qm->xQM[i][ZZ]/BOHR2NM);
-#else
fprintf(out, "%3d %10.7f %10.7f %10.7f\n",
qm->atomicnumberQM[i],
qm->xQM[i][XX]/BOHR2NM,
qm->xQM[i][YY]/BOHR2NM,
qm->xQM[i][ZZ]/BOHR2NM);
-#endif
}
/* MM point charge data */
if (QMMMrec->QMMMscheme != eQMMMschemeoniom && mm->nrMMatoms)
fprintf(out, "\n");
for (i = 0; i < mm->nrMMatoms; i++)
{
-#ifdef GMX_DOUBLE
- fprintf(out, "%10.7lf %10.7lf %10.7lf %8.4lf\n",
- mm->xMM[i][XX]/BOHR2NM,
- mm->xMM[i][YY]/BOHR2NM,
- mm->xMM[i][ZZ]/BOHR2NM,
- mm->MMcharges[i]);
-#else
fprintf(out, "%10.7f %10.7f %10.7f %8.4f\n",
mm->xMM[i][XX]/BOHR2NM,
mm->xMM[i][YY]/BOHR2NM,
mm->xMM[i][ZZ]/BOHR2NM,
mm->MMcharges[i]);
-#endif
}
}
if (bSA) /* put the SA coefficients at the end of the file */
{
-#ifdef GMX_DOUBLE
- fprintf(out, "\n%10.8lf %10.8lf\n",
- qm->SAstep*0.5/qm->SAsteps,
- 1-qm->SAstep*0.5/qm->SAsteps);
-#else
fprintf(out, "\n%10.8f %10.8f\n",
qm->SAstep*0.5/qm->SAsteps,
1-qm->SAstep*0.5/qm->SAsteps);
-#endif
fprintf(stderr, "State Averaging level = %d/%d\n", qm->SAstep, qm->SAsteps);
}
fprintf(out, "\n");
fprintf(out, "%2d%2d\n", qm->QMcharge, qm->multiplicity);
for (i = 0; i < qm->nrQMatoms; i++)
{
-#ifdef GMX_DOUBLE
- fprintf(out, "%3d %10.7lf %10.7lf %10.7lf\n",
- qm->atomicnumberQM[i],
- qm->xQM[i][XX]/BOHR2NM,
- qm->xQM[i][YY]/BOHR2NM,
- qm->xQM[i][ZZ]/BOHR2NM);
-#else
fprintf(out, "%3d %10.7f %10.7f %10.7f\n",
qm->atomicnumberQM[i],
qm->xQM[i][XX]/BOHR2NM,
qm->xQM[i][YY]/BOHR2NM,
qm->xQM[i][ZZ]/BOHR2NM);
-#endif
}
/* Pseudo Potential and ECP are included here if selected (MEthod suffix LAN) */
*/
for (i = 0; i < mm->nrMMatoms; i++)
{
-#ifdef GMX_DOUBLE
- fprintf(out, "%10.7lf %10.7lf %10.7lf %8.4lf 0.0 %10.7lf %10.7lf\n",
- mm->xMM[i][XX]/BOHR2NM,
- mm->xMM[i][YY]/BOHR2NM,
- mm->xMM[i][ZZ]/BOHR2NM,
- mm->MMcharges[i],
- mm->c6[i], mm->c12[i]);
-#else
fprintf(out, "%10.7f %10.7f %10.7f %8.4f 0.0 %10.7f %10.7f\n",
mm->xMM[i][XX]/BOHR2NM,
mm->xMM[i][YY]/BOHR2NM,
mm->xMM[i][ZZ]/BOHR2NM,
mm->MMcharges[i],
mm->c6[i], mm->c12[i]);
-#endif
}
fprintf(out, "\n");
}
{
for (i = 0; i < mm->nrMMatoms; i++)
{
-#ifdef GMX_DOUBLE
- fprintf(out, "%10.7lf %10.7lf %10.7lf %8.4lf\n",
- mm->xMM[i][XX]/BOHR2NM,
- mm->xMM[i][YY]/BOHR2NM,
- mm->xMM[i][ZZ]/BOHR2NM,
- mm->MMcharges[i]);
-#else
fprintf(out, "%10.7f %10.7f %10.7f %8.4f\n",
mm->xMM[i][XX]/BOHR2NM,
mm->xMM[i][YY]/BOHR2NM,
mm->xMM[i][ZZ]/BOHR2NM,
mm->MMcharges[i]);
-#endif
}
}
}
gmx_fatal(FARGS, "Error reading Gaussian output - not enough atom lines?");
}
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
sscanf(buf, "%d %lf %lf %lf\n",
&atnum,
&qm->xQM[i][XX],
gmx_fatal(FARGS, "Error reading Gaussian output");
}
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
sscanf(buf, "%lf\n", &QMener);
#else
sscanf(buf, "%f\n", &QMener);
{
gmx_fatal(FARGS, "Error reading Gaussian output");
}
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
sscanf(buf, "%lf %lf %lf\n",
&QMgrad[i][XX],
&QMgrad[i][YY],
{
gmx_fatal(FARGS, "Error reading Gaussian output");
}
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
sscanf(buf, "%lf %lf %lf\n",
&MMgrad[i][XX],
&MMgrad[i][YY],
gmx_fatal(FARGS, "Error reading Gaussian output");
}
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
sscanf(buf, "%lf %lf\n", &QMener, &DeltaE);
#else
sscanf(buf, "%f %f\n", &QMener, &DeltaE);
gmx_fatal(FARGS, "Error reading Gaussian output");
}
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
sscanf(buf, "%lf %lf %lf\n",
&QMgrad[i][XX],
&QMgrad[i][YY],
{
gmx_fatal(FARGS, "Error reading Gaussian output");
}
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
sscanf(buf, "%lf %lf %lf\n",
&MMgrad[i][XX],
&MMgrad[i][YY],
{
gmx_fatal(FARGS, "Error reading Gaussian output");
}
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
sscanf(buf, "%lf\n", &qm->CIvec1[i]);
#else
sscanf(buf, "%f\n", &qm->CIvec1[i]);
{
gmx_fatal(FARGS, "Error reading Gaussian output");
}
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
sscanf(buf, "%lf\n", &qm->CIvec2[i]);
#else
sscanf(buf, "%f\n", &qm->CIvec2[i]);
fprintf(LJCoeff, "%d\n", qm->nrQMatoms);
for (i = 0; i < qm->nrQMatoms; i++)
{
-#ifdef GMX_DOUBLE
- fprintf(LJCoeff, "%10.7lf %10.7lf\n", qm->c6[i], qm->c12[i]);
-#else
fprintf(LJCoeff, "%10.7f %10.7f\n", qm->c6[i], qm->c12[i]);
-#endif
}
fprintf(LJCoeff, "%d\n", mm->nrMMatoms);
for (i = 0; i < mm->nrMMatoms; i++)
{
-#ifdef GMX_DOUBLE
- fprintf(LJCoeff, "%10.7lf %10.7lf\n", mm->c6[i], mm->c12[i]);
-#else
fprintf(LJCoeff, "%10.7f %10.7f\n", mm->c6[i], mm->c12[i]);
-#endif
}
fclose(LJCoeff);
}
{
atomNr = qm->atomicnumberQM[i];
}
-#ifdef GMX_DOUBLE
- fprintf(out, "%3d %10.7lf %10.7lf %10.7lf\n",
- atomNr,
- qm->xQM[i][XX]/0.1,
- qm->xQM[i][YY]/0.1,
- qm->xQM[i][ZZ]/0.1);
-#else
fprintf(out, "%3d %10.7f %10.7f %10.7f\n",
atomNr,
qm->xQM[i][XX]/0.1,
qm->xQM[i][YY]/0.1,
qm->xQM[i][ZZ]/0.1);
-#endif
}
fprintf(out, "*\n");
fprintf(pcFile, "%d\n", mm->nrMMatoms);
for (i = 0; i < mm->nrMMatoms; i++)
{
-#ifdef GMX_DOUBLE
- fprintf(pcFile, "%8.4lf %10.7lf %10.7lf %10.7lf\n",
- mm->MMcharges[i],
- mm->xMM[i][XX]/0.1,
- mm->xMM[i][YY]/0.1,
- mm->xMM[i][ZZ]/0.1);
-#else
fprintf(pcFile, "%8.4f %10.7f %10.7f %10.7f\n",
mm->MMcharges[i],
mm->xMM[i][XX]/0.1,
mm->xMM[i][YY]/0.1,
mm->xMM[i][ZZ]/0.1);
-#endif
}
fprintf(pcFile, "\n");
fclose(pcFile);
{
gmx_fatal(FARGS, "Unexpected end of ORCA output");
}
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
sscanf(buf, "%d%lf%lf%lf\n",
&atnum,
&qm->xQM[i][XX],
{
gmx_fatal(FARGS, "Unexpected end of ORCA output");
}
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
sscanf(buf, "%lf\n", &QMener);
#else
sscanf(buf, "%f\n", &QMener);
{
gmx_fatal(FARGS, "Unexpected end of ORCA output");
}
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
if (i%3 == 0)
{
sscanf(buf, "%lf\n", &QMgrad[k][XX]);
{
gmx_fatal(FARGS, "Unexpected end of ORCA output");
}
- #ifdef GMX_DOUBLE
+ #if GMX_DOUBLE
sscanf(buf, "%lf%lf%lf\n",
&MMgrad[i][XX],
&MMgrad[i][YY],
* Generally, new would be better using DoubleOption, but this is provided for
* cases where the output value needs to be of type `real` for some reason.
*/
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
typedef DoubleOption RealOption;
typedef DoubleOptionInfo RealOptionInfo;
#else
*
* The defines in this top-level file will set default Gromacs real precision
* operations to either single or double precision based on whether
- * GMX_DOUBLE is defined. The actual implementation - including e.g.
+ * GMX_DOUBLE is 1. The actual implementation - including e.g.
* conversion operations specifically between single and double - is documented
* in impl_reference.h.
*
# include "impl_none/impl_none.h"
#endif
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
# define GMX_SIMD_HAVE_REAL GMX_SIMD_HAVE_DOUBLE
# define GMX_SIMD_REAL_WIDTH GMX_SIMD_DOUBLE_WIDTH
# define GMX_SIMD_HAVE_INT32_EXTRACT GMX_SIMD_HAVE_DINT32_EXTRACT
/*! \brief 1 if SimdReal is available, otherwise 0.
*
- * \ref GMX_SIMD_HAVE_DOUBLE if GMX_DOUBLE is set, otherwise \ref GMX_SIMD_HAVE_FLOAT.
+ * \ref GMX_SIMD_HAVE_DOUBLE if GMX_DOUBLE is 1, otherwise \ref GMX_SIMD_HAVE_FLOAT.
*/
# define GMX_SIMD_HAVE_REAL GMX_SIMD_HAVE_FLOAT
/*! \brief Width of SimdReal.
*
- * \ref GMX_SIMD_DOUBLE_WIDTH if GMX_DOUBLE is set, otherwise \ref GMX_SIMD_FLOAT_WIDTH.
+ * \ref GMX_SIMD_DOUBLE_WIDTH if GMX_DOUBLE is 1, otherwise \ref GMX_SIMD_FLOAT_WIDTH.
*/
# define GMX_SIMD_REAL_WIDTH GMX_SIMD_FLOAT_WIDTH
/*! \brief 1 if support is available for extracting elements from SimdInt32, otherwise 0
*
- * \ref GMX_SIMD_HAVE_DINT32_EXTRACT if GMX_DOUBLE is set, otherwise
+ * \ref GMX_SIMD_HAVE_DINT32_EXTRACT if GMX_DOUBLE is 1, otherwise
* \ref GMX_SIMD_HAVE_FINT32_EXTRACT.
*/
# define GMX_SIMD_HAVE_INT32_EXTRACT GMX_SIMD_HAVE_FINT32_EXTRACT
/*! \brief 1 if logical ops are supported on SimdInt32, otherwise 0.
*
- * \ref GMX_SIMD_HAVE_DINT32_LOGICAL if GMX_DOUBLE is set, otherwise
+ * \ref GMX_SIMD_HAVE_DINT32_LOGICAL if GMX_DOUBLE is 1, otherwise
* \ref GMX_SIMD_HAVE_FINT32_LOGICAL.
*/
# define GMX_SIMD_HAVE_INT32_LOGICAL GMX_SIMD_HAVE_FINT32_LOGICAL
/*! \brief 1 if arithmetic ops are supported on SimdInt32, otherwise 0.
*
- * \ref GMX_SIMD_HAVE_DINT32_ARITHMETICS if GMX_DOUBLE is set, otherwise
+ * \ref GMX_SIMD_HAVE_DINT32_ARITHMETICS if GMX_DOUBLE is 1, otherwise
* \ref GMX_SIMD_HAVE_FINT32_ARITHMETICS.
*/
# define GMX_SIMD_HAVE_INT32_ARITHMETICS GMX_SIMD_HAVE_FINT32_ARITHMETICS
/*! \brief 1 if gmx::simdGatherLoadUBySimdIntTranspose is present, otherwise 0
*
- * \ref GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_DOUBLE if GMX_DOUBLE is set, otherwise
+ * \ref GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_DOUBLE if GMX_DOUBLE is 1, otherwise
* \ref GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_FLOAT.
*/
# define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_REAL GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_FLOAT
/*! \brief 1 if real half-register load/store/reduce utils present, otherwise 0
*
- * \ref GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE if GMX_DOUBLE is set, otherwise
+ * \ref GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE if GMX_DOUBLE is 1, otherwise
* \ref GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT.
*/
# define GMX_SIMD_HAVE_HSIMD_UTIL_REAL GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT
/*! \brief 1 if Simd4Real is available, otherwise 0.
*
- * \ref GMX_SIMD4_HAVE_DOUBLE if GMX_DOUBLE is set, otherwise \ref GMX_SIMD4_HAVE_FLOAT.
+ * \ref GMX_SIMD4_HAVE_DOUBLE if GMX_DOUBLE is 1, otherwise \ref GMX_SIMD4_HAVE_FLOAT.
*/
# define GMX_SIMD4_HAVE_REAL GMX_SIMD4_HAVE_FLOAT
*
* This type is only available if \ref GMX_SIMD_HAVE_REAL is 1.
*
- * \ref SimdDouble if GMX_DOUBLE is set, otherwise \ref SimdFloat.
+ * \ref SimdDouble if GMX_DOUBLE is 1, otherwise \ref SimdFloat.
*
* \note This variable cannot be placed inside other structures or classes, since
* some compilers (including at least clang-3.7) appear to lose the
* alignment. This is likely particularly severe when allocating such
* memory on the heap, but it occurs for stack structures too.
*/
-# ifdef GMX_DOUBLE
+# if GMX_DOUBLE
typedef SimdDouble SimdReal;
# else
typedef SimdFloat SimdReal;
*
* This type is only available if \ref GMX_SIMD_HAVE_REAL is 1.
*
- * If GMX_DOUBLE is defined, this will be set to \ref SimdDBool
+ * If GMX_DOUBLE is 1, this will be set to \ref SimdDBool
* internally, otherwise \ref SimdFBool. This is necessary since some
* SIMD implementations use bitpatterns for marking truth, so single-
* vs. double precision booleans are not necessarily exchangable.
* alignment. This is likely particularly severe when allocating such
* memory on the heap, but it occurs for stack structures too.
*/
-# ifdef GMX_DOUBLE
+# if GMX_DOUBLE
typedef SimdDBool SimdBool;
# else
typedef SimdFBool SimdBool;
/*! \brief 32-bit integer SIMD type.
*
- * If GMX_DOUBLE is defined, this will be set to \ref SimdDInt32
+ * If GMX_DOUBLE is 1, this will be set to \ref SimdDInt32
* internally, otherwise \ref SimdFInt32. This might seem a strange
* implementation detail, but it is because some SIMD implementations use
* different types/widths of integers registers when converting from
* alignment. This is likely particularly severe when allocating such
* memory on the heap, but it occurs for stack structures too.
*/
-# ifdef GMX_DOUBLE
+# if GMX_DOUBLE
typedef SimdDInt32 SimdInt32;
# else
typedef SimdFInt32 SimdInt32;
*
* This type is only available if \ref GMX_SIMD_HAVE_INT32_ARITHMETICS is 1.
*
- * If GMX_DOUBLE is defined, this will be set to \ref SimdDIBool
+ * If GMX_DOUBLE is 1, this will be set to \ref SimdDIBool
* internally, otherwise \ref SimdFIBool. This is necessary since some
* SIMD implementations use bitpatterns for marking truth, so single-
* vs. double precision booleans are not necessarily exchangable, and while
* alignment. This is likely particularly severe when allocating such
* memory on the heap, but it occurs for stack structures too.
*/
-# ifdef GMX_DOUBLE
+# if GMX_DOUBLE
typedef SimdDIBool SimdIBool;
# else
typedef SimdFIBool SimdIBool;
#endif // GMX_SIMD_HAVE_INT32_ARITHMETICS
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
const int c_simdBestPairAlignment = c_simdBestPairAlignmentDouble;
#else
const int c_simdBestPairAlignment = c_simdBestPairAlignmentFloat;
*
* This type is only available if \ref GMX_SIMD4_HAVE_REAL is 1.
*
- * \ref Simd4Double if GMX_DOUBLE is set, otherwise \ref Simd4Float.
+ * \ref Simd4Double if GMX_DOUBLE is 1, otherwise \ref Simd4Float.
*
* \note This variable cannot be placed inside other structures or classes, since
* some compilers (including at least clang-3.7) appear to lose the
* alignment. This is likely particularly severe when allocating such
* memory on the heap, but it occurs for stack structures too.
*/
-# ifdef GMX_DOUBLE
+# if GMX_DOUBLE
typedef Simd4Double Simd4Real;
# else
typedef Simd4Float Simd4Real;
*
* This type is only available if \ref GMX_SIMD4_HAVE_REAL is 1.
*
- * If GMX_DOUBLE is defined, this will be set to \ref Simd4DBool
+ * If GMX_DOUBLE is 1, this will be set to \ref Simd4DBool
* internally, otherwise \ref Simd4FBool. This is necessary since some
* SIMD implementations use bitpatterns for marking truth, so single-
* vs. double precision booleans are not necessarily exchangable.
* alignment. This is likely particularly severe when allocating such
* memory on the heap, but it occurs for stack structures too.
*/
-# ifdef GMX_DOUBLE
+# if GMX_DOUBLE
typedef Simd4DBool Simd4Bool;
# else
typedef Simd4FBool Simd4Bool;
size_t i;
union {
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
double r; std::int64_t i;
#else
float r; std::int32_t i;
* exponentials, logarithms, and error functions.
*/
SimdBaseTest() :
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
ulpTol_((1LL << (2 + std::numeric_limits<double>::digits-GMX_SIMD_ACCURACY_BITS_DOUBLE))),
#else
ulpTol_((1LL << (2 + std::numeric_limits<float>::digits-GMX_SIMD_ACCURACY_BITS_SINGLE))),
const SimdReal rSimd_Exp = setSimdRealFrom3R( 1.4055235171027452623914516e+18,
5.3057102734253445623914516e-13,
-2.1057102745623934534514516e+16);
-# if GMX_SIMD_HAVE_DOUBLE && defined GMX_DOUBLE
+# if GMX_SIMD_HAVE_DOUBLE && GMX_DOUBLE
// Make sure we also test exponents outside single precision when we use double
const SimdReal rSimd_ExpDouble = setSimdRealFrom3R( 6.287393598732017379054414e+176,
8.794495252903116023030553e-140,
extern const SimdReal rSimd_m3p75; //!< Negative value that rounds down.
//! Three large floating-point values whose exponents are >32.
extern const SimdReal rSimd_Exp;
-# if GMX_SIMD_HAVE_DOUBLE && defined GMX_DOUBLE
+# if GMX_SIMD_HAVE_DOUBLE && GMX_DOUBLE
// Make sure we also test exponents outside single precision when we use double
extern const SimdReal rSimd_ExpDouble;
# endif
const Simd4Real rSimd4_Exp = setSimd4RealFrom3R( 1.4055235171027452623914516e+18,
5.3057102734253445623914516e-13,
-2.1057102745623934534514516e+16);
-# if GMX_SIMD_HAVE_DOUBLE && defined GMX_DOUBLE
+# if GMX_SIMD_HAVE_DOUBLE && GMX_DOUBLE
// Make sure we also test exponents outside single precision when we use double
const Simd4Real rSimd_ExpDouble = setSimd4RealFrom3R( 6.287393598732017379054414e+176,
8.794495252903116023030553e-140,
extern const Simd4Real rSimd4_m3p75; //!< Negative value that rounds down.
//! Three large floating-point values whose exponents are >32.
extern const Simd4Real rSimd4_Exp;
-# if GMX_SIMD_HAVE_DOUBLE && defined GMX_DOUBLE
+# if GMX_SIMD_HAVE_DOUBLE && GMX_DOUBLE
// Make sure we also test exponents outside single precision when we use double
extern const Simd4Real rSimd4_ExpDouble;
# endif
{
Simd4Real v1 = setSimd4RealFrom3R(1, 4, 5);
Simd4Real v2 = setSimd4RealFrom3R(3, 8, 2);
-# ifdef GMX_DOUBLE
+# if GMX_DOUBLE
EXPECT_DOUBLE_EQ(45.0, dotProduct(v1, v2));
# else
EXPECT_FLOAT_EQ(45.0, dotProduct(v1, v2));
int i, iter;
int niter = s_nPoints/GMX_SIMD4_WIDTH;
int npoints = niter*GMX_SIMD4_WIDTH;
-# ifdef GMX_DOUBLE
+# if GMX_DOUBLE
union {
double r; std::int64_t i;
} conv0, conv1;
GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom3I(61, -40, 55), exponent);
-#if GMX_SIMD_HAVE_DOUBLE && defined GMX_DOUBLE
+#if GMX_SIMD_HAVE_DOUBLE && GMX_DOUBLE
fraction = frexp(rSimd_ExpDouble, &exponent);
GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(0.6206306194761728178832527,
GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(pow(2.0, 60.0), pow(2.0, -41.0), pow(2.0, 54.0)),
ldexp(one, setSimdIntFrom3I(60, -41, 54)));
-#if GMX_SIMD_HAVE_DOUBLE && defined GMX_DOUBLE
+#if GMX_SIMD_HAVE_DOUBLE && GMX_DOUBLE
GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(pow(2.0, 587.0), pow(2.0, -462.0), pow(2.0, 672.0)),
ldexp(one, setSimdIntFrom3I(587, -462, 672)));
#endif
int i, iter;
int niter = s_nPoints/GMX_SIMD_REAL_WIDTH;
int npoints = niter*GMX_SIMD_REAL_WIDTH;
-# ifdef GMX_DOUBLE
+# if GMX_DOUBLE
union {
double r; std::int64_t i;
} conv0, conv1;
TEST_F(SimdMathTest, pmeForceCorrection)
{
// Pme correction only needs to be ~1e-6 accuracy single, 1e-10 double
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
setUlpTol(std::int64_t(5e-10/GMX_REAL_EPS));
#else
setUlpTol(std::int64_t(5e-6/GMX_REAL_EPS));
TEST_F(SimdMathTest, pmePotentialCorrection)
{
// Pme correction only needs to be ~1e-6 accuracy single, 1e-10 double
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
setUlpTol(std::int64_t(5e-10/GMX_REAL_EPS));
#else
setUlpTol(std::int64_t(5e-6/GMX_REAL_EPS));
else
{
// No tables are read
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
table->scale = 2000.0;
#else
table->scale = 500.0;
return _gmx_central_base_hash;
}
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
void gmx_is_double_precision()
{
}
return "fftw3";
# else
// Use the version string provided by libfftw3
-# ifdef GMX_DOUBLE
+# if GMX_DOUBLE
return fftw_version;
# else
return fftwf_version;
fprintf(fp, "Branched from: %s\n", base_hash);
}
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
fprintf(fp, "Precision: double\n");
#else
fprintf(fp, "Precision: single\n");
const char *prefix = settings.prefix_;
const char *suffix = settings.suffix_;
const char *precisionString = "";
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
precisionString = " (double precision)";
#endif
const char *const name = programContext.displayName();
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, 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.
/*! \def gmx_real_fullprecision_pfmt
* \brief Format string for full `real` precision.
*/
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
#ifndef HAVE_REAL
typedef double real;
* \hideinitializer
*/
-#ifdef GMX_DOUBLE
+#if GMX_DOUBLE
#define EXPECT_REAL_EQ_TOL(value1, value2, tolerance) \
EXPECT_DOUBLE_EQ_TOL(value1, value2, tolerance)
#define ASSERT_REAL_EQ_TOL(value1, value2, tolerance) \