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

Created API for platform-specific properties. CudaPlatform has a property for setting the device.

parent b2038773
......@@ -34,14 +34,16 @@
#include "Stream.h"
#include <map>
#include <string>
#include <vector>
#include "openmm/internal/windowsExport.h"
namespace OpenMM {
class Context;
class ContextImpl;
class Kernel;
class KernelFactory;
class ContextImpl;
class StreamFactory;
/**
......@@ -80,6 +82,42 @@ public:
* is permitted to implement double precision streams internally as single precision.
*/
virtual bool supportsDoublePrecision() const = 0;
/**
* Get the names of all Platform-specific properties this Platform supports.
*/
const std::vector<std::string>& getPropertyNames();
/**
* Get the value of a Platform-specific property for a Context.
*
* @param context the Context for which to get the property
* @param property the name of the property to get
* @return the value of the property
*/
virtual const std::string& getPropertyValue(const Context& context, const std::string& property) const;
/**
* Set the value of a Platform-specific property for a Context.
*
* @param context the Context for which to set the property
* @param property the name of the property to set
* @param value the value to set for the property
*/
virtual void setPropertyValue(Context& context, const std::string& property, const std::string& value) const;
/**
* Get the default value of a Platform-specific property. This is the value that will be used for
* newly created Contexts.
*
* @param property the name of the property to get
* @return the default value of the property
*/
const std::string& getPropertyDefaultValue(const std::string& property) const;
/**
* Set the default value of a Platform-specific property. This is the value that will be used for
* newly created Contexts.
*
* @param property the name of the property to set
* @param value the value to set for the property
*/
void setPropertyDefaultValue(const std::string& property, const std::string& value);
/**
* Get the default StreamFactory for this Platform. It will be used to create Streams whenever a
* different StreamFactory has not been registered for the requested stream name.
......@@ -199,6 +237,16 @@ public:
* @return the path to the default plugin directory
*/
static const std::string& getDefaultPluginsDirectory();
protected:
/**
* Get the ContextImpl for a Context.
*/
ContextImpl& getContextImpl(Context& context) const;
/**
* Get the ContextImpl for a Context.
*/
const ContextImpl& getContextImpl(const Context& context) const;
std::vector<std::string> platformProperties;
private:
// Retarded visual studio compiler complains about being unable to
......@@ -211,6 +259,7 @@ private:
std::map<std::string, KernelFactory*> kernelFactories;
std::map<std::string, StreamFactory*> streamFactories;
std::map<std::string, std::string> defaultProperties;
static std::vector<Platform*>& getPlatforms();
#if defined(_MSC_VER)
......
......@@ -30,6 +30,7 @@
* -------------------------------------------------------------------------- */
#include "openmm/Platform.h"
#include "openmm/Context.h"
#include "openmm/OpenMMException.h"
#include "openmm/Kernel.h"
#include "openmm/Stream.h"
......@@ -74,6 +75,29 @@ Platform::~Platform() {
delete *iter;
}
const vector<string>& Platform::getPropertyNames() {
return platformProperties;
}
const string& Platform::getPropertyValue(const Context& context, const string& property) const {
throw OpenMMException("getPropertyValue: Illegal property name");
}
void Platform::setPropertyValue(Context& context, const string& property, const string& value) const {
throw OpenMMException("setPropertyValue: Illegal property name");
}
const string& Platform::getPropertyDefaultValue(const string& property) const {
map<string, string>::const_iterator value = defaultProperties.find(property);
if (value == defaultProperties.end())
throw OpenMMException("getPropertyDefaultValue: Illegal property name");
return value->second;
}
void Platform::setPropertyDefaultValue(const string& property, const string& value) {
defaultProperties[property] = value;
}
void Platform::contextCreated(ContextImpl& context) const {
}
......@@ -217,3 +241,12 @@ const string& Platform::getDefaultPluginsDirectory() {
#endif
return directory;
}
ContextImpl& Platform::getContextImpl(Context& context) const {
return *context.impl;
}
const ContextImpl& Platform::getContextImpl(const Context& context) const {
return *context.impl;
}
......@@ -153,6 +153,7 @@ public:
*/
void reinitialize();
private:
friend class Platform;
ContextImpl* impl;
};
......
......@@ -144,6 +144,10 @@ public:
* Get the platform-specific data stored in this context.
*/
void* getPlatformData();
/**
* Get the platform-specific data stored in this context.
*/
const void* getPlatformData() const;
/**
* Set the platform-specific data stored in this context.
*/
......
......@@ -135,6 +135,10 @@ void* ContextImpl::getPlatformData() {
return platformData;
}
const void* ContextImpl::getPlatformData() const {
return platformData;
}
void ContextImpl::setPlatformData(void* data) {
platformData = data;
}
......@@ -210,7 +210,7 @@ class OPENMM_EXPORT BrookPlatform : public Platform {
#define bool bool
bool supportsDoublePrecision( void ) const;
/**
/**
* Return default Brook stream factory
*
* @return Brook stream factory
......
......@@ -454,7 +454,7 @@ bool BrookPlatform::supportsDoublePrecision( void ) const {
return (sizeof(RealOpenMM) >= sizeof(double));
}
/**
/**
* Return Stream factory
*
*/
......
......@@ -52,18 +52,25 @@ public:
return 100;
}
bool supportsDoublePrecision() 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;
const StreamFactory& getDefaultStreamFactory() const;
void contextCreated(ContextImpl& context) const;
void contextDestroyed(ContextImpl& context) const;
/**
* This is the name of the parameter for selecting which CUDA device to use.
*/
static const std::string& CudaDevice() {
static const std::string key = "CudaDevice";
return key;
}
private:
CudaStreamFactory defaultStreamFactory;
};
class CudaPlatform::PlatformData {
public:
PlatformData(_gpuContext* gpu) : gpu(gpu), removeCM(false), nonbondedMethod(0), hasBonds(false), hasAngles(false),
hasPeriodicTorsions(false), hasRB(false), hasNonbonded(false), primaryKernel(NULL), stepCount(0), computeForceCount(0), time(0.0) {
}
PlatformData(_gpuContext* gpu);
_gpuContext* gpu;
KernelImpl* primaryKernel;
bool removeCM;
......@@ -72,6 +79,7 @@ public:
int cmMotionFrequency;
int stepCount, computeForceCount;
double time;
std::map<std::string, std::string> propertyValues;
};
} // namespace OpenMM
......
......@@ -30,9 +30,14 @@
#include "openmm/PluginInitializer.h"
#include "openmm/internal/ContextImpl.h"
#include "kernels/gputypes.h"
#include "openmm/Context.h"
#include "openmm/System.h"
#include <sstream>
using namespace OpenMM;
using std::map;
using std::string;
using std::stringstream;
extern "C" void initOpenMMPlugin() {
if (gpuIsAvailable())
......@@ -56,19 +61,37 @@ CudaPlatform::CudaPlatform() {
registerKernelFactory(ApplyAndersenThermostatKernel::Name(), factory);
registerKernelFactory(CalcKineticEnergyKernel::Name(), factory);
registerKernelFactory(RemoveCMMotionKernel::Name(), factory);
platformProperties.push_back(CudaDevice());
setPropertyDefaultValue(CudaDevice(), "0");
}
bool CudaPlatform::supportsDoublePrecision() const {
return false;
}
const string& CudaPlatform::getPropertyValue(const Context& context, const string& property) const {
const ContextImpl& impl = getContextImpl(context);
const PlatformData* data = reinterpret_cast<const PlatformData*>(impl.getPlatformData());
map<string, string>::const_iterator value = data->propertyValues.find(property);
if (value != data->propertyValues.end())
return value->second;
return Platform::getPropertyValue(context, property);
}
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 {
unsigned int device = 0;
const string& devicePropValue = getPropertyDefaultValue(CudaDevice());
if (devicePropValue.length() > 0)
stringstream(devicePropValue) >> device;
int numParticles = context.getSystem().getNumParticles();
_gpuContext* gpu = (_gpuContext*) gpuInit(numParticles);
_gpuContext* gpu = (_gpuContext*) gpuInit(numParticles, device);
context.setPlatformData(new PlatformData(gpu));
}
......@@ -77,3 +100,10 @@ void CudaPlatform::contextDestroyed(ContextImpl& context) const {
gpuShutDown(data->gpu);
delete data;
}
CudaPlatform::PlatformData::PlatformData(_gpuContext* gpu) : gpu(gpu), removeCM(false), nonbondedMethod(0), hasBonds(false), hasAngles(false),
hasPeriodicTorsions(false), hasRB(false), hasNonbonded(false), primaryKernel(NULL), stepCount(0), computeForceCount(0), time(0.0) {
stringstream device;
device << gpu->device;
propertyValues[CudaPlatform::CudaDevice()] = device.str();
}
......@@ -1116,7 +1116,7 @@ bool gpuIsAvailable()
}
extern "C"
void* gpuInit(int numAtoms)
void* gpuInit(int numAtoms, unsigned int device)
{
gpuContext gpu = new _gpuContext;
int LRFSize = 0;
......@@ -1124,30 +1124,10 @@ void* gpuInit(int numAtoms)
int SMMajor = 0;
int SMMinor = 0;
// Get adapter
unsigned int device = 0;
char * pAdapter;
pAdapter = getenv ("NV_FAH_DEVICE");
if (pAdapter != NULL)
{
sscanf(pAdapter, "%d", &device);
}
// cudaError_t status = cudaSetDevice(device);
// RTERROR(status, "Error setting CUDA device")
// Determine which core to run on
#if 0
SYSTEM_INFO info;
GetSystemInfo(&info);
unsigned int cores = info.dwNumberOfProcessors;
if (cores > 1)
{
HANDLE hproc = GetCurrentProcess();
unsigned int core = (cores - 1) - (device % (cores - 1));
unsigned int mask = 1 << core;
SetProcessAffinityMask(hproc, mask);
}
#endif
// Select which device to use
cudaSetDevice(device); // Ignore errors
cudaError_t status = cudaGetDevice(&gpu->device);
RTERROR(status, "Error getting CUDA device")
// Determine kernel call configuration
cudaDeviceProp deviceProp;
......
......@@ -58,6 +58,7 @@ struct _gpuContext {
//Cache this here so that it doesn't
//have to be repeatedly passed around
int natoms;
int device;
gpuAtomType* gpAtomTable;
int gAtomTypes;
cudaGmxSimulation sim;
......@@ -204,7 +205,7 @@ extern "C"
void gpuInitializeRandoms(gpuContext gpu);
extern "C"
void* gpuInit(int numAtoms);
void* gpuInit(int numAtoms, unsigned int device);
extern "C"
void gpuSetIntegrationParameters(gpuContext gpu, float tau, float deltaT, float temperature);
......
......@@ -48,7 +48,7 @@ static const float RGAS = BOLTZMANN * AVOGADRO; // (J
static const float BOLTZ = (RGAS / KILO); // (kJ/(mol K))
void testGaussian() {
_gpuContext* gpu = (_gpuContext*) gpuInit(5000);
_gpuContext* gpu = (_gpuContext*) gpuInit(5000, 0);
gpu->sim.Yv = 1.0;
gpu->sim.Yx = 1.0;
gpu->sim.V = 1.0;
......
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