CudaKernels.h 20.1 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;
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
    int numParticles;
    System& system;
};

/**
 * This kernel is invoked by CustomNonbondedForce to calculate the forces acting on the system.
 */
class CudaCalcCustomNonbondedForceKernel : public CalcCustomNonbondedForceKernel {
public:
    CudaCalcCustomNonbondedForceKernel(std::string name, const Platform& platform, CudaPlatform::PlatformData& data, System& system) : CalcCustomNonbondedForceKernel(name, platform), data(data), system(system) {
    }
    ~CudaCalcCustomNonbondedForceKernel();
    /**
     * Initialize the kernel.
     *
     * @param system     the System this kernel will be applied to
     * @param force      the CustomNonbondedForce this kernel will be used for
     */
    void initialize(const System& system, const CustomNonbondedForce& force);
    /**
     * Execute the kernel to calculate the forces.
     *
     * @param context    the context in which to execute this kernel
     */
    void executeForces(ContextImpl& context);
    /**
     * Execute the kernel to calculate the energy.
     *
     * @param context    the context in which to execute this kernel
     * @return the potential energy due to the CustomNonbondedForce
     */
    double executeEnergy(ContextImpl& context);
private:
    CudaPlatform::PlatformData& data;
    int numParticles;
294
    System& system;
295
296
};

297
/**
298
 * This kernel is invoked by GBSAOBCForce to calculate the forces acting on the system.
299
 */
300
class CudaCalcGBSAOBCForceKernel : public CalcGBSAOBCForceKernel {
301
public:
302
    CudaCalcGBSAOBCForceKernel(std::string name, const Platform& platform, CudaPlatform::PlatformData& data) : CalcGBSAOBCForceKernel(name, platform), data(data) {
303
    }
304
    ~CudaCalcGBSAOBCForceKernel();
305
    /**
306
     * Initialize the kernel.
307
     * 
308
     * @param system     the System this kernel will be applied to
309
     * @param force      the GBSAOBCForce this kernel will be used for
310
     */
311
    void initialize(const System& system, const GBSAOBCForce& force);
312
313
314
    /**
     * Execute the kernel to calculate the forces.
     * 
315
     * @param context    the context in which to execute this kernel
316
     */
317
    void executeForces(ContextImpl& context);
318
319
320
    /**
     * Execute the kernel to calculate the energy.
     * 
321
     * @param context    the context in which to execute this kernel
322
     * @return the potential energy due to the GBSAOBCForce
323
     */
324
    double executeEnergy(ContextImpl& context);
325
326
327
private:
    CudaPlatform::PlatformData& data;
};
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349

/**
 * 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
     */
350
    void execute(ContextImpl& context, const VerletIntegrator& integrator);
351
352
353
354
private:
    CudaPlatform::PlatformData& data;
    double prevStepSize;
};
355
356
357
358
359
360

/**
 * This kernel is invoked by LangevinIntegrator to take one time step.
 */
class CudaIntegrateLangevinStepKernel : public IntegrateLangevinStepKernel {
public:
361
    CudaIntegrateLangevinStepKernel(std::string name, const Platform& platform, CudaPlatform::PlatformData& data) : IntegrateLangevinStepKernel(name, platform), data(data) {
362
363
364
    }
    ~CudaIntegrateLangevinStepKernel();
    /**
Peter Eastman's avatar
Peter Eastman committed
365
     * Initialize the kernel, setting up the particle masses.
366
     * 
367
368
     * @param system     the System this kernel will be applied to
     * @param integrator the LangevinIntegrator this kernel will be used for
369
     */
370
    void initialize(const System& system, const LangevinIntegrator& integrator);
371
372
373
    /**
     * Execute the kernel.
     * 
374
375
     * @param context    the context in which to execute this kernel
     * @param integrator the LangevinIntegrator this kernel is being used for
376
     */
377
    void execute(ContextImpl& context, const LangevinIntegrator& integrator);
378
private:
379
    CudaPlatform::PlatformData& data;
380
381
    double prevTemp, prevFriction, prevStepSize;
};
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403

/**
 * 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
     */
404
    void execute(ContextImpl& context, const BrownianIntegrator& integrator);
405
406
407
408
private:
    CudaPlatform::PlatformData& data;
    double prevTemp, prevFriction, prevStepSize;
};
409

410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
/**
 * 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
430
     * @param maxTime    the maximum time beyond which the simulation should not be advanced
431
     */
432
    void execute(ContextImpl& context, const VariableVerletIntegrator& integrator, double maxTime);
433
434
435
436
437
private:
    CudaPlatform::PlatformData& data;
    double prevErrorTol;
};

438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
/**
 * 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;
};

466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
/**
 * 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
     */
486
    void execute(ContextImpl& context);
487
488
489
490
private:
    CudaPlatform::PlatformData& data;
    double prevTemp, prevFrequency, prevStepSize;
};
491
492
493
494
495
496
497
498
499

/**
 * 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) {
    }
    /**
500
     * Initialize the kernel.
501
     * 
502
     * @param system     the System this kernel will be applied to
503
     */
504
    void initialize(const System& system);
505
506
507
    /**
     * Execute the kernel.
     * 
508
     * @param context    the context in which to execute this kernel
509
     */
510
    double execute(ContextImpl& context);
511
512
513
private:
    std::vector<double> masses;
};
514
515
516
517
518
519
520
521
522

/**
 * 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
523
     * Initialize the kernel, setting up the particle masses.
524
     * 
525
526
     * @param system     the System this kernel will be applied to
     * @param force      the CMMotionRemover this kernel will be used for
527
     */
528
    void initialize(const System& system, const CMMotionRemover& force);
529
530
531
    /**
     * Execute the kernel.
     * 
532
     * @param context    the context in which to execute this kernel
533
     */
534
    void execute(ContextImpl& context);
535
536
537
private:
    CudaPlatform::PlatformData& data;
};
538
539
540
541

} // namespace OpenMM

#endif /*OPENMM_CUDAKERNELS_H_*/