OpenCLContext.h 7.03 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#ifndef OPENMM_OPENCLCONTEXT_H_
#define OPENMM_OPENCLCONTEXT_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.               *
 *                                                                            *
 * Portions copyright (c) 2009 Stanford University and the Authors.           *
 * 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/>.      *
 * -------------------------------------------------------------------------- */

#define __CL_ENABLE_EXCEPTIONS
31
#include <cl.hpp>
32
33
34
35
36

namespace OpenMM {

template <class T>
class OpenCLArray;
37
38
class OpenCLForceInfo;
class System;
39

40
/**
41
42
43
 * We can't use predefined vector types like cl_float4, since different OpenCL implementations currently define
 * them in incompatible ways.  Hopefully that will be fixed in the future.  In the mean time, we define our own
 * types to represent them on the host.
44
45
 */

46
47
48
typedef struct {
    cl_float x, y;
} mm_float2;
49
50
51
typedef struct {
    cl_float x, y, z, w;
} mm_float4;
52
53
54
55
56
57
typedef struct {
    cl_int x, y;
} mm_int2;
typedef struct {
    cl_int x, y, z, w;
} mm_int4;
58
59
60
typedef struct {
    cl_int s0, s1, s2, s3, s4, s5, s6, s7;
} mm_int8;
61

62
63
64
65
66
67
/**
 * This class contains the information associated with a Context by the OpenCL Platform.
 */

class OpenCLContext {
public:
68
69
    static const int ThreadBlockSize = 64;
    static const int TileSize = 32;
70
    OpenCLContext(int numParticles, int deviceIndex);
71
    ~OpenCLContext();
72
73
74
75
76
77
78
79
80
    /**
     * This is called to initialize internal data structures after all Forces in the system
     * have been initialized.
     */
    void initialize(const System& system);
    /**
     * Add an OpenCLForce to this context.
     */
    void addForce(OpenCLForceInfo* force);
81
82
83
84
    /**
     * Get the cl::Context associated with this object.
     */
    cl::Context& getContext() {
85
        return context;
86
87
88
89
90
    }
    /**
     * Get the cl::CommandQueue associated with this object.
     */
    cl::CommandQueue& getQueue() {
91
        return queue;
92
93
94
95
    }
    /**
     * Get the array which contains the position and charge of each atom.
     */
96
    OpenCLArray<mm_float4>& getPosq() {
97
98
99
100
101
        return *posq;
    }
    /**
     * Get the array which contains the velocity and massof each atom.
     */
102
    OpenCLArray<mm_float4>& getVelm() {
103
104
105
106
107
        return *velm;
    }
    /**
     * Get the array which contains the force on each atom.
     */
108
    OpenCLArray<mm_float4>& getForce() {
109
110
        return *force;
    }
111
112
113
    /**
     * Get the array which contains the buffers in which forces are computed.
     */
114
    OpenCLArray<mm_float4>& getForceBuffers() {
115
116
        return *forceBuffers;
    }
117
118
119
120
121
122
    /**
     * Get the array which contains the buffer in which energy is computed.
     */
    OpenCLArray<cl_float>& getEnergyBuffer() {
        return *energyBuffer;
    }
123
124
125
126
127
128
    /**
     * Get the array which contains the index of each atom.
     */
    OpenCLArray<cl_int>& getAtomIndex() {
        return *atomIndex;
    }
129
130
131
132
133
134
135
136
    /**
     * Load OpenCL source code from a file in the kernels directory.
     */
    std::string loadSourceFromFile(const std::string& filename) const;
    /**
     * Create an OpenCL Program from source code.
     */
    cl::Program createProgram(const std::string source);
137
138
139
140
141
142
143
    /**
     * Execute a kernel.
     *
     * @param kernel    the kernel to execute
     * @param workUnits the maximum number of work units that should be used
     */
    void executeKernel(cl::Kernel& kernel, int workUnits);
144
145
146
147
148
149
150
    /**
     * Set all elements of an array to 0.
     */
    void clearBuffer(OpenCLArray<float>& array);
    /**
     * Set all elements of an array to 0.
     */
151
    void clearBuffer(OpenCLArray<mm_float4>& array);
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
    /**
     * Given a collection of buffers packed into an array, sum them and store
     * the sum in the first buffer.
     *
     * @param array       the array containing the buffers to reduce
     * @param numBuffers  the number of buffers packed into the array
     */
    void reduceBuffer(OpenCLArray<mm_float4>& array, int numBuffers);
    /**
     * Get the number of atoms.
     */
    int getNumAtoms() const {
        return numAtoms;
    }
    /**
     * Get the number of atoms, rounded up to a multiple of TileSize.  This is the actual size of
     * most arrays with one element per atom.
     */
    int getPaddedNumAtoms() const {
        return paddedNumAtoms;
    }
    /**
     * Get the number of blocks of TileSize atoms.
     */
    int getNumAtomBlocks() const {
        return numAtomBlocks;
    }
    /**
     * Get the standard number of thread blocks to use when executing kernels.
     */
    int getNumThreadBlocks() const {
        return numThreadBlocks;
    }
    /**
     * Get the total number of tiles used for nonbonded computation.
     */
    int getNumTiles() const {
        return numTiles;
    }
    /**
     * Get the number of force buffers.
     */
    int getNumForceBuffers() const {
        return numForceBuffers;
    }
private:
198
199
200
201
202
203
204
205
206
207
208
    int numAtoms;
    int paddedNumAtoms;
    int numAtomBlocks;
    int numTiles;
    int numThreadBlocks;
    int numForceBuffers;
    cl::Context context;
    cl::Device device;
    cl::CommandQueue queue;
    cl::Program utilities;
    cl::Kernel clearBufferKernel;
209
210
    cl::Kernel reduceFloat4Kernel;
    std::vector<OpenCLForceInfo*> forces;
211
212
213
214
    OpenCLArray<mm_float4>* posq;
    OpenCLArray<mm_float4>* velm;
    OpenCLArray<mm_float4>* force;
    OpenCLArray<mm_float4>* forceBuffers;
215
    OpenCLArray<cl_float>* energyBuffer;
216
217
218
219
220
221
    OpenCLArray<cl_int>* atomIndex;
};

} // namespace OpenMM

#endif /*OPENMM_OPENCLCONTEXT_H_*/