Advertisement
binarydepth

Untitled

Nov 22nd, 2024
185
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.15 KB | Software | 0 0
  1. #include <CL/cl.h>
  2. #include <fstream>
  3. #include <vector>
  4. #include <cstring>
  5. #include <iostream>
  6. #ifdef _WIN32
  7. #include <intrin.h>
  8. #else
  9. #include <cpuid.h>
  10. #endif
  11.  
  12. bool supportsBMI2() {
  13.     unsigned int eax, ebx, ecx, edx;
  14.  
  15. #ifdef _WIN32
  16.     int cpuInfo[4];
  17.     __cpuid(cpuInfo, 7);
  18.     ebx = cpuInfo[1];
  19. #else
  20.     __cpuid_count(7, 0, eax, ebx, ecx, edx);
  21. #endif
  22.  
  23.     return (ebx & (1 << 8)) != 0; // BMI2 is bit 8 of EBX for CPUID leaf 7
  24. }
  25.  
  26. void checkError(cl_int err, const char* operation) {
  27.     if (err != CL_SUCCESS) {
  28.         std::cerr << "Error during operation '" << operation << "': " << err << std::endl;
  29.         exit(1);
  30.     }
  31. }
  32.  
  33. const char* kernelSource = R"(
  34. __kernel void copyData(__global const char* input, __global char* output) {
  35.    int id = get_global_id(0);
  36.    output[id] = input[id];
  37. }
  38. )";
  39.  
  40. int main() {
  41.     if (!supportsBMI2()) {
  42.         std::cerr << "BMI2 is not supported by your CPU." << std::endl;
  43.         return 1;
  44.     } else {
  45.         std::cout << "BMI2 is supported!" << std::endl;
  46.     }
  47.  
  48.     // Load data from disk
  49.     std::ifstream file("data.bin", std::ios::binary);
  50.     if (!file) {
  51.         std::cerr << "Failed to open file 'data.bin'" << std::endl;
  52.         return 1;
  53.     }
  54.     std::vector<char> data(1024 * 1024);  // 1 MB buffer
  55.     file.read(data.data(), data.size());
  56.     file.close();
  57.  
  58.     // Initialize OpenCL
  59.     cl_platform_id platform;
  60.     cl_device_id device;
  61.     cl_context context;
  62.     cl_program program;
  63.     cl_kernel kernel;
  64.     cl_command_queue queue;
  65.     cl_int err;
  66.  
  67.     cl_uint num_platforms;
  68.     err = clGetPlatformIDs(1, &platform, &num_platforms);
  69.     checkError(err, "clGetPlatformIDs");
  70.     err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device, NULL);
  71.     checkError(err, "clGetDeviceIDs");
  72.     context = clCreateContext(NULL, 1, &device, NULL, NULL, &err);
  73.     checkError(err, "clCreateContext");
  74.     queue = clCreateCommandQueueWithProperties(context, device, 0, &err);
  75.     checkError(err, "clCreateCommandQueueWithProperties");
  76.  
  77.     const size_t lengths[] = {strlen(kernelSource)};
  78.     const char* sources[] = {kernelSource};
  79.     program = clCreateProgramWithSource(context, 1, sources, lengths, &err);
  80.     checkError(err, "clCreateProgramWithSource");
  81.     err = clBuildProgram(program, 1, &device, NULL, NULL, NULL);
  82.     if (err != CL_SUCCESS) {
  83.         size_t log_size;
  84.         clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, 0, NULL, &log_size);
  85.         std::vector<char> log(log_size);
  86.         clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, log_size, log.data(), NULL);
  87.         std::cerr << "Build log:\n" << log.data() << std::endl;
  88.         checkError(err, "clBuildProgram");
  89.     }
  90.     kernel = clCreateKernel(program, "copyData", &err);
  91.     checkError(err, "clCreateKernel");
  92.  
  93.     // Create OpenCL buffers
  94.     cl_mem inputBuffer = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, data.size(), data.data(), &err);
  95.     checkError(err, "clCreateBuffer(input)");
  96.     cl_mem outputBuffer = clCreateBuffer(context, CL_MEM_WRITE_ONLY, data.size(), NULL, &err);
  97.     checkError(err, "clCreateBuffer(output)");
  98.  
  99.     // Set kernel arguments and execute
  100.     err = clSetKernelArg(kernel, 0, sizeof(cl_mem), &inputBuffer);
  101.     checkError(err, "clSetKernelArg(input)");
  102.     err = clSetKernelArg(kernel, 1, sizeof(cl_mem), &outputBuffer);
  103.     checkError(err, "clSetKernelArg(output)");
  104.     const size_t globalSize = data.size();
  105.     err = clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &globalSize, NULL, 0, NULL, NULL);
  106.     checkError(err, "clEnqueueNDRangeKernel");
  107.     err = clFinish(queue);
  108.     checkError(err, "clFinish");
  109.  
  110.     std::vector<char> output(data.size());
  111.     err = clEnqueueReadBuffer(queue, outputBuffer, CL_TRUE, 0, output.size(), output.data(), 0, NULL, NULL);
  112.     checkError(err, "clEnqueueReadBuffer");
  113.  
  114.     std::cout << "Data copied to VRAM and back to RAM successfully!" << std::endl;
  115.  
  116.     clReleaseMemObject(inputBuffer);
  117.     clReleaseMemObject(outputBuffer);
  118.     clReleaseKernel(kernel);
  119.     clReleaseProgram(program);
  120.     clReleaseCommandQueue(queue);
  121.     clReleaseContext(context);
  122.  
  123.     return 0;
  124. }
  125.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement