I am new to c++ and openCL. I am trying to create caesar shift cipher using opencl. I have read the txt file in the host and passed the string value into the kernel to do the encryption and decryption. I have encounter the above error Unhandled exception at 0x79BCC1C0 (nvopencl32.dll) in Task2b.exe: 0xC0000005: Access violation reading location 0x00000086..
This is the host code:
#define CL_USE_DEPRECATED_OPENCL_2_0_APIS // using OpenCL 1.2, some functions deprecated in OpenCL 2.0
#define __CL_ENABLE_EXCEPTIONS // enable OpenCL exemptions
// C++ standard library and STL headers
#include <iostream>
#include <vector>
#include <fstream>
#include <string>
// OpenCL header, depending on OS
#ifdef __APPLE__
#include <OpenCL/cl.hpp>
#else
#include <CL/cl.hpp>
#endif
#include "common.h"
int main(void)
{
cl::Platform platform; // device's platform
cl::Device device; // device used
cl::Context context; // context for the device
cl::Program program; // OpenCL program object
cl::Kernel kernel; // a single kernel object
cl::CommandQueue queue; // commandqueue for a context and device
std::ifstream inputFile("plaintext.txt");
std::string plaintext((std::istreambuf_iterator<char>(inputFile)),
std::istreambuf_iterator<char>());
do
{
if (inputFile.eof())
plaintext += inputFile.get();
break;
} while (inputFile);
std::string& ciphertext = plaintext;
// declare data and memory objects
std::vector<cl_float> vectorA(ciphertext.size());
std::vector<cl_float> vectorB(ciphertext.size());
std::vector<cl_float> result(ciphertext.size());
cl::Buffer bufferA, bufferB, encrypted, decrypted;
try {
// select an OpenCL device
if (!select_one_device(&platform, &device))
{
// if no device selected
quit_program("Device not selected.");
}
// create a context from device
context = cl::Context(device);
// build the program
if(!build_program(&program, &context, "vecadd.cl"))
{
// if OpenCL program build error
quit_program("OpenCL program build error.");
}
int choice;
std::cout << "Choose 1 to encrypt." << std::endl;
std::cout << "Choose 2 to decrypt." << std::endl;
std::cout << "Choice";
std::cin >> choice;
// initialise values
for (int i = 0; i < ciphertext.size(); i++)
{
vectorA[i] = ciphertext[i];
}
// create a kernel
if (choice == 1) {
kernel = cl::Kernel(program, "encrypt");
// create command queue
queue = cl::CommandQueue(context, device);
// create buffers
bufferA = cl::Buffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(cl_float) * vectorA.size(), &vectorA[0]);
encrypted = cl::Buffer(context, CL_MEM_WRITE_ONLY, sizeof(cl_float) * result.size());
std::cout << "How many position to shift forward?: ";
int decipher;
std::cin >> decipher;
// set kernel arguments
kernel.setArg(0, bufferA);
kernel.setArg(1, decipher);
kernel.setArg(2, encrypted);
cl::NDRange offset(0);
cl::NDRange globalSize(ciphertext.size()); // work-units per kernel
queue.enqueueNDRangeKernel(kernel, offset, globalSize);
std::cout << "Kernel enqueued." << std::endl;
std::cout << "--------------------" << std::endl;
// enqueue command to read from device to host memory
queue.enqueueReadBuffer(encrypted, CL_TRUE, 0, sizeof(cl_float) * result.size(), &result[0]);
std::cout << "your file was converted and saved as: ciphertext.txt" << std::endl;
std::ofstream finale("ciphertext.txt");
finale << ciphertext << std::endl;
finale.close();
}
else {
std::ifstream inputFile("ciphertext.txt");
std::string plaintext((std::istreambuf_iterator<char>(inputFile)),
std::istreambuf_iterator<char>());
do
{
if (inputFile.eof())
plaintext += inputFile.get();
break;
} while (inputFile);
kernel = cl::Kernel(program, "decrypt");
// create command queue
queue = cl::CommandQueue(context, device);
// create buffers
bufferA = cl::Buffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(cl_float) * vectorB.size(), &vectorB[0]);
encrypted = cl::Buffer(context, CL_MEM_WRITE_ONLY, sizeof(cl_float) * result.size());
std::cout << "How many position to shift backwards?: ";
int decipher;
std::cin >> decipher;
// set kernel arguments
kernel.setArg(0, bufferB);
kernel.setArg(1, decipher);
kernel.setArg(2, decrypted);
cl::NDRange offset(0);
cl::NDRange globalSize(ciphertext.size()); // work-units per kernel
queue.enqueueNDRangeKernel(kernel, offset, globalSize);
std::cout << "Kernel enqueued." << std::endl;
std::cout << "--------------------" << std::endl;
// enqueue command to read from device to host memory
queue.enqueueReadBuffer(decrypted, CL_TRUE, 0, sizeof(cl_float) * result.size(), &result[0]);
std::cout << "your file was converted and saved as: decyrpted.txt" << std::endl;
std::ofstream finale("ciphertext.txt");
finale << ciphertext << std::endl;
finale.close();
}
}
// catch any OpenCL function errors
catch (cl::Error e) {
// call function to handle errors
handle_error(e);
}
#ifdef _WIN32
// wait for a keypress on Windows OS before exiting
std::cout << "\npress a key to quit...";
std::cin.ignore();
#endif
return 0;
}
This is the kernel code:
__kernel void encrypt(__global char *str,
__global int *key,
__global char *encrypted_message)
{
__local int shift;
shift = *key % 26;
__local int textsize;
textsize = get_local_size(0);
for(int i = 0; i < textsize; i++){
encrypted_message[i] = (str[i] - 'a' + shift) % 26 + 'a';
}
}__kernel void decrypt(__global char *str,
__global int *key,
__global char *decrypted_message)
{
__local int shift;
shift = *key % 26;
__local int textsize;
textsize = get_local_size(0);
for(int i = 0; i < textsize; i++){
decrypted_message[i] = (str[i] - 'a' - shift) % 26 + 'a';
}
}
The exception thrown in cl.hpp:
template <typename T>
cl_int setArg(cl_uint index, T value)
{
return detail::errHandler(
::clSetKernelArg(
object_,
index,
detail::KernelArgumentHandler<T>::size(value),
detail::KernelArgumentHandler<T>::ptr(value)),
__SET_KERNEL_ARGS_ERR);
}