Move nbnxm atomdata types to atomdata.h
[alexxy/gromacs.git] / src / gromacs / nbnxm / atomdata.h
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by
5  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6  * and including many others, as listed in the AUTHORS file in the
7  * top-level source directory and at http://www.gromacs.org.
8  *
9  * GROMACS is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * as published by the Free Software Foundation; either version 2.1
12  * of the License, or (at your option) any later version.
13  *
14  * GROMACS is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with GROMACS; if not, see
21  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
23  *
24  * If you want to redistribute modifications to GROMACS, please
25  * consider that scientific software is very special. Version
26  * control is crucial - bugs must be traceable. We will be happy to
27  * consider code for inclusion in the official distribution, but
28  * derived work must not be called official GROMACS. Details are found
29  * in the README & COPYING files - if they are missing, get the
30  * official version at http://www.gromacs.org.
31  *
32  * To help us fund GROMACS development, we humbly ask that you cite
33  * the research papers on the package. Check out http://www.gromacs.org.
34  */
35
36 #ifndef GMX_NBNXN_ATOMDATA_H
37 #define GMX_NBNXN_ATOMDATA_H
38
39 #include <cstdio>
40
41 #include "gromacs/gpu_utils/hostallocator.h"
42 #include "gromacs/math/vectypes.h"
43 #include "gromacs/utility/basedefinitions.h"
44 #include "gromacs/utility/bitmask.h"
45 #include "gromacs/utility/real.h"
46
47 #include "locality.h"
48
49 namespace gmx
50 {
51 class MDLogger;
52 }
53
54 struct gmx_wallcycle;
55 struct nbnxn_atomdata_t;
56 struct nbnxn_search;
57 struct nonbonded_verlet_t;
58 struct t_mdatoms;
59 struct tMPI_Atomic;
60
61 namespace Nbnxm
62 {
63 enum class KernelType;
64 }
65
66 /* Convenience type for vector with aligned memory */
67 template<typename T>
68 using AlignedVector = std::vector < T, gmx::AlignedAllocator < T>>;
69
70 enum {
71     nbatXYZ, nbatXYZQ, nbatX4, nbatX8
72 };
73
74 // Struct that holds force and energy output buffers
75 struct nbnxn_atomdata_output_t
76 {
77     /* Constructor
78      *
79      * \param[in] kernelType              Type of non-bonded kernel
80      * \param[in] numEnergyGroups         The number of energy groups
81      * \param[in] simdEnergyBufferStride  Stride for entries in the energy buffers for SIMD kernels
82      * \param[in] pinningPolicy           Sets the pinning policy for all buffers used on the GPU
83      */
84     nbnxn_atomdata_output_t(Nbnxm::KernelType  kernelType,
85                             int                numEnergyGroups,
86                             int                simdEnergyBUfferStride,
87                             gmx::PinningPolicy pinningPolicy);
88
89     gmx::HostVector<real> f;      // f, size natoms*fstride
90     gmx::HostVector<real> fshift; // Shift force array, size SHIFTS*DIM
91     gmx::HostVector<real> Vvdw;   // Temporary Van der Waals group energy storage
92     gmx::HostVector<real> Vc;     // Temporary Coulomb group energy storage
93     AlignedVector<real>   VSvdw;  // Temporary SIMD Van der Waals group energy storage
94     AlignedVector<real>   VSc;    // Temporary SIMD Coulomb group energy storage
95 };
96
97 /* Block size in atoms for the non-bonded thread force-buffer reduction,
98  * should be a multiple of all cell and x86 SIMD sizes (i.e. 2, 4 and 8).
99  * Should be small to reduce the reduction and zeroing cost,
100  * but too small will result in overhead.
101  * Currently the block size is NBNXN_BUFFERFLAG_SIZE*3*sizeof(real)=192 bytes.
102  */
103 #if GMX_DOUBLE
104 #define NBNXN_BUFFERFLAG_SIZE   8
105 #else
106 #define NBNXN_BUFFERFLAG_SIZE  16
107 #endif
108
109 /* We store the reduction flags as gmx_bitmask_t.
110  * This limits the number of flags to BITMASK_SIZE.
111  */
112 #define NBNXN_BUFFERFLAG_MAX_THREADS  (BITMASK_SIZE)
113
114 /* Flags for telling if threads write to force output buffers */
115 typedef struct {
116     int               nflag;       /* The number of flag blocks                         */
117     gmx_bitmask_t    *flag;        /* Bit i is set when thread i writes to a cell-block */
118     int               flag_nalloc; /* Allocation size of cxy_flag                       */
119 } nbnxn_buffer_flags_t;
120
121 /* LJ combination rules: geometric, Lorentz-Berthelot, none */
122 enum {
123     ljcrGEOM, ljcrLB, ljcrNONE, ljcrNR
124 };
125
126 /* Struct that stores atom related data for the nbnxn module
127  *
128  * Note: performance would improve slightly when all std::vector containers
129  *       in this struct would not initialize during resize().
130  */
131 struct nbnxn_atomdata_t
132 {   //NOLINT(clang-analyzer-optin.performance.Padding)
133     struct Params
134     {
135         /* Constructor
136          *
137          * \param[in] pinningPolicy  Sets the pinning policy for all data that might be transfered to a GPU
138          */
139         Params(gmx::PinningPolicy pinningPolicy);
140
141         // The number of different atom types
142         int                   numTypes;
143         // Lennard-Jone 6*C6 and 12*C12 parameters, size numTypes*2*2
144         gmx::HostVector<real> nbfp;
145         // Combination rule, see enum defined above
146         int                   comb_rule;
147         // LJ parameters per atom type, size numTypes*2
148         gmx::HostVector<real> nbfp_comb;
149         // As nbfp, but with a stride for the present SIMD architecture
150         AlignedVector<real>   nbfp_aligned;
151         // Atom types per atom
152         gmx::HostVector<int>  type;
153         // LJ parameters per atom for fast SIMD loading
154         gmx::HostVector<real> lj_comb;
155         // Charges per atom, not set with format nbatXYZQ
156         gmx::HostVector<real> q;
157         // The number of energy groups
158         int                   nenergrp;
159         // 2log(nenergrp)
160         int                   neg_2log;
161         // The energy groups, one int entry per cluster, only set when needed
162         gmx::HostVector<int>  energrp;
163     };
164
165     // Diagonal and topology exclusion helper data for all SIMD kernels
166     struct SimdMasks
167     {
168         SimdMasks();
169
170         // Helper data for setting up diagonal exclusion masks in the SIMD 4xN kernels
171         AlignedVector<real>     diagonal_4xn_j_minus_i;
172         // Helper data for setting up diaginal exclusion masks in the SIMD 2xNN kernels
173         AlignedVector<real>     diagonal_2xnn_j_minus_i;
174         // Filters for topology exclusion masks for the SIMD kernels
175         AlignedVector<uint32_t> exclusion_filter;
176         // Filters for topology exclusion masks for double SIMD kernels without SIMD int32 logical support
177         AlignedVector<uint64_t> exclusion_filter64;
178         // Array of masks needed for exclusions
179         AlignedVector<real>     interaction_array;
180     };
181
182     /* Constructor
183      *
184      * \param[in] pinningPolicy  Sets the pinning policy for all data that might be transfered to a GPU
185      */
186     nbnxn_atomdata_t(gmx::PinningPolicy pinningPolicy);
187
188     /* Returns a const reference to the parameters */
189     const Params &params() const
190     {
191         return params_;
192     }
193
194     /* Returns a non-const reference to the parameters */
195     Params &paramsDeprecated()
196     {
197         return params_;
198     }
199
200     /* Returns the current total number of atoms stored */
201     int numAtoms() const
202     {
203         return numAtoms_;
204     }
205
206     /* Return the coordinate buffer, and q with xFormat==nbatXYZQ */
207     gmx::ArrayRef<const real> x() const
208     {
209         return x_;
210     }
211
212     /* Return the coordinate buffer, and q with xFormat==nbatXYZQ */
213     gmx::ArrayRef<real> x()
214     {
215         return x_;
216     }
217
218     /* Resizes the coordinate buffer and sets the number of atoms */
219     void resizeCoordinateBuffer(int numAtoms);
220
221     /* Resizes the force buffers for the current number of atoms */
222     void resizeForceBuffers();
223
224     private:
225         // The LJ and charge parameters
226         Params                     params_;
227         // The total number of atoms currently stored
228         int                        numAtoms_;
229     public:
230         int                        natoms_local; /* Number of local atoms                           */
231         int                        XFormat;      /* The format of x (and q), enum                      */
232         int                        FFormat;      /* The format of f, enum                              */
233         gmx_bool                   bDynamicBox;  /* Do we need to update shift_vec every step?    */
234         gmx::HostVector<gmx::RVec> shift_vec;    /* Shift vectors, copied from t_forcerec              */
235         int                        xstride;      /* stride for a coordinate in x (usually 3 or 4)      */
236         int                        fstride;      /* stride for a coordinate in f (usually 3 or 4)      */
237     private:
238         gmx::HostVector<real>      x_;           /* x and possibly q, size natoms*xstride              */
239
240     public:
241         // Masks for handling exclusions in the SIMD kernels
242         const SimdMasks          simdMasks;
243
244         /* Output data */
245         std::vector<nbnxn_atomdata_output_t> out; /* Output data structures, 1 per thread */
246
247         /* Reduction related data */
248         gmx_bool                 bUseBufferFlags;     /* Use the flags or operate on all atoms     */
249         nbnxn_buffer_flags_t     buffer_flags;        /* Flags for buffer zeroing+reduc.  */
250         gmx_bool                 bUseTreeReduce;      /* Use tree for force reduction */
251         tMPI_Atomic             *syncStep;            /* Synchronization step for tree reduce */
252 };
253
254 /* Copy na rvec elements from x to xnb using nbatFormat, start dest a0,
255  * and fills up to na_round with coordinates that are far away.
256  */
257 void copy_rvec_to_nbat_real(const int *a, int na, int na_round,
258                             const rvec *x, int nbatFormat,
259                             real *xnb, int a0);
260
261 enum {
262     enbnxninitcombruleDETECT, enbnxninitcombruleGEOM, enbnxninitcombruleLB, enbnxninitcombruleNONE
263 };
264
265 /* Initialize the non-bonded atom data structure.
266  * The enum for nbatXFormat is in the file defining nbnxn_atomdata_t.
267  * Copy the ntypes*ntypes*2 sized nbfp non-bonded parameter list
268  * to the atom data structure.
269  * enbnxninitcombrule sets what combination rule data gets stored in nbat.
270  */
271 void nbnxn_atomdata_init(const gmx::MDLogger &mdlog,
272                          nbnxn_atomdata_t *nbat,
273                          Nbnxm::KernelType kernelType,
274                          int enbnxninitcombrule,
275                          int ntype, const real *nbfp,
276                          int n_energygroups,
277                          int nout);
278
279 void nbnxn_atomdata_set(nbnxn_atomdata_t    *nbat,
280                         const nbnxn_search  *nbs,
281                         const t_mdatoms     *mdatoms,
282                         const int           *atinfo);
283
284 /* Copy the shift vectors to nbat */
285 void nbnxn_atomdata_copy_shiftvec(gmx_bool          dynamic_box,
286                                   rvec             *shift_vec,
287                                   nbnxn_atomdata_t *nbat);
288
289 /* Copy x to nbat->x.
290  * FillLocal tells if the local filler particle coordinates should be zeroed.
291  */
292 void nbnxn_atomdata_copy_x_to_nbat_x(const nbnxn_search  *nbs,
293                                      Nbnxm::AtomLocality  locality,
294                                      gmx_bool             FillLocal,
295                                      rvec                *x,
296                                      nbnxn_atomdata_t    *nbat,
297                                      gmx_wallcycle       *wcycle);
298
299 /* Add the fshift force stored in nbat to fshift */
300 void nbnxn_atomdata_add_nbat_fshift_to_fshift(const nbnxn_atomdata_t *nbat,
301                                               rvec                   *fshift);
302
303 #endif