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

Windows run-rime error due to name conflict of DLLs #6

Closed
codrin-kruijne opened this issue Oct 25, 2020 · 8 comments
Closed

Windows run-rime error due to name conflict of DLLs #6

codrin-kruijne opened this issue Oct 25, 2020 · 8 comments

Comments

@codrin-kruijne
Copy link

codrin-kruijne commented Oct 25, 2020

When building the OpenCL package I run into an error regarding procedure entry point clBuildProgram.

According to the documentation I set paths and the OpenCL.dll from recent AMD Pro drivers is in my Windows/System32 which is on PATH. It is supported for OpenCL 2.0.

Windows, R and RTools are up to date. Can you help my fix the problem? Can't wait to try OpenCL accelerated evolutionary programming in R :-); thanks for your effort in advance!

Please see the screenshot for more details:

image

@aaronpuchert
Copy link
Collaborator

@s-u said in #2 that there is an installation procedure in NEWS, did you follow that?

If you did and that still doesn't help: back when I was on Windows I just renamed the package to get rid of this error, but I haven't used it there for a long time.

The problem, if I remember correctly, is that on Windows both the package and the system library have the file name OpenCL.dll, and the dynamic loader is confused by that.

@s-u s-u changed the title Build error Windows run-rime error Aug 14, 2021
@s-u s-u changed the title Windows run-rime error Windows run-rime error due to name conflict of DLLs Aug 15, 2021
@s-u
Copy link
Owner

s-u commented Aug 15, 2021

Assuming Aaron is right, the issue could be that the package DLL and the library DLL have the same name which may confuse Windows when resolving the dependency for the package DLL. Work-around would be to use static library if available or have someone find a way to work around the problem (other than re-naming the package; it may be easier to rename the OpenCL library) - PRs are welcome.

@s-u
Copy link
Owner

s-u commented Aug 15, 2021

One idea: can you, please, try to load the OpenCL library in R before the OpenCL package? So something like:

dyn.load("c:/.../OCL_SDK_Light/lib/x64/OpenCL.dll", FALSE, TRUE)
library(OpenCL)

if that works, then that may be a way to work around the problem.

@GerardTromp
Copy link

GerardTromp commented Sep 15, 2021

That did the trick.
For Nvidia CUDA 11.4 the following works

>echo %OCL%
C:/PROGRA~1/NVIDIA~2/CUDA/v11.4

>echo %OCLINC%
-IC:/PROGRA~1/NVIDIA~2/CUDA/v11.4/include

Compiled with:

R CMD INSTALL --no-clean-on-error --no-test-load OpenCL_0.2-2.tar.gz

Otherwise the test load causes the compile and install to abort and delete the compiled binary.

Execution requires

> dyn.load("C:/Windows/System32/OpenCL.dll", FALSE, TRUE)
> library(OpenCL)

Curiously, the Nvidia CUDA GPU Computing Toolkit installation places the OpenCL.dll in C:/Windows/System32/, perhaps as part of the driver installation.

Now to see if one can add an .onLoad() function in zzz.R and possibly make the execution dependent on the Windows OS.

Thank you.

Edit: I have run a number of the examples in the documentation to ensure that the GPU is recognized and that it can execute openCL code.

@s-u
Copy link
Owner

s-u commented Sep 15, 2021

@GerardTromp Thanks a lot for the test! That's great news! The annoying part is that it means we cannot use the automatic C symbol registration in the namespace, so I'll change the code to factor it out into a separate function and then call it only after the OCL implementation has been loaded.

Do you know if there is a way to detect the location of the implementation DLL at run-time? That's what we do with rJava - using the registry to find the path to the JVM, but I suspect there may not be a standard for OpenCL on Windows. At worst we can write $OCL into a file that gets installed with the package. If there is a way to find the DLL at compile time, we could even copy it into the package - but I wonder if that creates dependency issues in case the implementation is linked against something else...

@GerardTromp
Copy link

@s-u
There does not appear to be a registry entry that specifically defines the location of the file.
I am not too familiar with the design concept of the registry, but assume that since the file is installed in the default location for drivers, the location is not specifically recorded.

I am adding the information below as screengrabs since that is faster than trying to get the text equivalent.

Let me know if I can help out further.

These are all the registry entries (bar the shell search entries) for the text string "OpenCL.dll"
image

This is the detailed information for OpenCL.dll itself:
image

It is provided by Nvidia as can be seen in the Digital Signatures (there is also a signature from Microsoft):
image

@aaronpuchert
Copy link
Collaborator

other than re-naming the package; it may be easier to rename the OpenCL library

Maybe I was assuming that the library needs to have the same name as the package back then. If just renaming the library works, then I think that's the easiest solution.

I am not too familiar with the design concept of the registry, but assume that since the file is installed in the default location for drivers, the location is not specifically recorded.

Sounds reasonable to me. Other users of OpenCL.dll are probably also not searching the system, they're just taking it from C:/Windows/system32/ or C:/Windows/SysWOW64/ for 32-bit applications. Or perhaps they look it up in %PATH%? On Unix $PATH is different from where the dynamic loader looks, but I don't think Windows separates them. So if we go with this workaround, we should probably just iterate through %PATH%, or maybe use a function to look something up in there if it exists.

There is Sys.which, alas the docs suggest that it filters out libraries:

On Windows an ‘executable’ is a file with extension ‘.exe’, ‘.com’, ‘.cmd’ or ‘.bat’. Such files need not actually be executable, but they are what ‘system’ tries.

@s-u
Copy link
Owner

s-u commented Nov 27, 2023

Hopefully now addressed by #20

@s-u s-u closed this as completed Nov 27, 2023
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

4 participants