Advertisement
Guest User

Untitled

a guest
Apr 23rd, 2019
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.80 KB | None | 0 0
  1. #define __CL_ENABLE_EXCEPTIONS
  2. #include <CL/cl.h>
  3. #include <libclew/ocl_init.h>
  4.  
  5. #include <vector>
  6. #include <sstream>
  7. #include <iostream>
  8. #include <stdexcept>
  9. #include <vector>
  10. #include <fstream>
  11. #include <iostream>
  12. #include <iterator>
  13. #include <iomanip>
  14. #include <memory>
  15. #include "../cl.hpp"
  16.  
  17.  
  18. template <typename T>
  19. std::string to_string(T value)
  20. {
  21.     std::ostringstream ss;
  22.     ss << value;
  23.     return ss.str();
  24. }
  25.  
  26. void reportErr(cl_int err, const std::string& filename, int line)
  27. {
  28.     if (CL_SUCCESS == err)
  29.         return;
  30.     const std::string message = "OpenCL error code " + to_string(err) + " encountered at " + filename + ":" +
  31.         to_string(line);
  32.     throw std::runtime_error(message);
  33. }
  34.  
  35. #define OCL_SAFE_CALL(expr) reportErr(expr, __FILE__, __LINE__)
  36.  
  37. #define _CRT_SECURE_NO_WARNINGS
  38.  
  39. std::unique_ptr<double[]> read_matrix(size_t matrix_size)
  40. {
  41.     std::unique_ptr<double[]> result(new double[matrix_size]());
  42.     for (size_t i = 0; i < matrix_size; i++)
  43.     {
  44.         std::cin >> result.get()[i];
  45.     }
  46.     return result;
  47. }
  48.  
  49.  
  50. int main()
  51. {
  52.     if (!ocl_init())
  53.         throw std::runtime_error("Can't init OpenCL driver!");
  54.  
  55.     std::vector<cl::Platform> platforms;
  56.     std::vector<cl::Device> devices;
  57.     std::vector<cl::Kernel> kernels;
  58.     std::ofstream input("input.txt");
  59. #ifdef DEBUG
  60.     int N = 1;
  61.     int M = 9;
  62.  
  63.     input << N << " " << M << "\n";
  64.     for (int i = 0; i < N; i++)
  65.     {
  66.         for (int j = 0; j < N; j++)
  67.         {
  68.             input << 1 << " ";
  69.         }
  70.         input << "\n";
  71.     }
  72.     for (int i = 0; i < M; i++)
  73.     {
  74.         for (int j = 0; j < M; j++)
  75.         {
  76.             input << 1 << " ";
  77.         }
  78.         input << "\n";
  79.     }
  80.     input.flush();
  81. #endif
  82.     freopen("input.txt", "r", stdin);
  83.     freopen("output.txt", "w", stdout);
  84.     int n, m;
  85.     std::cin >> n >> m;
  86.     size_t matrix_size = n * n;
  87.     size_t kernel_matrix_size = m * m;
  88.     auto a = read_matrix(matrix_size);
  89.     auto b = read_matrix(kernel_matrix_size);
  90.     std::unique_ptr<double[]> result(new double[matrix_size]());
  91.     try
  92.     {
  93.         // create platform
  94.         cl::Platform::get(&platforms);
  95.         platforms[0].getDevices(CL_DEVICE_TYPE_CPU, &devices);
  96.  
  97.         // create context
  98.         cl::Context context(devices);
  99.  
  100.         // create command queue
  101.         cl::CommandQueue queue(context, devices[0]);
  102.  
  103.         // load opencl source
  104.         std::ifstream cl_file("matrix_convolution.cl");
  105.         std::string cl_string(std::istreambuf_iterator<char>(cl_file), (std::istreambuf_iterator<char>()));
  106.         cl::Program::Sources source(1, std::make_pair(cl_string.c_str(),
  107.                                                       cl_string.length() + 1));
  108.  
  109.         // create program
  110.         cl::Program program(context, source);
  111.  
  112.         // compile opencl source
  113.         size_t const block_size = 16;
  114.         program.build(devices, "-D BLOCK_SIZE=16");
  115.  
  116.         // allocate device buffer to hold message
  117.         cl::Buffer dev_a(context, CL_MEM_READ_ONLY, sizeof(double) * matrix_size);
  118.         cl::Buffer dev_b(context, CL_MEM_READ_ONLY, sizeof(double) * kernel_matrix_size);
  119.         cl::Buffer dev_c(context, CL_MEM_WRITE_ONLY, sizeof(double) * matrix_size);
  120.  
  121.         // copy from cpu to gpu
  122.         queue.enqueueWriteBuffer(dev_a, CL_TRUE, 0, sizeof(double) * matrix_size, a.get());
  123.         queue.enqueueWriteBuffer(dev_b, CL_TRUE, 0, sizeof(double) * kernel_matrix_size, b.get());
  124.  
  125.         // load named kernel from opencl source
  126.         cl::Kernel kernel(program, "matrix_convolution");
  127.         cl::KernelFunctor matrix_convolution(kernel, queue, cl::NullRange, cl::NDRange(n, n),
  128.                                              cl::NDRange(block_size, block_size));
  129.         matrix_convolution(dev_a, dev_b, dev_c, n, m);
  130.  
  131.  
  132.         queue.enqueueReadBuffer(dev_c, CL_TRUE, 0, sizeof(double) * matrix_size, result.get());
  133.         for (int i = 0; i < n; i++)
  134.         {
  135.             for (int j = 0; j < n; j++)
  136.             {
  137.                 std::cout << result.get()[i * n + j] << " ";
  138.             }
  139.             std::cout << std::endl;
  140.         }
  141.     }
  142.     catch (cl::Error& e)
  143.     {
  144.         std::cerr << std::endl << e.what() << " : " << e.err() << "\n";
  145.     }
  146.  
  147.     return 0;
  148. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement