2e130dcb835930729d9623cb47413bd9a98721eb
[alexxy/gromacs.git] / src / gromacs / listed_forces / listed_internal.h
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2014,2015,2016,2017,2018 by the GROMACS development team.
5  * Copyright (c) 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 /*! \internal \file
37  *
38  * \brief This file contains declarations for functions needed
39  * internally by the module.
40  *
41  * \author Mark Abraham <mark.j.abraham@gmail.com>
42  * \author Berk Hess <hess@kth.se>
43  * \ingroup module_listed_forces
44  */
45 #ifndef GMX_LISTED_FORCES_LISTED_INTERNAL_H
46 #define GMX_LISTED_FORCES_LISTED_INTERNAL_H
47
48 #include <memory>
49
50 #include "gromacs/math/vectypes.h"
51 #include "gromacs/mdtypes/enerdata.h"
52 #include "gromacs/topology/idef.h"
53 #include "gromacs/topology/ifunc.h"
54 #include "gromacs/utility/alignedallocator.h"
55 #include "gromacs/utility/bitmask.h"
56 #include "gromacs/utility/classhelpers.h"
57
58 /* We reduce the force array in blocks of 32 atoms. This is large enough
59  * to not cause overhead and 32*sizeof(rvec) is a multiple of the cache-line
60  * size on all systems.
61  */
62 static const int reduction_block_size = 32; /**< Force buffer block size in atoms*/
63 static const int reduction_block_bits = 5;  /**< log2(reduction_block_size) */
64
65 /*! \internal \brief The division of bonded interactions of the threads */
66 class WorkDivision
67 {
68 public:
69     //! Constructor
70     WorkDivision(int numThreads) : stride_(numThreads + 1), packedBounds_(F_NRE * stride_) {}
71
72     //! Sets the bound between threads \p boundIndex-1 and \p boundIndex to \p count
73     void setBound(int functionType, int boundIndex, int count)
74     {
75         packedBounds_[functionType * stride_ + boundIndex] = count;
76     }
77
78     //! Returns the bound between threads \p boundIndex-1 and \p boundIndex
79     int bound(int functionType, int boundIndex) const
80     {
81         return packedBounds_[functionType * stride_ + boundIndex];
82     }
83
84     //! Returns the last bound
85     int end(int ftype) const { return bound(ftype, stride_ - 1); }
86
87 private:
88     //! The stride_ between and size of the entries for a function type
89     int stride_;
90     //! The bounds stored as a flat array for fast access
91     std::vector<int> packedBounds_;
92 };
93
94 /*! \internal \brief struct with output for bonded forces, used per thread */
95 struct f_thread_t
96 {
97     //! Constructor
98     f_thread_t(int numEnergyGroups);
99
100     ~f_thread_t() = default;
101
102     //! Force array pointer, equals fBuffer.data(), needed because rvec4 is not a C++ type
103     rvec4* f = nullptr;
104     //! Force array buffer
105     std::vector<real, gmx::AlignedAllocator<real>> fBuffer;
106     //! Mask for marking which parts of f are filled, working array for constructing mask in bonded_threading_t
107     std::vector<gmx_bitmask_t> mask;
108     //! Number of blocks touched by our thread
109     int nblock_used = 0;
110     //! Index to touched blocks
111     std::vector<int> block_index;
112
113     //! Shift force array, size SHIFTS
114     std::vector<gmx::RVec> fshift;
115     //! Energy array
116     real ener[F_NRE];
117     //! Group pair energy data for pairs
118     gmx_grppairener_t grpp;
119     //! Free-energy dV/dl output
120     real dvdl[efptNR];
121
122     GMX_DISALLOW_COPY_MOVE_AND_ASSIGN(f_thread_t);
123 };
124
125 /*! \internal \brief struct contain all data for bonded force threading */
126 struct bonded_threading_t
127 {
128     //! Constructor
129     bonded_threading_t(int numThreads, int numEnergyGroups, FILE* fplog);
130
131     //! Number of threads to be used for bondeds
132     int nthreads = 0;
133     //! Force/energy data per thread, size nthreads, stored in unique_ptr to allow thread local allocation
134     std::vector<std::unique_ptr<f_thread_t>> f_t;
135     //! The number of force blocks to reduce
136     int nblock_used = 0;
137     //! Index of size nblock_used into mask
138     std::vector<int> block_index;
139     //! Mask array, one element corresponds to a block of reduction_block_size atoms of the force array, bit corresponding to thread indices set if a thread writes to that block
140     std::vector<gmx_bitmask_t> mask;
141     //! true if we have and thus need to reduce bonded forces
142     bool haveBondeds = false;
143     //! The number of atoms forces are computed for
144     int numAtomsForce = 0;
145
146     /* There are two different ways to distribute the bonded force calculation
147      * over the threads. We dedice which to use based on the number of threads.
148      */
149     //! Maximum thread count for uniform distribution of bondeds over threads
150     int max_nthread_uniform = 0;
151
152     //! The division of work in the t_list over threads.
153     WorkDivision workDivision;
154
155     //! Work division for free-energy foreign lambda calculations, always uses 1 thread
156     WorkDivision foreignLambdaWorkDivision;
157
158     GMX_DISALLOW_COPY_MOVE_AND_ASSIGN(bonded_threading_t);
159 };
160
161
162 /*! \brief Returns the global topology atom number belonging to local
163  * atom index i.
164  *
165  * This function is intended for writing ascii output and returns atom
166  * numbers starting at 1.  When global_atom_index=NULL returns i+1.
167  */
168 int glatnr(const int* global_atom_index, int i);
169
170 #endif