"platforms/cpu/include/CpuNonbondedForceVec8.h" did not exist on "c27f5d1f41a9e712331abb091b05b72b84e5c1a4"
OpenCLNonbondedUtilities.h 11 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
#ifndef OPENMM_OPENCLNONBONDEDUTILITIES_H_
#define OPENMM_OPENCLNONBONDEDUTILITIES_H_

/* -------------------------------------------------------------------------- *
 *                                   OpenMM                                   *
 * -------------------------------------------------------------------------- *
 * This is part of the OpenMM molecular simulation toolkit originating from   *
 * Simbios, the NIH National Center for Physics-Based Simulation of           *
 * Biological Structures at Stanford, funded under the NIH Roadmap for        *
 * Medical Research, grant U54 GM072970. See https://simtk.org.               *
 *                                                                            *
12
 * Portions copyright (c) 2009-2010 Stanford University and the Authors.      *
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 * Authors: Peter Eastman                                                     *
 * Contributors:                                                              *
 *                                                                            *
 * This program is free software: you can redistribute it and/or modify       *
 * it under the terms of the GNU Lesser General Public License as published   *
 * by the Free Software Foundation, either version 3 of the License, or       *
 * (at your option) any later version.                                        *
 *                                                                            *
 * This program is distributed in the hope that it will be useful,            *
 * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
 * GNU Lesser General Public License for more details.                        *
 *                                                                            *
 * You should have received a copy of the GNU Lesser General Public License   *
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.      *
 * -------------------------------------------------------------------------- */

#include "OpenCLContext.h"
#include "openmm/System.h"
32
#include "OpenCLExpressionUtilities.h"
33
34
35
36
37
#include <string>
#include <vector>

namespace OpenMM {

38
39
class OpenCLCompact;

40
/**
41
 * This class provides a generic interface for calculating nonbonded interactions.  It does this in two
42
 * ways.  First, it can be used to create Kernels that evaluate nonbonded interactions.  Clients
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
 * only need to provide the code for evaluating a single interaction and the list of parameters it depends on.
 * A complete kernel is then synthesized using an appropriate algorithm to evaluate all interactions on all
 * atoms.
 *
 * Second, this class itself creates and invokes a single "default" interaction kernel, allowing several
 * different forces to be evaluated at once for greater efficiency.  Call addInteraction() and addParameter()
 * to add interactions to this default kernel.
 *
 * During each force or energy evaluation, the following sequence of steps takes place:
 *
 * 1. Data structures (e.g. neighbor lists) are calculated to allow nonbonded interactions to be evaluated
 * quickly.
 *
 * 2. calcForces() or calcEnergy() is called on each ForceImpl in the System.
 *
 * 3. Finally, the default interaction kernel is invoked to calculate all interactions that were added
 * to it.
 *
 * This sequence means that the default interaction kernel may depend on quantities that were calculated
 * by ForceImpls during calcForces() or calcEnergy().
63
64
 */

65
class OPENMM_EXPORT OpenCLNonbondedUtilities {
66
public:
67
    class ParameterInfo;
68
69
70
    OpenCLNonbondedUtilities(OpenCLContext& context);
    ~OpenCLNonbondedUtilities();
    /**
71
     * Add a nonbonded interaction to be evaluated by the default interaction kernel.
72
73
74
     *
     * @param usesCutoff     specifies whether a cutoff should be applied to this interaction
     * @param usesPeriodic   specifies whether periodic boundary conditions should be applied to this interaction
75
     * @param usesExclusions specifies whether this interaction uses exclusions.  If this is true, it must have identical exclusions to every other interaction.
76
77
     * @param cutoffDistance the cutoff distance for this interaction (ignored if usesCutoff is false)
     * @param exclusionList  for each atom, specifies the list of other atoms whose interactions should be excluded
78
     * @param kernel         the code to evaluate the interaction
79
     */
80
    void addInteraction(bool usesCutoff, bool usesPeriodic, bool usesExclusions, double cutoffDistance, const std::vector<std::vector<int> >& exclusionList, const std::string& kernel);
81
    /**
82
     * Add a per-atom parameter that the default interaction kernel may depend on.
83
     */
84
    void addParameter(const ParameterInfo& parameter);
85
86
87
88
    /**
     * Add an array (other than a per-atom parameter) that should be passed as an argument to the default interaction kernel.
     */
    void addArgument(const ParameterInfo& parameter);
89
90
91
92
93
94
95
96
97
98
    /**
     * Initialize this object in preparation for a simulation.
     */
    void initialize(const System& system);
    /**
     * Get the number of force buffers required for nonbonded forces.
     */
    int getNumForceBuffers() {
        return numForceBuffers;
    }
99
100
101
102
103
104
105
106
107
108
109
110
    /**
     * Get whether a cutoff is being used.
     */
    bool getUseCutoff() {
        return useCutoff;
    }
    /**
     * Get whether periodic boundary conditions are being used.
     */
    bool getUsePeriodic() {
        return usePeriodic;
    }
111
112
113
114
115
116
    /**
     * Get whether there is one force buffer per atom block.
     */
    bool getForceBufferPerAtomBlock() {
        return forceBufferPerAtomBlock;
    }
117
118
119
120
121
122
    /**
     * Get the cutoff distance.
     */
    double getCutoffDistance() {
        return cutoff;
    }
123
124
125
126
127
128
129
130
131
    /**
     * Prepare to compute interactions.  This updates the neighbor list.
     */
    void prepareInteractions();
    /**
     * Compute the nonbonded interactions.  This will only be executed once after each call to
     * prepareInteractions().  Additional calls return immediately without doing anything.
     */
    void computeInteractions();
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
    /**
     * Get the array containing the center of each atom block.
     */
    OpenCLArray<mm_float4>& getBlockCenters() {
        return *blockCenter;
    }
    /**
     * Get the array containing the dimensions of each atom block.
     */
    OpenCLArray<mm_float4>& getBlockBoundingBoxes() {
        return *blockBoundingBox;
    }
    /**
     * Get the array containing the full set of tiles.
     */
    OpenCLArray<cl_uint>& getTiles() {
        return *tiles;
    }
    /**
     * Get the array whose first element contains the number of tiles with interactions.
     */
    OpenCLArray<cl_uint>& getInteractionCount() {
        return *interactionCount;
    }
    /**
     * Get the array containing tiles with interactions.
     */
    OpenCLArray<cl_uint>& getInteractingTiles() {
        return *interactingTiles;
    }
    /**
     * Get the array containing flags for tiles with interactions.
     */
    OpenCLArray<cl_uint>& getInteractionFlags() {
        return *interactionFlags;
    }
168
169
170
171
172
173
174
175
176
177
    /**
     * Get the array containing exclusion flags.
     */
    OpenCLArray<cl_uint>& getExclusions() {
        return *exclusions;
    }
    /**
     * Get the array containing the index into the exclusion array for each tile.
     */
    OpenCLArray<cl_uint>& getExclusionIndices() {
178
179
180
181
182
183
184
        return *exclusionIndices;
    }
    /**
     * Get the array listing where the exclusion data starts for each row.
     */
    OpenCLArray<cl_uint>& getExclusionRowIndices() {
        return *exclusionRowIndices;
185
    }
186
187
188
189
190
191
192
    /**
     * Create a Kernel for evaluating a nonbonded interaction.  Cutoffs and periodic boundary conditions
     * are assumed to be the same as those for the default interaction Kernel, since this kernel will use
     * the same neighbor list.
     * 
     * @param source        the source code for evaluating the force and energy
     * @param params        the per-atom parameters this kernel may depend on
193
     * @param arguments     arrays (other than per-atom parameters) that should be passed as arguments to the kernel
194
     * @param useExclusions specifies whether exclusions are applied to this interaction
195
     * @param isSymmetric   specifies whether the interaction is symmetric
196
     */
197
    cl::Kernel createInteractionKernel(const std::string& source, const std::vector<ParameterInfo>& params, const std::vector<ParameterInfo>& arguments, bool useExclusions, bool isSymmetric) const;
198
private:
199
    static int findExclusionIndex(int x, int y, const std::vector<cl_uint>& exclusionIndices, const std::vector<cl_uint>& exclusionRowIndices);
200
201
    OpenCLContext& context;
    cl::Kernel forceKernel;
202
203
204
    cl::Kernel findBlockBoundsKernel;
    cl::Kernel findInteractingBlocksKernel;
    cl::Kernel findInteractionsWithinBlocksKernel;
205
206
    OpenCLArray<cl_uint>* tiles;
    OpenCLArray<cl_uint>* exclusions;
207
208
    OpenCLArray<cl_uint>* exclusionIndices;
    OpenCLArray<cl_uint>* exclusionRowIndices;
209
210
211
212
213
    OpenCLArray<cl_uint>* interactingTiles;
    OpenCLArray<cl_uint>* interactionFlags;
    OpenCLArray<cl_uint>* interactionCount;
    OpenCLArray<mm_float4>* blockCenter;
    OpenCLArray<mm_float4>* blockBoundingBox;
214
215
    std::vector<std::vector<int> > atomExclusions;
    std::vector<ParameterInfo> parameters;
216
    std::vector<ParameterInfo> arguments;
217
    OpenCLCompact* compact;
218
    std::string kernelSource;
219
    std::map<std::string, std::string> kernelDefines;
220
    double cutoff;
221
    bool useCutoff, usePeriodic, forceBufferPerAtomBlock;
222
223
224
    int numForceBuffers;
};

225
226
227
228
/**
 * This class stores information about a per-atom parameter that may be used in a nonbonded kernel.
 */

229
230
class OpenCLNonbondedUtilities::ParameterInfo {
public:
231
232
233
    /**
     * Create a ParameterInfo object.
     *
234
235
236
237
238
     * @param name           the name of the parameter
     * @param type           the data type of the parameter's components
     * @param numComponents  the number of components in the parameter
     * @param size           the size of the parameter in bytes
     * @param memory         the memory containing the parameter values
239
     */
240
241
242
243
244
245
    ParameterInfo(const std::string& name, const std::string& componentType, int numComponents, int size, cl::Memory& memory) :
            name(name), componentType(componentType), numComponents(numComponents), size(size), memory(&memory) {
        if (numComponents == 1)
            type = componentType;
        else
            type = componentType+OpenCLExpressionUtilities::intToString(numComponents);
246
    }
247
248
249
    const std::string& getName() const {
        return name;
    }
250
251
252
    const std::string& getComponentType() const {
        return componentType;
    }
253
254
255
    const std::string& getType() const {
        return type;
    }
256
257
258
    int getNumComponents() const {
        return numComponents;
    }
259
260
261
    int getSize() const {
        return size;
    }
262
263
    cl::Memory& getMemory() const {
        return *memory;
264
265
    }
private:
266
    std::string name;
267
    std::string componentType;
268
    std::string type;
269
    int size, numComponents;
270
    cl::Memory* memory;
271
272
273
274
275
};

} // namespace OpenMM

#endif /*OPENMM_OPENCLNONBONDEDUTILITIES_H_*/