368ebcf34fa412eff11815bbf54b17a31c209e15
[alexxy/gromacs.git] / src / gromacs / nbnxm / internal.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 /*! \internal \file
37  *
38  * \brief Declares internal nbnxm module details
39  *
40  * \author Berk Hess <hess@kth.se>
41  *
42  * \ingroup module_nbnxm
43  */
44
45 #ifndef GMX_NBNXM_INTERNAL_H
46 #define GMX_NBNXM_INTERNAL_H
47
48 #include <memory>
49 #include <vector>
50
51 #include "gromacs/domdec/domdec.h"
52 #include "gromacs/math/vectypes.h"
53 #include "gromacs/nbnxm/atomdata.h"
54 #include "gromacs/nbnxm/pairlist.h"
55 #include "gromacs/timing/cyclecounter.h"
56 #include "gromacs/utility/alignedallocator.h"
57 #include "gromacs/utility/arrayref.h"
58 #include "gromacs/utility/real.h"
59
60 #include "gridset.h"
61
62 struct gmx_domdec_zones_t;
63
64
65 /*! \brief Convenience declaration for an std::vector with aligned memory */
66 template <class T>
67 using AlignedVector = std::vector < T, gmx::AlignedAllocator < T>>;
68
69
70 /* Local cycle count struct for profiling */
71 class nbnxn_cycle_t
72 {
73     public:
74         void start()
75         {
76             start_ = gmx_cycles_read();
77         }
78
79         void stop()
80         {
81             cycles_ += gmx_cycles_read() - start_;
82             count_++;
83         }
84
85         int count() const
86         {
87             return count_;
88         }
89
90         double averageMCycles() const
91         {
92             if (count_ > 0)
93             {
94                 return static_cast<double>(cycles_)*1e-6/count_;
95             }
96             else
97             {
98                 return 0;
99             }
100         }
101
102     private:
103         int          count_  = 0;
104         gmx_cycles_t cycles_ = 0;
105         gmx_cycles_t start_  = 0;
106 };
107
108 // TODO: Move nbnxn_search_work_t definition to its own file
109
110 /* Thread-local work struct, contains working data for Grid */
111 struct PairsearchWork
112 {
113     PairsearchWork();
114
115     ~PairsearchWork();
116
117     gmx_cache_protect_t       cp0;          /* Buffer to avoid cache polution */
118
119     std::vector<int>          sortBuffer;   /* Temporary buffer for sorting atoms within a grid column */
120
121     nbnxn_buffer_flags_t      buffer_flags; /* Flags for force buffer access */
122
123     int                       ndistc;       /* Number of distance checks for flop counting */
124
125
126     std::unique_ptr<t_nblist> nbl_fep;      /* Temporary FEP list for load balancing */
127
128     nbnxn_cycle_t             cycleCounter; /* Counter for thread-local cycles */
129
130     gmx_cache_protect_t       cp1;          /* Buffer to avoid cache polution */
131 };
132
133 /* Main pair-search struct, contains the grid(s), not the pair-list(s) */
134 class PairSearch
135 {
136     public:
137         /*! \internal
138          * \brief Description of the domain setup: PBC and the connections between domains
139          */
140         struct DomainSetup
141         {
142             /*! \internal
143              * \brief Description of the domain setup: PBC and the connections between domains
144              */
145             //! Constructor, without DD \p numDDCells and \p ddZones should be nullptr
146             DomainSetup(int                       ePBC,
147                         const ivec               *numDDCells,
148                         const gmx_domdec_zones_t *ddZones);
149
150             //! The type of PBC
151             int                       ePBC;
152             //! Tells whether we are using domain decomposition
153             bool                      haveDomDec;
154             //! Tells whether we are using domain decomposition per dimension
155             std::array<bool, DIM>     haveDomDecPerDim;
156             //! The domain decomposition zone setup
157             const gmx_domdec_zones_t *zones;
158         };
159
160         //! Local cycle count enum for profiling different parts of search
161         enum {
162             enbsCCgrid, enbsCCsearch, enbsCCcombine, enbsCCnr
163         };
164
165         struct SearchCycleCounting
166         {
167             //! Start a pair search cycle counter
168             void start(const int enbsCC)
169             {
170                 cc_[enbsCC].start();
171             }
172
173             //! Stop a pair search cycle counter
174             void stop(const int enbsCC)
175             {
176                 cc_[enbsCC].stop();
177             }
178
179             //! Print the cycle counts to \p fp
180             void printCycles(FILE                               *fp,
181                              gmx::ArrayRef<const PairsearchWork> work) const;
182
183             bool          recordCycles_ = false;
184             int           searchCount_  = 0;
185             nbnxn_cycle_t cc_[enbsCCnr];
186         };
187
188         //! Puts the atoms in \p ddZone on the grid and copies the coordinates to \p nbat
189         void putOnGrid(const matrix                    box,
190                        int                             ddZone,
191                        const rvec                      lowerCorner,
192                        const rvec                      upperCorner,
193                        const gmx::UpdateGroupsCog     *updateGroupsCog,
194                        int                             atomStart,
195                        int                             atomEnd,
196                        real                            atomDensity,
197                        const int                      *atinfo,
198                        gmx::ArrayRef<const gmx::RVec>  x,
199                        int                             numAtomsMoved,
200                        const int                      *move,
201                        nbnxn_atomdata_t               *nbat)
202         {
203             cycleCounting_.start(enbsCCgrid);
204
205             gridSet_.putOnGrid(box, ddZone, lowerCorner, upperCorner,
206                                updateGroupsCog, atomStart, atomEnd, atomDensity,
207                                atinfo, x, numAtomsMoved, move, nbat);
208
209             cycleCounting_.stop(enbsCCgrid);
210         }
211
212         /* \brief Constructor
213          *
214          * \param[in] ePBC            The periodic boundary conditions
215          * \param[in] numDDCells      The number of domain decomposition cells per dimension, without DD nullptr should be passed
216          * \param[in] zones           The domain decomposition zone setup, without DD nullptr should be passed
217          * \param[in] haveFep         Tells whether non-bonded interactions are perturbed
218          * \param[in] maxNumThreads   The maximum number of threads used in the search
219          */
220         PairSearch(int                       ePBC,
221                    const ivec               *numDDCells,
222                    const gmx_domdec_zones_t *zones,
223                    PairlistType              pairlistType,
224                    bool                      haveFep,
225                    int                       maxNumthreads);
226
227         //! Sets the order of the local atoms to the order grid atom ordering
228         void setLocalAtomOrder()
229         {
230             gridSet_.setLocalAtomOrder();
231         }
232
233         const DomainSetup domainSetup() const
234         {
235             return domainSetup_;
236         }
237
238         //! Returns the set of search grids
239         const Nbnxm::GridSet &gridSet() const
240         {
241             return gridSet_;
242         }
243
244         //! Returns the list of thread-local work objects
245         gmx::ArrayRef<const PairsearchWork> work() const
246         {
247             return work_;
248         }
249
250         //! Returns the list of thread-local work objects
251         gmx::ArrayRef<PairsearchWork> work()
252         {
253             return work_;
254         }
255
256     private:
257         //! The domain setup
258         DomainSetup                 domainSetup_;
259         //! The set of search grids
260         Nbnxm::GridSet              gridSet_;
261         //! Work objects, one entry for each thread
262         std::vector<PairsearchWork> work_;
263
264     public:
265         //! Cycle counting for measuring components of the search
266         SearchCycleCounting  cycleCounting_;
267 };
268
269 #endif