Replace defines with constexpr in ishift
[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,2021, 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 #include "gromacs/utility/enumerationhelpers.h"
58
59 /* We reduce the force array in blocks of 32 atoms. This is large enough
60  * to not cause overhead and 32*sizeof(rvec) is a multiple of the cache-line
61  * size on all systems.
62  */
63 static const int reduction_block_size = 32; /**< Force buffer block size in atoms*/
64 static const int reduction_block_bits = 5;  /**< log2(reduction_block_size) */
65
66 /*! \internal \brief The division of bonded interactions of the threads */
67 class WorkDivision
68 {
69 public:
70     //! Constructor
71     WorkDivision(int numThreads) : stride_(numThreads + 1), packedBounds_(F_NRE * stride_) {}
72
73     //! Sets the bound between threads \p boundIndex-1 and \p boundIndex to \p count
74     void setBound(int functionType, int boundIndex, int count)
75     {
76         packedBounds_[functionType * stride_ + boundIndex] = count;
77     }
78
79     //! Returns the bound between threads \p boundIndex-1 and \p boundIndex
80     int bound(int functionType, int boundIndex) const
81     {
82         return packedBounds_[functionType * stride_ + boundIndex];
83     }
84
85     //! Returns the last bound
86     int end(int ftype) const { return bound(ftype, stride_ - 1); }
87
88 private:
89     //! The stride_ between and size of the entries for a function type
90     int stride_;
91     //! The bounds stored as a flat array for fast access
92     std::vector<int> packedBounds_;
93 };
94
95 /*! \internal \brief struct with output for bonded forces, used per thread */
96 struct f_thread_t
97 {
98     //! Constructor
99     f_thread_t(int numEnergyGroups);
100
101     ~f_thread_t() = default;
102
103     //! Force array pointer, equals fBuffer.data(), needed because rvec4 is not a C++ type
104     rvec4* f = nullptr;
105     //! Force array buffer
106     std::vector<real, gmx::AlignedAllocator<real>> fBuffer;
107     //! Mask for marking which parts of f are filled, working array for constructing mask in bonded_threading_t
108     std::vector<gmx_bitmask_t> mask;
109     //! Number of blocks touched by our thread
110     int nblock_used = 0;
111     //! Index to touched blocks
112     std::vector<int> block_index;
113
114     //! Shift force array, size c_numShiftVectors
115     std::vector<gmx::RVec> fshift;
116     //! Energy array
117     real ener[F_NRE];
118     //! Group pair energy data for pairs
119     gmx_grppairener_t grpp;
120     //! Free-energy dV/dl output
121     gmx::EnumerationArray<FreeEnergyPerturbationCouplingType, real> dvdl;
122
123     GMX_DISALLOW_COPY_MOVE_AND_ASSIGN(f_thread_t);
124 };
125
126 /*! \internal \brief struct contain all data for bonded force threading */
127 struct bonded_threading_t
128 {
129     //! Constructor
130     bonded_threading_t(int numThreads, int numEnergyGroups, FILE* fplog);
131
132     //! Number of threads to be used for bondeds
133     int nthreads = 0;
134     //! Force/energy data per thread, size nthreads, stored in unique_ptr to allow thread local allocation
135     std::vector<std::unique_ptr<f_thread_t>> f_t;
136     //! The number of force blocks to reduce
137     int nblock_used = 0;
138     //! Index of size nblock_used into mask
139     std::vector<int> block_index;
140     //! 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
141     std::vector<gmx_bitmask_t> mask;
142     //! true if we have and thus need to reduce bonded forces
143     bool haveBondeds = false;
144     //! The number of atoms forces are computed for
145     int numAtomsForce = 0;
146
147     /* There are two different ways to distribute the bonded force calculation
148      * over the threads. We dedice which to use based on the number of threads.
149      */
150     //! Maximum thread count for uniform distribution of bondeds over threads
151     int max_nthread_uniform = 0;
152
153     //! The division of work in the t_list over threads.
154     WorkDivision workDivision;
155
156     //! Work division for free-energy foreign lambda calculations, always uses 1 thread
157     WorkDivision foreignLambdaWorkDivision;
158
159     GMX_DISALLOW_COPY_MOVE_AND_ASSIGN(bonded_threading_t);
160 };
161
162
163 /*! \brief Returns the global topology atom number belonging to local
164  * atom index i.
165  *
166  * This function is intended for writing ascii output and returns atom
167  * numbers starting at 1.  When global_atom_index=NULL returns i+1.
168  */
169 int glatnr(const int* global_atom_index, int i);
170
171 #endif