Hello everyone,
I would like to request some help from you. First of all, I am, by no means, a good programmer. In fact, I am just an electrical engineering student interested in programming in general. I wanted to try and learn OpenCL just for the fun of learning something new.
Now, what struck me as interesting is a lack of material on the internet when it comes to setting OpenCL in general. It took some time before I managed to set up my environment. I use Code::Blocks for development - I know I’ll catch some flak for this from console enthusiasts - because I couldn’t compile the ICD from the Khronos OpenCL registry via console (for both 32bit and 64bit architectures). When I compiled the libraries (on Windows) I tried running a simple program I found online - Tutorial: Simple start with OpenCL and C++ - on blog spot. The code compiled successfully for both architectures (I used the TDM-GCC-32 and TDM-GCC-64) and I got a result, meaning the environment is set up correctly. After that I wanted to try and write my own source by combining information from various site, but mostly from the Khronos reference pdf for the C++ wrapper, Fixstars OpenCL online book, and the site I got the example from. I would have provided URLs, but the forum won’t allow it. I ran into a problem when trying to set kernel arguments. The error code I receive is -38 (CL_MEM_INVALID_OBJECT) and I cant figure out what I am doing wrong, or rather, why is the buffer invalid. The code is very similar to the example + error checking, and I even tried rewriting the example code in the exact same pattern I wrote mine in - the rewritten example works, but my solo attempt doesn’t.
This is the kernel file. I named it kernel.cl.
__kernel void compute(__global char * data)
{
data[0] = 'H';
data[1] = 'e';
data[2] = 'l';
data[3] = 'l';
data[4] = 'o';
data[5] = ',';
data[6] = ' ';
data[7] = 'W';
data[8] = 'o';
data[9] = 'r';
data[10] = 'l';
data[11] = 'd';
data[12] = '!';
data[13] = '\0';
}
And this is the program I wrote.
#define CL_HPP_TARGET_OPENCL_VERSION 120
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <CL/cl.hpp>
int main()
{
const unsigned int DATA_POINTS(32); //indicates number of variables in a data array
cl_int err; //holds error information
if (err != CL_SUCCESS)
{
std::cout << "Unable to find compatible OpenCL platforms!" << std::endl;
std::cout << "Error code: " << err << std::endl << std::endl;
return -1;
}
std::vector< cl::Device > cl_devices;
for (cl::Platform & plat : cl_platforms)
{
std::vector< cl::Device > platform_devices;
err = plat.getDevices(CL_DEVICE_TYPE_ALL, &platform_devices);
cl_devices.insert(cl_devices.end(), platform_devices.begin(), platform_devices.end());
}
for (cl::Device & dev : cl_devices)
{
std::cout << "Device name: " << dev.getInfo< CL_DEVICE_NAME >() << std::endl;
std::cout << "OpenCL version: " << dev.getInfo< CL_DEVICE_VERSION >() << std::endl << std::endl;
}
cl::Context cl_context(cl_devices[0]);
cl::CommandQueue cl_command_queue(cl_context, cl_devices[0], 0, &err);
if (err != CL_SUCCESS)
{
std::cout << "Unable to create OpenCL command queue!" << std::endl;
std::cout << "Error code: " << err << std::endl << std::endl;
return -4;
}
cl::Buffer cl_buffer(cl_context, CL_MEM_READ_WRITE, sizeof(char) * DATA_POINTS, NULL, &err);
if (err != CL_SUCCESS)
{
std::cout << "Unable to allocate memory for OpenCL computation!" << std::endl;
std::cout << "Error code: " << err << std::endl << std::endl;
return -5;
}
const char file_path[]("kernel.cl");
std::fstream fs_source(file_path, std::fstream::in);
if (fs_source.fail())
{
fs_source.clear();
fs_source.open(file_path, std::fstream::out);
std::cout << "Unable to locate kernel source code file!" << std::endl;
std::cout << " New, empty file was created! Edit and try again!" << std::endl << std::endl;
return -6;
}
std::string cl_source(std::istreambuf_iterator< char >(fs_source), (std::istreambuf_iterator< char >()));
fs_source.close();
cl::Program cl_program(cl_context, cl_source, false, &err);
if (err != CL_SUCCESS)
{
std::cout << "Unable to create OpenCL Program!" << std::endl;
std::cout << "Error code: " << err << std::endl << std::endl;
return -7;
}
err = cl_program.build();
if (err != CL_SUCCESS)
{
std::string cl_build_log;
std::cout << "Unable to build OpenCL Program object!" << std::endl;
std::cout << "Error code: " << err << std::endl;
cl_program.getBuildInfo(cl_devices[0], CL_PROGRAM_BUILD_LOG, &cl_build_log);
std::cout << "Log:" << std::endl << cl_build_log << std::endl << std::endl;
return -8;
}
cl::Kernel cl_kernel(cl_program, "compute", &err);
if (err != CL_SUCCESS)
{
std::cout << "Unable to create OpenCL kernel!" << std::endl;
std::cout << "Error code: " << err << std::endl << std::endl;
return -9;
}
err = cl_kernel.setArg(0, &cl_buffer);
if (err != CL_SUCCESS)
{
std::cout << "Unable to set OpenCL kernel arguments!" << std::endl;
std::cout << "Error code: " << err << std::endl << std::endl;
return -10;
}
err = cl_command_queue.enqueueTask(cl_kernel, NULL, NULL);
if (err != CL_SUCCESS)
{
std::cout << "Unable to enqueue OpenCL task!" << std::endl;
std::cout << "Error code: " << err << std::endl << std::endl;
return -11;
}
char * my_data(new char [DATA_POINTS]);
err = cl_command_queue.enqueueReadBuffer(cl_buffer, CL_TRUE, 0, sizeof(char) * DATA_POINTS, my_data, NULL, NULL);
if (err != CL_SUCCESS)
{
std::cout << "Unable to enqueue OpenCL task!" << std::endl;
std::cout << "Error code: " << err << std::endl << std::endl;
return -12;
}
std::cout << "Result:" << std::endl;
for (unsigned int i(0); *(my_data + i) != '\0'; i++)
{
std::cout << *(my_data + i);
}
std::cout << std::endl << std::endl;
return 0;
}
Any help would be greatly appreciated.