CudaKernels.h 20.3 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
    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:
292
    void updateGlobalParams(ContextImpl& context);
293
294
    CudaPlatform::PlatformData& data;
    int numParticles;
295
296
    std::vector<std::string> globalParamNames;
    std::vector<float> globalParamValues;
297
    System& system;
298
299
};

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

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

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

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

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

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
466
467
468
/**
 * 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;
};

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

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

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

} // namespace OpenMM

#endif /*OPENMM_CUDAKERNELS_H_*/