PIVariant::fromValue<PIVariant> fix
PIOpenCL new Buffer class
This commit is contained in:
@@ -15,6 +15,11 @@ PRIVATE_DEFINITION_START(PIOpenCL::Context)
|
||||
PRIVATE_DEFINITION_END(PIOpenCL::Context)
|
||||
|
||||
|
||||
PRIVATE_DEFINITION_START(PIOpenCL::Buffer)
|
||||
cl_mem buffer;
|
||||
PRIVATE_DEFINITION_END(PIOpenCL::Buffer)
|
||||
|
||||
|
||||
PRIVATE_DEFINITION_START(PIOpenCL::Program)
|
||||
cl_program program;
|
||||
PRIVATE_DEFINITION_END(PIOpenCL::Program)
|
||||
@@ -141,6 +146,7 @@ PIOpenCL::Context::Context() {
|
||||
PIOpenCL::Context::~Context() {
|
||||
piCout << "destroy context" << this;
|
||||
deletePrograms();
|
||||
deleteBuffers();
|
||||
if (PRIVATE->queue)
|
||||
clReleaseCommandQueue(PRIVATE->queue);
|
||||
if (PRIVATE->context)
|
||||
@@ -151,6 +157,7 @@ PIOpenCL::Context::~Context() {
|
||||
|
||||
void PIOpenCL::Context::zero() {
|
||||
programs_.clear();
|
||||
buffers_.clear();
|
||||
PRIVATE->context = 0;
|
||||
PRIVATE->queue = 0;
|
||||
PRIVATE->devices.clear();
|
||||
@@ -158,7 +165,7 @@ void PIOpenCL::Context::zero() {
|
||||
|
||||
|
||||
void PIOpenCL::Context::deletePrograms() {
|
||||
piCout << "context: delete" << programs_.size() << "progs";
|
||||
piCout << "context: delete" << programs_.size() << "programs";
|
||||
PIVector<Program * > ptdl = programs_;
|
||||
programs_.clear();
|
||||
piForeach (Program * p, ptdl) {
|
||||
@@ -167,6 +174,16 @@ void PIOpenCL::Context::deletePrograms() {
|
||||
}
|
||||
|
||||
|
||||
void PIOpenCL::Context::deleteBuffers() {
|
||||
piCout << "context: delete" << buffers_.size() << "buffers";
|
||||
PIVector<Buffer * > btdl = buffers_;
|
||||
buffers_.clear();
|
||||
piForeach (Buffer * b, btdl) {
|
||||
if (b) delete b;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PIOpenCL::Context * PIOpenCL::Context::create(const PIOpenCL::DeviceList & dl) {
|
||||
if (dl.isEmpty()) return 0;
|
||||
Context * rc = 0;
|
||||
@@ -275,6 +292,105 @@ PIOpenCL::Program * PIOpenCL::Context::createProgram(const PIString & source, PI
|
||||
}
|
||||
|
||||
|
||||
PIOpenCL::Buffer * PIOpenCL::Context::createBuffer(PIOpenCL::Direction dir, void * container, int type, PIByteArray def, uint elements) {
|
||||
Buffer * ret = new Buffer();
|
||||
ret->context_ = this;
|
||||
ret->dir = dir;
|
||||
ret->type = (Buffer::Container)type;
|
||||
ret->container = container;
|
||||
ret->def = def;
|
||||
ret->elements = elements;
|
||||
if (!ret->init()) {
|
||||
delete ret;
|
||||
return 0;
|
||||
}
|
||||
buffers_ << ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
PIOpenCL::Buffer::Buffer() {
|
||||
zero();
|
||||
}
|
||||
|
||||
|
||||
PIOpenCL::Buffer::~Buffer() {
|
||||
if (context_)
|
||||
context_->buffers_.removeAll(this);
|
||||
if (PRIVATE->buffer)
|
||||
clReleaseMemObject(PRIVATE->buffer);
|
||||
zero();
|
||||
}
|
||||
|
||||
|
||||
void PIOpenCL::Buffer::zero() {
|
||||
type = cNone;
|
||||
container = 0;
|
||||
elements = 0;
|
||||
PRIVATE->buffer = 0;
|
||||
}
|
||||
|
||||
|
||||
bool PIOpenCL::Buffer::init() {
|
||||
cl_int ret = 0;
|
||||
cl_mem_flags f = container ? CL_MEM_COPY_HOST_PTR : 0;
|
||||
switch (dir) {
|
||||
case Input : f |= CL_MEM_READ_ONLY ; break;
|
||||
case Output : f |= CL_MEM_WRITE_ONLY; break;
|
||||
case InputOutput: f |= CL_MEM_READ_WRITE; break;
|
||||
default: break;
|
||||
}
|
||||
PRIVATE->buffer = clCreateBuffer(context_->PRIVATEWB->context, f, elements * def.size(), container ? containerData() : 0, &ret);
|
||||
if (ret != 0) {
|
||||
piCout << "[PIOpenCL::Buffer]" << "clCreateBuffer error" << ret;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void * PIOpenCL::Buffer::containerData() {
|
||||
if (type == cNone || !container) return 0;
|
||||
switch (type) {
|
||||
case cVector : return ((PIVector <uchar>*)container)->data();
|
||||
case cDeque : return ((PIDeque <uchar>*)container)->data();
|
||||
case cVector2D: return ((PIVector2D<uchar>*)container)->data();
|
||||
default: break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void PIOpenCL::Buffer::clear() {
|
||||
if (!PRIVATE->buffer) return;
|
||||
if (def.isEmpty() || elements == 0) return;
|
||||
cl_int ret = clEnqueueFillBuffer(context_->PRIVATEWB->queue, PRIVATE->buffer, def.data(), def.size_s(), 0, elements * def.size(), 0, 0, 0);
|
||||
if (ret != 0) {
|
||||
piCout << "[PIOpenCL::Buffer]" << "clEnqueueFillBuffer error" << ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIOpenCL::Buffer::copyToContainer() {
|
||||
if (!PRIVATE->buffer || !container) return;
|
||||
cl_int ret = clEnqueueReadBuffer(context_->PRIVATEWB->queue, PRIVATE->buffer, CL_TRUE, 0, elements * def.size(), containerData(), 0, 0, 0);
|
||||
if (ret != 0) {
|
||||
piCout << "[PIOpenCL::Buffer]" << "clEnqueueReadBuffer error" << ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIOpenCL::Buffer::copyFromContainer() {
|
||||
if (!PRIVATE->buffer || !container) return;
|
||||
cl_int ret = clEnqueueWriteBuffer(context_->PRIVATEWB->queue, PRIVATE->buffer, CL_TRUE, 0, elements * def.size(), containerData(), 0, 0, 0);
|
||||
if (ret != 0) {
|
||||
piCout << "[PIOpenCL::Buffer]" << "clEnqueueWriteBuffer error" << ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
PIOpenCL::Program::Program() {
|
||||
@@ -326,22 +442,11 @@ bool PIOpenCL::Kernel::execute() {
|
||||
piCout << "[PIOpenCL::Kernel]" << "Error: empty range";
|
||||
return false;
|
||||
}
|
||||
cl_int ret = 0;
|
||||
piCout << "execute" << dims;
|
||||
ret = clEnqueueNDRangeKernel(context_->PRIVATEWB->queue, PRIVATE->kernel, dims.size(), 0, dims.data(), 0, 0, 0, 0);
|
||||
cl_int ret = clEnqueueNDRangeKernel(context_->PRIVATEWB->queue, PRIVATE->kernel, dims.size(), 0, dims.data(), 0, 0, 0, 0);
|
||||
if (ret != 0) {
|
||||
piCout << "[PIOpenCL::Kernel]" << "clEnqueueNDRangeKernel error" << ret;
|
||||
return false;
|
||||
}
|
||||
piForeachC (KernelArg & ka, args_) {
|
||||
if (ka.direction == Output || ka.direction == InputOutput) {
|
||||
ret = clEnqueueReadBuffer(context_->PRIVATEWB->queue, (cl_mem)(ka.buffer), CL_TRUE, 0, ka.bytes, ka.data, 0, 0, 0);
|
||||
if (ret != 0) {
|
||||
piCout << "[PIOpenCL::Kernel]" << "clEnqueueWriteBuffer" << ka.type_name << ka.arg_name << "error" << ret;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -359,10 +464,6 @@ PIOpenCL::Kernel::Kernel() {
|
||||
|
||||
PIOpenCL::Kernel::~Kernel() {
|
||||
//piCout << "del Kernel" << this;
|
||||
piForeachC (void * b, buffers_) {
|
||||
clReleaseMemObject((cl_mem)b);
|
||||
}
|
||||
buffers_.clear();
|
||||
if (PRIVATE->kernel)
|
||||
clReleaseKernel(PRIVATE->kernel);
|
||||
}
|
||||
@@ -432,50 +533,18 @@ bool PIOpenCL::Kernel::setArgValueS(int index, const PIVariant & value) {
|
||||
}
|
||||
|
||||
|
||||
bool PIOpenCL::Kernel::bindArgValueV(int index, uint bytes, void * value, uint def_bytes, void * def_data, Direction dir) {
|
||||
bool PIOpenCL::Kernel::bindArgValue(int index, Buffer * buffer) {
|
||||
if (!buffer) return false;
|
||||
if (index < 0 || index >= args_.size_s()) {
|
||||
piCout << "[PIOpenCL::Kernel]" << "bindArgValue invalid index" << index;
|
||||
return false;
|
||||
}
|
||||
KernelArg & ka(args_[index]);
|
||||
if (ka.dims <= 0) {
|
||||
piCout << "[PIOpenCL::Kernel]" << "bindArgValue set vector to \"" << ka.type_name << ka.arg_name << "\"";
|
||||
piCout << "[PIOpenCL::Kernel]" << "bindArgValue set buffer to \"" << ka.type_name << ka.arg_name << "\"";
|
||||
return false;
|
||||
}
|
||||
cl_int ret = 0;
|
||||
cl_mem_flags f = CL_MEM_COPY_HOST_PTR;
|
||||
ka.direction = dir;
|
||||
//piCout << "acc" << ka.type_name << ka.arg_name << ka.access_qualifier << bytes << value;
|
||||
switch (ka.direction) {
|
||||
case Input : f |= CL_MEM_READ_ONLY ; break;
|
||||
case Output : f |= CL_MEM_WRITE_ONLY; break;
|
||||
case InputOutput: f |= CL_MEM_READ_WRITE; break;
|
||||
default: break;
|
||||
}
|
||||
cl_mem mem = clCreateBuffer(context_->PRIVATEWB->context, f, bytes, value, &ret);
|
||||
if (ret != 0) {
|
||||
piCout << "[PIOpenCL::Kernel]" << "clCreateBuffer" << ka.type_name << ka.arg_name << "error" << ret;
|
||||
return false;
|
||||
}
|
||||
buffers_ << (void*)mem;
|
||||
ka.bytes = bytes;
|
||||
ka.data = value;
|
||||
ka.buffer = (void*)mem;
|
||||
if (ka.direction == Input || ka.direction == InputOutput) {
|
||||
ret = clEnqueueWriteBuffer(context_->PRIVATEWB->queue, mem, CL_TRUE, 0, bytes, value, 0, 0, 0);
|
||||
if (ret != 0) {
|
||||
piCout << "[PIOpenCL::Kernel]" << "clEnqueueWriteBuffer" << ka.type_name << ka.arg_name << "error" << ret;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (ka.direction == Output || ka.direction == InputOutput) {
|
||||
ret = clEnqueueFillBuffer(context_->PRIVATEWB->queue, mem, def_data, def_bytes, 0, bytes, 0, 0, 0);
|
||||
if (ret != 0) {
|
||||
piCout << "[PIOpenCL::Kernel]" << "clEnqueueFillBuffer" << ka.type_name << ka.arg_name << "error" << ret;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
clSetKernelArg(PRIVATE->kernel, index, sizeof(mem), &mem);
|
||||
clSetKernelArg(PRIVATE->kernel, index, sizeof(buffer->PRIVATEWB->buffer), &(buffer->PRIVATEWB->buffer));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -505,8 +574,6 @@ PIOpenCL::KernelArg::KernelArg() {
|
||||
is_pointer = false;
|
||||
arg_type = Float;
|
||||
dims = 1;
|
||||
bytes = 0;
|
||||
buffer = data = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user