Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it possible to save/load CL_PROGRAM_BINARIES? #62

Open
trxcllnt opened this issue Apr 2, 2018 · 5 comments
Open

Is it possible to save/load CL_PROGRAM_BINARIES? #62

trxcllnt opened this issue Apr 2, 2018 · 5 comments

Comments

@trxcllnt
Copy link
Collaborator

trxcllnt commented Apr 2, 2018

Looking into improving container startup times, I noticed a common pattern is compiling kernels from source once per device, and loading the program binaries from disk on subsequent restarts.

Is it possible to get a handle on the underlying program binaries buffer in order to serialize them to disk, and if so, can the result be loaded via cl.createProgramWithBinaries()? Thanks Mike!

@mikeseven
Copy link
Owner

mikeseven commented Apr 2, 2018 via email

@trxcllnt
Copy link
Collaborator Author

trxcllnt commented Apr 2, 2018

Yep, I'm comfortable with that part. We can essentially make it part of the container's CMD startup script.

The part I'm stuck on is getting a reference to the raw char* pointer of the NoCLProgramBinary instances. The toString() value doesn't seem to include the PTX assembly, and there don't seem to be any other methods exposed to v8. Am I missing something?

p.s. I've looked into some other tools like clcc, but most I've found aren't maintained and/or segfault on various platforms, so a small node-opencl script seems like the most straightforward if it's possible.

@mikeseven
Copy link
Owner

mikeseven commented Apr 2, 2018 via email

@trxcllnt
Copy link
Collaborator Author

trxcllnt commented Apr 2, 2018

For reference, here's a snippet of what I'm trying to do (using our high-ish level wrapper lib around node-opencl):

const square = fs.readFileSync(path.resolve(__dirname, `square.cl`)).toString();

for (const device of CLPlatform.devices('all')) {
    const context = device.newContext();
    const program = context.newProgram(square).build();
    const binaries = program.BINARIES;
    const binarySizes = program.BINARY_SIZES;
    const binaryBuffers = binaries.map((x) => bufferFromBinary(x));
    try { fs.mkdirSync(path.resolve(__dirname, device.TYPE_NAME)); } catch(e) {}
    fs.writeFileSync(path.resolve(__dirname, device.TYPE_NAME, 'square.bin'), binaryBuffers[0]);
    fs.writeFileSync(path.resolve(__dirname, device.TYPE_NAME, 'square.sizes'), binarySizes[0]);
    program.release();
    context.release();
}

function bufferFromBinary(programBinary) {
  /* todo: implement for real */
  return new Buffer(programBinary);
  /* tested, doesn't work:
    const bin = programBinary.toString();
    const str = bin.substring(bin.indexOf('@') + 1, bin.lastIndexOf(']'));
    const buf = new Buffer(str);
    return buf;
  */
}

Yes or could even bind mount a volume.

Yep, exactly. Startup script just checks if the mounted volume has compiled binaries, and if so skips compilation.

It looks like you are using Nvidia GPU. You should try some of their examples to verify that you can save and load the binary and that it works.

Ah I'm just trying to do this on my MacbookPro at the moment, but I'll test on an Nvidia GPU when I get home tonight. I was using PTX as a stand-in for whatever the Apple/Intel/AMD drivers I have right now use.

I wouldn’t use toString() because that’s really an ArrayBuffer you get back (like all operations with OpenCL)

To clarify, are you saying the NoCLProgramBinary instances are ArrayBuffers? Or the raw pointer is? If the latter, is there a way to get a pointer to the ArrayBuffer from JS without calling toString()? I've also tried getRaw(), enumerating keys, slicing the bytes from the toString() result, creating a new Uint8Array from each NoCLProgramBinary instance, etc.

Thanks!

@mikeseven
Copy link
Owner

mikeseven commented Apr 3, 2018 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants