Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

embedding OpenCL code into executable

This is a followup to Using #include to load OpenCL code

I've noticed that when you use the method described by grrussel (and used in Bullet Physics), the created string has all newlines stripped (comments seem to be stripped, too, but I'm not too worried about that). Now for the most part this is fine if the included opencl code doesn't have any preprocessor definitions in it, but if there is the code will fail to compile with the OpenCL compiler.

Is there a way to get the #include to keep the newlines in there, or is there a better method to embed the opencl code into my executable (other than copying the string into a cpp file and putting quotes around everything)?

I tested this in Visual Studio 2010, I'm not sure if other compilers exhibit the same behavior. I would prefer a method which doesn't require any external tools and works with a variety of compilers/platforms.

Copied code from other answer:

In C++ / C source

#define MSTRINGIFY(A) #A
char* stringifiedSourceCL = 
#include "VectorAddKernels.cl"

In the OpenCL source

MSTRINGIFY(
   __kernel void VectorAdd(__global float8* c)
   {
    // snipped out OpenCL code...
    return;
   }
);
like image 346
helloworld922 Avatar asked Oct 23 '22 17:10

helloworld922


2 Answers

I'd write a small tool that generates a cpp with a constant string from the text file, which you would then compile along with the other stuff.

This is what Qt's resource compiler moc does (and more, since it has a whole API around it), and there's also the option of Windows's resource kit (see this answer below).

Anyway, a small build tool that walks a files in a dir and builds a cpp from them should be enough, and something you can put together in 15 minutes (given suitable scripting skills).

Update: As per Henry's comment, on Linux (or with Msys/Cygwin), you could use xxd with the -i (i.e. xxd -i ) flag, which reads a file and generates a c-include file with the exact contents defined properly.

like image 51
Macke Avatar answered Oct 29 '22 10:10

Macke


Excellent question!

One thing that works on Windows is to treat your OpenCL C files as Windows resources. Then the source code gets built into your executable. In your reasource (.rc) file, you would add something like this:

IDR_OPENCL_FILE_1            OPENCL_SOURCE           "mydir\\myfile.cl"

Then, in the host source, something like this:

// Load the resource memory
HRSRC resource = FindResource(NULL, L"IDR_OPENCL_FILE_1", L"OPENCL_SOURCE");
HGLOBAL resMem = LoadResource(NULL, resource);
char* source = (char*)LockResource(resMem);
// Build a STL string out of it
DWORD resSize = SizeofResource(NULL, resource);
std::string cl_source = string(source, resSize);

On Linux, objcopy will let you do something similar. You can build an elf .o with the source file exported as a symbol. Sorry I don't have a code snippet handy for that right now.

I wish there were a better platform-independent answer. If you come across it, let me know.

like image 29
boiler96 Avatar answered Oct 29 '22 09:10

boiler96