Commit f5aebbd4 authored by Peter Eastman's avatar Peter Eastman
Browse files

Eliminated Stream and related classes, replacing their functionality with UpdateStateDataKernel.

parent 21d67074
...@@ -47,7 +47,7 @@ extern "C" void initOpenMMPlugin() { ...@@ -47,7 +47,7 @@ extern "C" void initOpenMMPlugin() {
CudaPlatform::CudaPlatform() { CudaPlatform::CudaPlatform() {
CudaKernelFactory* factory = new CudaKernelFactory(); CudaKernelFactory* factory = new CudaKernelFactory();
registerKernelFactory(CalcForcesAndEnergyKernel::Name(), factory); registerKernelFactory(CalcForcesAndEnergyKernel::Name(), factory);
registerKernelFactory(UpdateTimeKernel::Name(), factory); registerKernelFactory(UpdateStateDataKernel::Name(), factory);
registerKernelFactory(CalcHarmonicBondForceKernel::Name(), factory); registerKernelFactory(CalcHarmonicBondForceKernel::Name(), factory);
registerKernelFactory(CalcHarmonicAngleForceKernel::Name(), factory); registerKernelFactory(CalcHarmonicAngleForceKernel::Name(), factory);
registerKernelFactory(CalcPeriodicTorsionForceKernel::Name(), factory); registerKernelFactory(CalcPeriodicTorsionForceKernel::Name(), factory);
...@@ -85,10 +85,6 @@ const string& CudaPlatform::getPropertyValue(const Context& context, const strin ...@@ -85,10 +85,6 @@ const string& CudaPlatform::getPropertyValue(const Context& context, const strin
void CudaPlatform::setPropertyValue(Context& context, const string& property, const string& value) const { void CudaPlatform::setPropertyValue(Context& context, const string& property, const string& value) const {
} }
const StreamFactory& CudaPlatform::getDefaultStreamFactory() const {
return defaultStreamFactory;
}
void CudaPlatform::contextCreated(ContextImpl& context) const { void CudaPlatform::contextCreated(ContextImpl& context) const {
unsigned int device = 0; unsigned int device = 0;
const string& devicePropValue = getPropertyDefaultValue(CudaDevice()); const string& devicePropValue = getPropertyDefaultValue(CudaDevice());
......
/* -------------------------------------------------------------------------- *
* 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: *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as published *
* by the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* -------------------------------------------------------------------------- */
#include "CudaPlatform.h"
#include "CudaStreamFactory.h"
#include "CudaStreamImpl.h"
#include "openmm/OpenMMException.h"
#include "openmm/internal/ContextImpl.h"
#include "kernels/gputypes.h"
using namespace OpenMM;
StreamImpl* CudaStreamFactory::createStreamImpl(std::string name, int size, Stream::DataType type, const Platform& platform, ContextImpl& context) const {
CudaPlatform::PlatformData& data = *static_cast<CudaPlatform::PlatformData*>(context.getPlatformData());
if (name == "particlePositions") {
float padding[] = {100000.0f, 100000.0f, 100000.0f, 0.2f};
return new CudaStreamImpl<float4>(name, size, type, platform, data.gpu->psPosq4, 4, padding, data.gpu);
}
if (name == "particleVelocities") {
float padding[] = {0.0f, 0.0f, 0.0f, 0.0f};
return new CudaStreamImpl<float4>(name, size, type, platform, data.gpu->psVelm4, 4, padding, data.gpu);
}
if (name == "particleForces") {
float padding[] = {0.0f, 0.0f, 0.0f, 0.0f};
return new CudaStreamImpl<float4>(name, size, type, platform, data.gpu->psForce4, 4, padding, data.gpu);
}
switch (type) {
case Stream::Float:
case Stream::Double:
return new CudaStreamImpl<float1>(name, size, type, platform, 1, data.gpu);
case Stream::Float2:
case Stream::Double2:
return new CudaStreamImpl<float2>(name, size, type, platform, 1, data.gpu);
case Stream::Float3:
case Stream::Double3:
return new CudaStreamImpl<float3>(name, size, type, platform, 1, data.gpu);
case Stream::Float4:
case Stream::Double4:
return new CudaStreamImpl<float4>(name, size, type, platform, 1, data.gpu);
case Stream::Integer:
return new CudaStreamImpl<int1>(name, size, type, platform, 1, data.gpu);
case Stream::Integer2:
return new CudaStreamImpl<int2>(name, size, type, platform, 1, data.gpu);
case Stream::Integer3:
return new CudaStreamImpl<int3>(name, size, type, platform, 1, data.gpu);
case Stream::Integer4:
return new CudaStreamImpl<int4>(name, size, type, platform, 1, data.gpu);
}
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: *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as published *
* by the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* -------------------------------------------------------------------------- */
#include "openmm/StreamImpl.h"
#include "kernels/gputypes.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, _gpuContext* gpu);
CudaStreamImpl(std::string name, int size, Stream::DataType type, const Platform& platform, CUDAStream<T>* stream, int rowOffset, float* padding, _gpuContext* gpu);
~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;
_gpuContext* gpu;
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, _gpuContext* gpu) :
StreamImpl(name, size, type, platform), stream(new CUDAStream<T>(size, substreams)), ownStream(true), gpu(gpu) {
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, _gpuContext* gpu) :
StreamImpl(name, size, type, platform), stream(stream), rowOffset(rowOffset), ownStream(false), gpu(gpu) {
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);
int* order = gpu->psAtomIndex->_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[order[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] = (float) arrayData[order[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] = (float) arrayData[order[i]*width+j];
}
for (int i = getSize(); i < (int) stream->_length; ++i)
for (int j = 0; j < rowOffset; ++j)
data[i*rowOffset+j] = paddingValues[j];
stream->Upload();
if (gpu && getName() == "particlePositions") {
gpu->bRecalculateBornRadii = true;
for (int i = 0; i < gpu->posCellOffsets.size(); i++)
gpu->posCellOffsets[i] = make_int3(0, 0, 0);
}
}
template <class T>
void CudaStreamImpl<T>::saveToArray(void* array) {
stream->Download();
float* data = reinterpret_cast<float*>(stream->_pSysData);
int* order = gpu->psAtomIndex->_pSysData;
if (baseType == Stream::Float) {
float* arrayData = (float*) array;
for (int i = 0; i < getSize(); ++i)
for (int j = 0; j < width; ++j)
arrayData[order[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[order[i]*width+j] = data[i*rowOffset+j];
if (gpu && getName() == "particlePositions") {
for (int i = 0; i < getSize(); i++) {
int3 offset = gpu->posCellOffsets[i];
arrayData[order[i]*width] -= offset.x*gpu->sim.periodicBoxSizeX;
arrayData[order[i]*width+1] -= offset.y*gpu->sim.periodicBoxSizeY;
arrayData[order[i]*width+2] -= offset.z*gpu->sim.periodicBoxSizeZ;
}
}
}
else {
int* arrayData = (int*) array;
for (int i = 0; i < getSize(); ++i)
for (int j = 0; j < width; ++j)
arrayData[order[i]*width+j] = (int) data[i*rowOffset+j];
}
}
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] = (float) valueData;
}
else {
int valueData = *((int*) value);
for (int i = 0; i < getSize(); ++i)
for (int j = 0; j < width; ++j)
data[i*rowOffset+j] = (float) valueData;
}
for (int i = getSize(); i < (int) stream->_length; ++i)
for (int j = 0; j < rowOffset; ++j)
data[i*rowOffset+j] = paddingValues[j];
stream->Upload();
if (gpu && getName() == "particlePositions") {
gpu->bRecalculateBornRadii = true;
for (int i = 0; i < gpu->posCellOffsets.size(); i++)
gpu->posCellOffsets[i] = make_int3(0, 0, 0);
}
}
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_*/
/* -------------------------------------------------------------------------- *
* 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 "openmm/Context.h"
#include "openmm/Stream.h"
#include "openmm/VerletIntegrator.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;
System system;
for (int i = 0; i < size; i++)
system.addParticle(1.0);
VerletIntegrator integrator(0.01);
Context context(system, integrator, platform);
ContextImpl* impl = *reinterpret_cast<ContextImpl**>(&context);
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((double) (i*scale), array[i], TOL);
ASSERT_EQUAL_TOL(0.0, (double) array[length], TOL);
}
int main() {
try {
testStream<float, 1>(Stream::Float, 0.1f);
testStream<float, 2>(Stream::Float2, 0.1f);
testStream<float, 3>(Stream::Float3, 0.1f);
testStream<float, 4>(Stream::Float4, 0.1f);
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;
}
...@@ -28,7 +28,6 @@ ...@@ -28,7 +28,6 @@
* -------------------------------------------------------------------------- */ * -------------------------------------------------------------------------- */
#include "openmm/Platform.h" #include "openmm/Platform.h"
#include "OpenCLStreamFactory.h"
struct _gpuContext; struct _gpuContext;
...@@ -54,7 +53,6 @@ public: ...@@ -54,7 +53,6 @@ public:
bool supportsDoublePrecision() const; bool supportsDoublePrecision() const;
const std::string& getPropertyValue(const Context& context, const std::string& property) const; const std::string& getPropertyValue(const Context& context, const std::string& property) const;
void setPropertyValue(Context& context, const std::string& property, const std::string& value) const; void setPropertyValue(Context& context, const std::string& property, const std::string& value) const;
const StreamFactory& getDefaultStreamFactory() const;
void contextCreated(ContextImpl& context) const; void contextCreated(ContextImpl& context) const;
void contextDestroyed(ContextImpl& context) const; void contextDestroyed(ContextImpl& context) const;
/** /**
...@@ -71,8 +69,6 @@ public: ...@@ -71,8 +69,6 @@ public:
static const std::string key = "OpenCLDeviceIndex"; static const std::string key = "OpenCLDeviceIndex";
return key; return key;
} }
private:
OpenCLStreamFactory defaultStreamFactory;
}; };
class OpenCLPlatform::PlatformData { class OpenCLPlatform::PlatformData {
......
#ifndef OPENMM_OPENCLSTREAMFACTORY_H_
#define OPENMM_OPENCLSTREAMFACTORY_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: *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as published *
* by the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* -------------------------------------------------------------------------- */
#include "openmm/StreamFactory.h"
namespace OpenMM {
/**
* This StreamFactory creates all streams for OpenCLPlatform.
*/
class OPENMM_EXPORT OpenCLStreamFactory : public StreamFactory {
public:
StreamImpl* createStreamImpl(std::string name, int size, Stream::DataType type, const Platform& platform, ContextImpl& context) const;
};
} // namespace OpenMM
#endif /*OPENMM_OPENCLSTREAMFACTORY_H_*/
...@@ -35,8 +35,8 @@ KernelImpl* OpenCLKernelFactory::createKernelImpl(std::string name, const Platfo ...@@ -35,8 +35,8 @@ KernelImpl* OpenCLKernelFactory::createKernelImpl(std::string name, const Platfo
OpenCLPlatform::PlatformData& data = *static_cast<OpenCLPlatform::PlatformData*>(context.getPlatformData()); OpenCLPlatform::PlatformData& data = *static_cast<OpenCLPlatform::PlatformData*>(context.getPlatformData());
if (name == CalcForcesAndEnergyKernel::Name()) if (name == CalcForcesAndEnergyKernel::Name())
return new OpenCLCalcForcesAndEnergyKernel(name, platform, data); return new OpenCLCalcForcesAndEnergyKernel(name, platform, data);
if (name == UpdateTimeKernel::Name()) if (name == UpdateStateDataKernel::Name())
return new OpenCLUpdateTimeKernel(name, platform, data); return new OpenCLUpdateStateDataKernel(name, platform, data);
// if (name == CalcHarmonicBondForceKernel::Name()) // if (name == CalcHarmonicBondForceKernel::Name())
// return new OpenCLCalcHarmonicBondForceKernel(name, platform, data, context.getSystem()); // return new OpenCLCalcHarmonicBondForceKernel(name, platform, data, context.getSystem());
// if (name == CalcHarmonicAngleForceKernel::Name()) // if (name == CalcHarmonicAngleForceKernel::Name())
...@@ -64,7 +64,7 @@ KernelImpl* OpenCLKernelFactory::createKernelImpl(std::string name, const Platfo ...@@ -64,7 +64,7 @@ KernelImpl* OpenCLKernelFactory::createKernelImpl(std::string name, const Platfo
// if (name == ApplyAndersenThermostatKernel::Name()) // if (name == ApplyAndersenThermostatKernel::Name())
// return new OpenCLApplyAndersenThermostatKernel(name, platform, data); // return new OpenCLApplyAndersenThermostatKernel(name, platform, data);
if (name == CalcKineticEnergyKernel::Name()) if (name == CalcKineticEnergyKernel::Name())
return new OpenCLCalcKineticEnergyKernel(name, platform); return new OpenCLCalcKineticEnergyKernel(name, platform, data);
// if (name == RemoveCMMotionKernel::Name()) // if (name == RemoveCMMotionKernel::Name())
// return new OpenCLRemoveCMMotionKernel(name, platform, data); // return new OpenCLRemoveCMMotionKernel(name, platform, data);
throw OpenMMException((std::string("Tried to create kernel with illegal kernel name '")+name+"'").c_str()); throw OpenMMException((std::string("Tried to create kernel with illegal kernel name '")+name+"'").c_str());
......
...@@ -24,8 +24,9 @@ ...@@ -24,8 +24,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * * along with this program. If not, see <http://www.gnu.org/licenses/>. *
* -------------------------------------------------------------------------- */ * -------------------------------------------------------------------------- */
#include "OpenCLArray.h"
#include "OpenCLKernels.h" #include "OpenCLKernels.h"
#include "OpenCLStreamImpl.h" #include "OpenCLContext.h"
#include "openmm/LangevinIntegrator.h" #include "openmm/LangevinIntegrator.h"
#include "openmm/Context.h" #include "openmm/Context.h"
#include "openmm/internal/ContextImpl.h" #include "openmm/internal/ContextImpl.h"
...@@ -51,17 +52,85 @@ double OpenCLCalcForcesAndEnergyKernel::finishEnergyComputation(ContextImpl& con ...@@ -51,17 +52,85 @@ double OpenCLCalcForcesAndEnergyKernel::finishEnergyComputation(ContextImpl& con
return 0.0; return 0.0;
} }
void OpenCLUpdateTimeKernel::initialize(const System& system) { void OpenCLUpdateStateDataKernel::initialize(const System& system) {
} }
double OpenCLUpdateTimeKernel::getTime(const ContextImpl& context) const { double OpenCLUpdateStateDataKernel::getTime(const ContextImpl& context) const {
return data.time; return data.time;
} }
void OpenCLUpdateTimeKernel::setTime(ContextImpl& context, double time) { void OpenCLUpdateStateDataKernel::setTime(ContextImpl& context, double time) {
data.time = time; data.time = time;
} }
void OpenCLUpdateStateDataKernel::getPositions(ContextImpl& context, std::vector<Vec3>& positions) {
OpenCLArray<cl_float4>& posq = data.context->getPosq();
posq.download();
OpenCLArray<cl_int>& order = data.context->getAtomIndex();
int numParticles = context.getSystem().getNumParticles();
positions.resize(numParticles);
for (int i = 0; i < numParticles; ++i) {
cl_float4 pos = posq[i];
// int3 offset = gpu->posCellOffsets[i];
// positions[order[i]] = Vec3(pos.x-offset.x*gpu->sim.periodicBoxSizeX, pos.y-offset.y*gpu->sim.periodicBoxSizeY, pos.z-offset.z*gpu->sim.periodicBoxSizeZ);
positions[order[i]] = Vec3(pos.f32[0], pos.f32[1], pos.f32[2]);
}
}
void OpenCLUpdateStateDataKernel::setPositions(ContextImpl& context, const std::vector<Vec3>& positions) {
OpenCLArray<cl_float4>& posq = data.context->getPosq();
OpenCLArray<cl_int>& order = data.context->getAtomIndex();
int numParticles = context.getSystem().getNumParticles();
for (int i = 0; i < numParticles; ++i) {
cl_float4& pos = posq[i];
const Vec3& p = positions[order[i]];
pos.f32[0] = p[0];
pos.f32[1] = p[1];
pos.f32[2] = p[2];
}
posq.upload();
// for (int i = 0; i < gpu->posCellOffsets.size(); i++)
// gpu->posCellOffsets[i] = make_int3(0, 0, 0);
}
void OpenCLUpdateStateDataKernel::getVelocities(ContextImpl& context, std::vector<Vec3>& velocities) {
OpenCLArray<cl_float4>& velm = data.context->getVelm();
velm.download();
OpenCLArray<cl_int>& order = data.context->getAtomIndex();
int numParticles = context.getSystem().getNumParticles();
velocities.resize(numParticles);
for (int i = 0; i < numParticles; ++i) {
cl_float4 vel = velm[i];
velocities[order[i]] = Vec3(vel.f32[0], vel.f32[1], vel.f32[2]);
}
}
void OpenCLUpdateStateDataKernel::setVelocities(ContextImpl& context, const std::vector<Vec3>& velocities) {
OpenCLArray<cl_float4>& velm = data.context->getVelm();
OpenCLArray<cl_int>& order = data.context->getAtomIndex();
int numParticles = context.getSystem().getNumParticles();
for (int i = 0; i < numParticles; ++i) {
cl_float4& vel = velm[i];
const Vec3& p = velocities[order[i]];
vel.f32[0] = p[0];
vel.f32[1] = p[1];
vel.f32[2] = p[2];
}
velm.upload();
}
void OpenCLUpdateStateDataKernel::getForces(ContextImpl& context, std::vector<Vec3>& forces) {
OpenCLArray<cl_float4>& force = data.context->getForce();
force.download();
OpenCLArray<cl_int>& order = data.context->getAtomIndex();
int numParticles = context.getSystem().getNumParticles();
forces.resize(numParticles);
for (int i = 0; i < numParticles; ++i) {
cl_float4 f = force[i];
forces[order[i]] = Vec3(f.f32[0], f.f32[1], f.f32[2]);
}
}
//OpenCLCalcHarmonicBondForceKernel::~OpenCLCalcHarmonicBondForceKernel() { //OpenCLCalcHarmonicBondForceKernel::~OpenCLCalcHarmonicBondForceKernel() {
//} //}
// //
...@@ -783,13 +852,12 @@ double OpenCLCalcKineticEnergyKernel::execute(ContextImpl& context) { ...@@ -783,13 +852,12 @@ double OpenCLCalcKineticEnergyKernel::execute(ContextImpl& context) {
// We don't currently have a GPU kernel to do this, so we retrieve the velocities and calculate the energy // We don't currently have a GPU kernel to do this, so we retrieve the velocities and calculate the energy
// on the CPU. // on the CPU.
const Stream& velocities = context.getVelocities(); OpenCLArray<cl_float4>& velm = data.context->getVelm();
double* v = new double[velocities.getSize()*3];
velocities.saveToArray(v);
double energy = 0.0; double energy = 0.0;
for (size_t i = 0; i < masses.size(); ++i) for (size_t i = 0; i < masses.size(); ++i) {
energy += masses[i]*(v[i*3]*v[i*3]+v[i*3+1]*v[i*3+1]+v[i*3+2]*v[i*3+2]); cl_float4 v = velm[i];
delete v; energy += masses[i]*(v.f32[0]*v.f32[0]+v.f32[1]*v.f32[1]+v.f32[2]*v.f32[2]);
}
return 0.5*energy; return 0.5*energy;
} }
// //
......
...@@ -84,11 +84,12 @@ private: ...@@ -84,11 +84,12 @@ private:
}; };
/** /**
* This kernel is invoked to get or set the current time. * This kernel provides methods for setting and retrieving various state data: time, positions,
* velocities, and forces.
*/ */
class OpenCLUpdateTimeKernel : public UpdateTimeKernel { class OpenCLUpdateStateDataKernel : public UpdateStateDataKernel {
public: public:
OpenCLUpdateTimeKernel(std::string name, const Platform& platform, OpenCLPlatform::PlatformData& data) : UpdateTimeKernel(name, platform), data(data) { OpenCLUpdateStateDataKernel(std::string name, const Platform& platform, OpenCLPlatform::PlatformData& data) : UpdateStateDataKernel(name, platform), data(data) {
} }
/** /**
* Initialize the kernel. * Initialize the kernel.
...@@ -108,6 +109,36 @@ public: ...@@ -108,6 +109,36 @@ public:
* @param context the context in which to execute this kernel * @param context the context in which to execute this kernel
*/ */
void setTime(ContextImpl& context, double time); void setTime(ContextImpl& context, double time);
/**
* Get the positions of all particles.
*
* @param positions on exit, this contains the particle positions
*/
void getPositions(ContextImpl& context, std::vector<Vec3>& positions);
/**
* Set the positions of all particles.
*
* @param positions a vector containg the particle positions
*/
void setPositions(ContextImpl& context, const std::vector<Vec3>& positions);
/**
* Get the velocities of all particles.
*
* @param velocities on exit, this contains the particle velocities
*/
void getVelocities(ContextImpl& context, std::vector<Vec3>& velocities);
/**
* Set the velocities of all particles.
*
* @param velocities a vector containg the particle velocities
*/
void setVelocities(ContextImpl& context, const std::vector<Vec3>& velocities);
/**
* Get the current forces on all particles.
*
* @param forces on exit, this contains the forces
*/
void getForces(ContextImpl& context, std::vector<Vec3>& forces);
private: private:
OpenCLPlatform::PlatformData& data; OpenCLPlatform::PlatformData& data;
}; };
...@@ -519,7 +550,7 @@ private: ...@@ -519,7 +550,7 @@ private:
*/ */
class OpenCLCalcKineticEnergyKernel : public CalcKineticEnergyKernel { class OpenCLCalcKineticEnergyKernel : public CalcKineticEnergyKernel {
public: public:
OpenCLCalcKineticEnergyKernel(std::string name, const Platform& platform) : CalcKineticEnergyKernel(name, platform) { OpenCLCalcKineticEnergyKernel(std::string name, const Platform& platform, OpenCLPlatform::PlatformData& data) : CalcKineticEnergyKernel(name, platform), data(data) {
} }
/** /**
* Initialize the kernel. * Initialize the kernel.
...@@ -534,6 +565,7 @@ public: ...@@ -534,6 +565,7 @@ public:
*/ */
double execute(ContextImpl& context); double execute(ContextImpl& context);
private: private:
OpenCLPlatform::PlatformData& data;
std::vector<double> masses; std::vector<double> masses;
}; };
......
...@@ -46,7 +46,7 @@ extern "C" void initOpenMMPlugin() { ...@@ -46,7 +46,7 @@ extern "C" void initOpenMMPlugin() {
OpenCLPlatform::OpenCLPlatform() { OpenCLPlatform::OpenCLPlatform() {
OpenCLKernelFactory* factory = new OpenCLKernelFactory(); OpenCLKernelFactory* factory = new OpenCLKernelFactory();
registerKernelFactory(CalcForcesAndEnergyKernel::Name(), factory); registerKernelFactory(CalcForcesAndEnergyKernel::Name(), factory);
registerKernelFactory(UpdateTimeKernel::Name(), factory); registerKernelFactory(UpdateStateDataKernel::Name(), factory);
// registerKernelFactory(CalcHarmonicBondForceKernel::Name(), factory); // registerKernelFactory(CalcHarmonicBondForceKernel::Name(), factory);
// registerKernelFactory(CalcHarmonicAngleForceKernel::Name(), factory); // registerKernelFactory(CalcHarmonicAngleForceKernel::Name(), factory);
// registerKernelFactory(CalcPeriodicTorsionForceKernel::Name(), factory); // registerKernelFactory(CalcPeriodicTorsionForceKernel::Name(), factory);
...@@ -84,10 +84,6 @@ const string& OpenCLPlatform::getPropertyValue(const Context& context, const str ...@@ -84,10 +84,6 @@ const string& OpenCLPlatform::getPropertyValue(const Context& context, const str
void OpenCLPlatform::setPropertyValue(Context& context, const string& property, const string& value) const { void OpenCLPlatform::setPropertyValue(Context& context, const string& property, const string& value) const {
} }
const StreamFactory& OpenCLPlatform::getDefaultStreamFactory() const {
return defaultStreamFactory;
}
void OpenCLPlatform::contextCreated(ContextImpl& context) const { void OpenCLPlatform::contextCreated(ContextImpl& context) const {
unsigned int platformIndex = 0; unsigned int platformIndex = 0;
const string& platformPropValue = getPropertyDefaultValue(OpenCLPlatformIndex()); const string& platformPropValue = getPropertyDefaultValue(OpenCLPlatformIndex());
......
/* -------------------------------------------------------------------------- *
* 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: *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as published *
* by the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* -------------------------------------------------------------------------- */
#include "OpenCLPlatform.h"
#include "OpenCLStreamFactory.h"
#include "OpenCLStreamImpl.h"
#include "openmm/OpenMMException.h"
#include "openmm/internal/ContextImpl.h"
using namespace OpenMM;
StreamImpl* OpenCLStreamFactory::createStreamImpl(std::string name, int size, Stream::DataType type, const Platform& platform, ContextImpl& context) const {
OpenCLPlatform::PlatformData& data = *static_cast<OpenCLPlatform::PlatformData*>(context.getPlatformData());
if (name == "particlePositions") {
float padding[] = {100000.0f, 100000.0f, 100000.0f, 0.2f};
return new OpenCLStreamImpl<cl_float4>(name, size, type, platform, &data.context->getPosq(), 4, *data.context);
}
if (name == "particleVelocities") {
float padding[] = {0.0f, 0.0f, 0.0f, 0.0f};
return new OpenCLStreamImpl<cl_float4>(name, size, type, platform, &data.context->getVelm(), 4, *data.context);
}
if (name == "particleForces") {
float padding[] = {0.0f, 0.0f, 0.0f, 0.0f};
return new OpenCLStreamImpl<cl_float4>(name, size, type, platform, &data.context->getForce(), 4, *data.context);
}
switch (type) {
case Stream::Float:
case Stream::Double:
return new OpenCLStreamImpl<cl_float>(name, size, type, platform, *data.context);
case Stream::Float2:
case Stream::Double2:
return new OpenCLStreamImpl<cl_float>(name, size, type, platform, *data.context);
case Stream::Float3:
case Stream::Double3:
return new OpenCLStreamImpl<cl_float>(name, size, type, platform, *data.context);
case Stream::Float4:
case Stream::Double4:
return new OpenCLStreamImpl<cl_float>(name, size, type, platform, *data.context);
case Stream::Integer:
return new OpenCLStreamImpl<cl_int>(name, size, type, platform, *data.context);
case Stream::Integer2:
return new OpenCLStreamImpl<cl_int>(name, size, type, platform, *data.context);
case Stream::Integer3:
return new OpenCLStreamImpl<cl_int>(name, size, type, platform, *data.context);
case Stream::Integer4:
return new OpenCLStreamImpl<cl_int>(name, size, type, platform, *data.context);
}
throw OpenMMException("Tried to create a Stream with an illegal DataType.");
}
#ifndef OPENMM_OPENCLSTREAMIMPL_H_
#define OPENMM_OPENCLSTREAMIMPL_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-2009 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as published *
* by the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* -------------------------------------------------------------------------- */
#include "openmm/StreamImpl.h"
#include "OpenCLArray.h"
namespace OpenMM {
/**
* This is the implementation of streams in the OpenCL Platform.
*/
template <class T>
class OpenCLStreamImpl : public StreamImpl {
public:
OpenCLStreamImpl(std::string name, int size, Stream::DataType type, const Platform& platform, OpenCLContext& context);
OpenCLStreamImpl(std::string name, int size, Stream::DataType type, const Platform& platform, OpenCLArray<T>* clarray, int rowOffset, OpenCLContext& context);
~OpenCLStreamImpl();
void loadFromArray(const void* array);
void saveToArray(void* array);
void fillWithValue(void* value);
const OpenCLArray<T>& getArray() const;
OpenCLArray<T>& getArray();
private:
void initType();
OpenCLArray<T>* clarray;
OpenCLContext& context;
bool ownArray;
int width, rowOffset;
Stream::DataType baseType;
};
template <class T>
OpenCLStreamImpl<T>::OpenCLStreamImpl(std::string name, int size, Stream::DataType type, const Platform& platform, OpenCLContext& context) :
StreamImpl(name, size, type, platform), ownArray(true), context(context) {
initType();
clarray = new OpenCLArray<T>(context, size*width, name, true);
rowOffset = width;
};
template <class T>
OpenCLStreamImpl<T>::OpenCLStreamImpl(std::string name, int size, Stream::DataType type, const Platform& platform, OpenCLArray<T>* clarray, int rowOffset, OpenCLContext& context) :
StreamImpl(name, size, type, platform), clarray(clarray), rowOffset(rowOffset), ownArray(false), context(context) {
initType();
};
template <class T>
void OpenCLStreamImpl<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>
OpenCLStreamImpl<T>::~OpenCLStreamImpl() {
if (ownArray)
delete clarray;
}
template <class T>
void OpenCLStreamImpl<T>::loadFromArray(const void* array) {
float* data = reinterpret_cast<float*>(clarray->getHostBuffer());
OpenCLArray<cl_int>& order = context.getAtomIndex();
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[order[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] = (float) arrayData[order[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] = (float) arrayData[order[i]*width+j];
}
clarray->upload();
// if (getName() == "particlePositions") {
// for (int i = 0; i < context->posCellOffsets.size(); i++)
// context.posCellOffsets[i] = make_int3(0, 0, 0);
// }
}
template <class T>
void OpenCLStreamImpl<T>::saveToArray(void* array) {
clarray->download();
float* data = reinterpret_cast<float*>(clarray->getHostBuffer());
OpenCLArray<cl_int>& order = context.getAtomIndex();
if (baseType == Stream::Float) {
float* arrayData = (float*) array;
for (int i = 0; i < getSize(); ++i)
for (int j = 0; j < width; ++j)
arrayData[order[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[order[i]*width+j] = data[i*rowOffset+j];
// if (context && getName() == "particlePositions") {
// for (int i = 0; i < getSize(); i++) {
// int3 offset = context->posCellOffsets[i];
// arrayData[order[i]*width] -= offset.x*context->sim.periodicBoxSizeX;
// arrayData[order[i]*width+1] -= offset.y*context->sim.periodicBoxSizeY;
// arrayData[order[i]*width+2] -= offset.z*context->sim.periodicBoxSizeZ;
// }
// }
}
else {
int* arrayData = (int*) array;
for (int i = 0; i < getSize(); ++i)
for (int j = 0; j < width; ++j)
arrayData[order[i]*width+j] = (int) data[i*rowOffset+j];
}
}
template <class T>
void OpenCLStreamImpl<T>::fillWithValue(void* value) {
float* data = reinterpret_cast<float*>(clarray->getHostBuffer());
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] = (float) valueData;
}
else {
int valueData = *((int*) value);
for (int i = 0; i < getSize(); ++i)
for (int j = 0; j < width; ++j)
data[i*rowOffset+j] = (float) valueData;
}
clarray->upload();
// if (context && getName() == "particlePositions") {
// context->bRecalculateBornRadii = true;
// for (int i = 0; i < context->posCellOffsets.size(); i++)
// context->posCellOffsets[i] = make_int3(0, 0, 0);
// }
}
template <class T>
const OpenCLArray<T>& OpenCLStreamImpl<T>::getArray() const {
return clarray;
}
template <class T>
OpenCLArray<T>& OpenCLStreamImpl<T>::getArray() {
return clarray;
}
} // namespace OpenMM
#endif /*OPENMM_OPENCLSTREAMIMPL_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-2009 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 OpenCL implementation of streams.
*/
#include "../../../tests/AssertionUtilities.h"
#include "OpenCLPlatform.h"
#include "openmm/Context.h"
#include "openmm/Stream.h"
#include "openmm/VerletIntegrator.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;
OpenCLPlatform platform;
System system;
for (int i = 0; i < size; i++)
system.addParticle(1.0);
VerletIntegrator integrator(0.01);
Context context(system, integrator, platform);
ContextImpl* impl = *reinterpret_cast<ContextImpl**>(&context);
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((double) (i*scale), array[i], TOL);
ASSERT_EQUAL_TOL(0.0, (double) array[length], TOL);
}
int main() {
try {
testStream<float, 1>(Stream::Float, 0.1f);
testStream<float, 2>(Stream::Float2, 0.1f);
testStream<float, 3>(Stream::Float3, 0.1f);
testStream<float, 4>(Stream::Float4, 0.1f);
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;
}
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
* -------------------------------------------------------------------------- */ * -------------------------------------------------------------------------- */
#include "openmm/Platform.h" #include "openmm/Platform.h"
#include "ReferenceStreamFactory.h"
#include "openmm/internal/windowsExport.h" #include "openmm/internal/windowsExport.h"
namespace OpenMM { namespace OpenMM {
...@@ -54,19 +53,19 @@ public: ...@@ -54,19 +53,19 @@ public:
return 1; return 1;
} }
bool supportsDoublePrecision() const; bool supportsDoublePrecision() const;
const StreamFactory& getDefaultStreamFactory() const;
void contextCreated(ContextImpl& context) const; void contextCreated(ContextImpl& context) const;
void contextDestroyed(ContextImpl& context) const; void contextDestroyed(ContextImpl& context) const;
private:
ReferenceStreamFactory defaultStreamFactory;
}; };
class ReferencePlatform::PlatformData { class ReferencePlatform::PlatformData {
public: public:
PlatformData() : time(0.0), stepCount(0) { PlatformData(int numParticles);
} ~PlatformData();
int stepCount; int numParticles, stepCount;
double time; double time;
void* positions;
void* velocities;
void* forces;
}; };
} // namespace OpenMM } // namespace OpenMM
......
#ifndef OPENMM_REFERENCESTREAMFACTORY_H_
#define OPENMM_REFERENCESTREAMFACTORY_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 "openmm/StreamFactory.h"
#include "openmm/internal/windowsExport.h"
namespace OpenMM {
/**
* This StreamFactory creates all streams for ReferencePlatform.
*/
class OPENMM_EXPORT ReferenceStreamFactory : public StreamFactory {
public:
StreamImpl* createStreamImpl(std::string name, int size, Stream::DataType type, const Platform& platform, ContextImpl& context) const;
};
} // namespace OpenMM
#endif /*OPENMM_REFERENCESTREAMFACTORY_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 "ReferenceFloatStreamImpl.h"
using namespace OpenMM;
ReferenceFloatStreamImpl::ReferenceFloatStreamImpl(std::string name, int size, Stream::DataType type, const Platform& platform) : StreamImpl(name, size, type, platform) {
switch (type) {
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;
}
switch (type) {
case Stream::Float:
case Stream::Double:
width = 1;
break;
case Stream::Float2:
case Stream::Double2:
width = 2;
break;
case Stream::Float3:
case Stream::Double3:
width = 3;
break;
case Stream::Float4:
case Stream::Double4:
width = 4;
break;
}
data = new RealOpenMM*[size];
for (int i = 0; i < size; ++i)
data[i] = new RealOpenMM[width];
}
ReferenceFloatStreamImpl::~ReferenceFloatStreamImpl() {
for (int i = 0; i < getSize(); i++)
delete[] data[i];
delete[] data;
}
void ReferenceFloatStreamImpl::loadFromArray(const void* array) {
if (baseType == Stream::Float) {
float* arrayData = (float*) array;
for (int i = 0; i < getSize(); ++i)
for (int j = 0; j < width; ++j)
data[i][j] = arrayData[i*width+j];
}
else {
double* arrayData = (double*) array;
for (int i = 0; i < getSize(); ++i)
for (int j = 0; j < width; ++j)
data[i][j] = static_cast<RealOpenMM>( arrayData[i*width+j] );
}
}
void ReferenceFloatStreamImpl::saveToArray(void* array) {
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][j];
}
else {
double* arrayData = (double*) array;
for (int i = 0; i < getSize(); ++i)
for (int j = 0; j < width; ++j)
arrayData[i*width+j] = data[i][j];
}
}
void ReferenceFloatStreamImpl::fillWithValue(void* value) {
if (baseType == Stream::Float) {
float valueData = *((float*) value);
for (int i = 0; i < getSize(); ++i)
for (int j = 0; j < width; ++j)
data[i][j] = valueData;
}
else {
double valueData = *((double*) value);
for (int i = 0; i < getSize(); ++i)
for (int j = 0; j < width; ++j)
data[i][j] = static_cast<RealOpenMM>(valueData);
}
}
const RealOpenMM* const * ReferenceFloatStreamImpl::getData() const {
return data;
}
RealOpenMM** ReferenceFloatStreamImpl::getData() {
return data;
}
#ifndef OPENMM_REFERENCEFLOATSTREAMIMPL_H_
#define OPENMM_REFERENCEFLOATSTREAMIMPL_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 "openmm/StreamImpl.h"
#include "SimTKUtilities/SimTKOpenMMRealType.h"
namespace OpenMM {
/**
* This is the implementation of Float and Double streams in the reference Platform.
*/
class ReferenceFloatStreamImpl : public StreamImpl {
public:
ReferenceFloatStreamImpl(std::string name, int size, Stream::DataType type, const Platform& platform);
~ReferenceFloatStreamImpl();
void loadFromArray(const void* array);
void saveToArray(void* array);
void fillWithValue(void* value);
const RealOpenMM* const * getData() const;
RealOpenMM** getData();
private:
int width;
Stream::DataType baseType;
RealOpenMM** data;
};
} // namespace OpenMM
#endif /*OPENMM_REFERENCEFLOATSTREAMIMPL_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 "ReferenceIntStreamImpl.h"
using namespace OpenMM;
ReferenceIntStreamImpl::ReferenceIntStreamImpl(std::string name, int size, Stream::DataType type, const Platform& platform) : StreamImpl(name, size, type, platform) {
switch (type) {
case Stream::Integer:
width = 1;
break;
case Stream::Integer2:
width = 2;
break;
case Stream::Integer3:
width = 3;
break;
case Stream::Integer4:
width = 4;
break;
}
data = new int*[size];
for (int i = 0; i < size; ++i)
data[i] = new int[width];
}
ReferenceIntStreamImpl::~ReferenceIntStreamImpl() {
delete data;
}
void ReferenceIntStreamImpl::loadFromArray(const void* array) {
int* arrayData = (int*) array;
for (int i = 0; i < getSize(); ++i)
for (int j = 0; j < width; ++j)
data[i][j] = arrayData[i*width+j];
}
void ReferenceIntStreamImpl::saveToArray(void* array) {
int* arrayData = (int*) array;
for (int i = 0; i < getSize(); ++i)
for (int j = 0; j < width; ++j)
arrayData[i*width+j] = data[i][j];
}
void ReferenceIntStreamImpl::fillWithValue(void* value) {
int valueData = *((int*) value);
for (int i = 0; i < getSize(); ++i)
for (int j = 0; j < width; ++j)
data[i][j] = valueData;
}
const int* const * ReferenceIntStreamImpl::getData() const {
return data;
}
int** ReferenceIntStreamImpl::getData() {
return data;
}
#ifndef OPENMM_REFERENCEINTSTREAMIMPL_H_
#define OPENMM_REFERENCEINTSTREAMIMPL_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 "openmm/StreamImpl.h"
namespace OpenMM {
/**
* This is the implementation of Float and Double streams in the reference Platform.
*/
class ReferenceIntStreamImpl : public StreamImpl {
public:
ReferenceIntStreamImpl(std::string name, int size, Stream::DataType type, const Platform& platform);
~ReferenceIntStreamImpl();
void loadFromArray(const void* array);
void saveToArray(void* array);
void fillWithValue(void* value);
const int* const * getData() const;
int** getData();
private:
int width;
Stream::DataType baseType;
int** data;
};
} // namespace OpenMM
#endif /*OPENMM_REFERENCEINTSTREAMIMPL_H_*/
...@@ -40,8 +40,8 @@ KernelImpl* ReferenceKernelFactory::createKernelImpl(std::string name, const Pla ...@@ -40,8 +40,8 @@ KernelImpl* ReferenceKernelFactory::createKernelImpl(std::string name, const Pla
ReferencePlatform::PlatformData& data = *static_cast<ReferencePlatform::PlatformData*>(context.getPlatformData()); ReferencePlatform::PlatformData& data = *static_cast<ReferencePlatform::PlatformData*>(context.getPlatformData());
if (name == CalcForcesAndEnergyKernel::Name()) if (name == CalcForcesAndEnergyKernel::Name())
return new ReferenceCalcForcesAndEnergyKernel(name, platform); return new ReferenceCalcForcesAndEnergyKernel(name, platform);
if (name == UpdateTimeKernel::Name()) if (name == UpdateStateDataKernel::Name())
return new ReferenceUpdateTimeKernel(name, platform, data); return new ReferenceUpdateStateDataKernel(name, platform, data);
if (name == CalcNonbondedForceKernel::Name()) if (name == CalcNonbondedForceKernel::Name())
return new ReferenceCalcNonbondedForceKernel(name, platform); return new ReferenceCalcNonbondedForceKernel(name, platform);
if (name == CalcCustomNonbondedForceKernel::Name()) if (name == CalcCustomNonbondedForceKernel::Name())
......
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