3f7c62705fa7045dc58762adcdbf8f4b3b305e30
[alexxy/gromacs.git] / src / gromacs / nbnxm / pairlist.h
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2012,2013,2014,2015,2016 by the GROMACS development team.
5  * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by
6  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
7  * and including many others, as listed in the AUTHORS file in the
8  * top-level source directory and at http://www.gromacs.org.
9  *
10  * GROMACS is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public License
12  * as published by the Free Software Foundation; either version 2.1
13  * of the License, or (at your option) any later version.
14  *
15  * GROMACS is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with GROMACS; if not, see
22  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
23  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
24  *
25  * If you want to redistribute modifications to GROMACS, please
26  * consider that scientific software is very special. Version
27  * control is crucial - bugs must be traceable. We will be happy to
28  * consider code for inclusion in the official distribution, but
29  * derived work must not be called official GROMACS. Details are found
30  * in the README & COPYING files - if they are missing, get the
31  * official version at http://www.gromacs.org.
32  *
33  * To help us fund GROMACS development, we humbly ask that you cite
34  * the research papers on the package. Check out http://www.gromacs.org.
35  */
36
37 #ifndef GMX_NBNXM_PAIRLIST_H
38 #define GMX_NBNXM_PAIRLIST_H
39
40 #include <cstddef>
41
42 #include "gromacs/gpu_utils/hostallocator.h"
43 #include "gromacs/math/vectypes.h"
44 #include "gromacs/mdtypes/locality.h"
45 #include "gromacs/mdtypes/nblist.h"
46 #include "gromacs/utility/basedefinitions.h"
47 #include "gromacs/utility/defaultinitializationallocator.h"
48 #include "gromacs/utility/enumerationhelpers.h"
49 #include "gromacs/utility/real.h"
50
51 // This file with constants is separate from this file to be able
52 // to include it during OpenCL jitting without including config.h
53 #include "constants.h"
54 #include "pairlistparams.h"
55
56 struct NbnxnPairlistCpuWork;
57 struct NbnxnPairlistGpuWork;
58
59
60 //! Convenience type for vector with aligned memory
61 template<typename T>
62 using AlignedVector = std::vector<T, gmx::AlignedAllocator<T>>;
63
64 //! Convenience type for vector that avoids initialization at resize()
65 template<typename T>
66 using FastVector = std::vector<T, gmx::DefaultInitializationAllocator<T>>;
67
68 /*! \brief Cache-line protection buffer
69  *
70  * A buffer data structure of 64 bytes
71  * to be placed at the beginning and end of structs
72  * to avoid cache invalidation of the real contents
73  * of the struct by writes to neighboring memory.
74  */
75 typedef struct
76 {
77     //! Unused field used to create space to protect cache lines that are in use
78     int dummy[16];
79 } gmx_cache_protect_t;
80
81 /*! \brief This is the actual cluster-pair list j-entry.
82  *
83  * cj is the j-cluster.
84  * The interaction bits in excl are indexed i-major, j-minor.
85  * The cj entries are sorted such that ones with exclusions come first.
86  * This means that once a full mask (=NBNXN_INTERACTION_MASK_ALL)
87  * is found, all subsequent j-entries in the i-entry also have full masks.
88  */
89 struct nbnxn_cj_t
90 {
91     //! The j-cluster
92     int cj;
93     //! The exclusion (interaction) bits
94     unsigned int excl;
95 };
96
97 /*! \brief Constants for interpreting interaction flags
98  *
99  * In nbnxn_ci_t the integer shift contains the shift in the lower 7 bits.
100  * The upper bits contain information for non-bonded kernel optimization.
101  * Simply calculating LJ and Coulomb for all pairs in a cluster pair is fine.
102  * But three flags can be used to skip interactions, currently only for subc=0
103  * !(shift & NBNXN_CI_DO_LJ(subc))   => we can skip LJ for all pairs
104  * shift & NBNXN_CI_HALF_LJ(subc)    => we can skip LJ for the second half of i
105  * !(shift & NBNXN_CI_DO_COUL(subc)) => we can skip Coulomb for all pairs
106  */
107 //! \{
108 #define NBNXN_CI_SHIFT 127
109 #define NBNXN_CI_DO_LJ(subc) (1 << (7 + 3 * (subc)))
110 #define NBNXN_CI_HALF_LJ(subc) (1 << (8 + 3 * (subc)))
111 #define NBNXN_CI_DO_COUL(subc) (1 << (9 + 3 * (subc)))
112 //! \}
113
114 /*! \brief Cluster-pair Interaction masks
115  *
116  * Bit i*j-cluster-size + j tells if atom i and j interact.
117  */
118 //! \{
119 // TODO: Rename according to convention when moving into Nbnxn namespace
120 //! All interaction mask is the same for all kernels
121 constexpr unsigned int NBNXN_INTERACTION_MASK_ALL = 0xffffffffU;
122 //! 4x4 kernel diagonal mask
123 constexpr unsigned int NBNXN_INTERACTION_MASK_DIAG = 0x08ceU;
124 //! 4x2 kernel diagonal masks
125 //! \{
126 constexpr unsigned int NBNXN_INTERACTION_MASK_DIAG_J2_0 = 0x0002U;
127 constexpr unsigned int NBNXN_INTERACTION_MASK_DIAG_J2_1 = 0x002fU;
128 //! \}
129 //! 4x8 kernel diagonal masks
130 //! \{
131 constexpr unsigned int NBNXN_INTERACTION_MASK_DIAG_J8_0 = 0xf0f8fcfeU;
132 constexpr unsigned int NBNXN_INTERACTION_MASK_DIAG_J8_1 = 0x0080c0e0U;
133 //! \}
134 //! \}
135
136 /*! \internal
137  * \brief Simple pair-list i-unit
138  */
139 struct nbnxn_ci_t
140 {
141     //! i-cluster
142     int ci;
143     //! Shift vector index plus possible flags, see above
144     int shift;
145     //! Start index into cj
146     int cj_ind_start;
147     //! End index into cj
148     int cj_ind_end;
149 };
150
151 //! Grouped pair-list i-unit
152 typedef struct
153 {
154     //! Returns the number of j-cluster groups in this entry
155     int numJClusterGroups() const { return cj4_ind_end - cj4_ind_start; }
156
157     //! i-super-cluster
158     int sci;
159     //! Shift vector index plus possible flags
160     int shift;
161     //! Start index into cj4
162     int cj4_ind_start;
163     //! End index into cj4
164     int cj4_ind_end;
165 } nbnxn_sci_t;
166
167 //! Interaction data for a j-group for one warp
168 struct nbnxn_im_ei_t
169 {
170     //! The i-cluster interactions mask for 1 warp
171     unsigned int imask = 0U;
172     //! Index into the exclusion array for 1 warp, default index 0 which means no exclusions
173     int excl_ind = 0;
174 };
175
176 //! Four-way j-cluster lists
177 typedef struct
178 {
179     //! The 4 j-clusters
180     int cj[c_nbnxnGpuJgroupSize];
181     //! The i-cluster mask data for 2 warps
182     nbnxn_im_ei_t imei[c_nbnxnGpuClusterpairSplit];
183 } nbnxn_cj4_t;
184
185 //! Struct for storing the atom-pair interaction bits for a cluster pair in a GPU pairlist
186 struct nbnxn_excl_t
187 {
188     //! Constructor, sets no exclusions, so all atom pairs interacting
189     nbnxn_excl_t()
190     {
191         for (unsigned int& pairEntry : pair)
192         {
193             pairEntry = NBNXN_INTERACTION_MASK_ALL;
194         }
195     }
196
197     //! Topology exclusion interaction bits per warp
198     unsigned int pair[c_nbnxnGpuExclSize];
199 };
200
201 //! Cluster pairlist type for use on CPUs
202 struct NbnxnPairlistCpu
203 {
204     NbnxnPairlistCpu();
205
206     //! Cache protection
207     gmx_cache_protect_t cp0;
208
209     //! The number of atoms per i-cluster
210     int na_ci;
211     //! The number of atoms per j-cluster
212     int na_cj;
213     //! The radius for constructing the list
214     real rlist;
215     //! The i-cluster list
216     FastVector<nbnxn_ci_t> ci;
217     //! The outer, unpruned i-cluster list
218     FastVector<nbnxn_ci_t> ciOuter;
219
220     //! The j-cluster list, size ncj
221     FastVector<nbnxn_cj_t> cj;
222     //! The outer, unpruned j-cluster list
223     FastVector<nbnxn_cj_t> cjOuter;
224     //! The number of j-clusters that are used by ci entries in this list, will be <= cj.size()
225     int ncjInUse;
226
227     //! The total number of i clusters
228     int nci_tot;
229
230     //! Working data storage for list construction
231     std::unique_ptr<NbnxnPairlistCpuWork> work;
232
233     //! Cache protection
234     gmx_cache_protect_t cp1;
235 };
236
237 /* Cluster pairlist type, with extra hierarchies, for on the GPU
238  *
239  * NOTE: for better performance when combining lists over threads,
240  *       all vectors should use default initialization. But when
241  *       changing this, excl should be intialized when adding entries.
242  */
243 struct NbnxnPairlistGpu
244 {
245     /*! \brief Constructor
246      *
247      * \param[in] pinningPolicy  Sets the pinning policy for all buffers used on the GPU
248      */
249     NbnxnPairlistGpu(gmx::PinningPolicy pinningPolicy);
250
251     //! Cache protection
252     gmx_cache_protect_t cp0;
253
254     //! The number of atoms per i-cluster
255     int na_ci;
256     //! The number of atoms per j-cluster
257     int na_cj;
258     //! The number of atoms per super cluster
259     int na_sc;
260     //! The radius for constructing the list
261     real rlist;
262     // The i-super-cluster list, indexes into cj4;
263     gmx::HostVector<nbnxn_sci_t> sci;
264     // The list of 4*j-cluster groups
265     gmx::HostVector<nbnxn_cj4_t> cj4;
266     // Atom interaction bits (non-exclusions)
267     gmx::HostVector<nbnxn_excl_t> excl;
268     // The total number of i-clusters
269     int nci_tot;
270
271     //! Working data storage for list construction
272     std::unique_ptr<NbnxnPairlistGpuWork> work;
273
274     //! Cache protection
275     gmx_cache_protect_t cp1;
276 };
277
278 //! Initializes a free-energy pair-list
279 void nbnxn_init_pairlist_fep(t_nblist* nl);
280
281 #endif