Merge branch 'origin/release-2020' into master
[alexxy/gromacs.git] / src / gromacs / nbnxm / pairlist.h
index 162954c89d0fc87871208fb7e09c548d14ac5ab1..04f33159905bdc48ef3400306e01ba907f826352 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2012,2013,2014,2015, The GROMACS development team.
- * Copyright (c) 2016,2017,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015,2016 by the GROMACS development team.
+ * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
 #include "gromacs/utility/enumerationhelpers.h"
 #include "gromacs/utility/real.h"
 
-// This file with constants is separate from this file to be able
-// to include it during OpenCL jitting without including config.h
-#include "constants.h"
 #include "pairlistparams.h"
 
 struct NbnxnPairlistCpuWork;
 struct NbnxnPairlistGpuWork;
 
 
-/* Convenience type for vector with aligned memory */
+//! Convenience type for vector with aligned memory
 template<typename T>
 using AlignedVector = std::vector<T, gmx::AlignedAllocator<T>>;
 
-/* Convenience type for vector that avoids initialization at resize() */
+//! Convenience type for vector that avoids initialization at resize()
 template<typename T>
 using FastVector = std::vector<T, gmx::DefaultInitializationAllocator<T>>;
 
-/* A buffer data structure of 64 bytes
+/*! \brief Cache-line protection buffer
+ *
+ * A buffer data structure of 64 bytes
  * to be placed at the beginning and end of structs
  * to avoid cache invalidation of the real contents
  * of the struct by writes to neighboring memory.
  */
 typedef struct
 {
+    //! Unused field used to create space to protect cache lines that are in use
     int dummy[16];
 } gmx_cache_protect_t;
 
-/* This is the actual cluster-pair list j-entry.
+/*! \brief This is the actual cluster-pair list j-entry.
+ *
  * cj is the j-cluster.
  * The interaction bits in excl are indexed i-major, j-minor.
  * The cj entries are sorted such that ones with exclusions come first.
@@ -84,11 +85,15 @@ typedef struct
  */
 struct nbnxn_cj_t
 {
-    int          cj;   /* The j-cluster                    */
-    unsigned int excl; /* The exclusion (interaction) bits */
+    //! The j-cluster
+    int cj;
+    //! The exclusion (interaction) bits
+    unsigned int excl;
 };
 
-/* In nbnxn_ci_t the integer shift contains the shift in the lower 7 bits.
+/*! \brief Constants for interpreting interaction flags
+ *
+ * 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
@@ -96,66 +101,113 @@ struct nbnxn_cj_t
  * 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)))
 #define NBNXN_CI_DO_COUL(subc) (1 << (9 + 3 * (subc)))
+//! \}
 
-/* Cluster-pair Interaction masks
+/*! \brief Cluster-pair Interaction masks
+ *
  * Bit i*j-cluster-size + j tells if atom i and j interact.
  */
+//! \{
 // TODO: Rename according to convention when moving into Nbnxn namespace
-/* All interaction mask is the same for all kernels */
+//! All interaction mask is the same for all kernels
 constexpr unsigned int NBNXN_INTERACTION_MASK_ALL = 0xffffffffU;
-/* 4x4 kernel diagonal mask */
+//! 4x4 kernel diagonal mask
 constexpr unsigned int NBNXN_INTERACTION_MASK_DIAG = 0x08ceU;
-/* 4x2 kernel diagonal masks */
+//! 4x2 kernel diagonal masks
+//! \{
 constexpr unsigned int NBNXN_INTERACTION_MASK_DIAG_J2_0 = 0x0002U;
 constexpr unsigned int NBNXN_INTERACTION_MASK_DIAG_J2_1 = 0x002fU;
-/* 4x8 kernel diagonal masks */
+//! \}
+//! 4x8 kernel diagonal masks
+//! \{
 constexpr unsigned int NBNXN_INTERACTION_MASK_DIAG_J8_0 = 0xf0f8fcfeU;
 constexpr unsigned int NBNXN_INTERACTION_MASK_DIAG_J8_1 = 0x0080c0e0U;
+//! \}
+//! \}
+
+/*! \brief Lower limit for square interaction distances in nonbonded kernels.
+ *
+ * For smaller values we will overflow when calculating r^-1 or r^-12, but
+ * to keep it simple we always apply the limit from the tougher r^-12 condition.
+ */
+#if GMX_DOUBLE
+// Some double precision SIMD architectures use single precision in the first
+// step, so although the double precision criterion would allow smaller rsq,
+// we need to stay in single precision with some margin for the N-R iterations.
+constexpr double c_nbnxnMinDistanceSquared = 1.0e-36;
+#else
+// The worst intermediate value we might evaluate is r^-12, which
+// means we should ensure r^2 stays above pow(GMX_FLOAT_MAX,-1.0/6.0)*1.01 (some margin)
+constexpr float c_nbnxnMinDistanceSquared = 3.82e-07F; // r > 6.2e-4
+#endif
 
-/* Simple pair-list i-unit */
+
+//! The number of clusters in a super-cluster, used for GPU
+constexpr int c_nbnxnGpuNumClusterPerSupercluster = 8;
+
+/*! \brief With GPU kernels we group cluster pairs in 4 to optimize memory usage
+ * of integers containing 32 bits.
+ */
+constexpr int c_nbnxnGpuJgroupSize = (32 / c_nbnxnGpuNumClusterPerSupercluster);
+
+/*! \internal
+ * \brief Simple pair-list i-unit
+ */
 struct nbnxn_ci_t
 {
-    int ci;           /* i-cluster             */
-    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     */
+    //! i-cluster
+    int ci;
+    //! Shift vector index plus possible flags, see above
+    int shift;
+    //! Start index into cj
+    int cj_ind_start;
+    //! End index into cj
+    int cj_ind_end;
 };
 
-/* Grouped pair-list i-unit */
+//! Grouped pair-list i-unit
 typedef struct
 {
-    /* Returns the number of j-cluster groups in this entry */
+    //! Returns the number of j-cluster groups in this entry
     int numJClusterGroups() const { return cj4_ind_end - cj4_ind_start; }
 
-    int sci;           /* i-super-cluster       */
-    int shift;         /* Shift vector index plus possible flags */
-    int cj4_ind_start; /* Start index into cj4  */
-    int cj4_ind_end;   /* End index into cj4    */
+    //! i-super-cluster
+    int sci;
+    //! Shift vector index plus possible flags
+    int shift;
+    //! Start index into cj4
+    int cj4_ind_start;
+    //! End index into cj4
+    int cj4_ind_end;
 } nbnxn_sci_t;
 
-/* Interaction data for a j-group for one warp */
+//! Interaction data for a j-group for one warp
 struct nbnxn_im_ei_t
 {
-    // The i-cluster interactions mask for 1 warp
+    //! The i-cluster interactions mask for 1 warp
     unsigned int imask = 0U;
-    // Index into the exclusion array for 1 warp, default index 0 which means no exclusions
+    //! Index into the exclusion array for 1 warp, default index 0 which means no exclusions
     int excl_ind = 0;
 };
 
+//! Four-way j-cluster lists
 typedef struct
 {
-    int           cj[c_nbnxnGpuJgroupSize];         /* The 4 j-clusters */
-    nbnxn_im_ei_t imei[c_nbnxnGpuClusterpairSplit]; /* The i-cluster mask data       for 2 warps */
+    //! The 4 j-clusters
+    int cj[c_nbnxnGpuJgroupSize];
+    //! The i-cluster mask data for 2 warps
+    nbnxn_im_ei_t imei[c_nbnxnGpuClusterpairSplit];
 } nbnxn_cj4_t;
 
-/* Struct for storing the atom-pair interaction bits for a cluster pair in a GPU pairlist */
+//! Struct for storing the atom-pair interaction bits for a cluster pair in a GPU pairlist
 struct nbnxn_excl_t
 {
-    /* Constructor, sets no exclusions, so all atom pairs interacting */
+    //! Constructor, sets no exclusions, so all atom pairs interacting
     MSVC_DIAGNOSTIC_IGNORE(26495) // pair is not being initialized!
     nbnxn_excl_t()
     {
@@ -166,32 +218,43 @@ struct nbnxn_excl_t
     }
     MSVC_DIAGNOSTIC_RESET
 
-    /* Topology exclusion interaction bits per warp */
+    //! Topology exclusion interaction bits per warp
     unsigned int pair[c_nbnxnGpuExclSize];
 };
 
-/* Cluster pairlist type for use on CPUs */
+//! Cluster pairlist type for use on CPUs
 struct NbnxnPairlistCpu
 {
     NbnxnPairlistCpu();
 
+    //! Cache protection
     gmx_cache_protect_t cp0;
 
-    int                    na_ci;   /* The number of atoms per i-cluster        */
-    int                    na_cj;   /* The number of atoms per j-cluster        */
-    real                   rlist;   /* The radius for constructing the list     */
-    FastVector<nbnxn_ci_t> ci;      /* The i-cluster list                       */
-    FastVector<nbnxn_ci_t> ciOuter; /* The outer, unpruned i-cluster list       */
-
-    FastVector<nbnxn_cj_t> cj;      /* The j-cluster list, size ncj             */
-    FastVector<nbnxn_cj_t> cjOuter; /* The outer, unpruned j-cluster list       */
-    int                    ncjInUse; /* The number of j-clusters that are used by ci entries in this list, will be <= cj.size() */
-
-    int nci_tot; /* The total number of i clusters           */
+    //! The number of atoms per i-cluster
+    int na_ci;
+    //! The number of atoms per j-cluster
+    int na_cj;
+    //! The radius for constructing the list
+    real rlist;
+    //! The i-cluster list
+    FastVector<nbnxn_ci_t> ci;
+    //! The outer, unpruned i-cluster list
+    FastVector<nbnxn_ci_t> ciOuter;
+
+    //! The j-cluster list, size ncj
+    FastVector<nbnxn_cj_t> cj;
+    //! The outer, unpruned j-cluster list
+    FastVector<nbnxn_cj_t> cjOuter;
+    //! The number of j-clusters that are used by ci entries in this list, will be <= cj.size()
+    int ncjInUse;
+
+    //! The total number of i clusters
+    int nci_tot;
 
-    /* Working data storage for list construction */
+    //! Working data storage for list construction
     std::unique_ptr<NbnxnPairlistCpuWork> work;
 
+    //! Cache protection
     gmx_cache_protect_t cp1;
 };
 
@@ -203,18 +266,23 @@ struct NbnxnPairlistCpu
  */
 struct NbnxnPairlistGpu
 {
-    /* Constructor
+    /*! \brief Constructor
      *
      * \param[in] pinningPolicy  Sets the pinning policy for all buffers used on the GPU
      */
     NbnxnPairlistGpu(gmx::PinningPolicy pinningPolicy);
 
+    //! Cache protection
     gmx_cache_protect_t cp0;
 
-    int  na_ci; /* The number of atoms per i-cluster        */
-    int  na_cj; /* The number of atoms per j-cluster        */
-    int  na_sc; /* The number of atoms per super cluster    */
-    real rlist; /* The radius for constructing the list     */
+    //! The number of atoms per i-cluster
+    int na_ci;
+    //! The number of atoms per j-cluster
+    int na_cj;
+    //! The number of atoms per super cluster
+    int na_sc;
+    //! The radius for constructing the list
+    real rlist;
     // The i-super-cluster list, indexes into cj4;
     gmx::HostVector<nbnxn_sci_t> sci;
     // The list of 4*j-cluster groups
@@ -224,9 +292,10 @@ struct NbnxnPairlistGpu
     // The total number of i-clusters
     int nci_tot;
 
-    /* Working data storage for list construction */
+    //! Working data storage for list construction
     std::unique_ptr<NbnxnPairlistGpuWork> work;
 
+    //! Cache protection
     gmx_cache_protect_t cp1;
 };