Hello there!
I have been having issues with having larger than 256kb 1D buffers. When the buffer is smaller I get no exceptions and the calculations seem correct. But when I set the buffer size bigger than 256kb the program below outputs the following:
Platform number is: 1
Platform is by: NVIDIA Corporation
std::vector inVec has size 2048000
terminate called after throwing an instance of ‘cl::Error’
what(): clFinish
Aborted
It is the statement “queue.finish()” in the source code that throws an exception. I have also tried using “event.wait()” with a similar result. Am I doing something terrebly wrong in the code? Or is it a bug in the drivers? opencl? Or perhaps the C++ header(I looked in there but it looks ok to me)? I would greatly appreciate any help or pointers on how to fix this.
My system:
Arch Linux i686, NVIDIA driver 256.35, OpenCL 1.0, GTX 460.
The complete code is included below.
Thanks!
Regards,
anlmat
kernels:
[codebox]__kernel void simple_add(__global int *in)
{
size_t tid = get_global_id(0);
in[tid] = in[tid]+2;
}
__kernel void simple_sub(__global int *in)
{
size_t tid = get_global_id(0);
in[tid] = in[tid]-1;
}[/codebox]
main.cpp:
[codebox]#define __CL_ENABLE_EXCEPTIONS
#include <CL/cl.hpp>
inline void
checkErr(cl_int err, const char * name)
{
if (err != CL_SUCCESS) {
std::cerr << "ERROR: " << name
<< " (" << err << ")" << std::endl;
exit(EXIT_FAILURE);
}
}
int
main(void)
{
cl_int err;
std::vector< cl::Platform > platformList;
cl::Platform::get(&platformList);
checkErr(platformList.size()!=0 ? CL_SUCCESS : -1, "cl::Platform::get");
std::cerr << "Platform number is: " << platformList.size() << std::endl;
std::string platformVendor;
platformList[0].getInfo((cl_platform_info)CL_PLATFORM_VENDOR
, &platformVendor);
std::cerr << "Platform is by: " << platformVendor << "\n";
cl_context_properties cprops[3] =
{CL_CONTEXT_PLATFORM, (cl_context_properties)(platformList[0])(), 0};
cl::Context context(CL_DEVICE_TYPE_GPU,cprops,NULL,NULL,&err);
checkErr(err, "Conext::Context()");
std::vector inVec(512000,50);
size_t vec_size = inVec.size()*sizeof(int);
std::cout << "std::vector<int> inVec has size " << vec_size << std::endl;
cl::Buffer devBuf(context, CL_MEM_READ_WRITE, vec_size, &inVec[0], &err);
checkErr(err, "Buffer::Buffer()");
std::vectorcl::Device devices;
devices = context.getInfo<CL_CONTEXT_DEVICES>();
checkErr(devices.size() > 0 ? CL_SUCCESS : -1, "devices.size() > 0");
std::ifstream file(“…/opencl_test/test_kernels.cl”);
checkErr(file.is_open() ? CL_SUCCESS:-1, "test_kernels.cl");
std::string prog(std::istreambuf_iterator(file),
(std::istreambuf_iterator<char>()));
cl::Program::Sources source(1, std::make_pair(prog.c_str(), prog.length()+1));
cl::Program program(context, source);
err = program.build(devices,"");
checkErr(file.is_open() ? CL_SUCCESS : -1, "Program::build()");
cl::Kernel simple_add_kernel(program, “simple_add”, &err);
cl::Kernel simple_sub_kernel(program, "simple_sub", &err);
cl::CommandQueue queue(context, devices[0], 0, &err);
cl::Event event;
err = queue.enqueueWriteBuffer(devBuf, CL_TRUE, 0, vec_size, &inVec[0]);
err = simple_add_kernel.setArg(0, devBuf);
err = simple_sub_kernel.setArg(0, devBuf);
err = queue.enqueueNDRangeKernel(simple_add_kernel, cl::NullRange, cl::NDRange(vec_size), cl::NDRange(32), NULL, &event);
err = queue.enqueueNDRangeKernel(simple_sub_kernel, cl::NullRange, cl::NDRange(vec_size), cl::NDRange(32), NULL, &event);
checkErr(err, “CommandQueue::enqueueNDRangeKernel()”);
queue.finish();
err = queue.enqueueReadBuffer(devBuf, CL_TRUE, 0, vec_size, &inVec[0]);
checkErr(err, "CommandQueue::enqueueReadBuffer()");
std::cout << "\n" << inVec[0];
return EXIT_SUCCESS;
}
[/codebox]