Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <CL/cl.h>
- #include <cstdio>
- #include <cstdlib>
- #include <iostream>
- #include <string>
- #include <fstream>
- #include <time.h>
- using namespace std;
- const char *getCLErrorString(cl_int err);
- bool checkErrors(cl_int err, const char *message);
- bool checkErrors(cl_int err, const string &message);
- void getPlatformIDs(cl_uint *numPlatforms, cl_platform_id **platforms);
- void deletePlatformIDs(cl_platform_id *platforms);
- void getGPUDeviceIDs(cl_uint numPlatforms, cl_platform_id *platforms, cl_uint **numDevices, cl_device_id ***devices);
- void getGPUDeviceIDsForPlatform(cl_platform_id platform, cl_uint *numDevices, cl_device_id **devices);
- void deleteGPUDeviceIDs(cl_uint numPlatforms, cl_uint *numDevices, cl_device_id **devices);
- void printDeviceInfo(cl_device_id device);
- bool createContext(const cl_device_id *device, cl_context *context);
- bool createCommandQueue(cl_context context, cl_device_id device, cl_command_queue *commandQueue);
- void printProgramBuildInfo(cl_program program, cl_device_id device);
- bool createAndBuildProgram(const char *filename, cl_device_id device, cl_context context, cl_program *program);
- bool createKernel(cl_program program, const char *kernelName, cl_kernel *kernel);
- int main(int argc, char **argv)
- {
- cl_uint num_platforms = 0;
- cl_platform_id *platforms = NULL;
- cl_uint *num_devices = NULL;
- cl_device_id **devices = NULL;
- getPlatformIDs(&num_platforms, &platforms);
- getGPUDeviceIDs(num_platforms, platforms, &num_devices, &devices);
- int use_platform = 0;
- int use_device = 0;
- cl_platform_id platform = platforms[use_platform];
- cl_device_id device = devices[use_platform][use_device];
- cl_context context = 0;
- cl_command_queue command_queue = 0;
- if (!createContext(&device, &context))
- {
- deleteGPUDeviceIDs(num_platforms, num_devices, devices);
- deletePlatformIDs(platforms);
- exit(EXIT_FAILURE);
- }
- if (!createCommandQueue(context, device, &command_queue))
- {
- clReleaseContext(context);
- deleteGPUDeviceIDs(num_platforms, num_devices, devices);
- deletePlatformIDs(platforms);
- exit(EXIT_FAILURE);
- }
- cl_program program1 = 0;
- cl_program program2 = 0;
- cl_program program3 = 0;
- cl_kernel kernel1 = 0;
- cl_kernel kernel2 = 0;
- cl_kernel kernel3 = 0;
- createAndBuildProgram("addVec.cl", device, context, &program1);
- createAndBuildProgram("subVec.cl", device, context, &program2);
- createAndBuildProgram("multVec.cl", device, context, &program3);
- createKernel(program1, "addVec", &kernel1);
- createKernel(program2, "subVec", &kernel2);
- createKernel(program3, "multVec", &kernel3);
- // ::TODO::
- cl_int err = 0;
- cl_uint size = 1000000;
- size_t bytes = size*sizeof(int);
- size_t global_work_size = size;
- float *tab1 = (float*)malloc(bytes);
- float *tab2 = (float*)malloc(bytes);
- float *tab3 = (float*)malloc(bytes);
- clock_t t1 = clock();
- for (int i = 0; i < size; i++){
- tab1[i] = rand() % 21 - 10;
- tab2[i] = rand() % 21 - 10;
- tab3[i] = rand() % 21 - 10;
- }
- for (int i = 0; i < size; i++){
- tab3[i] = tab1[i] + tab2[i];
- }
- float czasCPURazem = (((float)clock() - (float)t1)) / CLOCKS_PER_SEC;
- printf("Czas CPU razem: %f\n", czasCPURazem);
- cl_mem d_vec1 = clCreateBuffer(context, CL_MEM_READ_WRITE,
- bytes, NULL, &err);
- cl_mem d_vec2 = clCreateBuffer(context, CL_MEM_READ_WRITE,
- bytes, NULL, &err);
- cl_mem d_vec3 = clCreateBuffer(context, CL_MEM_READ_WRITE,
- bytes, NULL, &err);
- clock_t t2 = clock();
- clEnqueueWriteBuffer(command_queue, d_vec1, CL_TRUE, 0, sizeof(float) * size, tab1, 0, NULL, NULL);
- clFinish(command_queue);
- clEnqueueWriteBuffer(command_queue, d_vec2, CL_TRUE, 0, sizeof(float) * size, tab2, 0, NULL, NULL);
- clFinish(command_queue);
- clEnqueueWriteBuffer(command_queue, d_vec3, CL_TRUE, 0, sizeof(float) * size, tab3, 0, NULL, NULL);
- clFinish(command_queue);
- float czasKopiowania = (((float)clock() - (float)t2)) / CLOCKS_PER_SEC;
- printf("Czas kopiowania: %f\n", czasKopiowania);
- // Check for errors.
- err = clSetKernelArg(kernel1, 0, sizeof(cl_mem), &d_vec1);
- err |= clSetKernelArg(kernel1, 1, sizeof(cl_mem), &d_vec2);
- err |= clSetKernelArg(kernel1, 2, sizeof(cl_mem), &d_vec3);
- err |= clSetKernelArg(kernel1, 3, sizeof(cl_uint), &size);
- // Check for errors.
- clock_t t3 = clock();
- err = clEnqueueNDRangeKernel(command_queue, kernel1, 1, NULL,
- &global_work_size, NULL, 0, NULL, NULL);
- err = clFinish(command_queue);
- float czasWykonania = (((float)clock() - (float)t3)) / CLOCKS_PER_SEC;
- printf("Czas wykonania: %f\n", czasWykonania);
- // Check for errors.
- float czasRazem = czasKopiowania + czasWykonania;
- printf("Czas GPU razem: %f\n", czasRazem);
- clEnqueueReadBuffer(command_queue, d_vec3, CL_TRUE, 0, sizeof(float) * size, tab3, 0, NULL, NULL);
- clFinish(command_queue);
- for (int i = 0; i < size; i++){
- //printf("%f, ", tab3[i]);
- }
- printf("\n");
- ///////////
- free(tab1);
- free(tab2);
- free(tab3);
- clReleaseMemObject(d_vec1);
- clReleaseKernel(kernel1);
- clReleaseProgram(program1);
- clReleaseMemObject(d_vec2);
- clReleaseKernel(kernel2);
- clReleaseProgram(program2);
- clReleaseMemObject(d_vec3);
- clReleaseKernel(kernel3);
- clReleaseProgram(program3);
- clReleaseCommandQueue(command_queue);
- clReleaseContext(context);
- deleteGPUDeviceIDs(num_platforms, num_devices, devices);
- deletePlatformIDs(platforms);
- system("pause");
- return 0;
- }
- const char *getCLErrorString(cl_int err)
- {
- switch (err)
- {
- case CL_SUCCESS: return "CL_SUCCESS";
- case CL_DEVICE_NOT_FOUND: return "CL_DEVICE_NOT_FOUND";
- case CL_DEVICE_NOT_AVAILABLE: return "CL_DEVICE_NOT_AVAILABLE";
- case CL_COMPILER_NOT_AVAILABLE: return "CL_COMPILER_NOT_AVAILABLE";
- case CL_MEM_OBJECT_ALLOCATION_FAILURE: return "CL_MEM_OBJECT_ALLOCATION_FAILURE";
- case CL_OUT_OF_RESOURCES: return "CL_OUT_OF_RESOURCES";
- case CL_OUT_OF_HOST_MEMORY: return "CL_OUT_OF_HOST_MEMORY";
- case CL_PROFILING_INFO_NOT_AVAILABLE: return "CL_PROFILING_INFO_NOT_AVAILABLE";
- case CL_MEM_COPY_OVERLAP: return "CL_MEM_COPY_OVERLAP";
- case CL_IMAGE_FORMAT_MISMATCH: return "CL_IMAGE_FORMAT_MISMATCH";
- case CL_IMAGE_FORMAT_NOT_SUPPORTED: return "CL_IMAGE_FORMAT_NOT_SUPPORTED";
- case CL_BUILD_PROGRAM_FAILURE: return "CL_BUILD_PROGRAM_FAILURE";
- case CL_MAP_FAILURE: return "CL_MAP_FAILURE";
- case CL_MISALIGNED_SUB_BUFFER_OFFSET: return "CL_MISALIGNED_SUB_BUFFER_OFFSET";
- case CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST: return "CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST";
- case CL_INVALID_VALUE: return "CL_INVALID_VALUE";
- case CL_INVALID_DEVICE_TYPE: return "CL_INVALID_DEVICE_TYPE";
- case CL_INVALID_PLATFORM: return "CL_INVALID_PLATFORM";
- case CL_INVALID_DEVICE: return "CL_INVALID_DEVICE";
- case CL_INVALID_CONTEXT: return "CL_INVALID_CONTEXT";
- case CL_INVALID_QUEUE_PROPERTIES: return "CL_INVALID_QUEUE_PROPERTIES";
- case CL_INVALID_COMMAND_QUEUE: return "CL_INVALID_COMMAND_QUEUE";
- case CL_INVALID_HOST_PTR: return "CL_INVALID_HOST_PTR";
- case CL_INVALID_MEM_OBJECT: return "CL_INVALID_MEM_OBJECT";
- case CL_INVALID_IMAGE_FORMAT_DESCRIPTOR: return "CL_INVALID_IMAGE_FORMAT_DESCRIPTOR";
- case CL_INVALID_IMAGE_SIZE: return "CL_INVALID_IMAGE_SIZE";
- case CL_INVALID_SAMPLER: return "CL_INVALID_SAMPLER";
- case CL_INVALID_BINARY: return "CL_INVALID_BINARY";
- case CL_INVALID_BUILD_OPTIONS: return "CL_INVALID_BUILD_OPTIONS";
- case CL_INVALID_PROGRAM: return "CL_INVALID_PROGRAM";
- case CL_INVALID_PROGRAM_EXECUTABLE: return "CL_INVALID_PROGRAM_EXECUTABLE";
- case CL_INVALID_KERNEL_NAME: return "CL_INVALID_KERNEL_NAME";
- case CL_INVALID_KERNEL_DEFINITION: return "CL_INVALID_KERNEL_DEFINITION";
- case CL_INVALID_KERNEL: return "CL_INVALID_KERNEL";
- case CL_INVALID_ARG_INDEX: return "CL_INVALID_ARG_INDEX";
- case CL_INVALID_ARG_VALUE: return "CL_INVALID_ARG_VALUE";
- case CL_INVALID_ARG_SIZE: return "CL_INVALID_ARG_SIZE";
- case CL_INVALID_KERNEL_ARGS: return "CL_INVALID_KERNEL_ARGS";
- case CL_INVALID_WORK_DIMENSION: return "CL_INVALID_WORK_DIMENSION";
- case CL_INVALID_WORK_GROUP_SIZE: return "CL_INVALID_WORK_GROUP_SIZE";
- case CL_INVALID_WORK_ITEM_SIZE: return "CL_INVALID_WORK_ITEM_SIZE";
- case CL_INVALID_GLOBAL_OFFSET: return "CL_INVALID_GLOBAL_OFFSET";
- case CL_INVALID_EVENT_WAIT_LIST: return "CL_INVALID_EVENT_WAIT_LIST";
- case CL_INVALID_EVENT: return "CL_INVALID_EVENT";
- case CL_INVALID_OPERATION: return "CL_INVALID_OPERATION";
- case CL_INVALID_GL_OBJECT: return "CL_INVALID_GL_OBJECT";
- case CL_INVALID_BUFFER_SIZE: return "CL_INVALID_BUFFER_SIZE";
- case CL_INVALID_MIP_LEVEL: return "CL_INVALID_MIP_LEVEL";
- case CL_INVALID_GLOBAL_WORK_SIZE: return "CL_INVALID_GLOBAL_WORK_SIZE";
- case CL_INVALID_PROPERTY: return "CL_INVALID_PROPERTY";
- default: return "Unknown OpenCL error!";
- }
- }
- bool checkErrors(cl_int err, const char *message)
- {
- if (CL_SUCCESS == err)
- {
- return false;
- }
- cerr << message << endl;
- cerr << "Error code: " << getCLErrorString(err) << endl;
- system("pause > nul");
- return true;
- }
- bool checkErrors(cl_int err, const string &message)
- {
- return checkErrors(err, message.c_str());
- }
- void getPlatformIDs(cl_uint *numPlatforms, cl_platform_id **platforms)
- {
- cl_int err;
- err = clGetPlatformIDs(0, NULL, numPlatforms);
- if (checkErrors(err, "Error while obtaining the number of OpenCL platforms!"))
- {
- exit(EXIT_FAILURE);
- }
- cout << "The number of available OpenCL platforms: " << *numPlatforms << endl;
- *platforms = new cl_platform_id[*numPlatforms];
- err = clGetPlatformIDs(*numPlatforms, *platforms, NULL);
- if (checkErrors(err, "Error while obtaining the IDs of OpenCL platforms!"))
- {
- deletePlatformIDs(*platforms);
- exit(EXIT_FAILURE);
- }
- cout << "The IDs of OpenCL platforms obtained." << endl << endl;
- }
- void deletePlatformIDs(cl_platform_id *platforms)
- {
- delete[] platforms;
- }
- void getGPUDeviceIDs(cl_uint numPlatforms, cl_platform_id *platforms, cl_uint **numDevices, cl_device_id ***devices)
- {
- cl_uint sum_num_devices = 0;
- *numDevices = new cl_uint[numPlatforms];
- *devices = new cl_device_id*[numPlatforms];
- for (cl_uint i = 0; i < numPlatforms; ++i)
- {
- cout << ">> OpenCL platform #" << i << endl;
- (*numDevices)[i] = 0;
- (*devices)[i] = NULL;
- getGPUDeviceIDsForPlatform(platforms[i], *numDevices + i, *devices + i);
- sum_num_devices += (*numDevices)[i];
- for (cl_uint j = 0; j < (*numDevices)[i]; ++j)
- {
- cout << "> OpenCL GPU device #" << j << ":" << endl;
- printDeviceInfo((*devices)[i][j]);
- }
- cout << endl;
- }
- if (0 == sum_num_devices)
- {
- cerr << "OpenCL GPU devices were not found!" << endl;
- deleteGPUDeviceIDs(numPlatforms, *numDevices, *devices);
- deletePlatformIDs(platforms);
- system("pause > nul");
- exit(EXIT_FAILURE);
- }
- }
- void getGPUDeviceIDsForPlatform(cl_platform_id platform, cl_uint *numDevices, cl_device_id **devices)
- {
- cl_int err;
- err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 0, NULL, numDevices);
- if (checkErrors(err, "Error while obtaining the number of available OpenCL GPU devices!"))
- {
- return;
- }
- cout << "The number of available OpenCL GPU devices: " << *numDevices << endl;
- if (0 == *numDevices)
- {
- return;
- }
- *devices = new cl_device_id[*numDevices];
- err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, *numDevices, *devices, NULL);
- if (checkErrors(err, "Error while obtaining the IDs of OpenCL GPU devices!"))
- {
- delete[] * devices;
- *devices = NULL;
- *numDevices = 0;
- return;
- }
- cout << "The IDs of OpenCL GPU devices obtained." << endl;
- }
- void deleteGPUDeviceIDs(cl_uint numPlatforms, cl_uint *numDevices, cl_device_id **devices)
- {
- for (cl_uint i = 0; i < numPlatforms; ++i)
- {
- delete[] devices[i];
- }
- delete[] devices;
- delete[] numDevices;
- }
- void printDeviceInfo(cl_device_id device)
- {
- cl_int err;
- size_t param_value_size = 0;
- char *buffer = NULL;
- // CL_DEVICE_NAME
- err = clGetDeviceInfo(device, CL_DEVICE_NAME, 0, NULL, ¶m_value_size);
- if (!checkErrors(err, "Error while obtaining the size of device name string!"))
- {
- buffer = new char[param_value_size];
- clGetDeviceInfo(device, CL_DEVICE_NAME, param_value_size, static_cast<void *>(buffer), NULL);
- cout << "CL_DEVICE_NAME: " << buffer << endl;
- delete[] buffer;
- buffer = NULL;
- }
- // CL_DEVICE_VENDOR
- err = clGetDeviceInfo(device, CL_DEVICE_VENDOR, 0, NULL, ¶m_value_size);
- if (!checkErrors(err, "Error while obtaining the size of vendor name string!"))
- {
- buffer = new char[param_value_size];
- clGetDeviceInfo(device, CL_DEVICE_VENDOR, param_value_size, static_cast<void *>(buffer), NULL);
- cout << "CL_DEVICE_VENDOR: " << buffer << endl;
- delete[] buffer;
- buffer = NULL;
- }
- // CL_DEVICE_VERSION
- err = clGetDeviceInfo(device, CL_DEVICE_VERSION, 0, NULL, ¶m_value_size);
- if (!checkErrors(err, "Error while obtaining the size of OpenCL version string!"))
- {
- buffer = new char[param_value_size];
- clGetDeviceInfo(device, CL_DEVICE_VERSION, param_value_size, static_cast<void *>(buffer), NULL);
- cout << "CL_DEVICE_VERSION: " << buffer << endl;
- delete[] buffer;
- buffer = NULL;
- }
- // CL_DEVICE_PROFILE
- err = clGetDeviceInfo(device, CL_DEVICE_PROFILE, 0, NULL, ¶m_value_size);
- if (!checkErrors(err, "Error while obtaining the size of OpenCL profile string!"))
- {
- buffer = new char[param_value_size];
- clGetDeviceInfo(device, CL_DEVICE_PROFILE, param_value_size, static_cast<void *>(buffer), NULL);
- cout << "CL_DEVICE_PROFILE: " << buffer << endl;
- delete[] buffer;
- buffer = NULL;
- }
- // CL_DRIVER_VERSION
- err = clGetDeviceInfo(device, CL_DRIVER_VERSION, 0, NULL, ¶m_value_size);
- if (!checkErrors(err, "Error while obtaining the size of OpenCL software driver version string!"))
- {
- buffer = new char[param_value_size];
- clGetDeviceInfo(device, CL_DRIVER_VERSION, param_value_size, static_cast<void *>(buffer), NULL);
- cout << "CL_DRIVER_VERSION: " << buffer << endl;
- delete[] buffer;
- buffer = NULL;
- }
- }
- bool createContext(const cl_device_id *device, cl_context *context)
- {
- cl_int err;
- *context = clCreateContext(NULL, 1, device, NULL, NULL, &err);
- if (checkErrors(err, "Error while creating an OpenCL context!"))
- {
- *context = 0;
- return false;
- }
- cout << "An OpenCL context created." << endl << endl;
- return true;
- }
- bool createCommandQueue(cl_context context, cl_device_id device, cl_command_queue *commandQueue)
- {
- cl_int err;
- *commandQueue = clCreateCommandQueue(context, device, 0, &err);
- if (checkErrors(err, "Error while creating a command-queue!"))
- {
- *commandQueue = 0;
- return false;
- }
- cout << "A command-queue created." << endl << endl;
- return true;
- }
- void printProgramBuildInfo(cl_program program, cl_device_id device)
- {
- cl_int err;
- size_t param_value_size = 0;
- char *buffer = NULL;
- err = clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, 0, NULL, ¶m_value_size);
- if (!checkErrors(err, "Error while obtaining the size of build log string!"))
- {
- buffer = new char[param_value_size];
- clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, param_value_size, static_cast<void *>(buffer), NULL);
- cout << "Build log:" << endl << buffer << endl;
- delete[] buffer;
- buffer = NULL;
- }
- }
- bool createAndBuildProgram(const char *filename, cl_device_id device, cl_context context, cl_program *program)
- {
- cl_int err;
- ifstream file_cl(filename);
- string source_code;
- string line;
- char *buffer = NULL;
- if (!file_cl.is_open())
- {
- cerr << "Error while opening the file '" << filename << "'!" << endl;
- return false;
- }
- while (file_cl.good())
- {
- getline(file_cl, line);
- source_code += line;
- }
- file_cl.close();
- buffer = new char[source_code.length() + 1];
- sprintf(buffer, "%s", source_code.c_str());
- *program = clCreateProgramWithSource(context, 1, const_cast<const char **>(&buffer), NULL, &err);
- delete[] buffer;
- buffer = NULL;
- if (checkErrors(err, string("Error while creating a program object for the source code '") + filename + "'!"))
- {
- *program = 0;
- return false;
- }
- err = clBuildProgram(*program, 0, NULL, NULL, NULL, NULL);
- if (checkErrors(err, string("Error while building a program executable from the source code '") + filename + "'!"))
- {
- printProgramBuildInfo(*program, device);
- clReleaseProgram(*program);
- *program = 0;
- return false;
- }
- cout << "An OpenCL program created and built from the source code '" << filename << "'." << endl << endl;
- return true;
- }
- bool createKernel(cl_program program, const char *kernelName, cl_kernel *kernel)
- {
- cl_int err;
- *kernel = clCreateKernel(program, kernelName, &err);
- if (checkErrors(err, string("Error while creating a kernel object for a function '") + kernelName + "'!"))
- {
- *kernel = 0;
- return false;
- }
- cout << "A kernel object for a function '" << kernelName << "' created." << endl << endl;
- return true;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement