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