Merge "Ignore bool cast warning for MSVC and C++" into release-4-6
authorRoland Schulz <roland@utk.edu>
Mon, 7 Jan 2013 19:15:55 +0000 (20:15 +0100)
committerGerrit Code Review <gerrit@gerrit.gromacs.org>
Mon, 7 Jan 2013 19:15:55 +0000 (20:15 +0100)
43 files changed:
CMakeLists.txt
cmake/FindFFTW.cmake
include/edsam.h
include/gmx_arpack.h
include/gmx_cpuid.h
include/gmx_lapack.h
include/main.h
include/maths.h
include/nbsearch.h
include/network.h
include/thread_mpi/atomic/gcc_x86.h
include/trajana.h
include/types/nbnxn_pairlist.h
include/types/state.h
include/vec.h
scripts/GMXRC.cmakein
share/html/online/gro.html
share/template/CMakeLists.txt
src/config.h.cmakein
src/gmxlib/checkpoint.c
src/gmxlib/gmx_cpuid.c
src/gmxlib/gpu_utils/CMakeLists.txt
src/gmxlib/libgmx.pc.cmakein
src/gmxlib/thread_mpi/collective.c
src/gmxlib/thread_mpi/once.c
src/gmxlib/thread_mpi/tmpi_init.c
src/kernel/pdb2gmx.c
src/kernel/repl_ex.c
src/kernel/runner.c
src/mdlib/CMakeLists.txt
src/mdlib/constr.c
src/mdlib/edsam.c
src/mdlib/fft5d.h
src/mdlib/forcerec.c
src/mdlib/libmd.pc.cmakein
src/mdlib/nbnxn_cuda/CMakeLists.txt
src/mdlib/nbnxn_kernels/nbnxn_kernel_ref_outer.h
src/mdlib/nbnxn_kernels/nbnxn_kernel_simd_2xnn_outer.h
src/mdlib/nbnxn_kernels/nbnxn_kernel_simd_4xn_outer.h
src/mdlib/nbnxn_search.c
src/tools/gmx_angle.c
src/tools/gmx_helix.c
src/tools/gmx_make_edi.c

index 78c25c6036f8d3d0f2fad8e928373fbf69722398..0251e1048849676bc575a1965d3eee71910c0dee 100644 (file)
@@ -40,10 +40,9 @@ set(CMAKE_LEGACY_CYGWIN_WIN32 0) # Remove when CMake >= 2.8.4 is required
 set(CPACK_COMPONENT_GROUP_TOOLS_DESCRIPTION "All GROMACS executable tools")
 set(CPACK_COMPONENT_GROUP_MDRUN_DESCRIPTION "GROMACS executable for running simulations")
 
-# override bugs on OS X where Cmake picks gcc (GNU) for C instead of system default cc (Clang).
-if(APPLE)
-    set(CMAKE_C_COMPILER_INIT "cc")
-endif(APPLE)
+# CMake modules/macros are in a subdirectory to keep this file cleaner
+# This needs to be set before project() in order to pick up toolchain files
+list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Platform)
 
 project(Gromacs C)
 include(Dart)
@@ -57,7 +56,7 @@ mark_as_advanced(DART_ROOT)
 # machine with no git. 
 #
 # NOTE: when releasing the "-dev" suffix needs to be stripped off!
-set(PROJECT_VERSION "4.6-beta2-dev")
+set(PROJECT_VERSION "4.6-beta3-dev")
 set(CUSTOM_VERSION_STRING ""
     CACHE STRING "Custom version string (if empty, use hard-coded default)")
 mark_as_advanced(CUSTOM_VERSION_STRING)
@@ -86,9 +85,6 @@ endif()
 # provide backward compatibility of software written against the Gromacs API.
 set(API_VERSION ${NUM_VERSION})
 
-# Cmake modules/macros are in a subdirectory to keep this file cleaner
-set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
-
 if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT AND UNIX)
 set(CMAKE_INSTALL_PREFIX "/usr/local/gromacs" CACHE STRING "Installation prefix (installation will need write permissions here)" FORCE)
 endif()
@@ -171,6 +167,7 @@ IF( WIN32 AND NOT CYGWIN)
     SET(SHARED_LIBS_DEFAULT OFF)
   else()
     add_definitions(-DUSE_VISIBILITY -DTMPI_USE_VISIBILITY)
+    set(PKG_CFLAGS "$PKG_CFLAGS -DUSE_VISIBILITY -DTMPI_USE_VISIBILITY")
   endif()
 
   IF (GMX_PREFER_STATIC_LIBS)
@@ -189,6 +186,10 @@ IF( WIN32 AND NOT CYGWIN)
 
   #Workaround for cmake bug 13174. Replace deprecated options.
   IF( CMAKE_C_COMPILER_ID MATCHES "Intel" )
+    if(BUILD_SHARED_LIBS)
+        STRING(REPLACE "/INCREMENTAL:YES" "" CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS})
+        SET(CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} CACHE STRING "" FORCE)
+    endif()
     STRING(REPLACE /GZ /RTC1 CMAKE_C_FLAGS_DEBUG ${CMAKE_C_FLAGS_DEBUG})
     SET(CMAKE_C_FLAGS_DEBUG ${CMAKE_C_FLAGS_DEBUG} CACHE STRING "" FORCE)
   ENDIF()
@@ -211,8 +212,6 @@ option(GMX_MPI    "Build a parallel (message-passing) version of GROMACS" OFF)
 option(GMX_THREAD_MPI  "Build a thread-MPI-based multithreaded version of GROMACS (not compatible with MPI)" ON)
 option(GMX_SOFTWARE_INVSQRT "Use GROMACS software 1/sqrt" ON)
 mark_as_advanced(GMX_SOFTWARE_INVSQRT)
-option(GMX_POWERPC_INVSQRT "Use PowerPC hardware 1/sqrt" OFF)
-mark_as_advanced(GMX_POWERPC_INVSQRT)
 option(GMX_FAHCORE "Build a library with mdrun functionality" OFF)
 mark_as_advanced(GMX_FAHCORE)
 
@@ -373,9 +372,6 @@ endif(GMX_DOUBLE)
 if(GMX_SOFTWARE_INVSQRT)
   set(PKG_CFLAGS "${PKG_CFLAGS} -DGMX_SOFTWARE_INVSQRT")
 endif(GMX_SOFTWARE_INVSQRT)
-if(GMX_POWERPC_INVSQRT)
-  set(PKG_CFLAGS "${PKG_CFLAGS} -DGMX_POWERPC_INVSQRT")
-endif(GMX_POWERPC_INVSQRT)
 
 ########################################################################
 #Process MPI settings
@@ -865,7 +861,6 @@ elseif(${GMX_CPU_ACCELERATION} STREQUAL "BLUEGENE")
         set(BUILD_SHARED_LIBS OFF CACHE BOOL "Shared libraries not compatible with BlueGene/L, disabled!" FORCE)
     endif (${CMAKE_SYSTEM_NAME} STREQUAL "BlueGeneL")
     set(GMX_SOFTWARE_INVSQRT OFF CACHE BOOL "Do not use software reciprocal square root on BlueGene" FORCE)
-    set(GMX_POWERPC_INVSQRT ON CACHE BOOL "Use hardware reciprocal square root on BlueGene" FORCE)
     set(GMX_X11 OFF CACHE BOOL "X11 not compatible with BlueGene, disabled!" FORCE)
     set(GMX_THREAD_MPI OFF CACHE BOOL "Thread-MPI not compatible with BlueGene, disabled!" FORCE)
     set(GMX_MPI ON CACHE BOOL "Use MPI on BlueGene" FORCE)
@@ -876,10 +871,6 @@ elseif(${GMX_CPU_ACCELERATION} STREQUAL "BLUEGENE")
 # The automatic testing for endianness does not work for the BlueGene cross-compiler
     set(GMX_IEEE754_BIG_ENDIAN_BYTE_ORDER 1 CACHE INTERNAL "BlueGene has big endian FP byte order (by default)" FORCE)
     set(GMX_IEEE754_BIG_ENDIAN_WORD_ORDER 1 CACHE INTERNAL "BlueGene has big endian FP word order (by default)" FORCE)
-elseif(${GMX_CPU_ACCELERATION} STREQUAL "POWER6")
-    set(GMX_POWER6 1)
-    set(GMX_SOFTWARE_INVSQRT OFF CACHE BOOL "Do not use software reciprocal square root on Power6" FORCE)
-    set(GMX_POWERPC_INVSQRT ON CACHE BOOL "Use hardware reciprocal square root on Power6" FORCE)
 else(${GMX_CPU_ACCELERATION} STREQUAL "NONE")
     MESSAGE(FATAL_ERROR "Unrecognized option for accelerated kernels: ${GMX_CPU_ACCELERATION}. Pick one of None, SSE2, SSE4.1, AVX_128_FMA, AVX_256, BlueGene")
 endif(${GMX_CPU_ACCELERATION} STREQUAL "NONE")
@@ -1081,6 +1072,7 @@ if(NOT GMX_OPENMP)
     unset(OpenMP_LINKER_FLAGS CACHE)
     unset(OpenMP_SHARED_LINKER_FLAGS)
 endif()
+set(PKG_CFLAGS "${PKG_CFLAGS} ${OpenMP_C_FLAGS}")
 
 ######################################
 # Output compiler and CFLAGS used
index 6a4d724e626e03e112eefc1c78e79ffac50a1778..f9053cee9b9e081e5b9bf8d721853dd254a6bb0c 100644 (file)
@@ -134,4 +134,4 @@ if (${FFTW}_FOUND)
 endif (${FFTW}_FOUND)
 set(${FFTW}_HAVE_SIMD FALSE CACHE BOOL "If ${${FFTW}_PKG} was built with SIMD support")
 
-mark_as_advanced(${FFTW}_INCLUDE_DIR ${FFTW}_LIBRARY ${FFTW}_HAVE_SIMD)
+mark_as_advanced(${FFTW}_INCLUDE_DIR ${FFTW}_LIBRARY ${FFTW}_HAVE_SIMD ${FFTW}_HAVE_AVX)
index 80e189c6ff2fceaa95674aef543fa981a1345a96..f78215563d7b8f0ed43ccb01725881135fb713e7 100644 (file)
@@ -54,7 +54,7 @@ gmx_edsam_t ed_open(int nfile,const t_filenm fnm[],unsigned long Flags,t_commrec
 /* Sets the ED input/output filenames, opens output (.edo) file */
 
 void init_edsam(gmx_mtop_t *mtop,t_inputrec *ir,t_commrec *cr,
-                       gmx_edsam_t ed, rvec x[], matrix box);
+                       gmx_edsam_t ed, rvec x[], matrix box, edsamstate_t *edsamstate);
 /* Init routine for ED and flooding. Calls init_edi in a loop for every .edi-cycle 
  * contained in the input file, creates a NULL terminated list of t_edpar structures */
 
index 612ebf62fa30e379f81f9c0bf1d19a021a01faa2..d60a56e91085002bc0f8c626120fdabee94f6d73 100644 (file)
@@ -106,6 +106,7 @@ extern "C" {
  *                 and 3 that no shifts could be applied. Negative numbers
  *                 correspond to errors in the arguments provided.
  */
+GMX_LIBGMX_EXPORT
 void
 F77_FUNC(dsaupd,DSAUPD)(int *     ido, 
                         const char *    bmat, 
@@ -165,6 +166,7 @@ F77_FUNC(dsaupd,DSAUPD)(int *     ido,
  *  \param lworkl  Provide the same argument as you did to dsaupd()
  *  \param info    Provide the same argument as you did to dsaupd()
  */
+GMX_LIBGMX_EXPORT
 void
 F77_FUNC(dseupd,DSEUPD)(int *     rvec, 
                         const char *    howmny, 
index 71d89a9c54194c7aee3367455e21037b63c8f8ec..3b6673c807b195fe68605e232581d1e96be25e82 100644 (file)
  */
 #ifndef GMX_CPUID_H_
 #define GMX_CPUID_H_
+
+#include <stdio.h>
+
 #include "visibility.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
index c21f5b034c669df5531b70eef46490d4356e6074..a7bed9cc2462794d9c8d98bd52b7e0372e1e785f 100644 (file)
@@ -396,6 +396,7 @@ void
 F77_FUNC(dsytrd,DSYTRD)(const char *uplo, int *n, double *  a, int *lda, double *d, 
        double *e, double *tau, double *work, int *lwork, int *info);
 
+GMX_LIBGMX_EXPORT
 void
 F77_FUNC(dsyevr,DSYEVR)(const char *jobz, const char *range, const char *uplo, int *n, 
        double *a, int *lda, double *vl, double *vu, int *
index d6e7afc7ab6d1065a9b7173245079faf61766901..64d64466aaa0239de32221304ca942ec2e8fa641 100644 (file)
@@ -75,7 +75,7 @@ void check_multi_large_int(FILE *log,const gmx_multisim_t *ms,
  * The string name is used to print to the log file and in a fatal error
  * if the val's don't match.
  */
-
+GMX_LIBGMX_EXPORT
 void init_multisystem(t_commrec *cr, int nsim, char **multidirs,
                       int nfile, const t_filenm fnm[], gmx_bool bParFn);
 /* Splits the communication into nsim separate simulations
index 2895026cca6c894c0c518c9de1255745e5cf6c04..daa2ec58df3b01a9e49314aef460ce5435f00829 100644 (file)
@@ -121,6 +121,7 @@ real    sign(real x,real y);
 real    cuberoot (real a);
 GMX_LIBGMX_EXPORT
 double  gmx_erfd(double x);
+GMX_LIBGMX_EXPORT
 double  gmx_erfcd(double x);
 GMX_LIBGMX_EXPORT
 float   gmx_erff(float x);
index bff7a88a5285992cf34e6335fe3701ddad8b3507..6d51d00894368fb0fd60d17d0401e5c17daa0a79 100644 (file)
@@ -62,6 +62,7 @@ struct gmx_ana_pos_t;
 typedef struct gmx_ana_nbsearch_t gmx_ana_nbsearch_t;
 
 /** Create a new neighborhood search data structure. */
+GMX_LIBGMX_EXPORT
 int
 gmx_ana_nbsearch_create(gmx_ana_nbsearch_t **d, real cutoff, int maxn);
 /** Free memory allocated for neighborhood search. */
@@ -72,6 +73,7 @@ gmx_ana_nbsearch_free(gmx_ana_nbsearch_t *d);
 int
 gmx_ana_nbsearch_init(gmx_ana_nbsearch_t *d, t_pbc *pbc, int n, rvec x[]);
 /** Initializes neighborhood search for a frame using \c gmx_ana_pos_t.  */
+GMX_LIBGMX_EXPORT
 int
 gmx_ana_nbsearch_pos_init(gmx_ana_nbsearch_t *d, t_pbc *pbc,
                           struct gmx_ana_pos_t *p);
@@ -89,6 +91,7 @@ gmx_ana_nbsearch_pos_is_within(gmx_ana_nbsearch_t *d,
 real
 gmx_ana_nbsearch_mindist(gmx_ana_nbsearch_t *d, rvec x);
 /** Calculates the minimun distance from the reference points. */
+GMX_LIBGMX_EXPORT
 real
 gmx_ana_nbsearch_pos_mindist(gmx_ana_nbsearch_t *d,
                              struct gmx_ana_pos_t *p, int i);
index 35ce9bc5286506d0940d3400ddb8b854dd82e86f..680a88136f9435fa46f746334af55339514e572f 100644 (file)
@@ -129,6 +129,7 @@ GMX_LIBGMX_EXPORT
 void gmx_sumf_sim(int nr,float r[],const gmx_multisim_t *ms);
 /* Calculate the sum over the simulations of an array of floats */
 
+GMX_LIBGMX_EXPORT
 void gmx_sumd_sim(int nr,double r[],const gmx_multisim_t *ms);
 /* Calculate the sum over the simulations of an array of doubles */
 
index 08f878a0198a42ab7af97b093c0da22b64bf363b..9eb6679ca9b635f209a902ef47d6cef00e78dafa 100644 (file)
@@ -57,22 +57,23 @@ files.
 
 /* we put all of these on their own cache line by padding the data structure
    to the size of a cache line on x86 (64 bytes): */
+#define TMPI_SIZEOF_X86_CACHE_LINE 64
 typedef struct tMPI_Atomic
 {
     int value; 
-    char padding[64-sizeof(int)];
+    char padding[TMPI_SIZEOF_X86_CACHE_LINE-sizeof(int)];
 } tMPI_Atomic_t;
 
 typedef struct tMPI_Atomic_ptr
 {
     void* value; 
-    char padding[64-sizeof(void*)];
+    char padding[TMPI_SIZEOF_X86_CACHE_LINE-sizeof(void*)];
 } tMPI_Atomic_ptr_t;
 
 typedef struct tMPI_Spinlock
 {
     unsigned int lock; 
-    char padding[64-sizeof(unsigned int)];
+    char padding[TMPI_SIZEOF_X86_CACHE_LINE-sizeof(unsigned int)];
 } tMPI_Spinlock_t;
 
 
@@ -95,9 +96,12 @@ typedef struct tMPI_Spinlock
    as the 486, and gcc on some Linux versions still target 80386 by default). 
   
    We also specifically check for icc, because intrinsics are not always
-   supported there. */
-#if ( (TMPI_GCC_VERSION >= 40100) && defined(__x86_64__) &&  \
-     !defined(__INTEL_COMPILER) ) 
+   supported there.
+
+   llvm has issues with inline assembly and also in 32 bits has support for
+   the gcc intrinsics */
+#if ( ( (TMPI_GCC_VERSION >= 40100) && defined(__x86_64__) &&  \
+      !defined(__INTEL_COMPILER) )  || defined(__llvm__) )
 #include "gcc_intrinsics.h"
 
 #else
@@ -114,7 +118,7 @@ static inline int tMPI_Atomic_add_return(tMPI_Atomic_t *a, int i)
     __asm__ __volatile__("lock ; xaddl %0, %1;"
                          :"=r"(i) :"m"(a->value), "0"(i) : "memory");
     return i + __i;
-}  
+}
 
 static inline int tMPI_Atomic_fetch_add(tMPI_Atomic_t *a, int i)
 {
@@ -125,7 +129,7 @@ static inline int tMPI_Atomic_fetch_add(tMPI_Atomic_t *a, int i)
 
 static inline int tMPI_Atomic_cas(tMPI_Atomic_t *a, int oldval, int newval)
 {
-    unsigned int prev;
+    int prev;
     
     __asm__ __volatile__("lock ; cmpxchgl %1,%2"
                          : "=a"(prev)
index 42bff59464257bd6417020f890990b54abc78470..d4b32015c954e0e741c71b7637c51d51c89a416a 100644 (file)
@@ -196,6 +196,7 @@ gmx_ana_traj_free(gmx_ana_traj_t *d);
 int
 gmx_ana_add_flags(gmx_ana_traj_t *d, unsigned long flags);
 /** Sets the number of reference groups required. */
+GMX_LIBGMX_EXPORT
 int
 gmx_ana_set_nrefgrps(gmx_ana_traj_t *d, int nrefgrps);
 /** Sets the number of analysis groups required. */
@@ -250,6 +251,7 @@ GMX_LIBGMX_EXPORT
 int
 gmx_ana_get_nanagrps(gmx_ana_traj_t *d, int *nanagrps);
 /** Gets the selection object for a reference selection. */
+GMX_LIBGMX_EXPORT
 int
 gmx_ana_get_refsel(gmx_ana_traj_t *d, int i, gmx_ana_selection_t **sel);
 /** Gets the selection object for a reference selection. */
index b6bc9650c6d1d367ee4fe5e426958a1d74bd4924..4d337cf1a3f4a49260a2b6becafa5b6724b62df5 100644 (file)
@@ -71,6 +71,14 @@ typedef struct {
     unsigned excl;  /* The exclusion (interaction) bits */
 } nbnxn_cj_t;
 
+/* In nbnxn_ci_t the integer shift contains the shift in the lower 7 bits.
+ * The upper bits contain information for non-bonded kernel optimization.
+ * Simply calculating LJ and Coulomb for all pairs in a cluster pair is fine.
+ * But three flags can be used to skip interactions, currently only for subc=0
+ * !(shift & NBNXN_CI_DO_LJ(subc))   => we can skip LJ for all pairs
+ * shift & NBNXN_CI_HALF_LJ(subc)    => we can skip LJ for the second half of i
+ * !(shift & NBNXN_CI_DO_COUL(subc)) => we can skip Coulomb for all pairs
+ */
 #define NBNXN_CI_SHIFT          127
 #define NBNXN_CI_DO_LJ(subc)    (1<<(7+3*(subc)))
 #define NBNXN_CI_HALF_LJ(subc)  (1<<(8+3*(subc)))
@@ -79,7 +87,7 @@ typedef struct {
 /* Simple pair-list i-unit */
 typedef struct {
     int ci;             /* i-cluster             */
-    int shift;          /* Shift vector index plus possible flags */
+    int shift;          /* Shift vector index plus possible flags, see above */
     int cj_ind_start;   /* Start index into cj   */
     int cj_ind_end;     /* End index into cj     */
 } nbnxn_ci_t;
index 2b7d315ac258cbad4456b8131c29feae704918e3..107bd6c31804adb7c27386419bbdc14636702b81 100644 (file)
@@ -156,6 +156,28 @@ typedef struct
 }
 energyhistory_t;
 
+typedef struct
+{
+    /* If one uses essential dynamics or flooding on a group of atoms from
+     * more than one molecule, we cannot make this group whole with
+     * do_pbc_first_mtop(). We assume that the ED group has the correct PBC
+     * representation at the beginning of the simulation and keep track
+     * of the shifts to always get it into that representation.
+     * For proper restarts from a checkpoint we store the positions of the
+     * reference group at the time of checkpoint writing */
+    gmx_bool    bFromCpt;       /* Did we start from a checkpoint file?       */
+    int         nED;            /* No. of ED/Flooding data sets, if <1 no ED  */
+    int         *nref;          /* No. of atoms in i'th reference structure   */
+    int         *nav;           /* Same for average structure                 */
+    rvec        **old_sref;     /* Positions of the reference atoms
+                                   at the last time step (with correct PBC
+                                   representation)                            */
+    rvec        **old_sref_p;   /* Pointer to these positions                 */
+    rvec        **old_sav;      /* Same for the average positions             */
+    rvec        **old_sav_p;
+}
+edsamstate_t;
+
 typedef struct
 {
   int           natoms;
@@ -199,6 +221,7 @@ typedef struct
 
   energyhistory_t  enerhist; /* Energy history for statistics           */
   df_history_t  dfhist; /*Free energy history for free energy analysis  */
+  edsamstate_t  edsamstate;    /* Essential dynamics / flooding history */
 
   int           ddp_count; /* The DD partitioning count for this state  */
   int           ddp_count_cg_gl; /* The DD part. count for index_gl     */
index 6c9995f2770bcb528c39216b0d36ac27d83e2e54..410b35e53613db3097fb933c8c9cd913885c52b3 100644 (file)
@@ -183,40 +183,6 @@ static real gmx_software_invsqrt(real x)
 #define INVSQRT_DONE 
 #endif /* gmx_invsqrt */
 
-#ifdef GMX_POWERPC_SQRT
-static real gmx_powerpc_invsqrt(real x)
-{
-  const real  half=0.5;
-  const real  three=3.0;
-  t_convert   result,bit_pattern;
-  unsigned int exp,fract;
-  real        lu;
-  real        y;
-#ifdef GMX_DOUBLE
-  real        y2;
-#endif
-
-  lu = __frsqrte((double)x);
-
-  y=(half*lu*(three-((x*lu)*lu)));
-
-#if (GMX_POWERPC_SQRT==2)
-  /* Extra iteration required */
-  y=(half*y*(three-((x*y)*y)));
-#endif
-
-#ifdef GMX_DOUBLE
-  y2=(half*y*(three-((x*y)*y)));
-
-  return y2;                    /* 10 Flops */
-#else
-  return y;                     /* 5  Flops */
-#endif
-}
-#define gmx_invsqrt(x) gmx_powerpc_invsqrt(x)
-#define INVSQRT_DONE
-#endif /* powerpc_invsqrt */
-
 #ifndef INVSQRT_DONE
 #    ifdef GMX_DOUBLE
 #        ifdef HAVE_RSQRT
index de457e2b1b8b7a0921b3bada649bc0b3556af23b..b57659a9495927e3e7b38ecb9060f5a182907956 100644 (file)
@@ -5,9 +5,8 @@
 # If you only use one shell you can copy that GMXRC.* instead.
 
 
-# only csh/tcsh understand 'set'
-set is_csh = 123
-test "$is_csh" = 123 && goto CSH
+# only csh/tcsh set the variable $shell (note: lower case!)
+test $shell && goto CSH
 
 # if we got here, shell is bsh/bash/zsh/ksh
 # bsh cannot remove part of a variable with %%
index 4853808f5988ee3f49e268b2570fe5aad7dce768..963099586feaef488b35e235075c33d426932881 100644 (file)
@@ -67,7 +67,7 @@ without using the GROMACS libraries you can use the following formats:
 
 <dl>
 <dt>C format 
-<dd><tt>"%5d%5s%5s%5d%8.3f%8.3f%8.3f%8.4f%8.4f%8.4f"</tt>
+<dd><tt>"%5d%-5s%5s%5d%8.3f%8.3f%8.3f%8.4f%8.4f%8.4f"</tt>
 <dt>Fortran format 
 <dd><tt>(i5,2a5,i5,3f8.3,3f8.4)</tt>
 <dt>Pascal format
index b205633cf5fc4eb7d4aed9fb464541d78238120d..a4ace20c75582bcb0164f9095be653b3902f757c 100644 (file)
@@ -43,12 +43,23 @@ add_custom_command(OUTPUT gromacs
     DEPENDS ${GROMACS_HEADERS})
 add_custom_target(gromacs_include_links DEPENDS gromacs)
 
-add_executable(template template.c)
-remove_definitions( -DHAVE_CONFIG_H )
-add_definitions("${PKG_CFLAGS}")
-target_link_libraries(template gmx)
-include_directories("${CMAKE_CURRENT_BINARY_DIR}")
-add_dependencies(template gromacs_include_links)
+option(GMX_BUILD_TEMPLATE "Build gromacs template program" ON)
+mark_as_advanced(GMX_BUILD_TEMPLATE)
+# GMX_PREFER_STATIC_OPENMP=yes is a special case to build binaries
+# to distribute and as the template is not installed it can be
+# ignored.
+# The template is build in a user-like environment, hence we use
+# flags from PKG_CFLAGS. Again GMX_PREFER_STATIC_OPENMP=yes would
+# need special link flags (OpenMP_LINKER_FLAGS), which are not
+# very user-like.
+if (GMX_BUILD_TEMPLATE AND NOT GMX_PREFER_STATIC_OPENMP)
+    add_executable(template template.c)
+    remove_definitions( -DHAVE_CONFIG_H )
+    add_definitions("${PKG_CFLAGS}")
+    target_link_libraries(template gmx)
+    include_directories("${CMAKE_CURRENT_BINARY_DIR}")
+    add_dependencies(template gromacs_include_links)
+endif()
 
 install(FILES README template.c Makefile.pkg
         DESTINATION ${DATA_INSTALL_DIR}/template
index 74e28486f9364727b3cb628f1811a8580ac6052c..528b0bea7997deb8875b02547b5264f8920cd543 100644 (file)
 /* Use the GROMACS software 1/sqrt(x) */
 #cmakedefine GMX_SOFTWARE_INVSQRT
 
-/* Use the PowerPC hardware 1/sqrt(x) */
-#cmakedefine GMX_POWERPC_INVSQRT
-
 /* Use sub-counters */
 #cmakedefine GMX_CYCLE_SUBCOUNTERS
 
index 20be93520ff507525d42883a6b6b2735a07cdc17..d80c198d594c3d5d68f6f676b4b70de2363766bf 100644 (file)
@@ -103,7 +103,7 @@ gmx_ctime_r(const time_t *clock,char *buf, int n);
  * But old code can not read a new entry that is present in the file
  * (but can read a new format when new entries are not present).
  */
-static const int cpt_version = 14;
+static const int cpt_version = 15;
 
 
 const char *est_names[estNR]=
@@ -316,6 +316,39 @@ static void do_cpt_double_err(XDR *xd,const char *desc,double *f,FILE *list)
     }
 }
 
+static void do_cpt_real_err(XDR *xd,const char *desc,real *f)
+{
+    bool_t res=0;
+
+#ifdef GMX_DOUBLE
+    res = xdr_double(xd,f);
+#else
+    res = xdr_float(xd,f);
+#endif
+    if (res == 0)
+    {
+        cp_error();
+    }
+}
+
+static void do_cpt_n_rvecs_err(XDR *xd,const char *desc,int n, rvec f[],FILE *list)
+{
+    int i,j;
+
+    for (i=0; i<n; i++)
+    {
+        for (j=0; j<DIM; j++)
+        {
+            do_cpt_real_err(xd, desc, &f[i][j]);
+        }
+    }
+
+    if (list)
+    {
+        pr_rvecs(list,0,desc,f,n);
+    }
+}
+
 /* If nval >= 0, nval is used; on read this should match the passed value.
  * If nval n<0, *nptr is used; on read the value is stored in nptr
  */
@@ -771,6 +804,7 @@ static void do_cpt_header(XDR *xd,gmx_bool bRead,int *file_version,
                           int *natoms,int *ngtc, int *nnhpres, int *nhchainlength,
                           int *nlambda, int *flags_state,
                           int *flags_eks,int *flags_enh, int *flags_dfh,
+                          int *nED,
                           FILE *list)
 {
     bool_t res=0;
@@ -909,6 +943,15 @@ static void do_cpt_header(XDR *xd,gmx_bool bRead,int *file_version,
     } else {
         *flags_dfh = 0;
     }
+
+    if (*file_version >= 15)
+    {
+        do_cpt_int_err(xd,"ED data sets",nED,list);
+    }
+    else
+    {
+        *nED = 0;
+    }
 }
 
 static int do_cpt_footer(XDR *xd,gmx_bool bRead,int file_version)
@@ -1179,6 +1222,71 @@ static int do_cpt_df_hist(XDR *xd,gmx_bool bRead,int fflags,df_history_t *dfhist
     return ret;
 }
 
+
+/* This function stores the last whole configuration of the reference and
+ * average structure in the .cpt file
+ */
+static int do_cpt_EDstate(XDR *xd,gmx_bool bRead,
+        edsamstate_t *EDstate, FILE *list)
+{
+    int i,j;
+    int ret=0;
+    char buf[STRLEN];
+
+
+    EDstate->bFromCpt = bRead;
+
+    if (EDstate->nED <= 0)
+    {
+        return ret;
+    }
+
+    /* When reading, init_edsam has not been called yet,
+     * so we have to allocate memory first. */
+    if (bRead)
+    {
+        snew(EDstate->nref    , EDstate->nED);
+        snew(EDstate->old_sref, EDstate->nED);
+        snew(EDstate->nav     , EDstate->nED);
+        snew(EDstate->old_sav , EDstate->nED);
+    }
+
+    /* Read/write the last whole conformation of SREF and SAV for each ED dataset (usually only one) */
+    for (i=0; i< EDstate->nED; i++)
+    {
+        /* Reference structure SREF */
+        sprintf(buf, "ED%d # of atoms in reference structure", i+1);
+        do_cpt_int_err(xd, buf, &EDstate->nref[i],list);
+        sprintf(buf, "ED%d x_ref", i+1);
+        if (bRead)
+        {
+            snew(EDstate->old_sref[i], EDstate->nref[i]);
+            do_cpt_n_rvecs_err(xd, buf, EDstate->nref[i], EDstate->old_sref[i], list);
+        }
+        else
+        {
+            do_cpt_n_rvecs_err(xd, buf, EDstate->nref[i], EDstate->old_sref_p[i], list);
+        }
+
+        /* Average structure SAV */
+        sprintf(buf, "ED%d # of atoms in average structure", i+1);
+        do_cpt_int_err(xd, buf, &EDstate->nav[i] ,list);
+        sprintf(buf, "ED%d x_av", i+1);
+        if (bRead)
+        {
+            snew(EDstate->old_sav[i], EDstate->nav[i]);
+            do_cpt_n_rvecs_err(xd, buf, EDstate->nav[i], EDstate->old_sav[i], list);
+        }
+        else
+        {
+            do_cpt_n_rvecs_err(xd, buf, EDstate->nav[i], EDstate->old_sav_p[i], list);
+        }
+    }
+
+    return ret;
+}
+
+
 static int do_cpt_files(XDR *xd, gmx_bool bRead, 
                         gmx_file_position_t **p_outputfiles, int *nfiles, 
                         FILE *list, int file_version)
@@ -1418,6 +1526,7 @@ void write_checkpoint(const char *fn,gmx_bool bNumberAndKeep,
                   DOMAINDECOMP(cr) ? cr->dd->nc : NULL,&npmenodes,
                   &state->natoms,&state->ngtc,&state->nnhpres,
                   &state->nhchainlength,&(state->dfhist.nlambda),&state->flags,&flags_eks,&flags_enh,&flags_dfh,
+                  &state->edsamstate.nED,
                   NULL);
     
     sfree(version);
@@ -1430,6 +1539,7 @@ void write_checkpoint(const char *fn,gmx_bool bNumberAndKeep,
        (do_cpt_ekinstate(gmx_fio_getxdr(fp),FALSE,flags_eks,&state->ekinstate,NULL) < 0)||
        (do_cpt_enerhist(gmx_fio_getxdr(fp),FALSE,flags_enh,&state->enerhist,NULL) < 0)  ||
        (do_cpt_df_hist(gmx_fio_getxdr(fp),FALSE,flags_dfh,&state->dfhist,NULL) < 0)  ||
+       (do_cpt_EDstate(gmx_fio_getxdr(fp),FALSE,&state->edsamstate,NULL) < 0)      ||
        (do_cpt_files(gmx_fio_getxdr(fp),FALSE,&outputfiles,&noutputfiles,NULL,
                      file_version) < 0))
     {
@@ -1673,7 +1783,8 @@ static void read_checkpoint(const char *fn,FILE **pfplog,
                   &eIntegrator_f,simulation_part,step,t,
                   &nppnodes_f,dd_nc_f,&npmenodes_f,
                   &natoms,&ngtc,&nnhpres,&nhchainlength,&nlambda,
-                  &fflags,&flags_eks,&flags_enh,&flags_dfh,NULL);
+                  &fflags,&flags_eks,&flags_enh,&flags_dfh,
+                  &state->edsamstate.nED,NULL);
 
     if (bAppendOutputFiles &&
         file_version >= 13 && double_prec != GMX_CPT_BUILD_DP)
@@ -1862,6 +1973,12 @@ static void read_checkpoint(const char *fn,FILE **pfplog,
         cp_error();
     }
 
+    ret = do_cpt_EDstate(gmx_fio_getxdr(fp),TRUE,&state->edsamstate,NULL);
+    if (ret)
+    {
+        cp_error();
+    }
+
     if (file_version < 6)
     {
         const char *warn="Reading checkpoint file in old format, assuming that the run that generated this file started at step 0, if this is not the case the averages stored in the energy file will be incorrect.";
@@ -2098,7 +2215,8 @@ static void read_checkpoint_data(t_fileio *fp,int *simulation_part,
                   &version,&btime,&buser,&bhost,&double_prec,&fprog,&ftime,
                   &eIntegrator,simulation_part,step,t,&nppnodes,dd_nc,&npme,
                   &state->natoms,&state->ngtc,&state->nnhpres,&state->nhchainlength,
-                  &(state->dfhist.nlambda),&state->flags,&flags_eks,&flags_enh,&flags_dfh,NULL);
+                  &(state->dfhist.nlambda),&state->flags,&flags_eks,&flags_enh,&flags_dfh,
+                  &state->edsamstate.nED,NULL);
     ret =
         do_cpt_state(gmx_fio_getxdr(fp),TRUE,state->flags,state,bReadRNG,NULL);
     if (ret)
@@ -2124,6 +2242,12 @@ static void read_checkpoint_data(t_fileio *fp,int *simulation_part,
         cp_error();
     }
 
+    ret = do_cpt_EDstate(gmx_fio_getxdr(fp),TRUE,&state->edsamstate,NULL);
+    if (ret)
+    {
+        cp_error();
+    }
+
     ret = do_cpt_files(gmx_fio_getxdr(fp),TRUE,
                        outputfiles != NULL ? outputfiles : &files_loc,
                        outputfiles != NULL ? nfiles : &nfiles_loc,
@@ -2234,7 +2358,7 @@ void list_checkpoint(const char *fn,FILE *out)
                   &eIntegrator,&simulation_part,&step,&t,&nppnodes,dd_nc,&npme,
                   &state.natoms,&state.ngtc,&state.nnhpres,&state.nhchainlength,
                   &(state.dfhist.nlambda),&state.flags,
-                  &flags_eks,&flags_enh,&flags_dfh,out);
+                  &flags_eks,&flags_enh,&flags_dfh,&state.edsamstate.nED,out);
     ret = do_cpt_state(gmx_fio_getxdr(fp),TRUE,state.flags,&state,TRUE,out);
     if (ret)
     {
@@ -2255,6 +2379,12 @@ void list_checkpoint(const char *fn,FILE *out)
         ret = do_cpt_df_hist(gmx_fio_getxdr(fp),TRUE,
                              flags_dfh,&state.dfhist,out);
     }
+
+    if (ret == 0)
+    {
+        ret = do_cpt_EDstate(gmx_fio_getxdr(fp),TRUE,&state.edsamstate,out);
+    }
+
     if (ret == 0)
     {
                do_cpt_files(gmx_fio_getxdr(fp),TRUE,&outputfiles,&nfiles,out,file_version);
index 4304807723630695a4f010561d7b5b9c5b405afe..bf7c1302a2a17b9a14649174699b90aa1c72f945 100644 (file)
 #include <unistd.h>
 #endif
 
+#include "gmx_cpuid.h"
 
 
 
-#include "gmx_cpuid.h"
-
+/* For convenience, and to enable configure-time invocation, we keep all architectures
+ * in a single file, but to avoid repeated ifdefs we set the overall architecture here.
+ */
+#if defined (__i386__) || defined (__x86_64__) || defined (_M_IX86) || defined (_M_X64)
+#    define GMX_CPUID_X86
+#endif
 
 /* Global constant character strings corresponding to our enumerated types */
 const char *
@@ -209,10 +214,7 @@ compiled_acc = GMX_CPUID_ACCELERATION_NONE;
 #endif
 
 
-/* Currently CPUID is only supported (1) if we can use an instruction on MSVC, or (2)
- * if the compiler handles GNU-style inline assembly.
- */
-#if defined (__i386__) || defined (__x86_64__) || defined (_M_IX86) || defined (_M_X64)
+#ifdef GMX_CPUID_X86
 
 /* Execute CPUID on x86 class CPUs. level sets function to exec, and the
  * contents of register output is returned. See Intel/AMD docs for details.
@@ -231,6 +233,10 @@ execute_x86cpuid(unsigned int   level,
 {
     int rc = 0;
 
+    /* Currently CPUID is only supported (1) if we can use an instruction on MSVC, or (2)
+     * if the compiler handles GNU-style inline assembly.
+     */
+
 #if (defined _MSC_VER)
     int CPUInfo[4];
 
@@ -283,7 +289,6 @@ execute_x86cpuid(unsigned int   level,
 #endif
     return rc;
 }
-#endif /* architecture is x86 */
 
 
 /* Identify CPU features common to Intel & AMD - mainly brand string,
@@ -465,6 +470,9 @@ cpuid_check_intel_x86(gmx_cpuid_t                cpuid)
     }
     return 0;
 }
+#endif /* GMX_CPUID_X86 */
+
+
 
 /* Try to find the vendor of the current CPU, so we know what specific
  * detection routine to call.
@@ -480,6 +488,7 @@ cpuid_check_vendor(void)
     /* Set default first */
     vendor = GMX_CPUID_VENDOR_UNKNOWN;
 
+#ifdef GMX_CPUID_X86
     execute_x86cpuid(0x0,0,&eax,&ebx,&ecx,&edx);
 
     memcpy(vendorstring,&ebx,4);
@@ -495,7 +504,10 @@ cpuid_check_vendor(void)
             vendor = i;
         }
     }
-
+#else
+    vendor = GMX_CPUID_VENDOR_UNKNOWN;
+#endif
+    
     return vendor;
 }
 
@@ -521,12 +533,14 @@ gmx_cpuid_init               (gmx_cpuid_t *              pcpuid)
 
     switch(cpuid->vendor)
     {
+#ifdef GMX_CPUID_X86
         case GMX_CPUID_VENDOR_INTEL:
             cpuid_check_intel_x86(cpuid);
             break;
         case GMX_CPUID_VENDOR_AMD:
             cpuid_check_amd_x86(cpuid);
             break;
+#endif
         default:
             /* Could not find vendor */
             strncpy(cpuid->brand,"Unknown CPU brand",GMX_CPUID_BRAND_MAXLEN);
@@ -706,7 +720,7 @@ gmx_cpuid_acceleration_check(gmx_cpuid_t   cpuid,
 enum gmx_cpuid_x86_smt
 gmx_cpuid_x86_smt(gmx_cpuid_t cpuid)
 {
-
+#ifdef GMX_CPUID_X86
 #if (defined HAVE_SCHED_H && defined HAVE_SCHED_SETAFFINITY && defined HAVE_SYSCONF && defined __linux__)
     int            i;
     int            nproc;
@@ -787,6 +801,10 @@ gmx_cpuid_x86_smt(gmx_cpuid_t cpuid)
         return GMX_CPUID_X86_SMT_CANNOTDETECT;
     }
 #endif
+#else 
+    /* not x86 */
+    return GMX_CPUID_X86_SMT_CANNOTDETECT;
+#endif
 }
 
 
index 1ad107dfdbe9c174926f5bc66ed9325b8999b468..cc749674305e33aa0a436bb2b08a27cf967025d1 100644 (file)
@@ -55,5 +55,8 @@ CUDA_ADD_LIBRARY(gpu_utils STATIC ${GPU_UTILS_SOURCES}
                  OPTIONS ${_os_def}
                  RELWITHDEBINFO -g
                  DEBUG -g -D_DEBUG_=1 )
+#Because this is a static library linked into the (potential) shared library
+#it should have the export of the shared library.
+SET_TARGET_PROPERTIES(gpu_utils PROPERTIES DEFINE_SYMBOL "gmx_EXPORTS" )
 
 CUDA_BUILD_CLEAN_TARGET()
index 3b4227907e411d21ee86beb2203b98e916dc8e9b..0bc0b0d3cc71aff5d945b0454116d8bc5628e510 100644 (file)
@@ -6,7 +6,7 @@ Description: Gromacs default lib
 URL: http://www.gromacs.org
 Version: @PROJECT_VERSION@
 Requires:
-Libs.private: @CMAKE_THREAD_LIBS_INIT@ @PKG_DL_LIBS@
+Libs.private: @CMAKE_THREAD_LIBS_INIT@ @PKG_DL_LIBS@ @OpenMP_LINKER_FLAGS@
 Libs: -L${libdir} -lgmx@GMX_LIBS_SUFFIX@ -lm
 Cflags: -I${includedir} @PKG_CFLAGS@
 
index ace7940aa5fc761e8aff0d773e076a787c232b05..3cbf07e6aa6e0d82d288ab37c1fd7057edfea37d 100644 (file)
@@ -331,7 +331,7 @@ void tMPI_Mult_recv(tMPI_Comm comm, struct coll_env *cev, int rank,
                     /* We tried again, and this time there was a copied buffer. 
                        We use that, and indicate that we're not reading from the
                        regular buf. This case should be pretty rare.  */
-                    tMPI_Atomic_fetch_add(&(cev->met[rank].buf_readcount),-1);
+                    tMPI_Atomic_add_return(&(cev->met[rank].buf_readcount),-1);
                     tMPI_Atomic_memory_barrier_acq();
                     srcbuf=try_again_srcbuf;
                 }
@@ -354,7 +354,7 @@ void tMPI_Mult_recv(tMPI_Comm comm, struct coll_env *cev, int rank,
         {
             /* we decrement the read count; potentially releasing the buffer. */
             tMPI_Atomic_memory_barrier_rel();
-            tMPI_Atomic_fetch_add( &(cev->met[rank].buf_readcount), -1);
+            tMPI_Atomic_add_return( &(cev->met[rank].buf_readcount), -1);
         }
 #endif
     }
@@ -481,7 +481,7 @@ void tMPI_Wait_for_others(struct coll_env *cev, int myrank)
     else
     {
         /* wait until everybody else is done copying the original buffer. 
-           We use fetch_add because we want to be sure of coherency.
+           We use atomic add-return because we want to be sure of coherency.
            This wait is bound to be very short (otherwise it wouldn't 
            be double-buffering) so we always spin here. */
         /*tMPI_Atomic_memory_barrier_rel();*/
@@ -490,7 +490,7 @@ void tMPI_Wait_for_others(struct coll_env *cev, int myrank)
                                     -100000))
 #endif
 #if 0
-        while (tMPI_Atomic_fetch_add( &(cev->met[myrank].buf_readcount), 0) 
+        while (tMPI_Atomic_add_return( &(cev->met[myrank].buf_readcount), 0) 
                != 0)
 #endif
 #if 1
index a25c6db243452b4dfb844f14f57cc380e18b7d97..bee468ceea3fe522f374dbf7a0f633609eb369b8 100644 (file)
@@ -137,7 +137,7 @@ void* tMPI_Once_wait(tMPI_Comm comm, void* (*function)(void*), void *param,
 
         tMPI_Atomic_memory_barrier_rel();
         /* signal that we're done */
-        tMPI_Atomic_fetch_add(&(cev->coll.current_sync), 1);
+        tMPI_Atomic_add_return(&(cev->coll.current_sync), 1);
         /* we need to keep being in sync */
         csync->syncs++;
     }
index 7e59a300baabf3d351e7f6e09d9416b838a86433..ee3a906a0ff296afd8647136880479a4c8afe02e 100644 (file)
@@ -463,7 +463,7 @@ void tMPI_Start_threads(tmpi_bool main_returns, int N,
                 tMPI_Error(TMPI_COMM_WORLD, TMPI_ERR_INIT);
             }
         }
-        /* the main thread now also runs start_fn if we don't want
+        /* the main thread also runs start_fn if we don't want
            it to return */
         if (!main_returns)
             tMPI_Thread_starter((void*)&(threads[0]));
@@ -480,12 +480,11 @@ int tMPI_Init(int *argc, char ***argv,
     tMPI_Trace_print("tMPI_Init(%p, %p, %p)", argc, argv, start_function);
 #endif
 
-
     if (TMPI_COMM_WORLD==0) /* we're the main process */
     {
         int N=0;
         tMPI_Get_N(argc, argv, "-nt", &N);
-        tMPI_Start_threads(FALSE, N, TMPI_AFFINITY_ALL_CORES, argc, argv, 
+        tMPI_Start_threads(TRUE, N, TMPI_AFFINITY_ALL_CORES, argc, argv, 
                            NULL, NULL, start_function);
     }
     else
index ad1e79cb398e567fcf7a00194dabcef0a3c8fa90..687080c3d1387e4b92bc2094ba49b4f0ceb1ddfb 100644 (file)
@@ -268,9 +268,10 @@ static char *search_resrename(int nrr,rtprename_t *rr,
         {
             nn = rr[i].main;
         }
+        
         if (nn[0] == '-')
         {
-            gmx_fatal(FARGS,"In the chosen force field there is no residue type for '%s'%s",name,bStart ? " as a starting terminus" : (bEnd ? " as an ending terminus" : ""));
+            gmx_fatal(FARGS,"In the chosen force field there is no residue type for '%s'%s",name,bStart ? ( bEnd ? " as a standalone (starting & ending) residue" : " as a starting terminus") : (bEnd ? " as an ending terminus" : ""));
         }
     }
 
index 86878aa014e6ba08b1461e90c8d637d0e0404324..2b3a7c2b93ff81c31d2b1b8c302bef395a5cf062 100644 (file)
@@ -729,6 +729,17 @@ static void print_allswitchind(FILE *fplog,int n,int *ind,int *pind, int *allswa
     }
     fprintf(fplog,"\n");
 
+    /* the "Order After Exchange" is the state label corresponding to the configuration that
+       started in state listed in order, i.e.
+
+       3 0 1 2
+
+       means that the:
+       configuration starting in simulation 3 is now in simulation 0,
+       configuration starting in simulation 0 is now in simulation 1,
+       configuration starting in simulation 1 is now in simulation 2,
+       configuration starting in simulation 2 is now in simulation 3
+     */
     fprintf(fplog,"Order After Exchange: ");
     for (i=0;i<n;i++)
     {
@@ -797,6 +808,7 @@ static real calc_delta(FILE *fplog, gmx_bool bPrint, struct gmx_repl_ex *re, int
                  =  [H_b(x_a) + H_a(x_b)] - [H_b(x_b) + H_a(x_a)]
                  =  [H_b(x_a) - H_a(x_a)] + [H_a(x_b) - H_b(x_b)]
                  =  de[b][a] + de[a][b] */
+
         /* permuted:
            ediff =  E_new - E_old
                  =  [H_bp(x_a) + H_ap(x_b)] - [H_bp(x_b) + H_ap(x_a)]
@@ -804,6 +816,16 @@ static real calc_delta(FILE *fplog, gmx_bool bPrint, struct gmx_repl_ex *re, int
                  =  [H_bp(x_a) - H_a(x_a) + H_a(x_a) - H_ap(x_a)] + [H_ap(x_b) - H_b(x_b) + H_b(x_b) - H_bp(x_b)]
                  =  [H_bp(x_a) - H_a(x_a)] - [H_ap(x_a) - H_a(x_a)] + [H_ap(x_b) - H_b(x_b)] - H_bp(x_b) - H_b(x_b)]
                  =  (de[bp][a] - de[ap][a]) + (de[ap][b] - de[bp][b])    */
+        /* but, in the current code implementation, we flip configurations, not indices . . .
+           So let's examine that.
+                 =  [H_b(x_ap) - H_a(x_a)] - [H_a(x_ap) - H_a(x_a)] + [H_a(x_bp) - H_b(x_b)] - H_b(x_bp) - H_b(x_b)]
+                 =  [H_b(x_ap) - H_a(x_ap)]  + [H_a(x_bp) - H_b(x_pb)]
+                 = (de[b][ap] - de[a][ap]) + (de[a][bp] - de[b][bp]
+                 So, if we exchange b<=> bp and a<=> ap, we return to the same result.
+                 So the simple solution is to flip the
+                 position of perturbed and original indices in the tests.
+        */
+
         ediff = (de[bp][a] - de[ap][a]) + (de[ap][b] - de[bp][b]);
         delta = ediff*beta[a]; /* assume all same temperature in this case */
         break;
@@ -869,7 +891,7 @@ test_for_replica_exchange(FILE *fplog,
     gmx_bool bPrint,bMultiEx;
     gmx_bool *bEx = re->bEx;
     real *prob = re->prob;
-    int *pind = re->destinations;
+    int *pind = re->destinations; /* permuted index */
     gmx_bool bEpot=FALSE;
     gmx_bool bDLambda=FALSE;
     gmx_bool bVol=FALSE;
@@ -955,24 +977,32 @@ test_for_replica_exchange(FILE *fplog,
         for (i=0;i<re->nex;i++)
         {
             /* randomly select a pair  */
-            /* find out which state it is from, and what label that state currently has */
+            /* in theory, could reduce this by identifying only which switches had a nonneglibible
+               probability of occurring (log p > -100) and only operate on those switches */
+            /* find out which state it is from, and what label that state currently has. Likely
+               more work that useful. */
             i0 = (int)(re->nrepl*rando(&(re->seed)));
             i1 = (int)(re->nrepl*rando(&(re->seed)));
             if (i0==i1)
             {
                 i--;
-                continue;  /* got the same pair, back up and do it again */
+                continue;  /* self-exchange, back up and do it again */
             }
 
-            a = re->ind[i0];
+            a = re->ind[i0]; /* what are the indices of these states? */
             b = re->ind[i1];
             ap = pind[i0];
             bp = pind[i1];
 
             bPrint = FALSE; /* too noisy */
-            delta = calc_delta(fplog,bPrint,re,a,b,ap,bp); /* calculate the energy difference */
+            /* calculate the energy difference */
+            /* if the code changes to flip the STATES, rather than the configurations,
+               use the commented version of the code */
+            /* delta = calc_delta(fplog,bPrint,re,a,b,ap,bp); */
+            delta = calc_delta(fplog,bPrint,re,ap,bp,a,b);
 
-            /* we actually only use the first space, since there are actually many switches between pairs. */
+            /* we actually only use the first space in the prob and bEx array,
+               since there are actually many switches between pairs. */
 
             if (delta <= 0)
             {
@@ -1067,6 +1097,7 @@ test_for_replica_exchange(FILE *fplog,
         re->nmoves[re->ind[i]][pind[i]] +=1;
         re->nmoves[pind[i]][re->ind[i]] +=1;
     }
+    fflush(fplog); /* make sure we can see what the last exchange was */
 }
 
 static void write_debug_x(t_state *state)
@@ -1306,6 +1337,7 @@ gmx_bool replica_exchange(FILE *fplog,const t_commrec *cr,struct gmx_repl_ex *re
             /* There will be only one swap cycle with standard replica
              * exchange, but there may be multiple swap cycles if we
              * allow multiple swaps. */
+
             for (j = 0; j < maxswap; j++)
             {
                 exchange_partner = re->order[replica_id][j];
index 37e9854baa56eefe538113d0fa2179e5c61de49a..be3ed6b310c9a3a60ccdd5bdd9a496c62ef6936d 100644 (file)
@@ -1043,23 +1043,32 @@ static void set_cpu_affinity(FILE *fplog,
         }
         else
         {
-            /* check if some threads failed to set their affinities */
+            /* check & warn if some threads failed to set their affinities */
             if (nth_affinity_set != nthread_local)
             {
-                char sbuf[STRLEN];
-                sbuf[0] = '\0';
+                char sbuf1[STRLEN], sbuf2[STRLEN];
+
+                /* sbuf1 contains rank info, while sbuf2 OpenMP thread info */
+                sbuf1[0] = sbuf2[0] = '\0';
 #ifdef GMX_MPI
 #ifdef GMX_THREAD_MPI
-                sprintf(sbuf, "In thread-MPI thread #%d", cr->nodeid);
+                sprintf(sbuf1, "In thread-MPI thread #%d: ", cr->nodeid);
 #else /* GMX_LIB_MPI */
+                sprintf(sbuf1, "In MPI process #%d: ", cr->nodeid);
 #endif
-                sprintf(sbuf, "In MPI process #%d", cr->nodeid);
 #endif /* GMX_MPI */
+
+                if (nthread_local > 1)
+                {
+                    sprintf(sbuf2, "of %d/%d thread%s ",
+                            nthread_local - nth_affinity_set, nthread_local,
+                            (nthread_local - nth_affinity_set) > 1 ? "s" : "");
+                }
+
                 md_print_warn(NULL, fplog,
-                              "%s%d/%d thread%s failed to set their affinities. "
-                              "This can cause performance degradation!",
-                              sbuf, nthread_local - nth_affinity_set, nthread_local,
-                              (nthread_local - nth_affinity_set) > 1 ? "s" : "");
+                              "NOTE: %sAffinity setting %sfailed.\n"
+                              "      This can cause performance degradation!",
+                              sbuf1, sbuf2);
             }
         }
     }
index 54f236e0563cac6154acef40b3bf730f2bd60bf6..150bbd2e70f52c4d7df643df351b2b2aa6cace4f 100644 (file)
@@ -66,7 +66,14 @@ if(GMX_BUILD_OWN_FFTW)
     # disabling GMX_BUILD_OWN_FFTW changes dependencies correctly.
     add_dependencies(md gmxfftw)
 endif()
-set_target_properties(md PROPERTIES OUTPUT_NAME "md${GMX_LIBS_SUFFIX}" SOVERSION ${SOVERSION} INSTALL_NAME_DIR "${LIB_INSTALL_DIR}"
+option(GMX_PREFIX_LIBMD "Change install name of libmd to libgmxmd to avoid collision with BSD's/Martin Hinner's libmd, which is used in X11 and zfs" OFF)
+mark_as_advanced(GMX_PREFIX_LIBMD)
+if (GMX_PREFIX_LIBMD)
+  set(MD_PREFIX "gmx")
+else()
+  set(MD_PREFIX)
+endif()
+set_target_properties(md PROPERTIES OUTPUT_NAME "${MD_PREFIX}md${GMX_LIBS_SUFFIX}" SOVERSION ${SOVERSION} INSTALL_NAME_DIR "${LIB_INSTALL_DIR}"
     COMPILE_FLAGS "${OpenMP_C_FLAGS}")
 
 install(TARGETS md DESTINATION ${LIB_INSTALL_DIR} COMPONENT libraries)
@@ -74,5 +81,5 @@ install(TARGETS md DESTINATION ${LIB_INSTALL_DIR} COMPONENT libraries)
 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libmd.pc.cmakein ${CMAKE_CURRENT_BINARY_DIR}/libmd.pc @ONLY)
 install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libmd.pc
         DESTINATION ${LIB_INSTALL_DIR}/pkgconfig
-        RENAME "libmd${GMX_LIBS_SUFFIX}.pc"
+        RENAME "lib${MD_PREFIX}md${GMX_LIBS_SUFFIX}.pc"
         COMPONENT development)
index eb92debad552515233485d1db3256cedd9b1849c..2c08a97042854522f2b15a96e8141e081e392ea7 100644 (file)
@@ -1252,9 +1252,9 @@ gmx_constr_t init_constraints(FILE *fplog,
     /* Initialize the essential dynamics sampling.
      * Put the pointer to the ED struct in constr */
     constr->ed = ed;
-    if (ed != NULL
+    if (ed != NULL || state->edsamstate.nED > 0)
     {
-        init_edsam(mtop,ir,cr,ed,state->x,state->box);
+        init_edsam(mtop,ir,cr,ed,state->x,state->box,&state->edsamstate);
     }
     
     constr->warn_mtop = mtop;
index 80f2cd63349583311d6a585ef37aca94ff1bdca1..56b173861524e4211fe5da87e3f02957875fd44f 100644 (file)
@@ -138,9 +138,11 @@ typedef struct gmx_edx
                                    * with respect to the collective
                                    * anrs[0...nr-1] array                     */
     rvec          *x;             /* positions for this structure             */
-    rvec          *x_old;         /* used to keep track of the shift vectors
-                                     such that the ED molecule can always be
-                                     made whole in the parallel case          */
+    rvec          *x_old;         /* Last positions which have the correct PBC
+                                     representation of the ED group. In
+                                     combination with keeping track of the
+                                     shift vectors, the ED group can always
+                                     be made whole                            */
     real          *m;             /* masses                                   */
     real          mtot;           /* total mass (only used in sref)           */
     real          *sqrtm;         /* sqrt of the masses used for mass-
@@ -186,7 +188,6 @@ typedef struct gmx_edsam
     FILE          *edo;           /* output file pointer                  */
     t_edpar       *edpar;
     gmx_bool      bFirst;
-    gmx_bool      bStartFromCpt;
 } t_gmx_edsam;
 
 
@@ -238,7 +239,9 @@ static real projectx(t_edpar *edi, rvec *xcoll, rvec *vec)
 
 
     for (i=0; i<edi->sav.nr; i++)
+    {
         proj += edi->sav.sqrtm[i]*iprod(vec[i], xcoll[i]);
+    }
 
     return proj;
 }
@@ -254,7 +257,9 @@ static void rad_project(t_edpar *edi, rvec *x, t_eigvec *vec, t_commrec *cr)
 
     /* Subtract average positions */
     for (i = 0; i < edi->sav.nr; i++)
+    {
         rvec_dec(x[i], edi->sav.x[i]);
+    }
 
     for (i = 0; i < vec->neig; i++)
     {
@@ -265,7 +270,9 @@ static void rad_project(t_edpar *edi, rvec *x, t_eigvec *vec, t_commrec *cr)
 
     /* Add average positions */
     for (i = 0; i < edi->sav.nr; i++)
+    {
         rvec_inc(x[i], edi->sav.x[i]);
+    }
 }
 
 
@@ -283,14 +290,20 @@ static void project_to_eigvectors(rvec       *x,    /* The positions to project
 
     /* Subtract average positions */
     for (i=0; i<edi->sav.nr; i++)
+    {
         rvec_dec(x[i], edi->sav.x[i]);
+    }
 
     for (i=0; i<vec->neig; i++)
+    {
         vec->xproj[i] = projectx(edi, x, vec->vec[i]);
+    }
 
     /* Add average positions */
     for (i=0; i<edi->sav.nr; i++)
+    {
         rvec_inc(x[i], edi->sav.x[i]);
+    }
 }
 
 
@@ -316,7 +329,9 @@ static real calc_radius(t_eigvec *vec)
 
 
     for (i=0; i<vec->neig; i++)
+    {
         rad += pow((vec->refproj[i]-vec->xproj[i]),2);
+    }
 
     return rad=sqrt(rad);
 }
@@ -345,11 +360,13 @@ static void dump_xcoll(t_edpar *edi, struct t_do_edsam *buf, t_commrec *cr,
     fp = fopen(fn, "w");
 
     for (i=0; i<edi->sav.nr; i++)
+    {
         fprintf(fp, "%d %9.5f %9.5f %9.5f   %d %d %d   %d %d %d\n",
                 edi->sav.anrs[i]+1,
                 xcoll[i][XX]  , xcoll[i][YY]  , xcoll[i][ZZ],
                 shifts[i][XX] , shifts[i][YY] , shifts[i][ZZ],
                 eshifts[i][XX], eshifts[i][YY], eshifts[i][ZZ]);
+    }
 
     fclose(fp);
 }
@@ -363,16 +380,22 @@ static void dump_edi_positions(FILE *out, struct gmx_edx *s, const char name[])
 
     fprintf(out, "#%s positions:\n%d\n", name, s->nr);
     if (s->nr == 0)
+    {
         return;
+    }
 
     fprintf(out, "#index, x, y, z");
     if (s->sqrtm)
+    {
         fprintf(out, ", sqrt(m)");
+    }
     for (i=0; i<s->nr; i++)
     {
         fprintf(out, "\n%6d  %11.6f %11.6f %11.6f",s->anrs[i], s->x[i][XX], s->x[i][YY], s->x[i][ZZ]);
         if (s->sqrtm)
+        {
             fprintf(out,"%9.3f",s->sqrtm[i]);
+        }
     }
     fprintf(out, "\n");
 }
@@ -392,7 +415,9 @@ static void dump_edi_eigenvecs(FILE *out, t_eigvec *ev,
         fprintf(out, "EV %4d\ncomponents %d\nstepsize %f\nxproj %f\nfproj %f\nrefproj %f\nradius %f\nComponents:\n",
                 ev->ieig[i], length, ev->stpsz[i], ev->xproj[i], ev->fproj[i], ev->refproj[i], ev->radius);
         for (j=0; j<length; j++)
+        {
             fprintf(out, "%11.6f %11.6f %11.6f\n", ev->vec[i][j][XX], ev->vec[i][j][YY], ev->vec[i][j][ZZ]);
+        }
     }
 }
 
@@ -457,7 +482,9 @@ static void dump_rvec(FILE *out, int dim, rvec *x)
 
 
     for (i=0; i<dim; i++)
+    {
         fprintf(out,"%4d   %f %f %f\n",i,x[i][XX],x[i][YY],x[i][ZZ]);
+    }
 }
 
 
@@ -471,7 +498,9 @@ static void dump_mat(FILE* out, int dim, double** mat)
     for (i=0;i<dim;i++)
     {
         for (j=0;j<dim;j++)
+        {
             fprintf(out,"%f ",mat[i][j]);
+        }
         fprintf(out,"\n");
     }
 }
@@ -496,7 +525,9 @@ static void do_edfit(int natoms,rvec *xp,rvec *x,matrix R,t_edpar *edi)
     gmx_bool bFirst;
 
     if(edi->buf->do_edfit != NULL)
+    {
         bFirst = FALSE;
+    }
     else
     {
         bFirst = TRUE;
@@ -543,7 +574,9 @@ static void do_edfit(int natoms,rvec *xp,rvec *x,matrix R,t_edpar *edi)
     /* construct loc->omega */
     /* loc->omega is symmetric -> loc->omega==loc->omega' */
     for(r=0;(r<6);r++)
+    {
         for(c=0;(c<=r);c++)
+        {
             if ((r>=3) && (c<3))
             {
                 loc->omega[r][c]=u[r-3][c];
@@ -554,6 +587,8 @@ static void do_edfit(int natoms,rvec *xp,rvec *x,matrix R,t_edpar *edi)
                 loc->omega[r][c]=0;
                 loc->omega[c][r]=0;
             }
+        }
+    }
 
     /* determine h and k */
 #ifdef DEBUG
@@ -561,13 +596,17 @@ static void do_edfit(int natoms,rvec *xp,rvec *x,matrix R,t_edpar *edi)
         int i;
         dump_mat(stderr,2*DIM,loc->omega);
         for (i=0; i<6; i++)
+        {
             fprintf(stderr,"d[%d] = %f\n",i,d[i]);
+        }
     }
 #endif
     jacobi(loc->omega,6,d,loc->om,&irot);
 
     if (irot==0)
+    {
         fprintf(stderr,"IROT=0\n");
+    }
 
     index=0; /* For the compiler only */
 
@@ -575,11 +614,13 @@ static void do_edfit(int natoms,rvec *xp,rvec *x,matrix R,t_edpar *edi)
     {
         max_d=-1000;
         for(i=0;(i<6);i++)
+        {
             if (d[i]>max_d)
             {
                 max_d=d[i];
                 index=i;
             }
+        }
         d[index]=-10000;
         for(i=0;(i<3);i++)
         {
@@ -590,16 +631,26 @@ static void do_edfit(int natoms,rvec *xp,rvec *x,matrix R,t_edpar *edi)
 
     /* determine R */
     for(c=0;(c<3);c++)
+    {
         for(r=0;(r<3);r++)
+        {
             R[c][r]=vk[0][r]*vh[0][c]+
-            vk[1][r]*vh[1][c]+
-            vk[2][r]*vh[2][c];
+                    vk[1][r]*vh[1][c]+
+                    vk[2][r]*vh[2][c];
+        }
+    }
     if (det(R) < 0)
+    {
         for(c=0;(c<3);c++)
+        {
             for(r=0;(r<3);r++)
+            {
                 R[c][r]=vk[0][r]*vh[0][c]+
-                vk[1][r]*vh[1][c]-
-                vk[2][r]*vh[2][c];
+                        vk[1][r]*vh[1][c]-
+                        vk[2][r]*vh[2][c];
+            }
+        }
+    }
 }
 
 
@@ -696,7 +747,9 @@ static void write_edo_flood(t_edpar *edi, FILE *fp, gmx_large_int_t step)
         for (i = 0; i < edi->flood.vecs.neig; i++)
         {
             if (edi->flood.vecs.refprojslope[i] != 0.0)
+            {
                 bOutputRef=TRUE;
+            }
         }
         if (bOutputRef)
         {
@@ -711,7 +764,9 @@ static void write_edo_flood(t_edpar *edi, FILE *fp, gmx_large_int_t step)
     fprintf(fp,"FL_FORCES: ");
 
     for (i=0; i<edi->flood.vecs.neig; i++)
+    {
         fprintf(fp," %12.5e",edi->flood.vecs.fproj[i]);
+    }
 
     fprintf(fp,"\n");
 }
@@ -777,16 +832,20 @@ static void flood_forces(t_edpar *edi)
 
 
     if (edi->flood.bHarmonic)
+    {
         for (i=0; i<edi->flood.vecs.neig; i++)
         {
             edi->flood.vecs.fproj[i] = edi->flood.Efl* edi->flood.vecs.stpsz[i]*(edi->flood.vecs.xproj[i]-edi->flood.vecs.refproj[i]);
         }
+    }
     else
+    {
         for (i=0; i<edi->flood.vecs.neig; i++)
         {
             /* if Efl is zero the forces are zero if not use the formula */
             edi->flood.vecs.fproj[i] = edi->flood.Efl!=0 ? edi->flood.kT/edi->flood.Efl/edi->flood.alpha2*energy*edi->flood.vecs.stpsz[i]*(edi->flood.vecs.xproj[i]-edi->flood.vecs.refproj[i]) : 0;
         }
+    }
 }
 
 
@@ -817,7 +876,9 @@ static void flood_blowup(t_edpar *edi, rvec *forces_cart)
 
     /* Clear forces first */
     for (j=0; j<edi->sav.nr_loc; j++)
+    {
         clear_rvec(forces_cart[j]);
+    }
 
     /* Now compute atomwise */
     for (j=0; j<edi->sav.nr_loc; j++)
@@ -846,7 +907,9 @@ static void update_adaption(t_edpar *edi)
         edi->flood.Efl = edi->flood.Efl+edi->flood.dt/edi->flood.tau*(edi->flood.deltaF0-edi->flood.deltaF);
         /* check if restrain (inverted flooding) -> don't let EFL become positive */
         if (edi->flood.alpha2<0 && edi->flood.Efl>-0.00000001)
+        {
             edi->flood.Efl = 0;
+        }
 
         edi->flood.deltaF = (1-edi->flood.dt/edi->flood.tau)*edi->flood.deltaF+edi->flood.dt/edi->flood.tau*edi->flood.Vfl;
     }
@@ -881,8 +944,10 @@ static void do_single_flood(
 
     /* Only assembly REFERENCE positions if their indices differ from the average ones */
     if (!edi->bRefEqAv)
+    {
         communicate_group_positions(cr, buf->xc_ref, buf->shifts_xc_ref, buf->extra_shifts_xc_ref, bNS, x,
                 edi->sref.nr, edi->sref.nr_loc, edi->sref.anrs_loc, edi->sref.c_ind, edi->sref.x_old, box);
+    }
 
     /* If bUpdateShifts was TRUE, the shifts have just been updated in get_positions.
      * We do not need to update the shifts until the next NS step */
@@ -893,9 +958,13 @@ static void do_single_flood(
 
     /* Fit the reference indices to the reference structure */
     if (edi->bRefEqAv)
+    {
         fit_to_reference(buf->xcoll , transvec, rotmat, edi);
+    }
     else
+    {
         fit_to_reference(buf->xc_ref, transvec, rotmat, edi);
+    }
 
     /* Now apply the translation and rotation to the ED structure */
     translate_and_rotate(buf->xcoll, edi->sav.nr, transvec, rotmat);
@@ -924,11 +993,15 @@ static void do_single_flood(
 
     /* Finally add forces to the main force variable */
     for (i=0; i<edi->sav.nr_loc; i++)
+    {
         rvec_inc(force[edi->sav.anrs_loc[i]],edi->flood.forces_cartesian[i]);
+    }
 
     /* Output is written by the master process */
     if (do_per_step(step,edi->outfrq) && MASTER(cr))
+    {
         write_edo_flood(edi,edo,step);
+    }
 }
 
 
@@ -954,7 +1027,9 @@ extern void do_flood(
     {
         /* Call flooding for one matrix */
         if (edi->flood.vecs.neig)
+        {
             do_single_flood(ed->edo,x,force,edi,step,box,cr,bNS);
+        }
         edi = edi->next_edi;
     }
 }
@@ -962,7 +1037,7 @@ extern void do_flood(
 
 /* Called by init_edi, configure some flooding related variables and structures,
  * print headers to output files */
-static void init_flood(t_edpar *edi, gmx_edsam_t ed, real dt, t_commrec *cr)
+static void init_flood(t_edpar *edi, gmx_edsam_t ed, real dt, t_commrec *cr, gmx_bool bPrintheader)
 {
     int i;
 
@@ -991,9 +1066,13 @@ static void init_flood(t_edpar *edi, gmx_edsam_t ed, real dt, t_commrec *cr)
                         edi->flood.vecs.ieig[i], edi->flood.vecs.fproj[i]);
             }
         }
-        fprintf(ed->edo,"FL_HEADER: Flooding of matrix %d is switched on! The flooding output will have the following format:\n",
-                edi->flood.flood_id);
-        fprintf(ed->edo,"FL_HEADER: Step     Efl          Vfl       deltaF\n");
+
+        if (bPrintheader)
+        {
+            fprintf(ed->edo,"FL_HEADER: Flooding of matrix %d is switched on! The flooding output will have the following format:\n",
+                    edi->flood.flood_id);
+            fprintf(ed->edo,"FL_HEADER: Step     Efl          Vfl       deltaF\n");
+        }
     }
 }
 
@@ -1035,7 +1114,9 @@ static void get_flood_energies(t_edpar *edi, real Vfl[],int nnames)
         count++;
     }
     if (nnames!=count-1)
+    {
         gmx_fatal(FARGS,"Number of energies is not consistent with t_edi structure");
+    }
 }
 /************* END of FLOODING IMPLEMENTATION ****************************/
 #endif
@@ -1060,7 +1141,6 @@ gmx_edsam_t ed_open(int nfile,const t_filenm fnm[],unsigned long Flags,t_commrec
         fprintf(stderr,"ED sampling will be performed!\n");
         ed->edonam = ftp2fn(efEDO,nfile,fnm);
         ed->edo    = gmx_fio_fopen(ed->edonam,(Flags & MD_APPENDFILES)? "a+" : "w+");
-        ed->bStartFromCpt = Flags & MD_STARTFROMCPT;
     }
     return ed;
 }
@@ -1281,7 +1361,9 @@ static void init_edi(gmx_mtop_t *mtop,t_inputrec *ir,
 static void check(const char *line, const char *label)
 {
     if (!strstr(line,label))
+    {
         gmx_fatal(FARGS,"Could not find input parameter %s at expected position in edsam input-file (.edi)\nline read instead is %s",label,line);
+    }
 }
 
 
@@ -1351,7 +1433,9 @@ static void read_edx(FILE *file,int number,int *anrs,rvec *x)
         sscanf (line,"%d%lf%lf%lf",&anrs[i],&d[0],&d[1],&d[2]);
         anrs[i]--; /* we are reading FORTRAN indices */
         for(j=0; j<3; j++)
+        {
             x[i][j]=d[j]; /* always read as double and convert to single */
+        }
     }
 }
 
@@ -1432,7 +1516,9 @@ static void read_edvec(FILE *in,int nr,t_eigvec *tvec,gmx_bool bReadRefproj, gmx
             {
                 nscan = sscanf(line,"%d%lf",&idum,&rdum);
                 if (nscan != 2)
+                {
                     gmx_fatal(FARGS,"Expected 2 values for flooding vec: <nr> <stpsz>\n");
+                }
             }
             tvec->ieig[i]=idum;
             tvec->stpsz[i]=rdum;
@@ -1471,14 +1557,18 @@ static gmx_bool check_if_same(struct gmx_edx sref, struct gmx_edx sav)
     /* If the number of atoms differs between the two structures,
      * they cannot be identical */
     if (sref.nr != sav.nr)
+    {
         return FALSE;
+    }
 
     /* Now that we know that both stuctures have the same number of atoms,
      * check if also the indices are identical */
     for (i=0; i < sav.nr; i++)
     {
         if (sref.anrs[i] != sav.anrs[i])
+        {
             return FALSE;
+        }
     }
     fprintf(stderr, "ED: Note: Reference and average structure are composed of the same atom indices.\n");
 
@@ -1502,21 +1592,29 @@ static int read_edi(FILE* in, gmx_edsam_t ed,t_edpar *edi,int nr_mdatoms, int ed
     readmagic=read_edint(in,&bEOF);
     /* Check whether we have reached the end of the input file */
     if (bEOF)
+    {
         return 0;
+    }
 
     if (readmagic != magic)
     {
         if (readmagic==666 || readmagic==667 || readmagic==668)
+        {
             gmx_fatal(FARGS,"Wrong magic number: Use newest version of make_edi to produce edi file");
+        }
         else if (readmagic != 669)
+        {
             gmx_fatal(FARGS,"Wrong magic number %d in %s",readmagic,ed->edinam);
+        }
     }
 
     /* check the number of atoms */
     edi->nini=read_edint(in,&bEOF);
     if (edi->nini != nr_mdatoms)
+    {
         gmx_fatal(FARGS,"Nr of atoms in %s (%d) does not match nr of md atoms (%d)",
                 ed->edinam,edi->nini,nr_mdatoms);
+    }
 
     /* Done checking. For the rest we blindly trust the input */
     edi->fitmas          = read_checked_edint(in,"FITMAS");
@@ -1534,9 +1632,13 @@ static int read_edi(FILE* in, gmx_edsam_t ed,t_edpar *edi,int nr_mdatoms, int ed
     edi->flood.kT        = read_checked_edreal(in,"KT");
     edi->flood.bHarmonic = read_checked_edint(in,"HARMONIC");
     if (readmagic > 669)
+    {
         edi->flood.bConstForce = read_checked_edint(in,"CONST_FORCE_FLOODING");
+    }
     else
+    {
         edi->flood.bConstForce = FALSE;
+    }
     edi->flood.flood_id  = edi_nr;
     edi->sref.nr         = read_checked_edint(in,"NREF");
 
@@ -1575,13 +1677,13 @@ static int read_edi(FILE* in, gmx_edsam_t ed,t_edpar *edi,int nr_mdatoms, int ed
     edi->sori.nr=read_edint(in,&bEOF);
     if (edi->sori.nr > 0)
     {
-       if (bHaveReference)
-       {
-               /* Both an -ori structure and a at least one manual reference point have been
-                * specified. That's ambiguous and probably not intentional. */
-               gmx_fatal(FARGS, "ED: An origin structure has been provided and a at least one (moving) reference\n"
-                                "    point was manually specified in the edi file. That is ambiguous. Aborting.\n");
-       }
+        if (bHaveReference)
+        {
+            /* Both an -ori structure and a at least one manual reference point have been
+             * specified. That's ambiguous and probably not intentional. */
+            gmx_fatal(FARGS, "ED: An origin structure has been provided and a at least one (moving) reference\n"
+                             "    point was manually specified in the edi file. That is ambiguous. Aborting.\n");
+        }
         snew(edi->sori.anrs,edi->sori.nr);
         snew(edi->sori.x   ,edi->sori.nr);
         edi->sori.sqrtm    =NULL;
@@ -1597,7 +1699,7 @@ static int read_edi(FILE* in, gmx_edsam_t ed,t_edpar *edi,int nr_mdatoms, int ed
 /* Read in the edi input file. Note that it may contain several ED data sets which were
  * achieved by concatenating multiple edi files. The standard case would be a single ED
  * data set, though. */
-static void read_edi_file(gmx_edsam_t ed, t_edpar *edi, int nr_mdatoms, t_commrec *cr)
+static int read_edi_file(gmx_edsam_t ed, t_edpar *edi, int nr_mdatoms, t_commrec *cr)
 {
     FILE    *in;
     t_edpar *curr_edi,*last_edi;
@@ -1619,8 +1721,10 @@ static void read_edi_file(gmx_edsam_t ed, t_edpar *edi, int nr_mdatoms, t_commre
         edi_nr++;
         /* Make shure that the number of atoms in each dataset is the same as in the tpr file */
         if (edi->nini != nr_mdatoms)
+        {
             gmx_fatal(FARGS,"edi file %s (dataset #%d) was made for %d atoms, but the simulation contains %d atoms.",
                     ed->edinam, edi_nr, edi->nini, nr_mdatoms);
+        }
         /* Since we arrived within this while loop we know that there is still another data set to be read in */
         /* We need to allocate space for the data: */
         snew(edi_read,1);
@@ -1632,7 +1736,9 @@ static void read_edi_file(gmx_edsam_t ed, t_edpar *edi, int nr_mdatoms, t_commre
         curr_edi = edi_read;
     }
     if (edi_nr == 0)
+    {
         gmx_fatal(FARGS, "No complete ED data set found in edi file %s.", ed->edinam);
+    }
 
     /* Terminate the edi dataset list with a NULL pointer: */
     last_edi->next_edi = NULL;
@@ -1641,6 +1747,8 @@ static void read_edi_file(gmx_edsam_t ed, t_edpar *edi, int nr_mdatoms, t_commre
 
     /* Close the .edi file again */
     gmx_fio_fclose(in);
+
+    return edi_nr;
 }
 
 
@@ -1674,7 +1782,9 @@ static void fit_to_reference(rvec      *xcoll,    /* The positions to be fitted
 
     /* We do not touch the original positions but work on a copy. */
     for (i=0; i<edi->sref.nr; i++)
+    {
         copy_rvec(xcoll[i], loc->xcopy[i]);
+    }
 
     /* Calculate the center of mass */
     get_center(loc->xcopy, edi->sref.m, edi->sref.nr, com);
@@ -1716,7 +1826,9 @@ static real rmsd_from_structure(rvec           *x,  /* The positions under consi
 
 
     for (i=0; i < s->nr; i++)
+    {
         rmsd += distance2(s->x[i], x[i]);
+    }
 
     rmsd /= (real) s->nr;
     rmsd = sqrt(rmsd);
@@ -1739,8 +1851,10 @@ void dd_make_local_ed_indices(gmx_domdec_t *dd, struct gmx_edsam *ed)
             /* Local atoms of the reference structure (for fitting), need only be assembled
              * if their indices differ from the average ones */
             if (!edi->bRefEqAv)
+            {
                 dd_make_local_group_indices(dd->ga2la, edi->sref.nr, edi->sref.anrs,
                         &edi->sref.nr_loc, &edi->sref.anrs_loc, &edi->sref.nalloc_loc, edi->sref.c_ind);
+            }
 
             /* Local atoms of the average structure (on these ED will be performed) */
             dd_make_local_group_indices(dd->ga2la, edi->sav.nr, edi->sav.anrs,
@@ -1773,7 +1887,8 @@ static inline void ed_unshift_single_coord(matrix box, const rvec x, const ivec
         xu[XX] = x[XX]-tx*box[XX][XX]-ty*box[YY][XX]-tz*box[ZZ][XX];
         xu[YY] = x[YY]-ty*box[YY][YY]-tz*box[ZZ][YY];
         xu[ZZ] = x[ZZ]-tz*box[ZZ][ZZ];
-    } else
+    }
+    else
     {
         xu[XX] = x[XX]-tx*box[XX][XX];
         xu[YY] = x[YY]-ty*box[YY][YY];
@@ -1829,12 +1944,16 @@ static void do_linacc(rvec *xcoll, t_edpar *edi, t_commrec *cr)
         if (edi->vecs.linacc.stpsz[i] > 0.0)
         {
             if ((proj-edi->vecs.linacc.refproj[i]) < 0.0)
+            {
                 add = edi->vecs.linacc.refproj[i] - proj;
+            }
         }
         if (edi->vecs.linacc.stpsz[i] < 0.0)
         {
             if ((proj-edi->vecs.linacc.refproj[i]) > 0.0)
+            {
                 add = edi->vecs.linacc.refproj[i] - proj;
+            }
         }
 
         /* apply the correction */
@@ -1883,7 +2002,8 @@ static void do_radfix(rvec *xcoll, t_edpar *edi, int step, t_commrec *cr)
         /* apply the correction */
         proj[i] /= edi->sav.sqrtm[i];
         proj[i] *= ratio;
-        for (j=0; j<edi->sav.nr; j++) {
+        for (j=0; j<edi->sav.nr; j++)
+        {
             svmul(proj[i], edi->vecs.radfix.vec[i][j], vec_dum);
             rvec_inc(xcoll[j], vec_dum);
         }
@@ -2026,20 +2146,28 @@ static void ed_apply_constraints(rvec *xcoll, t_edpar *edi, gmx_large_int_t step
 
     /* subtract the average positions */
     for (i=0; i<edi->sav.nr; i++)
+    {
         rvec_dec(xcoll[i], edi->sav.x[i]);
+    }
 
     /* apply the constraints */
     if (step >= 0)
+    {
         do_linfix(xcoll, edi, step, cr);
+    }
     do_linacc(xcoll, edi, cr);
     if (step >= 0)
+    {
         do_radfix(xcoll, edi, step, cr);
+    }
     do_radacc(xcoll, edi, cr);
     do_radcon(xcoll, edi, cr);
 
     /* add back the average positions */
     for (i=0; i<edi->sav.nr; i++)
+    {
         rvec_inc(xcoll[i], edi->sav.x[i]);
+    }
 
     GMX_MPE_LOG(ev_ed_apply_cons_finish);
 }
@@ -2055,7 +2183,9 @@ static void write_edo(int nr_edi, t_edpar *edi, gmx_edsam_t ed, gmx_large_int_t
     if (edi->bNeedDoEdsam)
     {
         if (step == -1)
+        {
             fprintf(ed->edo, "Initial projections:\n");
+        }
         else
         {
             fprintf(ed->edo,"Step %s, ED #%d  ", gmx_step_str(step, buf), nr_edi);
@@ -2066,28 +2196,36 @@ static void write_edo(int nr_edi, t_edpar *edi, gmx_edsam_t ed, gmx_large_int_t
         {
             fprintf(ed->edo,"  Monitor eigenvectors");
             for (i=0; i<edi->vecs.mon.neig; i++)
+            {
                 fprintf(ed->edo," %d: %12.5e ",edi->vecs.mon.ieig[i],edi->vecs.mon.xproj[i]);
+            }
             fprintf(ed->edo,"\n");
         }
         if (edi->vecs.linfix.neig)
         {
             fprintf(ed->edo,"  Linfix  eigenvectors");
             for (i=0; i<edi->vecs.linfix.neig; i++)
+            {
                 fprintf(ed->edo," %d: %12.5e ",edi->vecs.linfix.ieig[i],edi->vecs.linfix.xproj[i]);
+            }
             fprintf(ed->edo,"\n");
         }
         if (edi->vecs.linacc.neig)
         {
             fprintf(ed->edo,"  Linacc  eigenvectors");
             for (i=0; i<edi->vecs.linacc.neig; i++)
+            {
                 fprintf(ed->edo," %d: %12.5e ",edi->vecs.linacc.ieig[i],edi->vecs.linacc.xproj[i]);
+            }
             fprintf(ed->edo,"\n");
         }
         if (edi->vecs.radfix.neig)
         {
             fprintf(ed->edo,"  Radfix  eigenvectors");
             for (i=0; i<edi->vecs.radfix.neig; i++)
+            {
                 fprintf(ed->edo," %d: %12.5e ",edi->vecs.radfix.ieig[i],edi->vecs.radfix.xproj[i]);
+            }
             fprintf(ed->edo,"\n");
             fprintf(ed->edo,"  fixed increment radius = %f\n", calc_radius(&edi->vecs.radfix));
         }
@@ -2095,7 +2233,9 @@ static void write_edo(int nr_edi, t_edpar *edi, gmx_edsam_t ed, gmx_large_int_t
         {
             fprintf(ed->edo,"  Radacc  eigenvectors");
             for (i=0; i<edi->vecs.radacc.neig; i++)
+            {
                 fprintf(ed->edo," %d: %12.5e ",edi->vecs.radacc.ieig[i],edi->vecs.radacc.xproj[i]);
+            }
             fprintf(ed->edo,"\n");
             fprintf(ed->edo,"  acceptance radius      = %f\n", calc_radius(&edi->vecs.radacc));
         }
@@ -2103,7 +2243,9 @@ static void write_edo(int nr_edi, t_edpar *edi, gmx_edsam_t ed, gmx_large_int_t
         {
             fprintf(ed->edo,"  Radcon  eigenvectors");
             for (i=0; i<edi->vecs.radcon.neig; i++)
+            {
                 fprintf(ed->edo," %d: %12.5e ",edi->vecs.radcon.ieig[i],edi->vecs.radcon.xproj[i]);
+            }
             fprintf(ed->edo,"\n");
             fprintf(ed->edo,"  contracting radius     = %f\n", calc_radius(&edi->vecs.radcon));
         }
@@ -2131,7 +2273,9 @@ static void copyEvecReference(t_eigvec* floodvecs)
 
 
     if (NULL==floodvecs->refproj0)
+    {
         snew(floodvecs->refproj0, floodvecs->neig);
+    }
 
     for (i=0; i<floodvecs->neig; i++)
     {
@@ -2140,31 +2284,144 @@ static void copyEvecReference(t_eigvec* floodvecs)
 }
 
 
+/* Call on MASTER only. Check whether the essential dynamics / flooding
+ * datasets of the checkpoint file are consistent with the provided .edi file. */
+static void crosscheck_edi_file_vs_checkpoint(gmx_edsam_t ed, edsamstate_t *EDstate)
+{
+    t_edpar *edi = NULL;    /* points to a single edi data set */
+    int i, edinum;
+
+
+    if (NULL == EDstate->nref || NULL == EDstate->nav)
+    {
+        gmx_fatal(FARGS, "Essential dynamics and flooding can only be switched on (or off) at the\n"
+                         "start of a new simulation. If a simulation runs with/without ED constraints,\n"
+                         "it must also continue with/without ED constraints when checkpointing.\n"
+                         "To switch on (or off) ED constraints, please prepare a new .tpr to start\n"
+                         "from without a checkpoint.\n");
+    }
+
+    edi=ed->edpar;
+    edinum = 0;
+    while(edi != NULL)
+    {
+        /* Check number of atoms in the reference and average structures */
+        if (EDstate->nref[edinum] != edi->sref.nr)
+        {
+            gmx_fatal(FARGS, "The number of reference structure atoms in ED dataset #%d is\n"
+                             "not the same in .cpt (NREF=%d) and .edi (NREF=%d) files!\n",
+                    edinum+1, EDstate->nref[edinum], edi->sref.nr);
+        }
+        if (EDstate->nav[edinum] != edi->sav.nr)
+        {
+            gmx_fatal(FARGS, "The number of average structure atoms in ED dataset #%d is\n"
+                             "not the same in .cpt (NREF=%d) and .edi (NREF=%d) files!\n",
+                    edinum+1, EDstate->nav[edinum], edi->sav.nr);
+        }
+        edi=edi->next_edi;
+        edinum++;
+    }
+
+    if (edinum != EDstate->nED)
+    {
+        gmx_fatal(FARGS, "The number of essential dynamics / flooding datasets is not consistent.\n"
+                         "There are %d ED datasets in .cpt file, but %d in .edi file!\n"
+                         "Are you shure this is the correct .edi file?\n", EDstate->nED, edinum);
+    }
+}
+
+
+/* The edsamstate struct stores the information we need to make the ED group
+ * whole again after restarts from a checkpoint file. Here we do the following:
+ * a) If we did not start from .cpt, we prepare the struct for proper .cpt writing,
+ * b) if we did start from .cpt, we copy over the last whole structures from .cpt,
+ * c) in any case, for subsequent checkpoint writing, we set the pointers in
+ * edsamstate to the x_old arrays, which contain the correct PBC representation of
+ * all ED structures at the last time step. */
+static void init_edsamstate(gmx_edsam_t ed, edsamstate_t *EDstate)
+{
+    int     i, nr_edi;
+    t_edpar *edi;
+
+
+    snew(EDstate->old_sref_p, EDstate->nED);
+    snew(EDstate->old_sav_p , EDstate->nED);
+
+    /* If we did not read in a .cpt file, these arrays are not yet allocated */
+    if (!EDstate->bFromCpt)
+    {
+        snew(EDstate->nref, EDstate->nED);
+        snew(EDstate->nav , EDstate->nED);
+    }
+
+    /* Loop over all ED/flooding data sets (usually only one, though) */
+    edi = ed->edpar;
+    for (nr_edi = 1; nr_edi <= EDstate->nED; nr_edi++)
+    {
+        /* We always need the last reference and average positions such that
+         * in the next time step we can make the ED group whole again
+         * if the atoms do not have the correct PBC representation */
+        if (EDstate->bFromCpt)
+        {
+            /* Copy the last whole positions of reference and average group from .cpt */
+            for (i=0; i<edi->sref.nr; i++)
+            {
+                copy_rvec(EDstate->old_sref[nr_edi-1][i], edi->sref.x_old[i]);
+            }
+            for (i=0; i<edi->sav.nr ; i++)
+            {
+                copy_rvec(EDstate->old_sav [nr_edi-1][i], edi->sav.x_old [i]);
+            }
+        }
+        else
+        {
+            EDstate->nref[nr_edi-1] = edi->sref.nr;
+            EDstate->nav [nr_edi-1] = edi->sav.nr;
+        }
+
+        /* For subsequent checkpoint writing, set the edsamstate pointers to the edi arrays: */
+        EDstate->old_sref_p[nr_edi-1] = edi->sref.x_old;
+        EDstate->old_sav_p [nr_edi-1] = edi->sav.x_old ;
+
+        edi = edi->next_edi;
+    }
+}
+
+
 void init_edsam(gmx_mtop_t  *mtop,   /* global topology                    */
                 t_inputrec  *ir,     /* input record                       */
                 t_commrec   *cr,     /* communication record               */
                 gmx_edsam_t ed,      /* contains all ED data               */
                 rvec        x[],     /* positions of the whole MD system   */
-                matrix      box)     /* the box                            */
+                matrix      box,     /* the box                            */
+                edsamstate_t *EDstate)
 {
     t_edpar *edi = NULL;    /* points to a single edi data set */
-    int     numedis=0;      /* keep track of the number of ED data sets in edi file */
     int     i,nr_edi,avindex;
     rvec    *x_pbc  = NULL; /* positions of the whole MD system with pbc removed  */
-    rvec    *xfit   = NULL; /* the positions which will be fitted to the reference structure  */
-    rvec    *xstart = NULL; /* the positions which are subject to ED sampling */
+    rvec    *xfit=NULL, *xstart=NULL; /* dummy arrays to determine initial RMSDs  */
     rvec    fit_transvec;   /* translation ... */
     matrix  fit_rotmat;     /* ... and rotation from fit to reference structure */
 
 
     if (!DOMAINDECOMP(cr) && PAR(cr) && MASTER(cr))
+    {
         gmx_fatal(FARGS, "Please switch on domain decomposition to use essential dynamics in parallel.");
+    }
 
     GMX_MPE_LOG(ev_edsam_start);
 
     if (MASTER(cr))
+    {
         fprintf(stderr, "ED: Initializing essential dynamics constraints.\n");
 
+        if (NULL == ed)
+        {
+            gmx_fatal(FARGS, "The checkpoint file you provided is from an essential dynamics or\n"
+                             "flooding simulation. Please also provide the correct .edi file with -ei.\n");
+        }
+    }
+
     /* Needed for initializing radacc radius in do_edsam */
     ed->bFirst = 1;
 
@@ -2175,7 +2432,14 @@ void init_edsam(gmx_mtop_t  *mtop,   /* global topology                    */
     {
         snew(ed->edpar,1);
         /* Read the whole edi file at once: */
-        read_edi_file(ed,ed->edpar,mtop->natoms,cr);
+        EDstate->nED = read_edi_file(ed,ed->edpar,mtop->natoms,cr);
+
+        /* Make shure the checkpoint was produced in a run using this .edi file */
+        if (EDstate->bFromCpt)
+        {
+            crosscheck_edi_file_vs_checkpoint(ed, EDstate);
+        }
+        init_edsamstate(ed, EDstate);
 
         /* Initialization for every ED/flooding dataset. Flooding uses one edi dataset per
          * flooding vector, Essential dynamics can be applied to more than one structure
@@ -2187,10 +2451,9 @@ void init_edsam(gmx_mtop_t  *mtop,   /* global topology                    */
             init_edi(mtop,ir,cr,ed,edi);
 
             /* Init flooding parameters if needed */
-            init_flood(edi,ed,ir->delta_t,cr);
+            init_flood(edi,ed,ir->delta_t,cr,!EDstate->bFromCpt);
 
             edi=edi->next_edi;
-            numedis++;
         }
     }
 
@@ -2209,32 +2472,34 @@ void init_edsam(gmx_mtop_t  *mtop,   /* global topology                    */
         edi=ed->edpar;
 
         /* Loop over all ED/flooding data sets (usually only one, though) */
-        for (nr_edi = 1; nr_edi <= numedis; nr_edi++)
+        for (nr_edi = 1; nr_edi <= EDstate->nED; nr_edi++)
         {
-            /* We use srenew to allocate memory since the size of the buffers
-             * is likely to change with every ED dataset */
-            srenew(xfit  , edi->sref.nr );
-            srenew(xstart, edi->sav.nr  );
-
-            /* Extract the positions of the atoms to which will be fitted */
-            for (i=0; i < edi->sref.nr; i++)
+            /* Extract the initial reference and average positions. When starting
+             * from .cpt, these have already been read into sref.x_old
+             * in init_edsamstate() */
+            if (!EDstate->bFromCpt)
             {
-                copy_rvec(x_pbc[edi->sref.anrs[i]], xfit[i]);
+                /* If this is the first run (i.e. no checkpoint present) we assume
+                 * that the starting positions give us the correct PBC representation */
+                for (i=0; i < edi->sref.nr; i++)
+                {
+                    copy_rvec(x_pbc[edi->sref.anrs[i]], edi->sref.x_old[i]);
+                }
 
-                /* Save the sref positions such that in the next time step we can make the ED group whole
-                 * in case any of the atoms do not have the correct PBC representation */
-                copy_rvec(xfit[i], edi->sref.x_old[i]);
+                for (i=0; i < edi->sav.nr; i++)
+                {
+                    copy_rvec(x_pbc[edi->sav.anrs[i]], edi->sav.x_old[i]);
+                }
             }
 
-            /* Extract the positions of the atoms subject to ED sampling */
-            for (i=0; i < edi->sav.nr; i++)
-            {
-                copy_rvec(x_pbc[edi->sav.anrs[i]], xstart[i]);
-
-                /* Save the sav positions such that in the next time step we can make the ED group whole
-                 * in case any of the atoms do not have the correct PBC representation */
-                copy_rvec(xstart[i], edi->sav.x_old[i]);
-            }
+            /* Now we have the PBC-correct start positions of the reference and
+               average structure. We copy that over to dummy arrays on which we
+               can apply fitting to print out the RMSD. We srenew the memory since
+               the size of the buffers is likely different for every ED dataset */
+            srenew(xfit  , edi->sref.nr );
+            srenew(xstart, edi->sav.nr  );
+            copy_rvecn(edi->sref.x_old, xfit, 0, edi->sref.nr);
+            copy_rvecn(edi->sav.x_old, xstart, 0, edi->sav.nr);
 
             /* Make the fit to the REFERENCE structure, get translation and rotation */
             fit_to_reference(xfit, fit_transvec, fit_rotmat, edi);
@@ -2278,12 +2543,17 @@ void init_edsam(gmx_mtop_t  *mtop,   /* global topology                    */
                     avindex = edi->star.nr - edi->sav.nr;
                 }
                 rad_project(edi, &edi->star.x[avindex], &edi->vecs.radcon, cr);
-            } else
+            }
+            else
+            {
                 rad_project(edi, xstart, &edi->vecs.radcon, cr);
+            }
 
             /* process structure that will serve as origin of expansion circle */
             if ( (eEDflood == ed->eEDtype) && (FALSE == edi->flood.bConstForce) )
+            {
                 fprintf(stderr, "ED: Setting center of flooding potential (0 = average structure)\n");
+            }
 
             if (edi->sori.nr > 0)
             {
@@ -2325,7 +2595,9 @@ void init_edsam(gmx_mtop_t  *mtop,   /* global topology                    */
                     {
                         fprintf(stderr, "ED: A (possibly changing) ref. projection will define the flooding potential center.\n");
                         for (i=0; i<edi->flood.vecs.neig; i++)
+                        {
                             edi->flood.vecs.refproj[i] = edi->flood.vecs.refproj0[i];
+                        }
                     }
                     else
                     {
@@ -2333,7 +2605,9 @@ void init_edsam(gmx_mtop_t  *mtop,   /* global topology                    */
                         /* Set center of flooding potential to the center of the covariance matrix,
                          * i.e. the average structure, i.e. zero in the projected system */
                         for (i=0; i<edi->flood.vecs.neig; i++)
+                        {
                             edi->flood.vecs.refproj[i] = 0.0;
+                        }
                     }
                 }
             }
@@ -2342,9 +2616,11 @@ void init_edsam(gmx_mtop_t  *mtop,   /* global topology                    */
             {
                 for (i=0; i<edi->flood.vecs.neig; i++)
                 {
-                    fprintf(stdout, "ED: EV %d flooding potential center: %11.4e", i, edi->flood.vecs.refproj[i]);
+                    fprintf(stdout, "ED: EV %d flooding potential center: %11.4e", edi->flood.vecs.ieig[i], edi->flood.vecs.refproj[i]);
                     if (edi->flood.bHarmonic)
+                    {
                         fprintf(stdout, " (adding %11.4e/timestep)", edi->flood.vecs.refprojslope[i]);
+                    }
                     fprintf(stdout, "\n");
                 }
             }
@@ -2354,8 +2630,10 @@ void init_edsam(gmx_mtop_t  *mtop,   /* global topology                    */
             rad_project(edi, xstart, &edi->vecs.linfix, cr);
 
             /* Output to file, set the step to -1 so that write_edo knows it was called from init_edsam */
-            if (ed->edo && !(ed->bStartFromCpt))
+            if (ed->edo && !(EDstate->bFromCpt))
+            {
                 write_edo(nr_edi, edi, ed, -1, 0);
+            }
 
             /* Prepare for the next edi data set: */
             edi=edi->next_edi;
@@ -2370,9 +2648,9 @@ void init_edsam(gmx_mtop_t  *mtop,   /* global topology                    */
     if (PAR(cr))
     {
         /* First let everybody know how many ED data sets to expect */
-        gmx_bcast(sizeof(numedis), &numedis, cr);
+        gmx_bcast(sizeof(EDstate->nED), &EDstate->nED, cr);
         /* Broadcast the essential dynamics / flooding data to all nodes */
-        broadcast_ed_data(cr, ed, numedis);
+        broadcast_ed_data(cr, ed, EDstate->nED);
     }
     else
     {
@@ -2381,7 +2659,7 @@ void init_edsam(gmx_mtop_t  *mtop,   /* global topology                    */
 
         /* Loop over all ED data sets (usually only one, though) */
         edi=ed->edpar;
-        for (nr_edi = 1; nr_edi <= numedis; nr_edi++)
+        for (nr_edi = 1; nr_edi <= EDstate->nED; nr_edi++)
         {
             edi->sref.anrs_loc = edi->sref.anrs;
             edi->sav.anrs_loc  = edi->sav.anrs;
@@ -2391,13 +2669,17 @@ void init_edsam(gmx_mtop_t  *mtop,   /* global topology                    */
             snew(edi->sav.c_ind, edi->sav.nr);
             /* Initialize the array */
             for (i=0; i<edi->sav.nr; i++)
+            {
                 edi->sav.c_ind[i] = i;
+            }
             /* In the general case we will need a different-sized array for the reference indices: */
             if (!edi->bRefEqAv)
             {
                 snew(edi->sref.c_ind, edi->sref.nr);
                 for (i=0; i<edi->sref.nr; i++)
+                {
                     edi->sref.c_ind[i] = i;
+                }
             }
             /* Point to the very same array in case of other structures: */
             edi->star.c_ind = edi->sav.c_ind;
@@ -2416,7 +2698,7 @@ void init_edsam(gmx_mtop_t  *mtop,   /* global topology                    */
     /* Allocate space for ED buffer variables */
     /* Again, loop over ED data sets */
     edi=ed->edpar;
-    for (nr_edi = 1; nr_edi <= numedis; nr_edi++)
+    for (nr_edi = 1; nr_edi <= EDstate->nED; nr_edi++)
     {
         /* Allocate space for ED buffer */
         snew(edi->buf, 1);
@@ -2451,7 +2733,9 @@ void init_edsam(gmx_mtop_t  *mtop,   /* global topology                    */
     /* Flush the edo file so that the user can check some things
      * when the simulation has started */
     if (ed->edo)
+    {
         fflush(ed->edo);
+    }
 
     GMX_MPE_LOG(ev_edsam_finish);
 }
@@ -2479,12 +2763,16 @@ void do_edsam(t_inputrec  *ir,
 
     /* Check if ED sampling has to be performed */
     if ( ed->eEDtype==eEDnone )
+    {
         return;
+    }
 
     /* Suppress output on first call of do_edsam if
      * two-step sd2 integrator is used */
     if ( (ir->eI==eiSD2) && (v != NULL) )
+    {
         bSuppress = TRUE;
+    }
 
     dt_1 = 1.0/ir->delta_t;
 
@@ -2500,8 +2788,10 @@ void do_edsam(t_inputrec  *ir,
             buf=edi->buf->do_edsam;
 
             if (ed->bFirst)
+            {
                 /* initialise radacc radius for slope criterion */
                 buf->oldrad=calc_radius(&edi->vecs.radacc);
+            }
 
             /* Copy the positions into buf->xc* arrays and after ED
              * feed back corrections to the official positions */
@@ -2519,8 +2809,10 @@ void do_edsam(t_inputrec  *ir,
 #endif
             /* Only assembly reference positions if their indices differ from the average ones */
             if (!edi->bRefEqAv)
+            {
                 communicate_group_positions(cr, buf->xc_ref, buf->shifts_xc_ref, buf->extra_shifts_xc_ref, PAR(cr) ? buf->bUpdateShifts : TRUE, xs,
                         edi->sref.nr, edi->sref.nr_loc, edi->sref.anrs_loc, edi->sref.c_ind, edi->sref.x_old, box);
+            }
 
             /* If bUpdateShifts was TRUE then the shifts have just been updated in communicate_group_positions.
              * We do not need to update the shifts until the next NS step. Note that dd_make_local_ed_indices
@@ -2532,9 +2824,13 @@ void do_edsam(t_inputrec  *ir,
 
             /* Fit the reference indices to the reference structure */
             if (edi->bRefEqAv)
+            {
                 fit_to_reference(buf->xcoll , transvec, rotmat, edi);
+            }
             else
+            {
                 fit_to_reference(buf->xc_ref, transvec, rotmat, edi);
+            }
 
             /* Now apply the translation and rotation to the ED structure */
             translate_and_rotate(buf->xcoll, edi->sav.nr, transvec, rotmat);
@@ -2574,8 +2870,11 @@ void do_edsam(t_inputrec  *ir,
                     project(buf->xcoll, edi);
                     rad_project(edi, buf->xcoll, &edi->vecs.radacc, cr);
                     buf->oldrad = 0.0;
-                } else
+                }
+                else
+                {
                     buf->oldrad = edi->vecs.radacc.radius;
+                }
             }
 
             /* apply the constraints */
@@ -2591,7 +2890,9 @@ void do_edsam(t_inputrec  *ir,
             {
                 project(buf->xcoll, edi);
                 if (MASTER(cr) && !bSuppress)
+                {
                     write_edo(edinr, edi, ed, step, rmsdev);
+                }
             }
 
             /* Copy back the positions unless monitoring only */
index 99ceba34e4c37d193043d46b77af70072e2e9a6b..fd25a5b1c0e65048553c4dd584f2e84868fc96f8 100644 (file)
@@ -53,7 +53,7 @@ FILE* debug;
 #include "gmxcomplex.h"
 #include "gmx_fft.h"
 
-#ifndef GMX_LIB_MPI
+#ifndef GMX_MPI
 double MPI_Wtime();
 #endif
 
index dc0758a3fccc3ecd0592fee4a932c8e4af81a476..c1955a99548da156ae3e27ad8b764c97997509dd 100644 (file)
@@ -1433,7 +1433,7 @@ static void pick_nbnxn_kernel_cpu(FILE *fp,
 #endif
         if (getenv("GMX_NBNXN_SIMD_4XN") != NULL)
         {
-#ifdef GMX_NBNXN_SIMD_2XNN
+#ifdef GMX_NBNXN_SIMD_4XN
             *kernel_type = nbnxnk4xN_SIMD_4xN;
 #else
             gmx_fatal(FARGS,"SIMD 4xN kernels requested, but Gromacs has been compiled without support for these kernels");
index d93a4c2b9ba5b3a43dd5da66361d629759fdb291..c9e881a7ffe1ecb845514296efab74202db2f4ff 100644 (file)
@@ -7,6 +7,6 @@ URL: http://www.gromacs.org
 Version: @PROJECT_VERSION@
 Requires: libgmx@GMX_LIBS_SUFFIX@ @PKG_FFT@
 Libs.private: -lm @CMAKE_THREAD_LIBS_INIT@
-Libs: -L${libdir} -lmd@GMX_LIBS_SUFFIX@ @PKG_FFT_LIBS@
+Libs: -L${libdir} -l@MD_PREFIX@md@GMX_LIBS_SUFFIX@ @PKG_FFT_LIBS@
 Cflags: -I${includedir} @PKG_CFLAGS@
 
index ddf2719dab070a9fe6a1c4be78118195fc6664e6..2b6398c1e4ab80d8a0e5e4242a98226afe885dd7 100644 (file)
@@ -39,4 +39,7 @@ if(GMX_GPU)
             OPTIONS
             RELWITHDEBINFO -g
             DEBUG -g -D_DEBUG_=1)
+    #Because this is a static library linked into the (potential) shared library
+    #it should have the export of the shared library.
+    SET_TARGET_PROPERTIES(nbnxn_cuda PROPERTIES DEFINE_SYMBOL "md_EXPORTS" )
 endif()
index 97a0ef84b9dc535806fa6e60a7935f913619edb4..ce5a6734c8953ba4ab7bb48f1890e226871e84ed 100644 (file)
@@ -108,7 +108,7 @@ NBK_FUNC_NAME(nbnxn_kernel_ref,energrp)
     real       *nbfp_i;
     int        n,ci,ci_sh;
     int        ish,ishf;
-    gmx_bool   half_LJ,do_coul;
+    gmx_bool   do_LJ,half_LJ,do_coul;
     int        cjind0,cjind1,cjind;
     int        ip,jp;
 
@@ -213,8 +213,15 @@ NBK_FUNC_NAME(nbnxn_kernel_ref,energrp)
         ci               = nbln->ci;
         ci_sh            = (ish == CENTRAL ? ci : -1);
 
-        half_LJ = (nbln->shift & NBNXN_CI_HALF_LJ(0));
+        /* We have 5 LJ/C combinations, but use only three inner loops,
+         * as the other combinations are unlikely and/or not much faster:
+         * inner half-LJ + C for half-LJ + C / no-LJ + C
+         * inner LJ + C      for full-LJ + C
+         * inner LJ          for full-LJ + no-C / half-LJ + no-C
+         */
+        do_LJ   = (nbln->shift & NBNXN_CI_DO_LJ(0));
         do_coul = (nbln->shift & NBNXN_CI_DO_COUL(0));
+        half_LJ = ((nbln->shift & NBNXN_CI_HALF_LJ(0)) || !do_LJ) && do_coul;
 
 #ifdef CALC_ENERGIES
 #ifndef ENERGY_GROUPS
@@ -237,8 +244,7 @@ NBK_FUNC_NAME(nbnxn_kernel_ref,energrp)
             }
         }
 
-        /* With half_LJ we currently always calculate Coulomb interactions */
-        if (do_coul || half_LJ)
+        if (do_coul)
         {
 #ifdef CALC_ENERGIES
             real Vc_sub_self;
index faa445efbfb1fb2ef9d67becdbc88ed1a9b46de2..78242d73cec848e792ceb3b70ec804a98caa7351 100644 (file)
@@ -35,7 +35,7 @@
  * the research papers on the package. Check out http://www.gromacs.org.
  */
 
-/* GMX_MM128_HERE or GMX_MM256_HERE should be set before including this file */
+/* GMX_MM256_HERE should be set before including this file */
 #include "gmx_simd_macros.h"
 
 #define SUM_SIMD4(x) (x[0]+x[1]+x[2]+x[3])
 #define UNROLLI    NBNXN_CPU_CLUSTER_I_SIZE
 #define UNROLLJ    (GMX_SIMD_WIDTH_HERE/2)
 
-#if defined GMX_MM128_HERE || defined GMX_DOUBLE
-#define STRIDE     4
-#endif
-#if defined GMX_MM256_HERE && !defined GMX_DOUBLE
+#if defined GMX_MM256_HERE
 #define STRIDE     4
 #endif 
 
-#ifdef GMX_MM128_HERE
-#ifndef GMX_DOUBLE
-/* SSE single precision 4x4 kernel */
-#define SUM_SIMD(x) SUM_SIMD4(x)
-#define TAB_FDV0
-#else
-/* SSE double precision 4x2 kernel */
-#define SUM_SIMD(x) (x[0]+x[1])
-#endif
-#endif
-
 #ifdef GMX_MM256_HERE
 #ifndef GMX_DOUBLE
-/* AVX single precision 4x8 kernel */
+/* single precision 2x(4+4) kernel */
 #define SUM_SIMD(x) (x[0]+x[1]+x[2]+x[3]+x[4]+x[5]+x[6]+x[7])
 #define TAB_FDV0
 #else
-/* AVX double precision 4x4 kernel */
-#define SUM_SIMD(x) SUM_SIMD4(x)
+#error "unsupported kernel configuration"
 #endif
 #endif
 
@@ -167,7 +152,7 @@ NBK_FUNC_NAME(nbnxn_kernel_simd_2xnn,energrp)
     int        nbfp_stride;
     int        n,ci,ci_sh;
     int        ish,ish3;
-    gmx_bool   half_LJ,do_coul;
+    gmx_bool   do_LJ,half_LJ,do_coul;
     int        sci,scix,sciy,sciz,sci2;
     int        cjind0,cjind1,cjind;
     int        ip,jp;
@@ -206,9 +191,6 @@ NBK_FUNC_NAME(nbnxn_kernel_simd_2xnn,energrp)
     gmx_mm_pr  diag_SSE0 = _mm256_castsi256_ps( _mm256_set_epi32( 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000 ));
     gmx_mm_pr  diag_SSE2 = _mm256_castsi256_ps( _mm256_set_epi32( 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000 ));
 
-#ifndef GMX_MM256_HERE
-    __m128i    zeroi_SSE = _mm_setzero_si128();
-#endif
 #ifdef GMX_X86_SSE4_1
     gmx_mm_pr  zero_SSE = gmx_set1_pr(0);
 #endif
@@ -407,7 +389,7 @@ NBK_FUNC_NAME(nbnxn_kernel_simd_2xnn,energrp)
     egps_jshift  = 2*nbat->neg_2log;
     egps_jmask   = (1<<egps_jshift) - 1;
     egps_jstride = (UNROLLJ>>1)*UNROLLJ;
-    /* Major division is over i-particles: divide nVS by 4 for i-stride */
+    /* Major division is over i-particle energy groups, determine the stride */
     Vstride_i    = nbat->nenergrp*(1<<nbat->neg_2log)*egps_jstride;
 #endif
 
@@ -420,9 +402,8 @@ NBK_FUNC_NAME(nbnxn_kernel_simd_2xnn,energrp)
 
         ish              = (nbln->shift & NBNXN_CI_SHIFT);
         ish3             = ish*3;
-        cjind0           = nbln->cj_ind_start;      
-        cjind1           = nbln->cj_ind_end;    
-        /* Currently only works super-cells equal to sub-cells */
+        cjind0           = nbln->cj_ind_start;
+        cjind1           = nbln->cj_ind_end;
         ci               = nbln->ci;
         ci_sh            = (ish == CENTRAL ? ci : -1);
 
@@ -441,8 +422,15 @@ NBK_FUNC_NAME(nbnxn_kernel_simd_2xnn,energrp)
         sci             += (ci & 1)*(STRIDE>>1);
 #endif
 
-        half_LJ = (nbln->shift & NBNXN_CI_HALF_LJ(0));
+        /* We have 5 LJ/C combinations, but use only three inner loops,
+         * as the other combinations are unlikely and/or not much faster:
+         * inner half-LJ + C for half-LJ + C / no-LJ + C
+         * inner LJ + C      for full-LJ + C
+         * inner LJ          for full-LJ + no-C / half-LJ + no-C
+         */
+        do_LJ   = (nbln->shift & NBNXN_CI_DO_LJ(0));
         do_coul = (nbln->shift & NBNXN_CI_DO_COUL(0));
+        half_LJ = ((nbln->shift & NBNXN_CI_HALF_LJ(0)) || !do_LJ) && do_coul;
 
 #ifdef ENERGY_GROUPS
         egps_i = nbat->energrp[ci];
@@ -513,8 +501,7 @@ NBK_FUNC_NAME(nbnxn_kernel_simd_2xnn,energrp)
         iz_SSE0          = gmx_add_pr(gmx_load2_hpr(x+sciz)  ,shZ_SSE);
         iz_SSE2          = gmx_add_pr(gmx_load2_hpr(x+sciz+2),shZ_SSE);
 
-        /* With half_LJ we currently always calculate Coulomb interactions */
-        if (do_coul || half_LJ)
+        if (do_coul)
         {
             gmx_mm_pr facel_SSE;
 
index 1ab915deaecc3e5670ac0de2fffbd6b7da69bf78..1545d40380c8d48fcc21b16b96477343ef881dfe 100644 (file)
 
 #ifdef GMX_MM128_HERE
 #ifndef GMX_DOUBLE
-/* SSE single precision 4x4 kernel */
+/* single precision 4x4 kernel */
 #define SUM_SIMD(x) SUM_SIMD4(x)
 #define TAB_FDV0
 #else
-/* SSE double precision 4x2 kernel */
+/* double precision 4x2 kernel */
 #define SUM_SIMD(x) (x[0]+x[1])
 #endif
 #endif
 
 #ifdef GMX_MM256_HERE
 #ifndef GMX_DOUBLE
-/* AVX single precision 4x8 kernel */
+/* single precision 4x8 kernel */
 #define SUM_SIMD(x) (x[0]+x[1]+x[2]+x[3]+x[4]+x[5]+x[6]+x[7])
 #define TAB_FDV0
 #else
-/* AVX double precision 4x4 kernel */
+/* double precision 4x4 kernel */
 #define SUM_SIMD(x) SUM_SIMD4(x)
 #endif
 #endif
@@ -167,7 +167,7 @@ NBK_FUNC_NAME(nbnxn_kernel_simd_4xn,energrp)
     int        nbfp_stride;
     int        n,ci,ci_sh;
     int        ish,ish3;
-    gmx_bool   half_LJ,do_coul;
+    gmx_bool   do_LJ,half_LJ,do_coul;
     int        sci,scix,sciy,sciz,sci2;
     int        cjind0,cjind1,cjind;
     int        ip,jp;
@@ -203,7 +203,7 @@ NBK_FUNC_NAME(nbnxn_kernel_simd_4xn,energrp)
     __m128d    fix2_SSE,fiy2_SSE,fiz2_SSE;
 #endif
 
-#ifndef GMX_MM256_HERE
+#ifdef GMX_MM128_HERE
 #ifndef GMX_DOUBLE
     __m128i    mask0 = _mm_set_epi32( 0x0008, 0x0004, 0x0002, 0x0001 );
     __m128i    mask1 = _mm_set_epi32( 0x0080, 0x0040, 0x0020, 0x0010 );
@@ -216,7 +216,8 @@ NBK_FUNC_NAME(nbnxn_kernel_simd_4xn,energrp)
     __m128i    mask2 = _mm_set_epi32( 0x0020, 0x0020, 0x0010, 0x0010 );
     __m128i    mask3 = _mm_set_epi32( 0x0080, 0x0080, 0x0040, 0x0040 );
 #endif
-#else
+#endif
+#ifdef GMX_MM256_HERE
     /* AVX: use floating point masks, as there are no integer instructions */
 #ifndef GMX_DOUBLE
     gmx_mm_pr  mask0 = _mm256_castsi256_ps(_mm256_set_epi32( 0x0080, 0x0040, 0x0020, 0x0010, 0x0008, 0x0004, 0x0002, 0x0001 ));
@@ -230,7 +231,7 @@ NBK_FUNC_NAME(nbnxn_kernel_simd_4xn,energrp)
 #endif
 #endif
 
-#ifndef GMX_MM256_HERE
+#ifdef GMX_MM128_HERE
 #ifndef GMX_DOUBLE
     __m128     diag_SSE0 = gmx_mm_castsi128_pr( _mm_set_epi32( 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000 ));
     __m128     diag_SSE1 = gmx_mm_castsi128_pr( _mm_set_epi32( 0xffffffff, 0xffffffff, 0x00000000, 0x00000000 ));
@@ -246,7 +247,8 @@ NBK_FUNC_NAME(nbnxn_kernel_simd_4xn,energrp)
     __m128d    diag1_SSE2 = gmx_mm_castsi128_pd( _mm_set_epi32( 0xffffffff, 0xffffffff, 0x00000000, 0x00000000 ));
     __m128d    diag1_SSE3 = gmx_mm_castsi128_pd( _mm_set_epi32( 0x00000000, 0x00000000, 0x00000000, 0x00000000 ));
 #endif
-#else /* GMX_MM256_HERE */
+#endif
+#ifdef GMX_MM256_HERE
 #ifndef GMX_DOUBLE
     gmx_mm_pr  diag0_SSE0 = _mm256_castsi256_ps( _mm256_set_epi32( 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000 ));
     gmx_mm_pr  diag0_SSE1 = _mm256_castsi256_ps( _mm256_set_epi32( 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000 ));
@@ -264,7 +266,7 @@ NBK_FUNC_NAME(nbnxn_kernel_simd_4xn,energrp)
 #endif
 #endif
 
-#ifndef GMX_MM256_HERE
+#ifdef GMX_MM128_HERE
     __m128i    zeroi_SSE = _mm_setzero_si128();
 #endif
 #ifdef GMX_X86_SSE4_1
@@ -475,7 +477,7 @@ NBK_FUNC_NAME(nbnxn_kernel_simd_4xn,energrp)
     egps_jshift  = 2*nbat->neg_2log;
     egps_jmask   = (1<<egps_jshift) - 1;
     egps_jstride = (UNROLLJ>>1)*UNROLLJ;
-    /* Major division is over i-particles: divide nVS by 4 for i-stride */
+    /* Major division is over i-particle energy groups, determine the stride */
     Vstride_i    = nbat->nenergrp*(1<<nbat->neg_2log)*egps_jstride;
 #endif
 
@@ -488,9 +490,8 @@ NBK_FUNC_NAME(nbnxn_kernel_simd_4xn,energrp)
 
         ish              = (nbln->shift & NBNXN_CI_SHIFT);
         ish3             = ish*3;
-        cjind0           = nbln->cj_ind_start;      
-        cjind1           = nbln->cj_ind_end;    
-        /* Currently only works super-cells equal to sub-cells */
+        cjind0           = nbln->cj_ind_start;
+        cjind1           = nbln->cj_ind_end;
         ci               = nbln->ci;
         ci_sh            = (ish == CENTRAL ? ci : -1);
 
@@ -509,8 +510,15 @@ NBK_FUNC_NAME(nbnxn_kernel_simd_4xn,energrp)
         sci             += (ci & 1)*(STRIDE>>1);
 #endif
 
-        half_LJ = (nbln->shift & NBNXN_CI_HALF_LJ(0));
+        /* We have 5 LJ/C combinations, but use only three inner loops,
+         * as the other combinations are unlikely and/or not much faster:
+         * inner half-LJ + C for half-LJ + C / no-LJ + C
+         * inner LJ + C      for full-LJ + C
+         * inner LJ          for full-LJ + no-C / half-LJ + no-C
+         */
+        do_LJ   = (nbln->shift & NBNXN_CI_DO_LJ(0));
         do_coul = (nbln->shift & NBNXN_CI_DO_COUL(0));
+        half_LJ = ((nbln->shift & NBNXN_CI_HALF_LJ(0)) || !do_LJ) && do_coul;
 
 #ifdef ENERGY_GROUPS
         egps_i = nbat->energrp[ci];
@@ -585,8 +593,7 @@ NBK_FUNC_NAME(nbnxn_kernel_simd_4xn,energrp)
         iz_SSE2          = gmx_add_pr(gmx_load1_pr(x+sciz+2),shZ_SSE);
         iz_SSE3          = gmx_add_pr(gmx_load1_pr(x+sciz+3),shZ_SSE);
 
-        /* With half_LJ we currently always calculate Coulomb interactions */
-        if (do_coul || half_LJ)
+        if (do_coul)
         {
             iq_SSE0      = gmx_set1_pr(facel*q[sci]);
             iq_SSE1      = gmx_set1_pr(facel*q[sci+1]);
index 0358e3523d40217794eafd3a8067056093e33f36..dd6b2c31df62d58d00fa3327c7dd63a9a12d71fa 100644 (file)
@@ -3362,13 +3362,17 @@ static void close_ci_entry_simple(nbnxn_pairlist_t *nbl)
     {
         sort_cj_excl(nbl->cj+nbl->ci[nbl->nci].cj_ind_start,jlen,nbl->work);
 
-        if (nbl->ci[nbl->nci].shift & NBNXN_CI_HALF_LJ(0))
+        /* The counts below are used for non-bonded pair/flop counts
+         * and should therefore match the available kernel setups.
+         */
+        if (!(nbl->ci[nbl->nci].shift & NBNXN_CI_DO_COUL(0)))
         {
-            nbl->work->ncj_hlj += jlen;
+            nbl->work->ncj_noq += jlen;
         }
-        else if (!(nbl->ci[nbl->nci].shift & NBNXN_CI_DO_COUL(0)))
+        else if ((nbl->ci[nbl->nci].shift & NBNXN_CI_HALF_LJ(0)) ||
+                 !(nbl->ci[nbl->nci].shift & NBNXN_CI_DO_LJ(0)))
         {
-            nbl->work->ncj_noq += jlen;
+            nbl->work->ncj_hlj += jlen;
         }
 
         nbl->nci++;
index 3f290d6dceae9129b6a5c383d8cdba0c0da80ead..51ba5123b50aa561d843d9901b47730aa5fefcc2 100644 (file)
@@ -97,20 +97,20 @@ int gmx_g_angle(int argc,char *argv[])
 {
   static const char *desc[] = {
     "[TT]g_angle[tt] computes the angle distribution for a number of angles",
-    "or dihedrals. This way you can check whether your simulation",
-    "is correct. With option [TT]-ov[tt] you can plot the average angle of",
-    "a group of angles as a function of time. With the [TT]-all[tt] option",
-    "the first graph is the average, the rest are the individual angles.[PAR]",
+    "or dihedrals.[PAR]",
+    "With option [TT]-ov[tt], you can plot the average angle of",
+    "a group of angles as a function of time. With the [TT]-all[tt] option,",
+    "the first graph is the average and the rest are the individual angles.[PAR]",
     "With the [TT]-of[tt] option, [TT]g_angle[tt] also calculates the fraction of trans",
     "dihedrals (only for dihedrals) as function of time, but this is",
-    "probably only fun for a selected few.[PAR]",
-    "With option [TT]-oc[tt] a dihedral correlation function is calculated.[PAR]",
-    "It should be noted that the index file should contain",
-    "atom-triples for angles or atom-quadruplets for dihedrals.",
+    "probably only fun for a select few.[PAR]",
+    "With option [TT]-oc[tt], a dihedral correlation function is calculated.[PAR]",
+    "It should be noted that the index file must contain",
+    "atom triplets for angles or atom quadruplets for dihedrals.",
     "If this is not the case, the program will crash.[PAR]",
-    "With option [TT]-or[tt] a trajectory file is dumped containing cos and",
-    "sin of selected dihedral angles which subsequently can be used as",
-    "input for a PCA analysis using [TT]g_covar[tt].[PAR]",
+    "With option [TT]-or[tt], a trajectory file is dumped containing cos and",
+    "sin of selected dihedral angles, which subsequently can be used as",
+    "input for a principal components analysis using [TT]g_covar[tt].[PAR]",
     "Option [TT]-ot[tt] plots when transitions occur between",
     "dihedral rotamers of multiplicity 3 and [TT]-oh[tt]",
     "records a histogram of the times between such transitions,",
index e1165e29b3a09c93328463565c7996553e0a9645..f813d8fc8dcec6c135dfbf00802bdb9d8b0621e9 100644 (file)
@@ -118,14 +118,12 @@ int gmx_helix(int argc,char *argv[])
     "of the", 
     "helix in nm. This is simply the average rise (see above) times the",  
     "number of helical residues (see below).[BR]",
-    "[BB]5.[bb] Number of helical residues (file [TT]n-ahx.xvg[tt]). The title says",
-    "it all.[BR]",
-    "[BB]6.[bb] Helix dipole, backbone only (file [TT]dip-ahx.xvg[tt]).[BR]",
-    "[BB]7.[bb] RMS deviation from ideal helix, calculated for the C[GRK]alpha[grk]",
+    "[BB]5.[bb] Helix dipole, backbone only (file [TT]dip-ahx.xvg[tt]).[BR]",
+    "[BB]6.[bb] RMS deviation from ideal helix, calculated for the C[GRK]alpha[grk]",
     "atoms only (file [TT]rms-ahx.xvg[tt]).[BR]",
-    "[BB]8.[bb] Average C[GRK]alpha[grk] - C[GRK]alpha[grk] dihedral angle (file [TT]phi-ahx.xvg[tt]).[BR]",
-    "[BB]9.[bb] Average [GRK]phi[grk] and [GRK]psi[grk] angles (file [TT]phipsi.xvg[tt]).[BR]",
-    "[BB]10.[bb] Ellipticity at 222 nm according to Hirst and Brooks.",
+    "[BB]7.[bb] Average C[GRK]alpha[grk] - C[GRK]alpha[grk] dihedral angle (file [TT]phi-ahx.xvg[tt]).[BR]",
+    "[BB]8.[bb] Average [GRK]phi[grk] and [GRK]psi[grk] angles (file [TT]phipsi.xvg[tt]).[BR]",
+    "[BB]9.[bb] Ellipticity at 222 nm according to Hirst and Brooks.",
     "[PAR]"
   };
   static const char *ppp[efhNR+2] = { 
index 4da7814f2ad1b8d339b83405c8af048630987a5f..3ea5828637bba53be0229f0fc090c1975a0749fe 100644 (file)
@@ -473,7 +473,7 @@ int gmx_make_edi(int argc,char *argv[])
   static const char *desc[] = {
       "[TT]make_edi[tt] generates an essential dynamics (ED) sampling input file to be used with [TT]mdrun[tt]",
       "based on eigenvectors of a covariance matrix ([TT]g_covar[tt]) or from a",
-      "normal modes anaysis ([TT]g_nmeig[tt]).",
+      "normal modes analysis ([TT]g_nmeig[tt]).",
       "ED sampling can be used to manipulate the position along collective coordinates",
       "(eigenvectors) of (biological) macromolecules during a simulation. Particularly,",
       "it may be used to enhance the sampling efficiency of MD simulations by stimulating",
@@ -518,10 +518,16 @@ int gmx_make_edi(int argc,char *argv[])
       "before a new cycle is started.[PAR]",
       "Note on the parallel implementation: since ED sampling is a 'global' thing",
       "(collective coordinates etc.), at least on the 'protein' side, ED sampling",
-      "is not very parallel-friendly from an implentation point of view. Because",
+      "is not very parallel-friendly from an implementation point of view. Because",
       "parallel ED requires some extra communication, expect the performance to be",
-      "lower as in a free MD simulation, especially on a large number of nodes. [PAR]",
-      "All output of [TT]mdrun[tt] (specify with [TT]-eo[tt]) is written to a .edo file. In the output",
+      "lower as in a free MD simulation, especially on a large number of nodes and/or",
+      "when the ED group contains a lot of atoms. [PAR]",
+      "Please also note that if your ED group contains more than a single protein,",
+      "then the [TT].tpr[tt] file must contain the correct PBC representation of the ED group.",
+      "Take a look on the initial RMSD from the reference structure, which is printed",
+      "out at the start of the simulation; if this is much higher than expected, one",
+      "of the ED molecules might be shifted by a box vector. [PAR]",
+      "All output of [TT]mdrun[tt] (specify with [TT]-eo[tt]) is written to a [TT].edo[tt] file. In the output",
       "file, per OUTFRQ step the following information is present: [PAR]",
       "[TT]*[tt] the step number[BR]",
       "[TT]*[tt] the number of the ED dataset. ([BB]Note[bb] that you can impose multiple ED constraints in",
@@ -537,7 +543,7 @@ int gmx_make_edi(int argc,char *argv[])
       "is kept in that region.",
       "[PAR]",
       "The origin is normally the average structure stored in the [TT]eigvec.trr[tt] file.",
-      "It can be changed with [TT]-ori[tt] to an arbitrary position in configurational space.",
+      "It can be changed with [TT]-ori[tt] to an arbitrary position in configuration space.",
       "With [TT]-tau[tt], [TT]-deltaF0[tt], and [TT]-Eflnull[tt] you control the flooding behaviour.",
       "Efl is the flooding strength, it is updated according to the rule of adaptive flooding.",
       "Tau is the time constant of adaptive flooding, high [GRK]tau[grk] means slow adaption (i.e. growth). ",