/* -------------------------------------------------------------------------- *
* 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) 2012-2019 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 . *
* -------------------------------------------------------------------------- */
#include "OpenCLArray.h"
#include "OpenCLContext.h"
#include
#include
#include
using namespace OpenMM;
OpenCLArray::OpenCLArray() : buffer(NULL), ownsBuffer(false) {
}
OpenCLArray::OpenCLArray(OpenCLContext& context, int size, int elementSize, const std::string& name, cl_int flags) : buffer(NULL) {
initialize(context, size, elementSize, name, flags);
}
OpenCLArray::OpenCLArray(OpenCLContext& context, cl::Buffer* buffer, int size, int elementSize, const std::string& name) : buffer(NULL) {
initialize(context, buffer, size, elementSize, name);
}
OpenCLArray::~OpenCLArray() {
if (buffer != NULL && ownsBuffer)
delete buffer;
}
void OpenCLArray::initialize(ComputeContext& context, int size, int elementSize, const std::string& name) {
initialize(dynamic_cast(context), size, elementSize, name, CL_MEM_READ_WRITE);
}
void OpenCLArray::initialize(OpenCLContext& context, int size, int elementSize, const std::string& name, cl_int flags) {
if (buffer != NULL)
throw OpenMMException("OpenCLArray has already been initialized");
this->context = &context;
this->size = size;
this->elementSize = elementSize;
this->name = name;
this->flags = flags;
ownsBuffer = true;
try {
buffer = new cl::Buffer(context.getContext(), flags, size*elementSize);
}
catch (cl::Error err) {
std::stringstream str;
str<<"Error creating array "<buffer != NULL)
throw OpenMMException("OpenCLArray has already been initialized");
this->context = &context;
this->buffer = buffer;
this->size = size;
this->elementSize = elementSize;
this->name = name;
ownsBuffer = false;
}
void OpenCLArray::resize(int size) {
if (buffer == NULL)
throw OpenMMException("OpenCLArray has not been initialized");
if (!ownsBuffer)
throw OpenMMException("Cannot resize an array that does not own its storage");
delete buffer;
buffer = NULL;
initialize(*context, size, elementSize, name, flags);
}
ComputeContext& OpenCLArray::getContext() {
return *context;
}
void OpenCLArray::upload(const void* data, bool blocking) {
if (buffer == NULL)
throw OpenMMException("OpenCLArray has not been initialized");
try {
context->getQueue().enqueueWriteBuffer(*buffer, blocking ? CL_TRUE : CL_FALSE, 0, size*elementSize, data);
}
catch (cl::Error err) {
std::stringstream str;
str<<"Error uploading array "<getQueue().enqueueReadBuffer(*buffer, blocking ? CL_TRUE : CL_FALSE, 0, size*elementSize, data);
}
catch (cl::Error err) {
std::stringstream str;
str<<"Error downloading array "<unwrap(dest);
try {
context->getQueue().enqueueCopyBuffer(*buffer, clDest.getDeviceBuffer(), 0, 0, size*elementSize);
}
catch (cl::Error err) {
std::stringstream str;
str<<"Error copying array "<