Skip to content

EasyCL - a library let you access the power of OpenCL easily.

License

Notifications You must be signed in to change notification settings

marty1885/EasyCL

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

59 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

EasyCL

EasyCL - a library let you access the power of OpenCL easily.

NOTE : EasyCL does not support images now. But is planned in the near future.
NOTE : There is currently no plain on supporting OpenGL/Direct3D data access.
NOTE : Please run doxygen your self. I don't have a good approach to do that in CMake. Sorry.
NOTE : EasyCL is currentlly designed to work with OpenCL 1.2. Not until Intel or Nvidia releases OpenCL 2.0 for Linux. There will be no support for OpenCL 2.0.

##What it does EasyCL is a library that enables you to build and lunch a OpenCL program in just a few lines of code.

OpenCL or Open Compute Language is the first open, royalty-free standard for cross-platform, parallel programming of modern processors found in personal computers, servers and handheld/embedded devices. OpenCL greatly improves speed and responsiveness for a wide spectrum of applications in numerous market categories from gaming and entertainment to scientific and medical software.
-Khronos

Although OpenCL is powerful, it's acuatlly a pritty tiring job to write the host application code. To solve this issue. EasyCL is created.

EasyCL is designed to enable you to launch OpenCL program in just a few line of code. Whith error/ warrning handler equiped.

EasyCL is released under the MIT license, so you can use it in open source or commercial code. Details will be in the LICENSE file in this repo.

EasyCL is guarantee to be able to be compiled on GCC/clang with the proper arguments and envitoment setted.

##What it does NOT 1.There is currently no plain on supporting OpenGL/Direct3D data access.
2.No guarantee to be able to be compiled on MSVC/Intel CC. If anyone needs it on those compilers. Send me a mail or post a issue. I'll do my best to help you.

##Show me some code ####The header

#include <EasyCl.h>

####Get a OpenCL device

	EasyCl::DeviceManager deviceManager;
	EasyCl::ComputeDevice* device = deviceManager.defaultDevice(CL_DEVICE_TYPE_GPU);

EasyCl::DeviceManager::defaultDevice returns the first device EasyCL finds in the selected category,
By changine CL_DEVICE_TYPE_GPU into CL_DEVICE_TYPE_CPU or CL_DEVICE_TYPE_ACCLERAOR, it will return devices in dirrerent category.
You can also do something like CL_DEVICE_GPU|CL_DEVICE_CPU to search in muiltple categories.

####Loading OpenCL source code.

	EasyCl::SourceCode sourceCode("someOpenCLCode.cl");

It's just that easy
There is also bool EasyCl::SourceCode::good() which tells you weather the loading is success.

####Building program In OpenCL, after loading your source code. What you wana to do next is to build a program.(compile OpenCL code)

	EasyCl::Software program(device, sourceCode);
	program.build();

int EasyCL::Software::build(std::string options) returns error code. If it returns CL_SUCCESS than the build is success.
build() also take a "option" argument. This is the OpenCL compilation argument. "option" will be driectly passed to OpenCL. EasyCL does not process/use it.
To add options to the building process. just program.build(<args here>);
Ex : program.build("-cl-denorms-are-zero -DOCL_KERNEL");

####Create a kernel After building a program, inorder to run it. We have to create what's called a Kernel. A Kernel is a speacial function declared with the tag __kernel and must return void. I'll not go to deep here since this is EasyCL's README not a OpenCL tutorial.

So, how to crate a Kernl in EasyCL? Well...

	EasyCl::Kernel kernel(program, "kernlNameHere");

####Setting kernl arguments(pass data to kernel) To set a argument to a kernel. just do

	kernel.setArgBuffer(0,CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR,30*sizeof(int),data);

it's declartion is

	cl_int Kernel::setArgBuffer(int index, cl_mem_flags flags, size_t size, void* ptr);

where index is the index of whtch argumrnt you want to set on the kernl
flags is how you want the memory can be accessed. The value is builed up with 2 parts. First reead/write fags, than allocation flags. The r/w flag can be CL_MEM_WRITE_ONLY, CL_MEM_READ_ONLY or CL_MEMREAD__WRITE. The allocation flag can be CL_MEM_USE_HOST_PTR, CL_MEM_USE_COPY_PTR, CL_MEM_ALLOC_HOST_PTR.
size is how big the gargument you want to pass is in bytes.
ptr is the pointer to the argumant you want to pass.

NOTE : ptr can also be NULL to create a blank memory for OpenCL. Please notice that if ptr = NULL, than flags must contain CL_MEM_ALLOC_HOST_PTR or else it will crash.

####Launching Kernel there are three modes EasyCL and launch a kernel.
#####NDRange (N Dimention Range) First, the classic NDRange mode. I'm not going to explain that is and how NDRange works here. For more infomation, please visit here NDRange-Explain.
To launch a NDRange Kernel. It's very easy. just few lines will do the job.

	cl::NDRange global(30);
	cl::NDRange local(1);
	cl::NDRange offset;
	kernel->enqueueNDRange(offset, global, local);

#####Task A Task means to launch a single threaded Kernel. It's equivalent as global = 1, loca0 = 1, offset = 0 than do a NDRange. It is NOT paralled.
To launch a task, please do the flowing

	kernl.enqueueTask();

#####SPMP This is a mode I created in EasyCL. If you are fimilar with OpenCL : It launches a work-item for each processing element. It's equivalent to global = PROCESSING_ELEMENT_COUNT, local = PREFERED_WORKGROUPE_BASE, offset = 0 than launch a 1D NDRange.
Or, in layman's terms : It give every core on your device a thread.
NOTE : SPMD stands for Single Program Muilt data. Not Single Prodessor Multi Data. To do a SPMD, do the flowing

	kernl.enqueueSPMD();

####Reading data back. After computing, you will want to read the result back. To do that, puease do

		kernel->readBuffer(0,30*sizeof(int),copy);

which is decleared as

	cl_int Kernel::readBuffer(int index, size_t size, void* ptr)

which index is the index of the argument you want to read of the Kernl
size is how much data you want to read back in bytes.
ptr is where you want the data to be read to.
readBuffer retuens a error code. if it returns CL_SUCCESS than everting in fine. Else, something is wrong.

##Sample Code This is a simple code of EasyCL in action. more can be find in the example folder in this repo.
example.cpp

#include <iostream>
#include <CL/cl.hpp>
#include <EasyCl.h>

using namespace std;

int main()
{
	EasyCl::DeviceManager deviceManager;
	EasyCl::ComputeDevice* device = deviceManager.defaultDevice(CL_DEVICE_TYPE_GPU);

	if(device == NULL)
	{
		cout << "No device avliable. exiting" << endl;
		exit(0);
	}

	cout << "selected device:" << endl;
	cout << "Name:\t\t" << device->device.getInfo<CL_DEVICE_NAME>() << endl;
	cout << "OpenCL version:\t" << device->device.getInfo<CL_DEVICE_VERSION>() << endl;

	EasyCl::SourceCode sourceCode("example.cl");
	if(sourceCode.good() == false)
		exit(0);
	//cout << sourceCode.code << endl;

	EasyCl::Software program(device, sourceCode);
	if(program.build() != CL_SUCCESS)
		exit(0);

	EasyCl::Kernel kernel(program, "neatStuff");
	int data[30] = {0};
	int copy[30] = {50};

	kernel.setArgBuffer(0,CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR,30*sizeof(int),copy);
	kernel.setArgBuffer(1,CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,30*sizeof(int),data);

	cl::NDRange global(30);
	cl::NDRange local(1);
	kernel.enqueueNDRange(cl::NullRange, global, local);

	kernel.readBuffer(0,30*sizeof(int),copy);
	for(int i=0;i<30;i++)
		cout << copy[i] << " ";
	cout << endl;

	return 0;
}

example.cl

__kernel void neatStuff(__global int* target, __global int* source)
{
	int id = get_global_id(0);
	target[id] = source[id]+id;
}

If everthing is working normally. It should print some info about your device, than numbers from 0 to 29.
Ex :

selected device:
Name:		Intel(R) HD Graphics
OpenCL version:	OpenCL 1.2 
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 

##Appendix ###Supported gfx and SDK The following are tested gfx and associated SDK. These suite should run our examples smoothly.

gfx OpenCL SDK
Intel i7-4650U CPU @ 1.70GHz (HD 5000) OpenCL 1.2 intel_code_builder_for_opencl_2015_ubuntu_5.0.0.43_x64.tgz

###Unsupported gfx and SDK The following are tested gfx and associated SDK with known or unknown issues. These suite did not run our examples smoothly.

gfx OpenCL SDK
Intel i7-4650U CPU @ 1.70GHz (HD 5000) OpenCL 1.2 intel_code_builder_for_opencl_mss_2015_5.0.0.93_x64.tgz

About

EasyCL - a library let you access the power of OpenCL easily.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published