Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

pass mat to opencl

How do i properly pass image data into opencl? Right now i'm trying to convert all the rgb values of image into one dimensional array for each channel and than pass it. Is their any other suitable way to pass the image in opencl?

include <iostream>

include <cl cl.hpp="">

include <chrono>

using namespace std; using namespace std::chrono; namespace Color { enum Code { FG_RED = 31, FG_GREEN = 32, FG_BLUE = 34, FG_DEFAULT = 39, BG_RED = 41, BG_GREEN = 42, BG_BLUE = 44, BG_DEFAULT = 49 }; class Modifier { Code code; public: Modifier(Code pCode) : code(pCode) {} friend std::ostream& operator<<(std::ostream& os, const Modifier& mod) { return os << "\033[" << mod.code << "m"; } }; } int main(){ Color::Modifier green(Color::FG_GREEN); Color::Modifier red(Color::FG_RED); Color::Modifier def(Color::FG_DEFAULT); int size = 294400; int A[size], B[size], C[size], D[size], E[size], F[size], G[size]; int count = 0;

while(true) {
  count++;
  //get all platforms (drivers)
  std::vector<cl::Platform> all_platforms;
  cl::Platform::get(&all_platforms);
  if(all_platforms.size()==0){
      std::cout<<" No platforms found. Check OpenCL installation!\n";
      exit(1);
  }
  cl::Platform default_platform=all_platforms[0];
  std::cout <<green<< "Using platform: "<<def<<default_platform.getInfo<CL_PLATFORM_NAME>()<<"\n";

  //get default device of the default platform
  std::vector<cl::Device> all_devices;
  default_platform.getDevices(CL_DEVICE_TYPE_ALL, &all_devices);
  if(all_devices.size()==0){
      std::cout<<" No devices found. Check OpenCL installation!\n";
      exit(1);
  }
  cl::Device default_device=all_devices[0];
  std::cout<< green<<"Using device: "<<def<<default_device.getInfo<CL_DEVICE_NAME>()<<"\n";


  cl::Context context({default_device});

  cl::Program::Sources sources;

  // kernel calculates for each element C=A+B
  std::string kernel_code=
          "   void kernel simple_add(global const int* A, global const int* B, global int* C,global int* D,global int* E,global int* F,global int* G){       "
          "       C[get_global_id(0)]=A[get_global_id(0)]+B[get_global_id(0)]+D[get_global_id(0)]+E[get_global_id(0)]+F[get_global_id(0)];                 "
          "   }                                                                               ";
  sources.push_back({kernel_code.c_str(),kernel_code.length()});

  cl::Program program(context,sources);
  if(program.build({default_device})!=CL_SUCCESS){
      std::cout<<" Error building: "<<program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(default_device)<<"\n";
      exit(1);
  }
  // create buffers on the device
  cl::Buffer buffer_A(context,CL_MEM_READ_WRITE,sizeof(int)*size);
  cl::Buffer buffer_B(context,CL_MEM_READ_WRITE,sizeof(int)*size);
  cl::Buffer buffer_C(context,CL_MEM_READ_WRITE,sizeof(int)*size);
  cl::Buffer buffer_D(context,CL_MEM_READ_WRITE,sizeof(int)*size);
  cl::Buffer buffer_E(context,CL_MEM_READ_WRITE,sizeof(int)*size);
  cl::Buffer buffer_F(context,CL_MEM_READ_WRITE,sizeof(int)*size);
  cl::Buffer buffer_G(context,CL_MEM_READ_WRITE,sizeof(int)*size);

  cl::CommandQueue queue(context,default_device);
  auto start1 = high_resolution_clock::now();
  for(int i=0;i<size;i++) {
    A[i] = count;
    B[i] = count;
    D[i] = count;
    E[i] = count;
    F[i] = count;
    G[i] = count;
  }
  //create queue to which we will push commands for the device.

  //write arrays A and B to the device
  queue.enqueueWriteBuffer(buffer_A,CL_TRUE,0,sizeof(int)*size,A);
  queue.enqueueWriteBuffer(buffer_B,CL_TRUE,0,sizeof(int)*size,B);
  queue.enqueueWriteBuffer(buffer_D,CL_TRUE,0,sizeof(int)*size,D);
  queue.enqueueWriteBuffer(buffer_E,CL_TRUE,0,sizeof(int)*size,E);
  queue.enqueueWriteBuffer(buffer_F,CL_TRUE,0,sizeof(int)*size,F);
  queue.enqueueWriteBuffer(buffer_G,CL_TRUE,0,sizeof(int)*size,G);

  //run the kernel
  /*cl::KernelFunctor simple_add(cl::Kernel(program,"simple_add"),queue,cl::NullRange,cl::NDRange(10),cl::NullRange);
  simple_add(buffer_A,buffer_B,buffer_C);*/

  //alternative way to run the kernel
  cl::Kernel kernel_add=cl::Kernel(program,"simple_add");
  kernel_add.setArg(0,buffer_A);
  kernel_add.setArg(1,buffer_B);
  kernel_add.setArg(2,buffer_C);
  kernel_add.setArg(0,buffer_D);
  kernel_add.setArg(1,buffer_E);
  kernel_add.setArg(2,buffer_F);
  kernel_add.setArg(2,buffer_G);
  queue.enqueueNDRangeKernel(kernel_add,cl::NullRange,cl::NDRange(size),cl::NullRange);
  queue.finish();

  //read result C from the device to array C
  queue.enqueueReadBuffer(buffer_C,CL_TRUE,0,sizeof(int)*size,C);

  cout<<count<<" ";
  for(int i=0;i<10;i++){
      std::cout<< C[i]<<" ";
  }
  cout<<"\n";
  auto stop1 = high_resolution_clock::now();
  auto duration1 = duration_cast<microseconds>(stop1 - start1);
  auto FPS = 1000000.0/duration1.count();
  cout<<"Segmentation FPS="<<FPS<<"\t"<<"Execution Time(sec)="<<duration1.count()/1000000.0<<endl;
}
return 0;

}