OpenCLArray.h 9.89 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
#ifndef OPENMM_OPENCLARRAY_H_
#define OPENMM_OPENCLARRAY_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-2019 Stanford University and the Authors.      *
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 * 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/>.      *
 * -------------------------------------------------------------------------- */

peastman's avatar
peastman committed
30
31
#define __CL_ENABLE_EXCEPTIONS
#define CL_USE_DEPRECATED_OPENCL_1_1_APIS
32
#include "openmm/OpenMMException.h"
33
34
#include "openmm/common/windowsExportCommon.h"
#include "openmm/common/ArrayInterface.h"
peastman's avatar
peastman committed
35
#include <cl.hpp>
36
37
#include <iostream>
#include <sstream>
38
39
40
41
#include <vector>

namespace OpenMM {

peastman's avatar
peastman committed
42
43
class OpenCLContext;

44
45
/**
 * This class encapsulates an OpenCL Buffer.  It provides a simplified API for working with it,
46
 * and for copying data to and from the OpenCL Buffer.
47
48
 */

49
class OPENMM_EXPORT_COMMON OpenCLArray : public ArrayInterface {
50
51
public:
    /**
52
53
     * Create an OpenCLArray object.  The object is allocated on the heap with the "new" operator.
     * The template argument is the data type of each array element.
54
55
56
57
     *
     * @param context           the context for which to create the array
     * @param size              the number of elements in the array
     * @param name              the name of the array
58
     * @param flags             the set of flags to specify when creating the OpenCL Buffer
59
     */
60
61
62
    template <class T>
    static OpenCLArray* create(OpenCLContext& context, int size, const std::string& name, cl_int flags = CL_MEM_READ_WRITE) {
        return new OpenCLArray(context, size, sizeof(T), name, flags);
63
    }
64
    /**
65
66
     * Create an OpenCLArray object that uses a preexisting Buffer.  The object is allocated on the heap with the "new" operator.
     * The template argument is the data type of each array element.
67
68
69
70
71
72
     *
     * @param context           the context for which to create the array
     * @param buffer            the OpenCL Buffer this object encapsulates
     * @param size              the number of elements in the array
     * @param name              the name of the array
     */
73
74
75
    template <class T>
    static OpenCLArray* create(OpenCLContext& context, cl::Buffer* buffer, int size, const std::string& name) {
        return new OpenCLArray(context, buffer, size, sizeof(T), name);
76
    }
peastman's avatar
peastman committed
77
78
79
80
81
    /**
     * Create an uninitialized OpenCLArray object.  It does not point to any OpenCL Buffer,
     * and cannot be used until initialize() is called on it.
     */
    OpenCLArray();
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
    /**
     * Create an OpenCLArray object.
     *
     * @param context           the context for which to create the array
     * @param size              the number of elements in the array
     * @param elementSize       the size of each element in bytes
     * @param name              the name of the array
     * @param flags             the set of flags to specify when creating the OpenCL Buffer
     */
    OpenCLArray(OpenCLContext& context, int size, int elementSize, const std::string& name, cl_int flags = CL_MEM_READ_WRITE);
    /**
     * Create an OpenCLArray object that uses a preexisting Buffer.
     *
     * @param context           the context for which to create the array
     * @param buffer            the OpenCL Buffer this object encapsulates
     * @param size              the number of elements in the array
     * @param elementSize       the size of each element in bytes
     * @param name              the name of the array
     */
    OpenCLArray(OpenCLContext& context, cl::Buffer* buffer, int size, int elementSize, const std::string& name);
    ~OpenCLArray();
103
104
105
106
107
108
109
110
111
    /**
     * Initialize this array.
     *
     * @param context           the context for which to create the array
     * @param size              the number of elements in the array
     * @param elementSize       the size of each element in bytes
     * @param name              the name of the array
     */
    void initialize(ComputeContext& context, int size, int elementSize, const std::string& name);
peastman's avatar
peastman committed
112
113
114
115
116
117
118
119
120
    /**
     * Initialize this object.
     *
     * @param context           the context for which to create the array
     * @param size              the number of elements in the array
     * @param elementSize       the size of each element in bytes
     * @param name              the name of the array
     * @param flags             the set of flags to specify when creating the OpenCL Buffer
     */
121
    void initialize(OpenCLContext& context, int size, int elementSize, const std::string& name, cl_int flags);
peastman's avatar
peastman committed
122
123
124
125
126
127
128
129
130
131
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
    /**
     * Initialize this object to use a preexisting Buffer.
     *
     * @param context           the context for which to create the array
     * @param buffer            the OpenCL Buffer this object encapsulates
     * @param size              the number of elements in the array
     * @param elementSize       the size of each element in bytes
     * @param name              the name of the array
     */
    void initialize(OpenCLContext& context, cl::Buffer* buffer, int size, int elementSize, const std::string& name);
    /**
     * Initialize this object.  The template argument is the data type of each array element.
     *
     * @param context           the context for which to create the array
     * @param size              the number of elements in the array
     * @param name              the name of the array
     * @param flags             the set of flags to specify when creating the OpenCL Buffer
     */
    template <class T>
    void initialize(OpenCLContext& context, int size, const std::string& name, cl_int flags = CL_MEM_READ_WRITE) {
        initialize(context, size, sizeof(T), name, flags);
    }
    /**
     * Initialize this object to use a preexisting Buffer.  The template argument
     * is the data type of each array element.
     *
     * @param context           the context for which to create the array
     * @param buffer            the OpenCL Buffer this object encapsulates
     * @param size              the number of elements in the array
     * @param name              the name of the array
     */
    template <class T>
    void initialize(OpenCLContext& context, cl::Buffer* buffer, int size, const std::string& name) {
        initialize(context, buffer, size, sizeof(T), name);
    }
    /**
     * Recreate the internal storage to have a different size.
     */
    void resize(int size);
    /**
     * Get whether this array has been initialized.
     */
    bool isInitialized() const {
        return (buffer != NULL);
    }
167
168
169
    /**
     * Get the size of the array.
     */
170
    int getSize() const {
171
172
        return size;
    }
173
174
175
176
177
178
    /**
     * Get the size of each element in bytes.
     */
    int getElementSize() const {
        return elementSize;
    }
179
180
181
    /**
     * Get the name of the array.
     */
182
    const std::string& getName() const {
183
184
        return name;
    }
185
186
187
188
    /**
     * Get the context this array belongs to.
     */
    ComputeContext& getContext();
189
190
191
192
193
194
    /**
     * Get the OpenCL Buffer object.
     */
    cl::Buffer& getDeviceBuffer() {
        return *buffer;
    }
195
196
197
    /**
     * Copy the values in a vector to the Buffer.
     */
198
    template <class T>
199
200
    void upload(const std::vector<T>& data, bool convert=false) {
        ArrayInterface::upload(data, convert);
201
    }
202
203
204
    /**
     * Copy the values in the Buffer to a vector.
     */
205
    template <class T>
206
207
    void download(std::vector<T>& data) const {
        ArrayInterface::download(data);
208
    }
209
210
    /**
     * Copy the values in an array to the Buffer.
211
212
213
     * 
     * @param data     the data to copy
     * @param blocking if true, this call will block until the transfer is complete.
214
     */
215
    void upload(const void* data, bool blocking=true);
216
    /**
217
     * Copy the values in the Buffer to an array.
218
219
220
     * 
     * @param data     the array to copy the memory to
     * @param blocking if true, this call will block until the transfer is complete.
221
     */
222
    void download(void* data, bool blocking=true) const;
223
    /**
224
225
226
     * Copy the values in the Buffer to a second OpenCLArray.
     * 
     * @param dest     the destination array to copy to
227
     */
228
    void copyTo(ArrayInterface& dest) const;
229
private:
peastman's avatar
peastman committed
230
    OpenCLContext* context;
231
    cl::Buffer* buffer;
232
    int size, elementSize;
peastman's avatar
peastman committed
233
    cl_int flags;
234
    bool ownsBuffer;
235
236
237
238
239
240
    std::string name;
};

} // namespace OpenMM

#endif /*OPENMM_OPENCLARRAY_H_*/