OpenCL with C++ wrapper - unable to get a simple program working

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.

OK, nevermind the question. I found out what was the problem.

When setting the arguments of the kernel through the cl::Kernel::setArg() function I wrote err = cl_kernel.setArg(0, &cl_buffer); instead of err = cl_kernel.setArg(0, cl_buffer);
I was passing the address of the buffer instead of the buffer itself. Rookie mistake.

Sorry I posted this inquiry, but after two - three day with no progress, I though this was my only chance.