Commit 74a8266f authored by Peter Eastman's avatar Peter Eastman
Browse files

Began implementing CudaPlatform

parent 50643058
/* -------------------------------------------------------------------------- *
* 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: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
#include "CudaKernelFactory.h"
#include "CudaKernels.h"
using namespace OpenMM;
KernelImpl* CudaKernelFactory::createKernelImpl(std::string name, const Platform& platform, OpenMMContextImpl& context) const {
// if (name == CalcStandardMMForceFieldKernel::Name())
// return new CudaCalcStandardMMForceFieldKernel(name, platform);
// if (name == CalcGBSAOBCForceFieldKernel::Name())
// return new CudaCalcGBSAOBCForceFieldKernel(name, platform);
// if (name == IntegrateVerletStepKernel::Name())
// return new CudaIntegrateVerletStepKernel(name, platform);
// if (name == IntegrateLangevinStepKernel::Name())
// return new CudaIntegrateLangevinStepKernel(name, platform);
// if (name == IntegrateBrownianStepKernel::Name())
// return new CudaIntegrateBrownianStepKernel(name, platform);
// if (name == ApplyAndersenThermostatKernel::Name())
// return new CudaApplyAndersenThermostatKernel(name, platform);
// if (name == CalcKineticEnergyKernel::Name())
// return new CudaCalcKineticEnergyKernel(name, platform);
// if (name == RemoveCMMotionKernel::Name())
// return new CudaRemoveCMMotionKernel(name, platform);
}
#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: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
#include "kernels.h"
class CudaAndersenThermostat;
class CudaBrownianDynamics;
class CudaStochasticDynamics;
class CudaShakeAlgorithm;
class CudaVerletDynamics;
namespace OpenMM {
///**
// * This kernel is invoked by StandardMMForceField to calculate the forces acting on the system.
// */
//class CudaCalcStandardMMForceFieldKernel : public CalcStandardMMForceFieldKernel {
//public:
// CudaCalcStandardMMForceFieldKernel(std::string name, const Platform& platform) : CalcStandardMMForceFieldKernel(name, platform) {
// }
// ~CudaCalcStandardMMForceFieldKernel();
// /**
// * Initialize the kernel, setting up the values of all the force field parameters.
// *
// * @param bondIndices the two atoms connected by each bond term
// * @param bondParameters the force parameters (length, k) for each bond term
// * @param angleIndices the three atoms connected by each angle term
// * @param angleParameters the force parameters (angle, k) for each angle term
// * @param periodicTorsionIndices the four atoms connected by each periodic torsion term
// * @param periodicTorsionParameters the force parameters (k, phase, periodicity) for each periodic torsion term
// * @param rbTorsionIndices the four atoms connected by each Ryckaert-Bellemans torsion term
// * @param rbTorsionParameters the coefficients (in order of increasing powers) for each Ryckaert-Bellemans torsion term
// * @param bonded14Indices each element contains the indices of two atoms whose nonbonded interactions should be reduced since
// * they form a bonded 1-4 pair
// * @param lj14Scale the factor by which van der Waals interactions should be reduced for bonded 1-4 pairs
// * @param coulomb14Scale the factor by which Coulomb interactions should be reduced for bonded 1-4 pairs
// * @param exclusions the i'th element lists the indices of all atoms with which the i'th atom should not interact through
// * nonbonded forces. Bonded 1-4 pairs are also included in this list, since they should be omitted from
// * the standard nonbonded calculation.
// * @param nonbondedParameters the nonbonded force parameters (charge, sigma, epsilon) for each atom
// */
// void initialize(const std::vector<std::vector<int> >& bondIndices, const std::vector<std::vector<double> >& bondParameters,
// const std::vector<std::vector<int> >& angleIndices, const std::vector<std::vector<double> >& angleParameters,
// const std::vector<std::vector<int> >& periodicTorsionIndices, const std::vector<std::vector<double> >& periodicTorsionParameters,
// const std::vector<std::vector<int> >& rbTorsionIndices, const std::vector<std::vector<double> >& rbTorsionParameters,
// const std::vector<std::vector<int> >& bonded14Indices, double lj14Scale, double coulomb14Scale,
// const std::vector<std::set<int> >& exclusions, const std::vector<std::vector<double> >& nonbondedParameters);
// /**
// * Execute the kernel to calculate the forces.
// *
// * @param positions a Stream of type Double3 containing the position (x, y, z) of each atom
// * @param forces a Stream of type Double3 containing the force (x, y, z) on each atom. On entry, this contains the forces that
// * have been calculated so far. The kernel should add its own forces to the values already in the stream.
// */
// void executeForces(const Stream& positions, Stream& forces);
// /**
// * Execute the kernel to calculate the energy.
// *
// * @param positions a Stream of type Double3 containing the position (x, y, z) of each atom
// * @return the potential energy due to the StandardMMForceField
// */
// double executeEnergy(const Stream& positions);
//private:
// int numAtoms, numBonds, numAngles, numPeriodicTorsions, numRBTorsions, num14;
// int **bondIndexArray, **angleIndexArray, **periodicTorsionIndexArray, **rbTorsionIndexArray, **exclusionArray, **bonded14IndexArray;
// RealOpenMM **bondParamArray, **angleParamArray, **periodicTorsionParamArray, **rbTorsionParamArray, **atomParamArray, **bonded14ParamArray;
//};
//
///**
// * This kernel is invoked by GBSAOBCForceField to calculate the forces acting on the system.
// */
//class CudaCalcGBSAOBCForceFieldKernel : public CalcGBSAOBCForceFieldKernel {
//public:
// CudaCalcGBSAOBCForceFieldKernel(std::string name, const Platform& platform) : CalcGBSAOBCForceFieldKernel(name, platform) {
// }
// ~CudaCalcGBSAOBCForceFieldKernel();
// /**
// * Initialize the kernel, setting up the values of all the force field parameters.
// *
// * @param atomParameters the force parameters (charge, atomic radius, scaling factor) for each atom
// * @param solventDielectric the dielectric constant of the solvent
// * @param soluteDielectric the dielectric constant of the solute
// */
// void initialize(const std::vector<std::vector<double> >& atomParameters, double solventDielectric, double soluteDielectric);
// /**
// * Execute the kernel to calculate the forces.
// *
// * @param positions a Stream of type Double3 containing the position (x, y, z) of each atom
// * @param forces a Stream of type Double3 containing the force (x, y, z) on each atom. On entry, this contains the forces that
// * have been calculated so far. The kernel should add its own forces to the values already in the stream.
// */
// void executeForces(const Stream& positions, Stream& forces);
// /**
// * Execute the kernel to calculate the energy.
// *
// * @param positions a Stream of type Double3 containing the position (x, y, z) of each atom
// * @return the potential energy due to the GBSAOBCForceField
// */
// double executeEnergy(const Stream& positions);
//private:
// CpuObc* obc;
// std::vector<RealOpenMM> charges;
//};
//
///**
// * This kernel is invoked by VerletIntegrator to take one time step.
// */
//class CudaIntegrateVerletStepKernel : public IntegrateVerletStepKernel {
//public:
// CudaIntegrateVerletStepKernel(std::string name, const Platform& platform) : IntegrateVerletStepKernel(name, platform),
// dynamics(0), shake(0), masses(0), shakeParameters(0), constraintIndices(0) {
// }
// ~CudaIntegrateVerletStepKernel();
// /**
// * Initialize the kernel, setting up all parameters related to integrator.
// *
// * @param masses the mass of each atom
// * @param constraintIndices each element contains the indices of two atoms whose distance should be constrained
// * @param constraintLengths the required distance between each pair of constrained atoms
// */
// void initialize(const std::vector<double>& masses, const std::vector<std::vector<int> >& constraintIndices,
// const std::vector<double>& constraintLengths);
// /**
// * Execute the kernel.
// *
// * @param positions a Stream of type Double3 containing the position (x, y, z) of each atom
// * @param velocities a Stream of type Double3 containing the velocity (x, y, z) of each atom
// * @param forces a Stream of type Double3 containing the force (x, y, z) on each atom
// * @param stepSize the integration step size
// */
// void execute(Stream& positions, Stream& velocities, const Stream& forces, double stepSize);
//private:
// CudaVerletDynamics* dynamics;
// CudaShakeAlgorithm* shake;
// RealOpenMM* masses;
// RealOpenMM** shakeParameters;
// int** constraintIndices;
// int numConstraints;
// double prevStepSize;
//};
//
///**
// * This kernel is invoked by LangevinIntegrator to take one time step.
// */
//class CudaIntegrateLangevinStepKernel : public IntegrateLangevinStepKernel {
//public:
// CudaIntegrateLangevinStepKernel(std::string name, const Platform& platform) : IntegrateLangevinStepKernel(name, platform),
// dynamics(0), shake(0), masses(0), shakeParameters(0), constraintIndices(0) {
// }
// ~CudaIntegrateLangevinStepKernel();
// /**
// * Initialize the kernel, setting up all parameters related to integrator.
// *
// * @param masses the mass of each atom
// * @param constraintIndices each element contains the indices of two atoms whose distance should be constrained
// * @param constraintLengths the required distance between each pair of constrained atoms
// */
// void initialize(const std::vector<double>& masses, const std::vector<std::vector<int> >& constraintIndices,
// const std::vector<double>& constraintLengths);
// /**
// * Execute the kernel.
// *
// * @param positions a Stream of type Double3 containing the position (x, y, z) of each atom
// * @param velocities a Stream of type Double3 containing the velocity (x, y, z) of each atom
// * @param forces a Stream of type Double3 containing the force (x, y, z) on each atom
// * @param temperature the temperature of the heat bath
// * @param friction the friction coefficient coupling the system to the heat bath
// * @param stepSize the integration step size
// */
// void execute(Stream& positions, Stream& velocities, const Stream& forces, double temperature, double friction, double stepSize);
//private:
// CudaStochasticDynamics* dynamics;
// CudaShakeAlgorithm* shake;
// RealOpenMM* masses;
// RealOpenMM** shakeParameters;
// int** constraintIndices;
// int numConstraints;
// double prevTemp, prevFriction, prevStepSize;
//};
//
///**
// * This kernel is invoked by BrownianIntegrator to take one time step.
// */
//class CudaIntegrateBrownianStepKernel : public IntegrateBrownianStepKernel {
//public:
// CudaIntegrateBrownianStepKernel(std::string name, const Platform& platform) : IntegrateBrownianStepKernel(name, platform),
// dynamics(0), shake(0), masses(0), shakeParameters(0), constraintIndices(0) {
// }
// ~CudaIntegrateBrownianStepKernel();
// /**
// * Initialize the kernel, setting up all parameters related to integrator.
// *
// * @param masses the mass of each atom
// * @param constraintIndices each element contains the indices of two atoms whose distance should be constrained
// * @param constraintLengths the required distance between each pair of constrained atoms
// */
// void initialize(const std::vector<double>& masses, const std::vector<std::vector<int> >& constraintIndices,
// const std::vector<double>& constraintLengths);
// /**
// * Execute the kernel.
// *
// * @param positions a Stream of type Double3 containing the position (x, y, z) of each atom
// * @param velocities a Stream of type Double3 containing the velocity (x, y, z) of each atom
// * @param forces a Stream of type Double3 containing the force (x, y, z) on each atom
// * @param temperature the temperature of the heat bath
// * @param friction the friction coefficient coupling the system to the heat bath
// * @param stepSize the integration step size
// */
// void execute(Stream& positions, Stream& velocities, const Stream& forces, double temperature, double friction, double stepSize);
//private:
// CudaBrownianDynamics* dynamics;
// CudaShakeAlgorithm* shake;
// RealOpenMM* masses;
// RealOpenMM** shakeParameters;
// int** constraintIndices;
// int numConstraints;
// double prevTemp, prevFriction, prevStepSize;
//};
//
///**
// * This kernel is invoked by AndersenThermostat at the start of each time step to adjust the atom velocities.
// */
//class CudaApplyAndersenThermostatKernel : public ApplyAndersenThermostatKernel {
//public:
// CudaApplyAndersenThermostatKernel(std::string name, const Platform& platform) : ApplyAndersenThermostatKernel(name, platform), thermostat(0) {
// }
// ~CudaApplyAndersenThermostatKernel();
// /**
// * Initialize the kernel, setting up the values of unchanging parameters.
// *
// * @param masses the mass of each atom
// */
// void initialize(const std::vector<double>& masses);
// /**
// * Execute the kernel.
// *
// * @param velocities a Stream of type Double3 containing the velocity (x, y, z) of each atom
// * @param temperature the temperature of the heat bath
// * @param collisionFrequency the frequency at which atom collide with particles in the heat bath
// * @param stepSize the integration step size
// */
// void execute(Stream& velocities, double temperature, double collisionFrequency, double stepSize);
//private:
// CudaAndersenThermostat* thermostat;
// RealOpenMM* masses;
//};
//
///**
// * 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) {
// }
// /**
// * Initialize the kernel, setting up the atomic masses.
// *
// * @param masses the mass of each atom
// */
// void initialize(const std::vector<double>& masses);
// /**
// * Execute the kernel.
// *
// * @param velocities a Stream of type Double3 containing the velocity (x, y, z) of each atom
// * @return the kinetic energy of the system
// */
// double execute(const Stream& velocities);
//private:
// std::vector<double> masses;
//};
//
///**
// * 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) : RemoveCMMotionKernel(name, platform) {
// }
// /**
// * Initialize the kernel, setting up the atomic masses.
// *
// * @param masses the mass of each atom
// */
// void initialize(const std::vector<double>& masses);
// /**
// * Execute the kernel.
// *
// * @param velocities a Stream of type Double3 containing the velocity (x, y, z) of each atom
// */
// void execute(Stream& velocities);
//private:
// std::vector<double> masses;
//};
} // namespace OpenMM
#endif /*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: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
#include "CudaPlatform.h"
#include "CudaKernelFactory.h"
#include "CudaKernels.h"
#include "internal/OpenMMContextImpl.h"
#include "kernels/gpuTypes.h"
using namespace OpenMM;
CudaPlatform::CudaPlatform() {
CudaKernelFactory* factory = new CudaKernelFactory();
// registerKernelFactory(CalcStandardMMForceFieldKernel::Name(), factory);
// registerKernelFactory(CalcGBSAOBCForceFieldKernel::Name(), factory);
// registerKernelFactory(IntegrateVerletStepKernel::Name(), factory);
// registerKernelFactory(IntegrateLangevinStepKernel::Name(), factory);
// registerKernelFactory(IntegrateBrownianStepKernel::Name(), factory);
// registerKernelFactory(ApplyAndersenThermostatKernel::Name(), factory);
// registerKernelFactory(CalcKineticEnergyKernel::Name(), factory);
// registerKernelFactory(RemoveCMMotionKernel::Name(), factory);
}
bool CudaPlatform::supportsDoublePrecision() const {
return false;
}
const StreamFactory& CudaPlatform::getDefaultStreamFactory() const {
return defaultStreamFactory;
}
void CudaPlatform::contextCreated(OpenMMContextImpl& context) const {
context.setPlatformData(new _gpuContext());
}
void CudaPlatform::contextDestroyed(OpenMMContextImpl& context) const {
_gpuContext* data = reinterpret_cast<_gpuContext*>(context.getPlatformData());
delete data;
}
/* -------------------------------------------------------------------------- *
* 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: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
#include "CudaStreamFactory.h"
#include "CudaStreamImpl.h"
#include "OpenMMException.h"
#include "internal/OpenMMContextImpl.h"
#include "kernels/gpuTypes.h"
using namespace OpenMM;
StreamImpl* CudaStreamFactory::createStreamImpl(std::string name, int size, Stream::DataType type, const Platform& platform, OpenMMContextImpl& context) const {
if (name == "atomPositions") {
_gpuContext& gpu = *reinterpret_cast<_gpuContext*>(context.getPlatformData());
float padding[] = {100000.0f, 100000.0f, 100000.0f, 0.2f};
return new CudaStreamImpl<float4>(name, size, type, platform, gpu.psPosq4, 4, padding);
}
if (name == "atomVelocities") {
_gpuContext& gpu = *reinterpret_cast<_gpuContext*>(context.getPlatformData());
float padding[] = {0.0f, 0.0f, 0.0f, 0.0f};
return new CudaStreamImpl<float4>(name, size, type, platform, gpu.psVelm4, 4, padding);
}
if (name == "atomForces") {
_gpuContext& gpu = *reinterpret_cast<_gpuContext*>(context.getPlatformData());
float padding[] = {0.0f, 0.0f, 0.0f, 0.0f};
return new CudaStreamImpl<float4>(name, size, type, platform, gpu.psForce4, 4, padding);
}
switch (type) {
case Stream::Float:
case Stream::Double:
return new CudaStreamImpl<float1>(name, size, type, platform, 1);
case Stream::Float2:
case Stream::Double2:
return new CudaStreamImpl<float2>(name, size, type, platform, 1);
case Stream::Float3:
case Stream::Double3:
return new CudaStreamImpl<float3>(name, size, type, platform, 1);
case Stream::Float4:
case Stream::Double4:
return new CudaStreamImpl<float4>(name, size, type, platform, 1);
case Stream::Integer:
return new CudaStreamImpl<int1>(name, size, type, platform, 1);
case Stream::Integer2:
return new CudaStreamImpl<int2>(name, size, type, platform, 1);
case Stream::Integer3:
return new CudaStreamImpl<int3>(name, size, type, platform, 1);
case Stream::Integer4:
return new CudaStreamImpl<int4>(name, size, type, platform, 1);
}
throw OpenMMException("Tried to create a Stream with an illegal DataType.");
}
#ifndef OPENMM_CUDASTREAMIMPL_H_
#define OPENMM_CUDASTREAMIMPL_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: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
#include "StreamImpl.h"
#include "kernels/cudatypes.h"
namespace OpenMM {
/**
* This is the implementation of streams in the CUDA Platform.
*/
template <class T>
class CudaStreamImpl : public StreamImpl {
public:
CudaStreamImpl(std::string name, int size, Stream::DataType type, const Platform& platform, int substreams);
CudaStreamImpl(std::string name, int size, Stream::DataType type, const Platform& platform, CUDAStream<T>* stream, int rowOffset, float* padding);
~CudaStreamImpl();
void loadFromArray(const void* array);
void saveToArray(void* array);
void fillWithValue(void* value);
const CUDAStream<T>& getStream() const;
CUDAStream<T>& getStream();
private:
void initType();
CUDAStream<T>* stream;
bool ownStream;
int width, rowOffset;
float paddingValues[4];
Stream::DataType baseType;
};
template <class T>
CudaStreamImpl<T>::CudaStreamImpl(std::string name, int size, Stream::DataType type, const Platform& platform, int substreams) :
StreamImpl(name, size, type, platform), stream(new CUDAStream<T>(size, substreams)), ownStream(true) {
initType();
rowOffset = width;
};
template <class T>
CudaStreamImpl<T>::CudaStreamImpl(std::string name, int size, Stream::DataType type, const Platform& platform, CUDAStream<T>* stream, int rowOffset, float* padding) :
StreamImpl(name, size, type, platform), stream(stream), rowOffset(rowOffset), ownStream(false) {
initType();
for (int i = 0; i < 4; ++i)
paddingValues[i] = padding[i];
};
template <class T>
void CudaStreamImpl<T>::initType() {
switch (getDataType()) {
case Stream::Float:
case Stream::Float2:
case Stream::Float3:
case Stream::Float4:
baseType = Stream::Float;
break;
case Stream::Double:
case Stream::Double2:
case Stream::Double3:
case Stream::Double4:
baseType = Stream::Double;
break;
case Stream::Integer:
case Stream::Integer2:
case Stream::Integer3:
case Stream::Integer4:
baseType = Stream::Integer;
break;
}
switch (getDataType()) {
case Stream::Float:
case Stream::Double:
case Stream::Integer:
width = 1;
break;
case Stream::Float2:
case Stream::Double2:
case Stream::Integer2:
width = 2;
break;
case Stream::Float3:
case Stream::Double3:
case Stream::Integer3:
width = 3;
break;
case Stream::Float4:
case Stream::Double4:
case Stream::Integer4:
width = 4;
break;
}
}
template <class T>
CudaStreamImpl<T>::~CudaStreamImpl() {
if (ownStream)
delete stream;
}
template <class T>
void CudaStreamImpl<T>::loadFromArray(const void* array) {
float* data = reinterpret_cast<float*>(stream->_pSysData);
if (baseType == Stream::Float) {
float* arrayData = (float*) array;
for (int i = 0; i < getSize(); ++i)
for (int j = 0; j < width; ++j)
data[i*rowOffset+j] = arrayData[i*width+j];
}
else if (baseType == Stream::Double) {
double* arrayData = (double*) array;
for (int i = 0; i < getSize(); ++i)
for (int j = 0; j < width; ++j)
data[i*rowOffset+j] = arrayData[i*width+j];
}
else {
int* arrayData = (int*) array;
for (int i = 0; i < getSize(); ++i)
for (int j = 0; j < width; ++j)
data[i*rowOffset+j] = arrayData[i*width+j];
}
for (int i = getSize(); i < stream->_length; ++i)
for (int j = 0; j < rowOffset; ++j)
data[i*rowOffset+j] = paddingValues[j];
stream->Upload();
}
template <class T>
void CudaStreamImpl<T>::saveToArray(void* array) {
float* data = reinterpret_cast<float*>(stream->_pSysData);
if (baseType == Stream::Float) {
float* arrayData = (float*) array;
for (int i = 0; i < getSize(); ++i)
for (int j = 0; j < width; ++j)
arrayData[i*width+j] = data[i*rowOffset+j];
}
else if (baseType == Stream::Double) {
double* arrayData = (double*) array;
for (int i = 0; i < getSize(); ++i)
for (int j = 0; j < width; ++j)
arrayData[i*width+j] = data[i*rowOffset+j];
}
else {
int* arrayData = (int*) array;
for (int i = 0; i < getSize(); ++i)
for (int j = 0; j < width; ++j)
arrayData[i*width+j] = data[i*rowOffset+j];
}
stream->Download();
}
template <class T>
void CudaStreamImpl<T>::fillWithValue(void* value) {
float* data = reinterpret_cast<float*>(stream->_pSysData);
if (baseType == Stream::Float) {
float valueData = *((float*) value);
for (int i = 0; i < getSize(); ++i)
for (int j = 0; j < width; ++j)
data[i*rowOffset+j] = valueData;
}
else if (baseType == Stream::Double) {
double valueData = *((double*) value);
for (int i = 0; i < getSize(); ++i)
for (int j = 0; j < width; ++j)
data[i*rowOffset+j] = valueData;
}
else {
int valueData = *((int*) value);
for (int i = 0; i < getSize(); ++i)
for (int j = 0; j < width; ++j)
data[i*rowOffset+j] = valueData;
}
for (int i = getSize(); i < stream->_length; ++i)
for (int j = 0; j < rowOffset; ++j)
data[i*rowOffset+j] = paddingValues[j];
stream->Upload();
}
template <class T>
const CUDAStream<T>& CudaStreamImpl<T>::getStream() const {
return stream;
}
template <class T>
CUDAStream<T>& CudaStreamImpl<T>::getStream() {
return stream;
}
} // namespace OpenMM
#endif /*OPENMM_CUDASTREAMIMPL_H_*/
#
# Testing
#
ENABLE_TESTING()
# Automatically create tests using files named "Test*.cpp"
FILE(GLOB TEST_PROGS "*Test*.cpp")
FOREACH(TEST_PROG ${TEST_PROGS})
GET_FILENAME_COMPONENT(TEST_ROOT ${TEST_PROG} NAME_WE)
# Link with shared library
ADD_EXECUTABLE(${TEST_ROOT} ${TEST_PROG})
TARGET_LINK_LIBRARIES(${TEST_ROOT} ${SHARED_TARGET})
ADD_TEST(${TEST_ROOT} ${EXECUTABLE_OUTPUT_PATH}/${TEST_ROOT})
# Link with static library
# SET(TEST_STATIC ${TEST_ROOT}Static)
# ADD_EXECUTABLE(${TEST_STATIC} ${TEST_PROG})
# SET_TARGET_PROPERTIES(${TEST_STATIC}
# PROPERTIES
# COMPILE_FLAGS "-DOPENMM_USE_STATIC_LIBRARIES"
# )
# TARGET_LINK_LIBRARIES(${TEST_STATIC} ${STATIC_TARGET})
# ADD_TEST(${TEST_STATIC} ${EXECUTABLE_OUTPUT_PATH}/${TEST_STATIC})
ENDFOREACH(TEST_PROG ${TEST_PROGS})
/* -------------------------------------------------------------------------- *
* 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: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
/**
* This tests the CUDA implementation of streams.
*/
#include "../../../tests/AssertionUtilities.h"
#include "CudaPlatform.h"
#include "Stream.h"
#include <iostream>
using namespace OpenMM;
using namespace std;
const double TOL = 1e-6;
template <class T, int WIDTH>
void testStream(Stream::DataType type, T scale) {
const int size = 100;
CudaPlatform platform;
OpenMMContextImpl* impl = 0; // We need to pass an OpenMMContextImpl to createStream, but it will be ignored.
Stream stream = platform.createStream("", size, type, *impl);
const int length = size*WIDTH;
T array[size*WIDTH+1];
array[length] = 0;
T value = 3;
// Test fillWithValue.
stream.fillWithValue(&value);
stream.saveToArray(array);
for (int i = 0; i < length; ++i)
ASSERT_EQUAL(3, array[i]);
ASSERT_EQUAL(0, array[length]);
// Test loadFromArray.
for (int i = 0; i < length; ++i)
array[i] = i*scale;
stream.loadFromArray(array);
for (int i = 0; i < length; ++i)
array[i] = 0;
stream.saveToArray(array);
for (int i = 0; i < length; ++i)
ASSERT_EQUAL_TOL((i*scale), array[i], TOL);
ASSERT_EQUAL_TOL(0, array[length], TOL);
}
int main() {
try {
testStream<float, 1>(Stream::Float, 0.1);
testStream<float, 2>(Stream::Float2, 0.1);
testStream<float, 3>(Stream::Float3, 0.1);
testStream<float, 4>(Stream::Float4, 0.1);
testStream<double, 1>(Stream::Double, 0.1);
testStream<double, 2>(Stream::Double2, 0.1);
testStream<double, 3>(Stream::Double3, 0.1);
testStream<double, 4>(Stream::Double4, 0.1);
testStream<int, 1>(Stream::Integer, 1);
testStream<int, 2>(Stream::Integer2, 1);
testStream<int, 3>(Stream::Integer3, 1);
testStream<int, 4>(Stream::Integer4, 1);
}
catch(const exception& e) {
cout << "exception: " << e.what() << endl;
return 1;
}
cout << "Done" << endl;
return 0;
}
...@@ -42,7 +42,7 @@ namespace OpenMM { ...@@ -42,7 +42,7 @@ namespace OpenMM {
class ReferenceKernelFactory : public KernelFactory { class ReferenceKernelFactory : public KernelFactory {
public: public:
KernelImpl* createKernelImpl(std::string name, const Platform& platform) const; KernelImpl* createKernelImpl(std::string name, const Platform& platform, OpenMMContextImpl& context) const;
}; };
} // namespace OpenMM } // namespace OpenMM
......
...@@ -42,7 +42,7 @@ namespace OpenMM { ...@@ -42,7 +42,7 @@ namespace OpenMM {
class ReferenceStreamFactory : public StreamFactory { class ReferenceStreamFactory : public StreamFactory {
public: public:
StreamImpl* createStreamImpl(std::string name, int size, Stream::DataType type, const Platform& platform) const; StreamImpl* createStreamImpl(std::string name, int size, Stream::DataType type, const Platform& platform, OpenMMContextImpl& context) const;
}; };
} // namespace OpenMM } // namespace OpenMM
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
using namespace OpenMM; using namespace OpenMM;
KernelImpl* ReferenceKernelFactory::createKernelImpl(std::string name, const Platform& platform) const { KernelImpl* ReferenceKernelFactory::createKernelImpl(std::string name, const Platform& platform, OpenMMContextImpl& context) const {
if (name == CalcStandardMMForceFieldKernel::Name()) if (name == CalcStandardMMForceFieldKernel::Name())
return new ReferenceCalcStandardMMForceFieldKernel(name, platform); return new ReferenceCalcStandardMMForceFieldKernel(name, platform);
if (name == CalcGBSAOBCForceFieldKernel::Name()) if (name == CalcGBSAOBCForceFieldKernel::Name())
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
using namespace OpenMM; using namespace OpenMM;
StreamImpl* ReferenceStreamFactory::createStreamImpl(std::string name, int size, Stream::DataType type, const Platform& platform) const { StreamImpl* ReferenceStreamFactory::createStreamImpl(std::string name, int size, Stream::DataType type, const Platform& platform, OpenMMContextImpl& context) const {
switch (type) { switch (type) {
case Stream::Float: case Stream::Float:
case Stream::Float2: case Stream::Float2:
......
...@@ -55,19 +55,19 @@ void testSingleAtom() { ...@@ -55,19 +55,19 @@ void testSingleAtom() {
system.setAtomMass(0, 2.0); system.setAtomMass(0, 2.0);
LangevinIntegrator integrator(0, 0.1, 0.01); LangevinIntegrator integrator(0, 0.1, 0.01);
GBSAOBCForceField* forceField = new GBSAOBCForceField(1); GBSAOBCForceField* forceField = new GBSAOBCForceField(1);
forceField->setAtomParameters(0, 0.5, 1.5, 1); forceField->setAtomParameters(0, 0.5, 0.15, 1);
system.addForce(forceField); system.addForce(forceField);
OpenMMContext context(system, integrator, platform); OpenMMContext context(system, integrator, platform);
vector<Vec3> positions(1); vector<Vec3> positions(1);
positions[0] = Vec3(0, 0, 0); positions[0] = Vec3(0, 0, 0);
context.setPositions(positions); context.setPositions(positions);
State state = context.getState(State::Energy); State state = context.getState(State::Energy);
double bornRadius = 1.5-0.09; // dielectric offset double bornRadius = 0.15-0.009; // dielectric offset
double eps0 = EPSILON0*A2NM*CAL2JOULE; double eps0 = EPSILON0;
double bornEnergy = (-0.5*0.5/(8*PI_M*eps0))*(1.0/forceField->getSoluteDielectric()-1.0/forceField->getSolventDielectric())/bornRadius; double bornEnergy = (-0.5*0.5/(8*PI_M*eps0))*(1.0/forceField->getSoluteDielectric()-1.0/forceField->getSolventDielectric())/bornRadius;
double extendedRadius = bornRadius+1.4; // probe radius double extendedRadius = bornRadius+0.14; // probe radius
double nonpolarEnergy = PI_M*0.0216*extendedRadius*extendedRadius*std::pow(1.5/bornRadius, 6.0); // Where did this formula come from? Just copied it from CpuImplicitSolvent.cpp double nonpolarEnergy = CAL2JOULE*PI_M*0.0216*(10*extendedRadius)*(10*extendedRadius)*std::pow(0.15/bornRadius, 6.0); // Where did this formula come from? Just copied it from CpuImplicitSolvent.cpp
ASSERT_EQUAL_TOL(bornEnergy+nonpolarEnergy, state.getPotentialEnergy(), 0.01); ASSERT_EQUAL_TOL((bornEnergy+nonpolarEnergy), state.getPotentialEnergy(), 0.01);
} }
void testForce() { void testForce() {
...@@ -77,7 +77,7 @@ void testForce() { ...@@ -77,7 +77,7 @@ void testForce() {
LangevinIntegrator integrator(0, 0.1, 0.01); LangevinIntegrator integrator(0, 0.1, 0.01);
GBSAOBCForceField* forceField = new GBSAOBCForceField(numAtoms); GBSAOBCForceField* forceField = new GBSAOBCForceField(numAtoms);
for (int i = 0; i < numAtoms; ++i) for (int i = 0; i < numAtoms; ++i)
forceField->setAtomParameters(i, i%2 == 0 ? -1 : 1, 1.5, 1); forceField->setAtomParameters(i, i%2 == 0 ? -1 : 1, 0.15, 1);
system.addForce(forceField); system.addForce(forceField);
OpenMMContext context(system, integrator, platform); OpenMMContext context(system, integrator, platform);
......
...@@ -58,7 +58,7 @@ void throwException(const char* file, int line, const std::string& details) { ...@@ -58,7 +58,7 @@ void throwException(const char* file, int line, const std::string& details) {
#define ASSERT_EQUAL(expected, found) {if ((expected) != (found)) {std::stringstream details; details << "Expected "<<(expected)<<", found "<<(found); throwException(__FILE__, __LINE__, details.str());}}; #define ASSERT_EQUAL(expected, found) {if ((expected) != (found)) {std::stringstream details; details << "Expected "<<(expected)<<", found "<<(found); throwException(__FILE__, __LINE__, details.str());}};
#define ASSERT_EQUAL_TOL(expected, found, tol) {double scale = std::max(1.0, std::fabs(expected)); if (std::fabs((expected)-(found))/scale > (tol)) {std::stringstream details; details << "Expected "<<(expected)<<", found "<<(found); throwException(__FILE__, __LINE__, details.str());}}; #define ASSERT_EQUAL_TOL(expected, found, tol) {double _scale_ = std::fabs(expected) > 1.0 ? std::fabs(expected) : 1.0; if (std::fabs((expected)-(found))/_scale_ > (tol)) {std::stringstream details; details << "Expected "<<(expected)<<", found "<<(found); throwException(__FILE__, __LINE__, details.str());}};
#define ASSERT_EQUAL_VEC(expected, found, tol) {ASSERT_EQUAL_TOL((expected)[0], (found)[0], (tol)); ASSERT_EQUAL_TOL((expected)[1], (found)[1], (tol)); ASSERT_EQUAL_TOL((expected)[2], (found)[2], (tol));}; #define ASSERT_EQUAL_VEC(expected, found, tol) {ASSERT_EQUAL_TOL((expected)[0], (found)[0], (tol)); ASSERT_EQUAL_TOL((expected)[1], (found)[1], (tol)); ASSERT_EQUAL_TOL((expected)[2], (found)[2], (tol));};
......
...@@ -189,7 +189,7 @@ public: ...@@ -189,7 +189,7 @@ public:
class DummyKernelFactory : public KernelFactory { class DummyKernelFactory : public KernelFactory {
public: public:
KernelImpl* createKernelImpl(string name, const Platform& platform) const { KernelImpl* createKernelImpl(string name, const Platform& platform, OpenMMContextImpl& context) const {
if (name == CalcStandardMMForceFieldKernel::Name()) if (name == CalcStandardMMForceFieldKernel::Name())
return new DummyForceKernel(name, platform); return new DummyForceKernel(name, platform);
if (name == IntegrateVerletStepKernel::Name()) if (name == IntegrateVerletStepKernel::Name())
...@@ -202,7 +202,7 @@ public: ...@@ -202,7 +202,7 @@ public:
class DummyStreamFactory : public StreamFactory { class DummyStreamFactory : public StreamFactory {
public: public:
StreamImpl* createStreamImpl(string name, int size, Stream::DataType type, const Platform& platform) const { StreamImpl* createStreamImpl(string name, int size, Stream::DataType type, const Platform& platform, OpenMMContextImpl& context) const {
return new DummyStreamImpl(name, size, type, platform); return new DummyStreamImpl(name, size, type, platform);
} }
}; };
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment