Commit 437ca02f authored by Peter Eastman's avatar Peter Eastman
Browse files

Very beginnings of support for OpenCL

parent 15811b7c
......@@ -293,6 +293,10 @@ IF(OPENMM_BUILD_BROOK_LIB)
ADD_SUBDIRECTORY(platforms/brook)
ENDIF(OPENMM_BUILD_BROOK_LIB)
SET(OPENMM_BUILD_OPENCL_LIB OFF CACHE BOOL "Build OpenMMOpenCL library for Nvidia GPUs")
IF(OPENMM_BUILD_OPENCL_LIB)
ADD_SUBDIRECTORY(platforms/opencl)
ENDIF(OPENMM_BUILD_OPENCL_LIB)
INSTALL_TARGETS(/lib RUNTIME_DIRECTORY /lib ${SHARED_TARGET})
INSTALL_TARGETS(/lib RUNTIME_DIRECTORY /lib ${STATIC_TARGET})
......
#---------------------------------------------------
# OpenMM OpenCL Platform
#
# Creates OpenMM library, base name=OpenMMOpenCL.
# Default libraries are shared & optimized. Variants
# are created for static (_static) and debug (_d).
#
# Windows:
# OpenMMOpenCL[_d].dll
# OpenMMOpenCL[_d].lib
# OpenMMOpenCL_static[_d].lib
# Unix:
# libOpenMMOpenCL[_d].so
# libOpenMMOpenCL_static[_d].a
#----------------------------------------------------
SUBDIRS (tests)
# The source is organized into subdirectories, but we handle them all from
# this CMakeLists file rather than letting CMake visit them as SUBDIRS.
SET(OPENMM_SOURCE_SUBDIRS .)
# Collect up information about the version of the OpenMM library we're building
# and make it available to the code so it can be built into the binaries.
SET(OPENMMOPENCL_LIBRARY_NAME OpenMMOpenCL)
SET(SHARED_TARGET ${OPENMMOPENCL_LIBRARY_NAME})
SET(STATIC_TARGET ${OPENMMOPENCL_LIBRARY_NAME}_static)
# Ensure that debug libraries have "_d" appended to their names.
# CMake gets this right on Windows automatically with this definition.
IF (${CMAKE_GENERATOR} MATCHES "Visual Studio")
SET(CMAKE_DEBUG_POSTFIX "_d" CACHE INTERNAL "" FORCE)
ENDIF (${CMAKE_GENERATOR} MATCHES "Visual Studio")
# But on Unix or Cygwin we have to add the suffix manually
IF (UNIX AND CMAKE_BUILD_TYPE MATCHES Debug)
SET(SHARED_TARGET ${SHARED_TARGET}_d)
SET(STATIC_TARGET ${STATIC_TARGET}_d)
ENDIF (UNIX AND CMAKE_BUILD_TYPE MATCHES Debug)
# These are all the places to search for header files which are
# to be part of the API.
SET(API_INCLUDE_DIRS) # start empty
FOREACH(subdir ${OPENMM_SOURCE_SUBDIRS})
# append
SET(API_INCLUDE_DIRS ${API_INCLUDE_DIRS}
${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/include
${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/include/internal)
ENDFOREACH(subdir)
# We'll need both *relative* path names, starting with their API_INCLUDE_DIRS,
# and absolute pathnames.
SET(API_REL_INCLUDE_FILES) # start these out empty
SET(API_ABS_INCLUDE_FILES)
FOREACH(dir ${API_INCLUDE_DIRS})
FILE(GLOB fullpaths ${dir}/*.h) # returns full pathnames
SET(API_ABS_INCLUDE_FILES ${API_ABS_INCLUDE_FILES} ${fullpaths})
FOREACH(pathname ${fullpaths})
GET_FILENAME_COMPONENT(filename ${pathname} NAME)
SET(API_REL_INCLUDE_FILES ${API_REL_INCLUDE_FILES} ${dir}/${filename})
ENDFOREACH(pathname)
ENDFOREACH(dir)
# collect up source files
SET(SOURCE_FILES) # empty
SET(SOURCE_INCLUDE_FILES)
FOREACH(subdir ${OPENMM_SOURCE_SUBDIRS})
FILE(GLOB_RECURSE src_files ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/src/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/src/*.c)
FILE(GLOB incl_files ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/src/*.h)
SET(SOURCE_FILES ${SOURCE_FILES} ${src_files}) #append
SET(SOURCE_INCLUDE_FILES ${SOURCE_INCLUDE_FILES} ${incl_files})
INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/include)
ENDFOREACH(subdir)
INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/src)
SUBDIRS (sharedTarget)
set(ENV_OPENCL_DIR $ENV{OPENCL_DIR})
if(ENV_OPENCL_DIR)
find_path(OPENCL_INCLUDE_DIR NAMES CL/cl.h PATHS $ENV{OPENCL_DIR}/include NO_DEFAULT_PATH)
if("${CMAKE_SYSTEM_NAME}" MATCHES "Linux")
if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64")
set(OPENCL_LIB_SEARCH_PATH ${OPENCL_LIB_SEARCH_PATH} $ENV{OPENCL_DIR}/lib/x86_64)
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "i686")
set(OPENCL_LIB_SEARCH_PATH ${OPENCL_LIB_SEARCH_PATH} $ENV{OPENCL_DIR}/lib/x86)
endif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64")
endif("${CMAKE_SYSTEM_NAME}" MATCHES "Linux")
find_library(OPENCL_LIBRARY NAMES OpenCL PATHS ${OPENCL_LIB_SEARCH_PATH} NO_DEFAULT_PATH)
else(ENV_OPENCL_DIR)
find_path(OPENCL_INCLUDE_DIR NAMES CL/cl.h)
find_library(OPENCL_LIBRARY NAMES OpenCL)
endif(ENV_OPENCL_DIR)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(OPENCL DEFAULT_MSG OPENCL_LIBRARY OPENCL_INCLUDE_DIR)
if(OPENCL_FOUND)
set(OPENCL_LIBRARIES ${OPENCL_LIBRARY})
else(OPENCL_FOUND)
set(OPENCL_LIBRARIES)
endif(OPENCL_FOUND)
mark_as_advanced(OPENCL_INCLUDE_DIR OPENCL_LIBRARY)
\ No newline at end of file
#ifndef OPENMM_OPENCLKERNELFACTORY_H_
#define OPENMM_OPENCLKERNELFACTORY_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/KernelFactory.h"
namespace OpenMM {
/**
* This KernelFactory creates all kernels for OpenCLPlatform.
*/
class OpenCLKernelFactory : public KernelFactory {
public:
KernelImpl* createKernelImpl(std::string name, const Platform& platform, ContextImpl& context) const;
};
} // namespace OpenMM
#endif /*OPENMM_OPENCLKERNELFACTORY_H_*/
#ifndef OPENMM_OPENCLPLATFORM_H_
#define OPENMM_OPENCLPLATFORM_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/Platform.h"
#include "OpenCLStreamFactory.h"
struct _gpuContext;
namespace OpenMM {
class OpenCLContext;
/**
* This Platform subclass uses OpenCL implementations of the OpenMM kernels.
*/
class OPENMM_EXPORT OpenCLPlatform : public Platform {
public:
class PlatformData;
OpenCLPlatform();
const std::string& getName() const {
static const std::string name = "OpenCL";
return name;
}
double getSpeed() const {
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 OpenCL platform to use.
*/
static const std::string& OpenCLPlatformIndex() {
static const std::string key = "OpenCLPlatformIndex";
return key;
}
/**
* This is the name of the parameter for selecting which OpenCL device to use.
*/
static const std::string& OpenCLDeviceIndex() {
static const std::string key = "OpenCLDeviceIndex";
return key;
}
private:
OpenCLStreamFactory defaultStreamFactory;
};
class OpenCLPlatform::PlatformData {
public:
PlatformData(int numParticles, int platformIndex, int deviceIndex);
OpenCLContext* context;
bool removeCM;
int cmMotionFrequency;
int stepCount, computeForceCount;
double time;
std::map<std::string, std::string> propertyValues;
};
} // namespace OpenMM
#endif /*OPENMM_OPENCLPLATFORM_H_*/
#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_*/
#
# Include OpenCL related files.
#
INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/../FindOpenCL.cmake)
INCLUDE_DIRECTORIES(${OPENCL_INCLUDE_DIR})
ADD_LIBRARY(${SHARED_TARGET} SHARED ${SOURCE_FILES} ${SOURCE_INCLUDE_FILES} ${API_ABS_INCLUDE_FILES})
TARGET_LINK_LIBRARIES(${SHARED_TARGET} debug ${OPENMM_LIBRARY_NAME}_d optimized ${OPENMM_LIBRARY_NAME} ${OPENCL_LIBRARIES})
SET_TARGET_PROPERTIES(${SHARED_TARGET} PROPERTIES COMPILE_FLAGS "-DOPENMM_BUILDING_SHARED_LIBRARY")
INSTALL_TARGETS(/lib/plugins RUNTIME_DIRECTORY /lib/plugins ${SHARED_TARGET})
#ifndef OPENMM_OPENCLARRAY_H_
#define OPENMM_OPENCLARRAY_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) 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 "OpenCLContext.h"
#include "openmm/OpenMMException.h"
#include <vector>
namespace OpenMM {
/**
* This class encapsulates an OpenCL Buffer. It provides a simplified API for working with it,
* an optionally includes a buffer in host memory for copying data to and from the OpenCL Buffer.
*/
template <class T>
class OpenCLArray {
public:
/**
* Create an OpenCLArray object.
*
* @param context the context for which to create the array
* @param size the number of elements in the array
* @param name the name of the array
* @param createHostBuffer specifies whether to create a buffer in host memory for copying data to and from
* the OpenCL Buffer
*/
OpenCLArray(OpenCLContext& context, int size, const std::string& name, bool createHostBuffer = false) :
context(context), size(size), name(name), local(createHostBuffer ? size : 0) {
buffer = new cl::Buffer(context.getContext(), CL_MEM_READ_WRITE, size*sizeof(T));
}
~OpenCLArray() {
delete buffer;
}
const T& operator[](int index) const {
return local[index];
}
T& operator[](int index) {
return local[index];
}
/**
* Get a pointer to the host buffer.
*/
T* getHostBuffer() {
return &local[0];
}
/**
* Get an element of the host buffer.
*/
const T& get(int index) const {
return local[index];
}
/**
* Set an element of the host buffer.
*/
void set(int index, const T& value) {
local[index] = value;
}
/**
* Copy the values in a vector to the Buffer.
*/
void upload(std::vector<T>& data) {
context.getQueue().enqueueWriteBuffer(*buffer, true, 0, size*sizeof(T), &data[0]);
}
/**
* Copy the values in the Buffer to a vector.
*/
void download(std::vector<T>& data) const {
context.getQueue().enqueueReadBuffer(*buffer, true, 0, size*sizeof(T), &data[0]);
}
/**
* Copy the values in the host buffer to the OpenCL Buffer.
*/
void upload() {
if (local.size() == 0)
throw OpenMMException(name+": Called upload() on an OpenCLArray with no host buffer");
upload(local);
}
/**
* Copy the values in the Buffer to the host buffer.
*/
void download() {
if (local.size() == 0)
throw OpenMMException(name+": Called download() on an OpenCLArray with no host buffer");
download(local);
}
private:
OpenCLContext& context;
cl::Buffer* buffer;
std::vector<T> local;
int size;
std::string name;
};
} // namespace OpenMM
#endif /*OPENMM_OPENCLARRAY_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) 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 "OpenCLContext.h"
#include "OpenCLArray.h"
using namespace OpenMM;
OpenCLContext::OpenCLContext(int numParticles, int platformIndex, int deviceIndex) {
// TODO Select the platform and device correctly
context = new cl::Context(CL_DEVICE_TYPE_CPU);
queue = new cl::CommandQueue(getContext(), getContext().getInfo<CL_CONTEXT_DEVICES>()[0]);
posq = new OpenCLArray<cl_float4>(*this, numParticles, "posq", true);
velm = new OpenCLArray<cl_float4>(*this, numParticles, "velm", true);
force = new OpenCLArray<cl_float4>(*this, numParticles, "force", true);
atomIndex = new OpenCLArray<cl_int>(*this, numParticles, "atomIndex", true);
}
OpenCLContext::~OpenCLContext() {
delete context;
delete queue;
delete posq;
delete velm;
delete force;
delete atomIndex;
}
#ifndef OPENMM_OPENCLCONTEXT_H_
#define OPENMM_OPENCLCONTEXT_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) 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/>. *
* -------------------------------------------------------------------------- */
#define __CL_ENABLE_EXCEPTIONS
#include <CL/cl.hpp>
namespace OpenMM {
template <class T>
class OpenCLArray;
/**
* This class contains the information associated with a Context by the OpenCL Platform.
*/
class OpenCLContext {
public:
OpenCLContext(int numParticles, int platformIndex, int deviceIndex);
~OpenCLContext();
/**
* Get the cl::Context associated with this object.
*/
cl::Context& getContext() {
return *context;
}
/**
* Get the cl::CommandQueue associated with this object.
*/
cl::CommandQueue& getQueue() {
return *queue;
}
/**
* Get the array which contains the position and charge of each atom.
*/
OpenCLArray<cl_float4>& getPosq() {
return *posq;
}
/**
* Get the array which contains the velocity and massof each atom.
*/
OpenCLArray<cl_float4>& getVelm() {
return *velm;
}
/**
* Get the array which contains the force on each atom.
*/
OpenCLArray<cl_float4>& getForce() {
return *force;
}
/**
* Get the array which contains the index of each atom.
*/
OpenCLArray<cl_int>& getAtomIndex() {
return *atomIndex;
}
private:
cl::Context* context;
cl::CommandQueue* queue;
OpenCLArray<cl_float4>* posq;
OpenCLArray<cl_float4>* velm;
OpenCLArray<cl_float4>* force;
OpenCLArray<cl_int>* atomIndex;
};
} // namespace OpenMM
#endif /*OPENMM_OPENCLCONTEXT_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 "OpenCLKernelFactory.h"
#include "OpenCLKernels.h"
#include "openmm/internal/ContextImpl.h"
#include "openmm/OpenMMException.h"
using namespace OpenMM;
KernelImpl* OpenCLKernelFactory::createKernelImpl(std::string name, const Platform& platform, ContextImpl& context) const {
OpenCLPlatform::PlatformData& data = *static_cast<OpenCLPlatform::PlatformData*>(context.getPlatformData());
// if (name == InitializeForcesKernel::Name())
// return new OpenCLInitializeForcesKernel(name, platform);
// if (name == UpdateTimeKernel::Name())
// return new OpenCLUpdateTimeKernel(name, platform, data);
// if (name == CalcHarmonicBondForceKernel::Name())
// return new OpenCLCalcHarmonicBondForceKernel(name, platform, data, context.getSystem());
// if (name == CalcHarmonicAngleForceKernel::Name())
// return new OpenCLCalcHarmonicAngleForceKernel(name, platform, data, context.getSystem());
// if (name == CalcPeriodicTorsionForceKernel::Name())
// return new OpenCLCalcPeriodicTorsionForceKernel(name, platform, data, context.getSystem());
// if (name == CalcRBTorsionForceKernel::Name())
// return new OpenCLCalcRBTorsionForceKernel(name, platform, data, context.getSystem());
// if (name == CalcNonbondedForceKernel::Name())
// return new OpenCLCalcNonbondedForceKernel(name, platform, data, context.getSystem());
// if (name == CalcCustomNonbondedForceKernel::Name())
// return new OpenCLCalcCustomNonbondedForceKernel(name, platform, data, context.getSystem());
// if (name == CalcGBSAOBCForceKernel::Name())
// return new OpenCLCalcGBSAOBCForceKernel(name, platform, data);
// if (name == IntegrateVerletStepKernel::Name())
// return new OpenCLIntegrateVerletStepKernel(name, platform, data);
// if (name == IntegrateLangevinStepKernel::Name())
// return new OpenCLIntegrateLangevinStepKernel(name, platform, data);
// if (name == IntegrateBrownianStepKernel::Name())
// return new OpenCLIntegrateBrownianStepKernel(name, platform, data);
// if (name == IntegrateVariableVerletStepKernel::Name())
// return new OpenCLIntegrateVariableVerletStepKernel(name, platform, data);
// if (name == IntegrateVariableLangevinStepKernel::Name())
// return new OpenCLIntegrateVariableLangevinStepKernel(name, platform, data);
// if (name == ApplyAndersenThermostatKernel::Name())
// return new OpenCLApplyAndersenThermostatKernel(name, platform, data);
// if (name == CalcKineticEnergyKernel::Name())
// return new OpenCLCalcKineticEnergyKernel(name, platform);
// if (name == RemoveCMMotionKernel::Name())
// return new OpenCLRemoveCMMotionKernel(name, platform, data);
throw OpenMMException((std::string("Tried to create kernel with illegal kernel name '")+name+"'").c_str());
}
This diff is collapsed.
/* -------------------------------------------------------------------------- *
* 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 "OpenCLContext.h"
#include "OpenCLPlatform.h"
#include "OpenCLKernelFactory.h"
#include "OpenCLKernels.h"
#include "openmm/PluginInitializer.h"
#include "openmm/internal/ContextImpl.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() {
Platform::registerPlatform(new OpenCLPlatform());
}
OpenCLPlatform::OpenCLPlatform() {
OpenCLKernelFactory* factory = new OpenCLKernelFactory();
// registerKernelFactory(InitializeForcesKernel::Name(), factory);
// registerKernelFactory(UpdateTimeKernel::Name(), factory);
// registerKernelFactory(CalcHarmonicBondForceKernel::Name(), factory);
// registerKernelFactory(CalcHarmonicAngleForceKernel::Name(), factory);
// registerKernelFactory(CalcPeriodicTorsionForceKernel::Name(), factory);
// registerKernelFactory(CalcRBTorsionForceKernel::Name(), factory);
// registerKernelFactory(CalcNonbondedForceKernel::Name(), factory);
// registerKernelFactory(CalcCustomNonbondedForceKernel::Name(), factory);
// registerKernelFactory(CalcGBSAOBCForceKernel::Name(), factory);
// registerKernelFactory(IntegrateVerletStepKernel::Name(), factory);
// registerKernelFactory(IntegrateLangevinStepKernel::Name(), factory);
// registerKernelFactory(IntegrateBrownianStepKernel::Name(), factory);
// registerKernelFactory(IntegrateVariableVerletStepKernel::Name(), factory);
// registerKernelFactory(IntegrateVariableLangevinStepKernel::Name(), factory);
// registerKernelFactory(ApplyAndersenThermostatKernel::Name(), factory);
// registerKernelFactory(CalcKineticEnergyKernel::Name(), factory);
// registerKernelFactory(RemoveCMMotionKernel::Name(), factory);
platformProperties.push_back(OpenCLPlatformIndex());
platformProperties.push_back(OpenCLDeviceIndex());
setPropertyDefaultValue(OpenCLPlatformIndex(), "0");
setPropertyDefaultValue(OpenCLDeviceIndex(), "0");
}
bool OpenCLPlatform::supportsDoublePrecision() const {
return false;
}
const string& OpenCLPlatform::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 OpenCLPlatform::setPropertyValue(Context& context, const string& property, const string& value) const {
}
const StreamFactory& OpenCLPlatform::getDefaultStreamFactory() const {
return defaultStreamFactory;
}
void OpenCLPlatform::contextCreated(ContextImpl& context) const {
unsigned int platformIndex = 0;
const string& platformPropValue = getPropertyDefaultValue(OpenCLPlatformIndex());
if (platformPropValue.length() > 0)
stringstream(platformPropValue) >> platformIndex;
unsigned int deviceIndex = 0;
const string& devicePropValue = getPropertyDefaultValue(OpenCLDeviceIndex());
if (devicePropValue.length() > 0)
stringstream(devicePropValue) >> deviceIndex;
int numParticles = context.getSystem().getNumParticles();
context.setPlatformData(new PlatformData(numParticles, platformIndex, deviceIndex));
}
void OpenCLPlatform::contextDestroyed(ContextImpl& context) const {
PlatformData* data = reinterpret_cast<PlatformData*>(context.getPlatformData());
// gpuShutDown(data->gpu);
delete data;
}
OpenCLPlatform::PlatformData::PlatformData(int numParticles, int platformIndex, int deviceIndex) : removeCM(false), stepCount(0), computeForceCount(0), time(0.0) {
context = new OpenCLContext(numParticles, platformIndex, deviceIndex);
stringstream platform;
// device << gpu->platform;
stringstream device;
// device << gpu->device;
propertyValues[OpenCLPlatform::OpenCLPlatformIndex()] = platform.str();
propertyValues[OpenCLPlatform::OpenCLDeviceIndex()] = device.str();
}
/* -------------------------------------------------------------------------- *
* 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_*/
#
# Testing
#
ENABLE_TESTING()
INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/../FindOpenCL.cmake)
INCLUDE_DIRECTORIES(${OPENCL_INCLUDE_DIR})
# 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})
# TestOpenCLUsingParameterFile customized w/ command-line argument (input file name used in test)
#ADD_EXECUTABLE(TestOpenCLUsingParameterFile TstOpenCLUsingParameterFile.cpp)
#TARGET_LINK_LIBRARIES(TestOpenCLUsingParameterFile ${SHARED_TARGET})
#ADD_TEST(TestOpenCLUsingParameterFile "${EXECUTABLE_OUTPUT_PATH}/TestOpenCLUsingParameterFile" "-parameterFileName" "${CMAKE_CURRENT_SOURCE_DIR}/lambdaSdObcParameters.txt")
#ADD_TEST(TestOpenCLUsingParameterFile "${EXECUTABLE_OUTPUT_PATH}/TestOpenCLUsingParameterFile" "-parameterFileName" "${CMAKE_CURRENT_SOURCE_DIR}/bptiMdRfNoPbcParameters.txt")
SET(TEST_ROOT TestOpenCLUsingParameterFile)
SET(TEST_PROG TstOpenCLUsingParameterFile.cpp)
SET(TEST_STATIC ${TEST_ROOT}Static)
SET(INCLUDE_OPENCL_STATIC 1)
#IF(INCLUDE_OPENCL_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} ${STATIC_BROOK_TARGET})
# ADD_TEST(${TEST_STATIC} "${EXECUTABLE_OUTPUT_PATH}/TestOpenCLUsingParameterFileStatic" "-parameterFileName" "${CMAKE_CURRENT_SOURCE_DIR}/lambdaSdObcParameters.txt")
# ADD_TEST(${TEST_STATIC} "${EXECUTABLE_OUTPUT_PATH}/TestOpenCLUsingParameterFileStatic" "-parameterFileName" "${CMAKE_CURRENT_SOURCE_DIR}/bptiMdRfNoPbcParameters.txt")
# ADD_TEST(${TEST_STATIC} "${EXECUTABLE_OUTPUT_PATH}/TestOpenCLUsingParameterFileStatic" "-parameterFileName" "${CMAKE_CURRENT_SOURCE_DIR}/bptiMdRfPbcParameters.txt" " +checkEnergyForceConsistent -checkForces" )
#ENDIF(INCLUDE_OPENCL_STATIC)
/* -------------------------------------------------------------------------- *
* 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;
}
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