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

How to create an ocl::Program with binary files? #99

Closed
nocduro opened this issue Mar 11, 2018 · 5 comments
Closed

How to create an ocl::Program with binary files? #99

nocduro opened this issue Mar 11, 2018 · 5 comments

Comments

@nocduro
Copy link

nocduro commented Mar 11, 2018

Hi, I'm trying to migrate some c++ opencl code to Rust and need to be able to create the Program with binary files.

I found the function create_program_with_binary but it uses ocl_core::Program. I thought it would be possible to convert it to a ocl::Program by doing:

use ocl::{Buffer, Context, Device, Kernel, Platform, Program, Queue};
use ocl_core::{self, Program as ProgramCore};

// context, device setup omitted

let program_core: ProgramCore =
    ocl_core::create_program_with_binary(context.as_core(), &device_core_slice, binaries)
        .unwrap();
let program = Program(program_core);

But this gives a somewhat cryptic error:

error[E0423]: expected function, found struct `Program`
  --> src\opencl.rs:63:23
   |
63 |         let program = Program(program_core);
   |                       ^^^^^^^ did you mean `Program { /* fields */ }`?
help: possible better candidates are found in other modules, you can import them into scope
   |
1  | use ocl_core::EmptyInfoResultError::Program;
   |
1  | use ocl_core::KernelInfo::Program;
   |
1  | use ocl_core::KernelInfoResult::Program;

The only thing I could find on the error is this issue: rust-lang/rust#42944
Because the tuple struct (?) is private I can't make a Program from a ProgramCore.

I'm currently using a workaround (compiles, but untested) by making a local copy of the crate and implementing From for ProgramCore in the file: ocl/src/standard/program.rs

impl From<ProgramCore> for Program {
    fn from(core: ProgramCore) -> Self {
        Program(core)
    }
}

and then in my code:

let program_core: ProgramCore =
    ocl_core::create_program_with_binary(context.as_core(), &device_core_slice, binaries)
        .unwrap();
let program = program_core.into();

I guess I'm asking if there is a better way to do this that I missed? Or maybe I didn't import the correct crates/modules hence the 'private' problem?

If not, I can make a pull request to add this in? I'm still a bit new to rust and opencl, so I'm not sure if using a trait like From is appropriate here.

Thanks for your help!

@c0gent
Copy link
Member

c0gent commented Mar 11, 2018

You've got the right idea...

I added impl From<ProgramCore>. I also added ProgramBuilder::binaries which will allow you to specify your binaries using the program builder.

Example usage would be:

let program = Program::builder()
    .devices(device)
    .binaries(binary)
    .build(context)?;

I'm not sure whether the method should be called binaries (since it accepts a slice of binaries) or binary (to be consistent with the naming of clCreateProgramWithBinary). Let me know if you have an opinion either way.

The changes are on master. There are also a significant number of changes to Kernel, details on which you can find in RELEASES.md (the change log).

I'd really appreciate if you could test the changes, particularly ProgramBuilder::binaries, and let me know how it goes :)

@nocduro
Copy link
Author

nocduro commented Mar 13, 2018

Thank you, these changes look great!

I have to admit I am very new to OpenCL so my feedback might not be too useful.

The reason I need precompiled binaries is for an Intel FPGA: https://www.altera.com/documentation/mwh1391807965224.html#ewa1411489297252

I'm in university and doing a capstone project with the FPGA and OpenCL, so can only test on the Cyclone V dev board (Dual core ARM A9 with FPGA) when I'm in the lab.

I spent most of my time today getting the cross compiler working (fun times...) and have gotten the host application to start and load the binaries! I'm running into a problem with Intel's tools right now (I think I have Intel's offline compiler configured wrong) so I haven't gotten the trivial.rs example to fully run yet. I'll get back to you if I get it sorted out.

I'm not sure whether the method should be called binaries (since it accepts a slice of binaries) or binary (to be consistent with the naming of clCreateProgramWithBinary). Let me know if you have an opinion either way.

For the intel fpga stuff it is just a single binary file trivial.aocx that is loaded, but I'm not sure about other platforms.

edit: now that I think about it, binaries makes more sense, since each binary matches up with a device in devices

Here's how I'm currently calling it:

let mut aocx = Vec::new();
let binary_file = File::open(binary_filename).expect("couldn't open file");
let mut buf_reader = BufReader::new(binary_file);
buf_reader.read_to_end(&mut aocx).expect("unable to read file");

// ...

let program = Program::builder()
    .devices(device)
    .binaries(&[&aocx])
    .build(&context)
    .expect("program setup failed");

@c0gent
Copy link
Member

c0gent commented Mar 13, 2018

Sounds interesting. Let me know if I can be of any help in the Rust or OpenCL department. I'm happy to answer any questions or have ideas bounced off of.

@c0gent
Copy link
Member

c0gent commented Mar 14, 2018

I'll close this issue for now. Comment here or in the ocl gitter channel.

@nocduro nocduro closed this as completed Mar 14, 2018
@c0gent
Copy link
Member

c0gent commented Mar 14, 2018

Heh, thanks :)

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