-1

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);
}
Zihao
  • 1
  • 1
  • 3
    Have you tried to [*debug*](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/) your code? For example be using a [*debugger*](https://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems) to catch the crash "in action" and see when and where in your code it happens? – Some programmer dude May 18 '22 at 10:32
  • "Access violation reading location 0x00000086" - Seeing a read of a location near zero is often an indication that something tried to read a member variable via a null pointer. This is a perfect case were a debugger is useful to catch the problem in the act, be able to examine any pointers involved at that moment, and then investigate backwards as to why one was unexpectedly null. – TheUndeadFish May 20 '22 at 16:14

1 Answers1

0

I just tested your code and it works without any crash, both the encrypt and decrypt variant.

Make sure all files that are loaded at runtime are in the correct directory. If the error persists, maybe update your graphics driver / OpenCL runtime.

ProjectPhysX
  • 4,535
  • 2
  • 14
  • 34