Blame c++/contourgl/clcontext.cpp

Ivan Mahonin c76ce8
/*
Ivan Mahonin c76ce8
    ......... 2015 Ivan Mahonin
Ivan Mahonin c76ce8
Ivan Mahonin c76ce8
    This program is free software: you can redistribute it and/or modify
Ivan Mahonin c76ce8
    it under the terms of the GNU General Public License as published by
Ivan Mahonin c76ce8
    the Free Software Foundation, either version 3 of the License, or
Ivan Mahonin c76ce8
    (at your option) any later version.
Ivan Mahonin c76ce8
Ivan Mahonin c76ce8
    This program is distributed in the hope that it will be useful,
Ivan Mahonin c76ce8
    but WITHOUT ANY WARRANTY; without even the implied warranty of
Ivan Mahonin c76ce8
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Ivan Mahonin c76ce8
    GNU General Public License for more details.
Ivan Mahonin c76ce8
Ivan Mahonin c76ce8
    You should have received a copy of the GNU General Public License
Ivan Mahonin c76ce8
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
Ivan Mahonin c76ce8
*/
Ivan Mahonin c76ce8
Ivan Mahonin c76ce8
#include <cassert>
Ivan Mahonin c76ce8
Ivan Mahonin c76ce8
#include <iostream>
Ivan Mahonin c76ce8
#include <fstream>
Ivan Mahonin c76ce8
Ivan Mahonin c76ce8
#include "clcontext.h"
Ivan Mahonin c76ce8
Ivan Mahonin c76ce8
Ivan Mahonin c76ce8
using namespace std;
Ivan Mahonin c76ce8
Ivan Mahonin c76ce8
Ivan Mahonin f83e6b
ClContext::ClContext(): err(), context(), queue() {
Ivan Mahonin c76ce8
Ivan Mahonin c76ce8
	// platform
Ivan Mahonin c76ce8
Ivan Mahonin c76ce8
	cl_uint platform_count = 0;
Ivan Mahonin c76ce8
	clGetPlatformIDs(0, NULL, &platform_count);
Ivan Mahonin c76ce8
	assert(platform_count);
Ivan Mahonin f29469
	//cout << platform_count << " platforms" << endl;
Ivan Mahonin c76ce8
	vector<cl_platform_id> platforms(platform_count);
Ivan Mahonin c76ce8
	clGetPlatformIDs(platforms.size(), &platforms.front(), NULL);
Ivan Mahonin c76ce8
	cl_platform_id platform = platforms[0];
Ivan Mahonin c76ce8
Ivan Mahonin c76ce8
	char vendor[256] = { };
Ivan Mahonin c76ce8
	err = clGetPlatformInfo(platform, CL_PLATFORM_VENDOR, sizeof(vendor), vendor, NULL);
Ivan Mahonin c76ce8
	assert(!err);
Ivan Mahonin f29469
	//cout << "Use CL platform 0 by " << vendor << endl;
Ivan Mahonin c76ce8
Ivan Mahonin 5890eb
    char platform_version[256];
Ivan Mahonin 5890eb
    err = clGetPlatformInfo(platform, CL_PLATFORM_VERSION, sizeof(platform_version), platform_version, NULL);
Ivan Mahonin 5890eb
	assert(!err);
Ivan Mahonin f29469
    //cout << "Platform 0 OpenCL version " << platform_version << endl;
Ivan Mahonin 5890eb
Ivan Mahonin c76ce8
	// devices
Ivan Mahonin c76ce8
Ivan Mahonin c76ce8
	cl_uint device_count = 0;
Ivan Mahonin c76ce8
    err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 0, NULL, &device_count);
Ivan Mahonin c76ce8
    assert(!err);
Ivan Mahonin f29469
    //cout << device_count << " devices" << endl;
Ivan Mahonin c76ce8
Ivan Mahonin c76ce8
    devices.resize(device_count);
Ivan Mahonin c76ce8
    err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, devices.size(), &devices.front(), NULL);
Ivan Mahonin c76ce8
    assert(!err);
Ivan Mahonin c76ce8
Ivan Mahonin 5890eb
    char device_name[256];
Ivan Mahonin 5890eb
    clGetDeviceInfo(devices.front(), CL_DEVICE_NAME, sizeof(device_name), device_name, NULL);
Ivan Mahonin f29469
    //cout << "Device 0 name " << device_name << endl;
Ivan Mahonin 5890eb
Ivan Mahonin 5890eb
    char device_version[256];
Ivan Mahonin 5890eb
    clGetDeviceInfo(devices.front(), CL_DEVICE_VERSION, sizeof(device_version), device_version, NULL);
Ivan Mahonin f29469
    //cout << "Device 0 OpenCL version " << device_version << endl;
Ivan Mahonin 5890eb
Ivan Mahonin c76ce8
    // context
Ivan Mahonin c76ce8
Ivan Mahonin c7fa36
    cl_context_properties context_props[] = {
Ivan Mahonin c7fa36
    	CL_CONTEXT_PLATFORM, (cl_context_properties)platform,
Ivan Mahonin c7fa36
		CL_NONE };
Ivan Mahonin c7fa36
    context = clCreateContext(context_props, 1, &devices.front(), callback, NULL, &err);
Ivan Mahonin c76ce8
    assert(context);
Ivan Mahonin f83e6b
Ivan Mahonin f83e6b
	// command queue
Ivan Mahonin f83e6b
Ivan Mahonin c7fa36
	queue = clCreateCommandQueue(context, devices.front(), CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, NULL);
Ivan Mahonin f83e6b
	assert(queue);
Ivan Mahonin f83e6b
Ivan Mahonin c76ce8
}
Ivan Mahonin c76ce8
Ivan Mahonin c76ce8
ClContext::~ClContext() {
Ivan Mahonin f83e6b
	clReleaseCommandQueue(queue);
Ivan Mahonin c76ce8
	clReleaseContext(context);
Ivan Mahonin c76ce8
}
Ivan Mahonin c76ce8
Ivan Mahonin c7fa36
void ClContext::callback(const char *, const void *, size_t, void *) { }
Ivan Mahonin c7fa36
Ivan Mahonin f83e6b
cl_program ClContext::load_program(const std::string &filename) {
Ivan Mahonin f83e6b
	ifstream f(("cl/" + filename).c_str());
Ivan Mahonin f83e6b
	string text((istreambuf_iterator<char>(f)), istreambuf_iterator<char>());
Ivan Mahonin f83e6b
	const char *text_pointer = text.c_str();
Ivan Mahonin f83e6b
	cl_program program = clCreateProgramWithSource(context, 1, &text_pointer, NULL, NULL);
Ivan Mahonin f83e6b
	assert(program);
Ivan Mahonin f83e6b
Ivan Mahonin 5890eb
	err = clBuildProgram(program, 1, &devices.front(), "", NULL, NULL);
Ivan Mahonin 5890eb
	if (err) {
Ivan Mahonin 5890eb
		size_t size;
Ivan Mahonin 5890eb
		clGetProgramBuildInfo(program, devices.front(), CL_PROGRAM_BUILD_LOG, 0, NULL, &size);
Ivan Mahonin 5890eb
		char *log = new char[size];
Ivan Mahonin 5890eb
		clGetProgramBuildInfo(program, devices.front(), CL_PROGRAM_BUILD_LOG, size, log, NULL);
Ivan Mahonin 5890eb
		cout << log << endl;
Ivan Mahonin 5890eb
		delete[] log;
Ivan Mahonin 5890eb
	}
Ivan Mahonin f83e6b
	assert(!err);
Ivan Mahonin f83e6b
Ivan Mahonin f83e6b
	return program;
Ivan Mahonin f83e6b
}
Ivan Mahonin f83e6b
Ivan Mahonin c76ce8
void ClContext::hello() {
Ivan Mahonin c76ce8
Ivan Mahonin c76ce8
	// data
Ivan Mahonin c76ce8
Ivan Mahonin c76ce8
	char data[] = "......";
Ivan Mahonin c76ce8
Ivan Mahonin c76ce8
	// buffer
Ivan Mahonin c76ce8
Ivan Mahonin c76ce8
	cl_mem buffer = clCreateBuffer(context, CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR, sizeof(data), data, NULL);
Ivan Mahonin c76ce8
	assert(buffer);
Ivan Mahonin c76ce8
Ivan Mahonin c76ce8
	// program
Ivan Mahonin c76ce8
Ivan Mahonin f83e6b
	cl_program program = load_program("hello.cl");
Ivan Mahonin c76ce8
Ivan Mahonin c76ce8
	// kernel
Ivan Mahonin c76ce8
Ivan Mahonin c76ce8
	cl_kernel kernel = clCreateKernel(program, "hello", NULL);
Ivan Mahonin c76ce8
	assert(kernel);
Ivan Mahonin c76ce8
	err = clSetKernelArg(kernel, 0, sizeof(buffer), &buffer);
Ivan Mahonin c76ce8
	assert(!err);
Ivan Mahonin c76ce8
Ivan Mahonin c76ce8
	size_t work_group_size = sizeof(data);
Ivan Mahonin c76ce8
	cl_event event = NULL;
Ivan Mahonin c76ce8
	err = clEnqueueNDRangeKernel(
Ivan Mahonin c76ce8
		queue,
Ivan Mahonin c76ce8
		kernel,
Ivan Mahonin c76ce8
		1,
Ivan Mahonin c76ce8
		NULL,
Ivan Mahonin c76ce8
		&work_group_size,
Ivan Mahonin c76ce8
		NULL,
Ivan Mahonin c76ce8
		0,
Ivan Mahonin c76ce8
		NULL,
Ivan Mahonin c76ce8
		&event );
Ivan Mahonin c76ce8
	assert(!err);
Ivan Mahonin c76ce8
Ivan Mahonin c76ce8
	clWaitForEvents(1, &event);
Ivan Mahonin c76ce8
Ivan Mahonin c76ce8
	// read
Ivan Mahonin c76ce8
Ivan Mahonin c76ce8
	clEnqueueReadBuffer(queue, buffer, CL_TRUE, 0, sizeof(data), data, 0, NULL, &event);
Ivan Mahonin c76ce8
	clWaitForEvents(1, &event);
Ivan Mahonin c76ce8
	cout << data << endl;
Ivan Mahonin f83e6b
Ivan Mahonin f83e6b
	// deinitialize
Ivan Mahonin f83e6b
Ivan Mahonin f83e6b
	clReleaseKernel(kernel);
Ivan Mahonin f83e6b
	clReleaseProgram(program);
Ivan Mahonin f83e6b
	clReleaseMemObject(buffer);
Ivan Mahonin c76ce8
}