-
Notifications
You must be signed in to change notification settings - Fork 75
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
Forced dependency on opencl #107
Comments
That would be a great feature. Pull request welcome :) |
I've been looking into implementing this using the dlopen crate. Basic testing is promising - I was able to dynamically load OpenCL library at runtime on both Windows and Linux, and confirm that I could map a symbol and call a function from it. However, implementing it is going to be a huge challenge. The easiest way I can think of would be to have a lazily initialized static field for the OpenCL library container, and rewrite all functions in Any thoughts on this approach before I invest too much time into it? |
I believe this can be done without ANY overhead. Filling in imports table from dynamically loaded dll should not be any different from what the loader does. Other option would be to boobytrap the opencl imports with an initialization routine which overwrites the imports with the real ones upon first call of any opencl function, then jumps to that function, or returns error safely when not available. Transparent but hacky. |
Could you elaborate on how you would hijack in the imports? I've been trying to think of ways to do it without breaking API compatibility. |
This is for windows, linux will probably have to be done differently.
For each opencl function, we would have:
Then we would have an initialization function, that would try to LoadLibrary the opencl.dll, and GetProcAddress each export and set the function pointer for each export. If opencl.dll is not found, or does not contain the symbol because it is of an earlier version of opencl, set the function pointer to the error stub. This way, we end up with at most exactly the same per call overhead as normal import library. |
Hmm. If I understand you correctly, this would just be a statically-linked library that exports the OpenCL API, but dynamically loads the actual OpenCL implementation using |
Yes of course you can do that. |
I'd be happy to merge either (or both) @dmarcuse's dlopen or @hlavaatch's more involved solution (or even a complete ICD loader replacement) as long as they were placed behind a feature flag. I assume this would be as straightforward as using an alternative import to Keep in mind that the extra performance overhead of calling OpenCL functions dynamically is small relative to the cost of OpenCL calls in general due to the latency involved. It's up to you whether you think it's worth investing time in this @dmarcuse but it would be a nice feature to have. I'd like to help out but I'm stretched pretty thin for the foreseeable future. If you're in a situation where you need to hand write a bunch of FFI code, let me know and I'll try to help out with some of the grunt work. |
I'll look into it a little bit more, but right now I'm leaning towards implementing this by rewriting the functions in the I'm not sure how much will need to be handwritten - I'll need to copy most of the stubs, but I think I can use macros to implement the actual function proxies. |
Note that there are other API DLLs in need of similar solution - OpenGL, Vulkan... so having a good generic solution for this would ber great |
If you need to save some typing there are lists of the OpenCL functions in the ICD sources at https://github.com/KhronosGroup/OpenCL-ICD-Loader |
Thanks! I've been thinking a little bit more about reusability and thought that it might be possible to write a tool to parse the headers and generate Rust code or something, but it may be more work than is necessary. |
@hlavaatch You can using cargo features and adding something like this in your application:
And build your app with |
I was assuming he meant runtime-optional, as in one binary that can enable/disable OpenCL support automatically. |
I did. :) |
Still it is a very specific issue, not a general one. You may compile your binary two times: with gpu and without gpu, then create a third binary which will try to load your binary with gpu and then fallback to a binary without a gpu if the first one fails to load libOpenCL. |
I've been working on a new crate, |
Fixed linking with the opencl ICD loader means the application will fail to execute at all when OpenCL support is not installed on the machine the application is run.
This makes it impossible to make OpenCL support optional in an application.
Maybe it should be dynamically loaded and fail gracefully instead?
The text was updated successfully, but these errors were encountered: