CudaKernels.h 18.9 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#ifndef OPENMM_CUDAKERNELS_H_
#define OPENMM_CUDAKERNELS_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) 2008 Stanford University and the Authors.           *
 * Authors: Peter Eastman                                                     *
 * Contributors:                                                              *
 *                                                                            *
16
17
18
19
 * 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.                                        *
20
 *                                                                            *
21
22
23
24
 * 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.                        *
25
 *                                                                            *
26
27
 * 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/>.      *
28
29
 * -------------------------------------------------------------------------- */

30
#include "CudaPlatform.h"
31
#include "openmm/kernels.h"
32
#include "kernels/gputypes.h"
33
#include "openmm/System.h"
34
35
36
37
38
39
40
41
42

class CudaAndersenThermostat;
class CudaBrownianDynamics;
class CudaStochasticDynamics;
class CudaShakeAlgorithm;
class CudaVerletDynamics;

namespace OpenMM {

43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
/**
 * This kernel is invoked at the start of each force evaluation to clear the forces.
 */
class CudaInitializeForcesKernel : public InitializeForcesKernel {
public:
    CudaInitializeForcesKernel(std::string name, const Platform& platform) : InitializeForcesKernel(name, platform) {
    }
    /**
     * Initialize the kernel.
     * 
     * @param system     the System this kernel will be applied to
     */
    void initialize(const System& system);
    /**
     * Execute the kernel.
     * 
     * @param context    the context in which to execute this kernel
     */
61
    void execute(ContextImpl& context);
62
};
63

64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
/**
 * This kernel is invoked to get or set the current time.
 */
class CudaUpdateTimeKernel : public UpdateTimeKernel {
public:
    CudaUpdateTimeKernel(std::string name, const Platform& platform, CudaPlatform::PlatformData& data) : UpdateTimeKernel(name, platform), data(data) {
    }
    /**
     * Initialize the kernel.
     *
     * @param system     the System this kernel will be applied to
     */
    void initialize(const System& system);
    /**
     * Get the current time (in picoseconds).
     *
     * @param context    the context in which to execute this kernel
     */
82
    double getTime(const ContextImpl& context) const;
83
84
85
86
87
    /**
     * Set the current time (in picoseconds).
     *
     * @param context    the context in which to execute this kernel
     */
88
    void setTime(ContextImpl& context, double time);
89
90
91
92
private:
    CudaPlatform::PlatformData& data;
};

93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/**
 * This kernel is invoked by HarmonicBondForce to calculate the forces acting on the system and the energy of the system.
 */
class CudaCalcHarmonicBondForceKernel : public CalcHarmonicBondForceKernel {
public:
    CudaCalcHarmonicBondForceKernel(std::string name, const Platform& platform, CudaPlatform::PlatformData& data, System& system) : CalcHarmonicBondForceKernel(name, platform), data(data), system(system) {
    }
    ~CudaCalcHarmonicBondForceKernel();
    /**
     * Initialize the kernel.
     * 
     * @param system     the System this kernel will be applied to
     * @param force      the HarmonicBondForce this kernel will be used for
     */
    void initialize(const System& system, const HarmonicBondForce& force);
    /**
     * Execute the kernel to calculate the forces.
     * 
     * @param context    the context in which to execute this kernel
     */
113
    void executeForces(ContextImpl& context);
114
115
116
117
118
119
    /**
     * Execute the kernel to calculate the energy.
     * 
     * @param context    the context in which to execute this kernel
     * @return the potential energy due to the HarmonicBondForce
     */
120
    double executeEnergy(ContextImpl& context);
121
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
private:
    int numBonds;
    CudaPlatform::PlatformData& data;
    System& system;
};

/**
 * This kernel is invoked by HarmonicAngleForce to calculate the forces acting on the system and the energy of the system.
 */
class CudaCalcHarmonicAngleForceKernel : public CalcHarmonicAngleForceKernel {
public:
    CudaCalcHarmonicAngleForceKernel(std::string name, const Platform& platform, CudaPlatform::PlatformData& data, System& system) : CalcHarmonicAngleForceKernel(name, platform), data(data), system(system) {
    }
    ~CudaCalcHarmonicAngleForceKernel();
    /**
     * Initialize the kernel.
     * 
     * @param system     the System this kernel will be applied to
     * @param force      the HarmonicAngleForce this kernel will be used for
     */
    void initialize(const System& system, const HarmonicAngleForce& force);
    /**
     * Execute the kernel to calculate the forces.
     * 
     * @param context    the context in which to execute this kernel
     */
147
    void executeForces(ContextImpl& context);
148
149
150
151
152
153
    /**
     * Execute the kernel to calculate the energy.
     * 
     * @param context    the context in which to execute this kernel
     * @return the potential energy due to the HarmonicAngleForce
     */
154
    double executeEnergy(ContextImpl& context);
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
private:
    int numAngles;
    CudaPlatform::PlatformData& data;
    System& system;
};

/**
 * This kernel is invoked by PeriodicTorsionForce to calculate the forces acting on the system and the energy of the system.
 */
class CudaCalcPeriodicTorsionForceKernel : public CalcPeriodicTorsionForceKernel {
public:
    CudaCalcPeriodicTorsionForceKernel(std::string name, const Platform& platform, CudaPlatform::PlatformData& data, System& system) : CalcPeriodicTorsionForceKernel(name, platform), data(data), system(system) {
    }
    ~CudaCalcPeriodicTorsionForceKernel();
    /**
     * Initialize the kernel.
     * 
     * @param system     the System this kernel will be applied to
     * @param force      the PeriodicTorsionForce this kernel will be used for
     */
    void initialize(const System& system, const PeriodicTorsionForce& force);
    /**
     * Execute the kernel to calculate the forces.
     * 
     * @param context    the context in which to execute this kernel
     */
181
    void executeForces(ContextImpl& context);
182
183
184
185
186
187
    /**
     * Execute the kernel to calculate the energy.
     * 
     * @param context    the context in which to execute this kernel
     * @return the potential energy due to the PeriodicTorsionForce
     */
188
    double executeEnergy(ContextImpl& context);
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
private:
    int numTorsions;
    CudaPlatform::PlatformData& data;
    System& system;
};

/**
 * This kernel is invoked by RBTorsionForce to calculate the forces acting on the system and the energy of the system.
 */
class CudaCalcRBTorsionForceKernel : public CalcRBTorsionForceKernel {
public:
    CudaCalcRBTorsionForceKernel(std::string name, const Platform& platform, CudaPlatform::PlatformData& data, System& system) : CalcRBTorsionForceKernel(name, platform), data(data), system(system) {
    }
    ~CudaCalcRBTorsionForceKernel();
    /**
     * Initialize the kernel.
     * 
     * @param system     the System this kernel will be applied to
     * @param force      the RBTorsionForce this kernel will be used for
     */
    void initialize(const System& system, const RBTorsionForce& force);
    /**
     * Execute the kernel to calculate the forces.
     * 
     * @param context    the context in which to execute this kernel
     */
215
    void executeForces(ContextImpl& context);
216
217
218
219
220
221
    /**
     * Execute the kernel to calculate the energy.
     * 
     * @param context    the context in which to execute this kernel
     * @return the potential energy due to the RBTorsionForce
     */
222
    double executeEnergy(ContextImpl& context);
223
224
225
226
227
228
private:
    int numTorsions;
    CudaPlatform::PlatformData& data;
    System& system;
};

229
/**
230
 * This kernel is invoked by NonbondedForce to calculate the forces acting on the system.
231
 */
232
class CudaCalcNonbondedForceKernel : public CalcNonbondedForceKernel {
233
public:
234
    CudaCalcNonbondedForceKernel(std::string name, const Platform& platform, CudaPlatform::PlatformData& data, System& system) : CalcNonbondedForceKernel(name, platform), data(data), system(system) {
235
    }
236
    ~CudaCalcNonbondedForceKernel();
237
    /**
238
     * Initialize the kernel.
239
     * 
240
     * @param system     the System this kernel will be applied to
241
     * @param force      the NonbondedForce this kernel will be used for
242
     */
243
    void initialize(const System& system, const NonbondedForce& force);
244
245
246
    /**
     * Execute the kernel to calculate the forces.
     * 
247
     * @param context    the context in which to execute this kernel
248
     */
249
    void executeForces(ContextImpl& context);
250
251
252
    /**
     * Execute the kernel to calculate the energy.
     * 
253
     * @param context    the context in which to execute this kernel
254
     * @return the potential energy due to the NonbondedForce
255
     */
256
    double executeEnergy(ContextImpl& context);
257
private:
258
    CudaPlatform::PlatformData& data;
Peter Eastman's avatar
Peter Eastman committed
259
    int numParticles, num14;
260
    System& system;
261
262
};

263
/**
264
 * This kernel is invoked by GBSAOBCForce to calculate the forces acting on the system.
265
 */
266
class CudaCalcGBSAOBCForceKernel : public CalcGBSAOBCForceKernel {
267
public:
268
    CudaCalcGBSAOBCForceKernel(std::string name, const Platform& platform, CudaPlatform::PlatformData& data) : CalcGBSAOBCForceKernel(name, platform), data(data) {
269
    }
270
    ~CudaCalcGBSAOBCForceKernel();
271
    /**
272
     * Initialize the kernel.
273
     * 
274
     * @param system     the System this kernel will be applied to
275
     * @param force      the GBSAOBCForce this kernel will be used for
276
     */
277
    void initialize(const System& system, const GBSAOBCForce& force);
278
279
280
    /**
     * Execute the kernel to calculate the forces.
     * 
281
     * @param context    the context in which to execute this kernel
282
     */
283
    void executeForces(ContextImpl& context);
284
285
286
    /**
     * Execute the kernel to calculate the energy.
     * 
287
     * @param context    the context in which to execute this kernel
288
     * @return the potential energy due to the GBSAOBCForce
289
     */
290
    double executeEnergy(ContextImpl& context);
291
292
293
private:
    CudaPlatform::PlatformData& data;
};
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315

/**
 * This kernel is invoked by VerletIntegrator to take one time step.
 */
class CudaIntegrateVerletStepKernel : public IntegrateVerletStepKernel {
public:
    CudaIntegrateVerletStepKernel(std::string name, const Platform& platform, CudaPlatform::PlatformData& data) : IntegrateVerletStepKernel(name, platform), data(data) {
    }
    ~CudaIntegrateVerletStepKernel();
    /**
     * Initialize the kernel.
     * 
     * @param system     the System this kernel will be applied to
     * @param integrator the VerletIntegrator this kernel will be used for
     */
    void initialize(const System& system, const VerletIntegrator& integrator);
    /**
     * Execute the kernel.
     * 
     * @param context    the context in which to execute this kernel
     * @param integrator the VerletIntegrator this kernel is being used for
     */
316
    void execute(ContextImpl& context, const VerletIntegrator& integrator);
317
318
319
320
private:
    CudaPlatform::PlatformData& data;
    double prevStepSize;
};
321
322
323
324
325
326

/**
 * This kernel is invoked by LangevinIntegrator to take one time step.
 */
class CudaIntegrateLangevinStepKernel : public IntegrateLangevinStepKernel {
public:
327
    CudaIntegrateLangevinStepKernel(std::string name, const Platform& platform, CudaPlatform::PlatformData& data) : IntegrateLangevinStepKernel(name, platform), data(data) {
328
329
330
    }
    ~CudaIntegrateLangevinStepKernel();
    /**
Peter Eastman's avatar
Peter Eastman committed
331
     * Initialize the kernel, setting up the particle masses.
332
     * 
333
334
     * @param system     the System this kernel will be applied to
     * @param integrator the LangevinIntegrator this kernel will be used for
335
     */
336
    void initialize(const System& system, const LangevinIntegrator& integrator);
337
338
339
    /**
     * Execute the kernel.
     * 
340
341
     * @param context    the context in which to execute this kernel
     * @param integrator the LangevinIntegrator this kernel is being used for
342
     */
343
    void execute(ContextImpl& context, const LangevinIntegrator& integrator);
344
private:
345
    CudaPlatform::PlatformData& data;
346
347
    double prevTemp, prevFriction, prevStepSize;
};
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369

/**
 * This kernel is invoked by BrownianIntegrator to take one time step.
 */
class CudaIntegrateBrownianStepKernel : public IntegrateBrownianStepKernel {
public:
    CudaIntegrateBrownianStepKernel(std::string name, const Platform& platform, CudaPlatform::PlatformData& data) : IntegrateBrownianStepKernel(name, platform), data(data) {
    }
    ~CudaIntegrateBrownianStepKernel();
    /**
     * Initialize the kernel.
     * 
     * @param system     the System this kernel will be applied to
     * @param integrator the BrownianIntegrator this kernel will be used for
     */
    void initialize(const System& system, const BrownianIntegrator& integrator);
    /**
     * Execute the kernel.
     * 
     * @param context    the context in which to execute this kernel
     * @param integrator the BrownianIntegrator this kernel is being used for
     */
370
    void execute(ContextImpl& context, const BrownianIntegrator& integrator);
371
372
373
374
private:
    CudaPlatform::PlatformData& data;
    double prevTemp, prevFriction, prevStepSize;
};
375

376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
/**
 * This kernel is invoked by VariableVerletIntegrator to take one time step.
 */
class CudaIntegrateVariableVerletStepKernel : public IntegrateVariableVerletStepKernel {
public:
    CudaIntegrateVariableVerletStepKernel(std::string name, const Platform& platform, CudaPlatform::PlatformData& data) : IntegrateVariableVerletStepKernel(name, platform), data(data) {
    }
    ~CudaIntegrateVariableVerletStepKernel();
    /**
     * Initialize the kernel.
     *
     * @param system     the System this kernel will be applied to
     * @param integrator the VerletIntegrator this kernel will be used for
     */
    void initialize(const System& system, const VariableVerletIntegrator& integrator);
    /**
     * Execute the kernel.
     *
     * @param context    the context in which to execute this kernel
     * @param integrator the VerletIntegrator this kernel is being used for
396
     * @param maxTime    the maximum time beyond which the simulation should not be advanced
397
     */
398
    void execute(ContextImpl& context, const VariableVerletIntegrator& integrator, double maxTime);
399
400
401
402
403
private:
    CudaPlatform::PlatformData& data;
    double prevErrorTol;
};

404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
/**
 * This kernel is invoked by VariableLangevinIntegrator to take one time step.
 */
class CudaIntegrateVariableLangevinStepKernel : public IntegrateVariableLangevinStepKernel {
public:
    CudaIntegrateVariableLangevinStepKernel(std::string name, const Platform& platform, CudaPlatform::PlatformData& data) : IntegrateVariableLangevinStepKernel(name, platform), data(data) {
    }
    ~CudaIntegrateVariableLangevinStepKernel();
    /**
     * Initialize the kernel, setting up the particle masses.
     *
     * @param system     the System this kernel will be applied to
     * @param integrator the VariableLangevinIntegrator this kernel will be used for
     */
    void initialize(const System& system, const VariableLangevinIntegrator& integrator);
    /**
     * Execute the kernel.
     *
     * @param context    the context in which to execute this kernel
     * @param integrator the VariableLangevinIntegrator this kernel is being used for
     * @param maxTime    the maximum time beyond which the simulation should not be advanced
     */
    void execute(ContextImpl& context, const VariableLangevinIntegrator& integrator, double maxTime);
private:
    CudaPlatform::PlatformData& data;
    double prevTemp, prevFriction, prevErrorTol;
};

432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
/**
 * This kernel is invoked by AndersenThermostat at the start of each time step to adjust the particle velocities.
 */
class CudaApplyAndersenThermostatKernel : public ApplyAndersenThermostatKernel {
public:
    CudaApplyAndersenThermostatKernel(std::string name, const Platform& platform, CudaPlatform::PlatformData& data) : ApplyAndersenThermostatKernel(name, platform), data(data) {
    }
    ~CudaApplyAndersenThermostatKernel();
    /**
     * Initialize the kernel.
     * 
     * @param system     the System this kernel will be applied to
     * @param thermostat the AndersenThermostat this kernel will be used for
     */
    void initialize(const System& system, const AndersenThermostat& thermostat);
    /**
     * Execute the kernel.
     * 
     * @param context    the context in which to execute this kernel
     */
452
    void execute(ContextImpl& context);
453
454
455
456
private:
    CudaPlatform::PlatformData& data;
    double prevTemp, prevFrequency, prevStepSize;
};
457
458
459
460
461
462
463
464
465

/**
 * This kernel is invoked to calculate the kinetic energy of the system.
 */
class CudaCalcKineticEnergyKernel : public CalcKineticEnergyKernel {
public:
    CudaCalcKineticEnergyKernel(std::string name, const Platform& platform) : CalcKineticEnergyKernel(name, platform) {
    }
    /**
466
     * Initialize the kernel.
467
     * 
468
     * @param system     the System this kernel will be applied to
469
     */
470
    void initialize(const System& system);
471
472
473
    /**
     * Execute the kernel.
     * 
474
     * @param context    the context in which to execute this kernel
475
     */
476
    double execute(ContextImpl& context);
477
478
479
private:
    std::vector<double> masses;
};
480
481
482
483
484
485
486
487
488

/**
 * This kernel is invoked to remove center of mass motion from the system.
 */
class CudaRemoveCMMotionKernel : public RemoveCMMotionKernel {
public:
    CudaRemoveCMMotionKernel(std::string name, const Platform& platform, CudaPlatform::PlatformData& data) : RemoveCMMotionKernel(name, platform), data(data) {
    }
    /**
Peter Eastman's avatar
Peter Eastman committed
489
     * Initialize the kernel, setting up the particle masses.
490
     * 
491
492
     * @param system     the System this kernel will be applied to
     * @param force      the CMMotionRemover this kernel will be used for
493
     */
494
    void initialize(const System& system, const CMMotionRemover& force);
495
496
497
    /**
     * Execute the kernel.
     * 
498
     * @param context    the context in which to execute this kernel
499
     */
500
    void execute(ContextImpl& context);
501
502
503
private:
    CudaPlatform::PlatformData& data;
};
504
505
506
507

} // namespace OpenMM

#endif /*OPENMM_CUDAKERNELS_H_*/