-
-
Save PontiacGTX/dbe6c80390f0047df74e5013fd1d2e2e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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