2

I need to pass a vector<vector<string>> to a kernel OpenCL. What is the easiest way of doing it? Passing a char*** gives me an error:

__kernel void vadd(
   __global char*** sets,
   __global int* m,
   __global long* result)
{}

ERROR: clBuildProgram(CL_BUILD_PROGRAM_FAILURE)

anatolyg
  • 26,506
  • 9
  • 60
  • 134
pinotto
  • 45
  • 7
  • 2
    Can OpenCL make sense of `std::vector` arguments? Those are not interchangeable with pointers. You must convert, as in map out with `data()`. Likewise with `std::string` you'll have to map out `c_str()`. – tadman Jan 30 '20 at 18:20
  • You kinda need to allocate and copy the data to the device. And use designated pointers. You cannot just use `std::vector...` (In case you use Sycl - it might be working in a different manner). – ALX23z Jan 30 '20 at 18:23
  • If the internal vectors are all the same size, just use 2D array emulation and pass in `char**` instead. – tadman Jan 30 '20 at 18:30
  • @tadman what do you mean for 2D array emulation? – pinotto Jan 30 '20 at 18:36
  • Instead of `x[y][z]` you do `x[y * w + z]` where `w` is the "width" of each sub-element. – tadman Jan 30 '20 at 18:37

1 Answers1

4

In OpenCL 1.x, this sort of thing is basically not possible. You'll need to convert your data such that it fits into a single buffer object, or at least into a fixed number of buffer objects. Pointers on the host don't make sense on the device. (With OpenCL 2's SVM feature, you can pass pointer values between host and kernel code, but you'll still need to ensure the memory is allocated in a way that's appropriate for this.)

One option I can think of, bearing in mind I know nothing about the rest of your program, is as follows:

  1. Create an OpenCL buffer for all the strings. Add up the number of bytes required for all your strings. (possibly including nul termination, depending on what you're trying to do)
  2. Create a buffer for looking up string start offsets (and possibly length). Looks like you have 2 dimensions of lookup (nested vectors) so how you lay this out will depend on whether your inner vectors (second dimension) are all the same size or not.
  3. Write your strings back-to-back into the first buffer, recording start offsets (and length, if necessary) in the second buffer.
pmdj
  • 22,018
  • 3
  • 52
  • 103
  • Do you kwon if there is a version from which on it is possible to use directly strings and vectors? – pinotto Jan 30 '20 at 19:31
  • @pinotto [OpenCL 2.2 introduces support for C++ kernels](https://en.wikipedia.org/wiki/OpenCL#OpenCL_2.2) but this is a subset [with some fairly severe restrictions](https://www.khronos.org/registry/OpenCL/specs/2.2/html/OpenCL_Cxx.html#opencl_cxx_restrictions) which rules out near enough all of the standard library. In other words: no. On implementations with SVM, you could probably create C++ classes which behave similarly to vector and string on the host (but allocate via SVM) and which have equivalents in the kernel. I'm not convinced the effort required for this would be worth it though. – pmdj Jan 30 '20 at 19:35