Skip to content

Instantly share code, notes, and snippets.

@PontiacGTX
Last active June 19, 2019 19:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PontiacGTX/dbe6c80390f0047df74e5013fd1d2e2e to your computer and use it in GitHub Desktop.
Save PontiacGTX/dbe6c80390f0047df74e5013fd1d2e2e to your computer and use it in GitHub Desktop.
#define CL_USE_DEPRECATED_OPENCL_2_0_APIS
#define _CRT_SECURE_NO_DEPRECATE /*open with FILE*/
#include <iostream>
#include "ApplicationCL.h"
unsigned long int sizeArr = 256;
char* characterArr = nullptr; /*Contains 255 characters*/
float limit;
unsigned long filebyteCount = 0;
unsigned char* compressedBytes = nullptr;
unsigned long* indexByte = nullptr;
unsigned char* fileBytes = nullptr;
int Program::ParseFile(std::string& content, const std::string& filename)
{
std::ifstream* openFile = new std::ifstream(filename, std::ios::binary);
size_t fileSize = 0;
if (openFile->is_open())
{
openFile->seekg(0, std::fstream::end);
fileSize = openFile->tellg();
openFile->seekg(0, std::fstream::beg);
}
content.reserve(fileSize);
content.insert(content.begin(), std::istreambuf_iterator<char>(*openFile), std::istreambuf_iterator<char>());
delete openFile;
if (content.size() <= 1)
return 1;
return 0;
}
void GetMessageError(cl_int status, cl_program program, cl_device_id device)
{
size_t length = 0;
status = clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, 0, NULL, &length);
size_t total = length * sizeof(char);
char* buffer = new char[total];
status = clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, length, buffer, NULL);
std::string message(buffer, total);
if (!message.empty())
std::cout << message << std::endl;
else
std::cout << "Error: " << status << std::endl;
delete[] buffer;
}
void CheckErrorCode(cl_int status, cl_program& program, cl_device_id& devices, const std::string& message)
{
if (status != 0)
{
std::cout << message << std::endl;
GetMessageError(status, program, devices);
}
}
void Program::GetPlatform(cl_platform_id& platform)
{
cl_uint numberPlatforms = 0;
cl_int status = clGetPlatformIDs(0, NULL, &numberPlatforms);
if (status == 1)
{
std::cout << "Failed Platforms not found" << std::endl;
}
if (numberPlatforms > 0)
{
cl_platform_id* platforms = new cl_platform_id[numberPlatforms * sizeof(cl_platform_id)];
status = clGetPlatformIDs(numberPlatforms, &platforms[0], &numberPlatforms);
platform = platforms[0];
if (platform == nullptr)
{
std::cout << "Error Obtaining platformId" << std::endl;
}
//std::string temp = "";
//GetPlatformInfo(numberPlatforms,platforms,1,temp);
delete[] platforms;
}
}
void Program::GetDeviceIDs(cl_device_id*& devices, const cl_platform_id& platform)
{
cl_uint deviceCount = 0;
cl_int status = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 0, NULL, &deviceCount);
if (deviceCount == 0)
{
std::cout << "No GPU device available." << std::endl;
std::cout << "Choose CPU as default device." << std::endl;
status = clGetDeviceIDs(platform, CL_DEVICE_TYPE_CPU, 0, NULL, &deviceCount);
devices = new cl_device_id[deviceCount * sizeof(cl_device_id)];
status = clGetDeviceIDs(platform, CL_DEVICE_TYPE_CPU, deviceCount, devices, NULL);
}
else
{
devices = new cl_device_id[(deviceCount * sizeof(cl_device_id))];
status = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, deviceCount, devices, NULL);
}
}
void Program::GetContext(cl_context& context, const cl_platform_id& platform, cl_device_id*& devices)
{
cl_context_properties contextProperties[] = { CL_CONTEXT_PLATFORM,reinterpret_cast<cl_context_properties>(platform), 0 };
cl_int status = 0;
context = clCreateContext(contextProperties, 1, devices, NULL, NULL, &status);
if (status != 0)
{
std::cout << "Error creating context for device" << std::endl;
}
}
void Program::GetCommandQueue(cl_command_queue& commandQueue, const cl_context& context, cl_device_id*& devices)
{
commandQueue = clCreateCommandQueue(context, devices[0], 0, NULL);
}
template<size_t size>
void Program::CreateProgramWithSource(const char*& filePath, std::string& SourceStr, size_t(&sourceSize)[size], cl_context& context, cl_program& program)
{
bool parsedFile = ParseFile(SourceStr, filePath);
if (parsedFile == 0)
{
std::cout << "File Parsed" << std::endl;
}
const char* Source = SourceStr.c_str();
sourceSize[0] = { strlen(Source) };
program = clCreateProgramWithSource(context, 1, &Source, sourceSize, NULL);
}
void Program::BuildProgram(cl_program& program, const cl_uint& deviceCount, cl_device_id*& devices)
{
status = clBuildProgram(program, 1, devices, NULL, NULL, NULL);
if (status != 0)
{
std::cout << "Program couldnt be built" << std::endl;
GetMessageError(status, program, devices[0]);
}
}
int readfilec(const char* filePath, unsigned char*& content, unsigned long* filesize)
{
FILE* fp;
fp = fopen(filePath, "rb");
fseek(fp, 0, SEEK_END); // seek to end of file
*filesize = ftell(fp); // get current file pointer
fseek(fp, 0, SEEK_SET);
content = new unsigned char[*filesize + 1];
//unsigned char* buff = (unsigned char*)malloc(*filesize * sizeof(unsigned char));
/* checking the fread return value is not necessary but recommended */
if ((fread(content, sizeof(unsigned char), *filesize, fp)) != *filesize)
return 1;
content[*filesize + 1] = '\0';
//content = &buff;
fclose(fp);
/* remember to free the memory */
delete fp;
return 0;
}
int main()
{
Program p1;
p1.GetPlatform(p1.platform);
p1.GetDeviceIDs(p1.devices,p1.platform);
p1.GetContext(p1.context,p1.platform,p1.devices);
p1.GetCommandQueue(p1.commandQueue,p1.context,p1.devices);
p1.CreateProgramWithSource(p1.filePath,p1.strSource,p1.sourceSize,p1.context,p1.program);
p1.BuildProgram(p1.program,1,p1.devices);
characterArr = new char[sizeArr];
limit=256.0f;
float c = 0;
cl_mem outputBuffer = clCreateBuffer(p1.context, CL_MEM_WRITE_ONLY, (sizeArr/*+ 1*/) * sizeof(char), NULL, &p1.status);
/*cl_mem cbuff = clCreateBuffer(p1.context, CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(float), (void*)& c, NULL);*/
//create kernel
cl_kernel kernelAdd = clCreateKernel(p1.program, "Add", &p1.status);
CheckErrorCode(p1.status, p1.program, p1.devices[0], "Failed Creating Kernel");
//create kernel argument
p1.status = clSetKernelArg(kernelAdd, 0, sizeof(cl_float), (void*)& limit);
CheckErrorCode(p1.status,p1.program,p1.devices[0], "Failed adding Argument 0");
p1.status = clSetKernelArg(kernelAdd, 1, sizeof(cl_mem), (void*)& outputBuffer);
CheckErrorCode(p1.status, p1.program, p1.devices[0], "Failed adding Argument 1");
//array of work_dim unsigned values that describe the number of global work - items in work_dim dimensions
//that will execute the kernel function.The total number of global work - items is computed as global_work_size[0] * … * global_work_size[work_dim – 1].
/****************************************/
size_t globalWorkSize[1] = { sizeArr };
//enqueues a command to execute a kernel on a device
/****************************************/
size_t localWorkSize = 64;
p1.status = clEnqueueNDRangeKernel(p1.commandQueue, kernelAdd, 1, NULL, globalWorkSize,&localWorkSize , 0, NULL, NULL);
CheckErrorCode(p1.status, p1.program, p1.devices[0], "Failed EnqueueNDRangeKernel 0");
//enqueue the buffer for read
p1.status = clEnqueueReadBuffer(p1.commandQueue, outputBuffer, CL_TRUE, 0, sizeof(char)*sizeArr, characterArr, 0, NULL, NULL); //call request that the device send data to the host,(sends the output result)
CheckErrorCode(p1.status, p1.program, p1.devices[0], "Failed clEnqueueReadBuffer 0");
///
///output[sizeInput] = '\0'; //Add the terminal character to the end of output.
///
if (characterArr != nullptr)
{
std::cout << "Array initialized" << std::endl;
}
const char* path = "log.txt";
//Reads File's bytes with c function and get array size
readfilec(path,fileBytes,&filebyteCount);
filebyteCount += 1;
compressedBytes = (unsigned char*)malloc(filebyteCount * sizeof(unsigned char));
indexByte = (unsigned long*)malloc(filebyteCount * sizeof(unsigned long));
cl_kernel kernelCopyBytes = clCreateKernel(p1.program, "CopyBytes", &p1.status);
CheckErrorCode(p1.status, p1.program, p1.devices[0], "Failed Creating kernel 1");
cl_kernel kernelCopyBytes = clCreateKernel(p1.program, "CopyBytes", &p1.status);
CheckErrorCode(p1.status, p1.program, p1.devices[0], "Failed Creating kernel 1");
cl_mem fileBytesBuffer = clCreateBuffer(p1.context, CL_MEM_READ_ONLY| CL_MEM_USE_HOST_PTR, filebyteCount * sizeof(unsigned char),(void*)fileBytes,&p1.status);
CheckErrorCode(p1.status, p1.program, p1.devices[0], "Failed Creating buffer 0");
cl_mem bufferSize = clCreateBuffer(p1.context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(unsigned long int), (void*)&filebyteCount, &p1.status);
CheckErrorCode(p1.status, p1.program, p1.devices[0], "Failed Creating buffer 1");
cl_mem compressedBytesbuffer = clCreateBuffer(p1.context, CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR, filebyteCount * sizeof(unsigned char),(void*)compressedBytes, &p1.status);
CheckErrorCode(p1.status, p1.program, p1.devices[0], "Failed Creating buffer 2");
cl_mem indexByteBuffer = clCreateBuffer(p1.context, CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR, filebyteCount * sizeof(unsigned char), (void*)indexByte, &p1.status);
CheckErrorCode(p1.status, p1.program, p1.devices[0], "Failed Creating buffer 3");
p1.status = clEnqueueWriteBuffer(p1.commandQueue, fileBytesBuffer, CL_TRUE, 0, filebyteCount * sizeof(unsigned char), fileBytes, 0, NULL, NULL);
CheckErrorCode(p1.status, p1.program, p1.devices[0], "Failed EnqueueReadBuffer 1");
p1.status = clSetKernelArg(kernelCopyBytes,0,sizeof(cl_mem),(void*)&fileBytesBuffer);
CheckErrorCode(p1.status, p1.program, p1.devices[0], "Failed Adding Argument 0");
p1.status = clSetKernelArg(kernelCopyBytes, 1, sizeof(cl_mem), (void*)& bufferSize);
CheckErrorCode(p1.status, p1.program, p1.devices[0], "Failed Adding Argument 1");
p1.status = clSetKernelArg(kernelCopyBytes, 2, sizeof(cl_mem), (void*)& compressedBytesbuffer);
CheckErrorCode(p1.status, p1.program, p1.devices[0], "Failed Adding Argument 2");
p1.status = clSetKernelArg(kernelCopyBytes, 3, sizeof(cl_mem), (void*)& indexByteBuffer);
CheckErrorCode(p1.status, p1.program, p1.devices[0], "Failed Adding Argument 3");
p1.status = clEnqueueNDRangeKernel(p1.commandQueue, kernelCopyBytes, 1, NULL, globalWorkSize, &localWorkSize, 0, NULL, NULL);
CheckErrorCode(p1.status, p1.program, p1.devices[0], "Failed EnqueueNDRangeKernel 1");
//enqueue the buffer for read
p1.status = clEnqueueReadBuffer(p1.commandQueue, compressedBytesbuffer, CL_TRUE, 0, filebyteCount * sizeof(unsigned char), compressedBytes, 0, NULL, NULL);
CheckErrorCode(p1.status, p1.program, p1.devices[0], "Failed EnqueueReadBuffer 1");
p1.status = clEnqueueReadBuffer(p1.commandQueue, indexByteBuffer, CL_TRUE, 0, filebyteCount * sizeof(unsigned char), indexByte, 0, NULL, NULL);
CheckErrorCode(p1.status, p1.program, p1.devices[0], "Failed EnqueueReadBuffer 1");
if (compressedBytes[0] != (char)NULL)
{
std::cout << "File bytes passed to compressBytes array" << std::endl;
}
for (unsigned long i = 0; i < filebyteCount; i++)
{
std::cout << *(indexByte+i) << std::endl;
}
//Step 12: Clean the resources.
/******************************/
//Release kernel.
p1.status = clReleaseKernel(kernelAdd);
//Release the program object.
p1.status = clReleaseProgram(p1.program);
//Release mem object.
/****************************/
//status = clReleaseMemObject(inputBuffer);
p1.status = clReleaseMemObject(outputBuffer);
//Release Command queue.
p1.status = clReleaseCommandQueue(p1.commandQueue);
//Release Command queue.
p1.status = clReleaseContext(p1.context);
/*if (output != NULL)
{
free(output);
output = NULL;
}*/
if (p1.devices != NULL)
{
free(p1.devices);
p1.devices = NULL;
}
std::cout << "Passed!\n";
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment