Hello!
I am trying to make a very simple XOR file encryption program using OpenCL, learning purposes. Program asks for source txt file, password (max 32 characters), destination path and file name of encrypted file. Problem is, that after compilation and running program, the final encrypted file contains only ĚĚĚĚĚĚĚĚĚ… symbols no matter what was in source file.
#include<iostream>
#include<string>
#include<fstream>
#include <CL/cl.h>
// Kernel (OpenCL funkcia), ktora vykonava samotny proces sifrovania / OpenCL kernel
const char* OpenCLkernel[] = {
"__kernel void sifrovanie (__global char* subor, __global char* heslo, __global char* vystup)",
"{",
"vystup[get_global_id(0)] = subor[get_global_id(0)] ^ heslo[get_global_id(0)];",
"}",
};
using namespace std;
int main()
{
char c;
ifstream zdrojovy;
ofstream cielovy;
string zdrojovy_fname;
string cielovy_fname;
cout<<"Vlozte cestu ku suboru, ktory sa ma zasifrovat / path to the source file: "<<endl;
cin>>zdrojovy_fname;
zdrojovy.open(zdrojovy_fname.c_str());
cout<<endl;
cout<<"Vlozte cestu a nazov zasifrovaného suboru / path and name of final encrypted file: "<<endl;
cin>>cielovy_fname;
cielovy.open(cielovy_fname.c_str());
// Vypytanie si hesla od pouzivatela a jeho vlozenie do pola / ask for a password and put it in array=============================
string heslo;
cout<<"\n\nVlozte vase heslo o maximalnej dlzke 32 znakov: / password (max 32 characters) "<<endl;
cin>>heslo;
int heslo_dlzka; // pocet znakov v hesle / number of characters in password
heslo_dlzka = heslo.length();
while(heslo_dlzka>32)
{
cout<<"Heslo, ktore ste vlozili ma viac ako 32 znakov, prosim vlozte nove heslo: / password is too long ";
getline(cin,heslo);
heslo_dlzka = heslo.length();
}
char heslo_pole[32];
for(int i=0; i<heslo_dlzka; i++)
{
heslo_pole[i] = heslo[i];
}
char file_array[32];
char final_array[32];
while(!zdrojovy.eof())
{
// Vkladanie casti suboru do pola, ktore zodpoveda velkosti hesla / add part of source file to the array with the size of password===========
int j=0;
while(!zdrojovy.eof() && j<heslo_dlzka)
{
zdrojovy.get(c);
file_array[j] = c;
j++;
if(zdrojovy.eof())
heslo_dlzka = j;
}
//OPENCL
// Query platform ID
cl_platform_id platform;
clGetPlatformIDs (1, &platform, NULL);
// Setup context properties
cl_context_properties props[3];
props[0] = (cl_context_properties)CL_CONTEXT_PLATFORM;
props[1] = (cl_context_properties)platform;
props[2] = (cl_context_properties)0;
// Create a context to run OpenCL on our CUDA-enabled NVIDIA GPU
cl_context GPUContext = clCreateContextFromType(props, CL_DEVICE_TYPE_GPU,NULL, NULL, NULL);
// Get the list of GPU devices associated with this context
size_t ParmDataBytes;
clGetContextInfo(GPUContext, CL_CONTEXT_DEVICES, 0, NULL, &ParmDataBytes);
cl_device_id* GPUDevices = (cl_device_id*)malloc(ParmDataBytes);
clGetContextInfo(GPUContext, CL_CONTEXT_DEVICES, ParmDataBytes, GPUDevices, NULL);
// Create a command-queue on the first GPU device
cl_command_queue GPUCommandQueue = clCreateCommandQueue(GPUContext, GPUDevices[0], 0, NULL);
// Allocate GPU memory for source vectors AND initialize from CPU memory
cl_mem GPUfile_array = clCreateBuffer(GPUContext, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(cl_int) * heslo_dlzka, file_array, NULL);
cl_mem GPUheslo_pole = clCreateBuffer(GPUContext, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(cl_int) * heslo_dlzka, heslo_pole, NULL);
// Allocate output memory on GPU
cl_mem GPUfinal_array = clCreateBuffer(GPUContext, CL_MEM_WRITE_ONLY,sizeof(cl_int) * heslo_dlzka, NULL, NULL);
// Create OpenCL program with source code
cl_program OpenCLProgram = clCreateProgramWithSource(GPUContext, 7, OpenCLkernel, NULL, NULL);
// Build the program (OpenCL JIT compilation)
clBuildProgram(OpenCLProgram, 0, NULL, NULL, NULL, NULL);
// Create a handle to the compiled OpenCL function (Kernel)
cl_kernel OpenCLsifrovanie = clCreateKernel(OpenCLProgram, "sifrovanie", NULL);
// In the next step we associate the GPU memory with the Kernel arguments
clSetKernelArg(OpenCLsifrovanie, 0, sizeof(cl_mem), (void*)&GPUfinal_array);
clSetKernelArg(OpenCLsifrovanie, 1, sizeof(cl_mem), (void*)&GPUfile_array);
clSetKernelArg(OpenCLsifrovanie, 2, sizeof(cl_mem), (void*)&GPUheslo_pole);
// Launch the Kernel on the GPU
size_t WorkSize[1] = {heslo_dlzka}; // one dimensional Range
clEnqueueNDRangeKernel(GPUCommandQueue, OpenCLsifrovanie, 1, NULL, WorkSize, NULL, 0, NULL, NULL);
// Copy the output in GPU memory back to CPU memory
char Hostfinal_array[32];
clEnqueueReadBuffer(GPUCommandQueue, GPUfinal_array, CL_TRUE, 0, heslo_dlzka * sizeof(cl_int), final_array, 0, NULL, NULL);
// Cleanup
free(GPUDevices);
clReleaseKernel(OpenCLsifrovanie);
clReleaseProgram(OpenCLProgram);
clReleaseCommandQueue(GPUCommandQueue);
clReleaseContext(GPUContext);
clReleaseMemObject(GPUfile_array);
clReleaseMemObject(GPUheslo_pole);
clReleaseMemObject(GPUfinal_array);
// ************************************************
// Sifrovanie / put encrypted array into file==========
for(int k=0; k<heslo_dlzka; k++)
{
cielovy.put(Hostfinal_array[k]);
}
}
return 0;
}
Program is in Slovak, but I translate some important parts to English, so I hope it is readable. Every help appreciated. Sorry for my english :-)