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

kernel wrapper example for oclRun does not handle integer input #10

Closed
mtmorgan opened this issue Mar 16, 2022 · 4 comments
Closed

kernel wrapper example for oclRun does not handle integer input #10

mtmorgan opened this issue Mar 16, 2022 · 4 comments

Comments

@mtmorgan
Copy link

After

example(oclRun)

we have very different values

> n = 5L; x = 1L:n; all.equal(f(x), dnorm(x))
[1] "Mean relative difference: 0.8493372"

I guess x is a 'compact' representation

> .Internal(inspect(x))
@138d2d948 13 INTSXP g0c0 [REF(65535)]  1 : 5 (compact)

Correct results are obtained by forcing expansion of compact representation

> n = 5L; x = 1L:n/1L; all.equal(f(x), dnorm(x))
[1] "Mean relative difference: 3.111545e-08"
@s-u
Copy link
Owner

s-u commented Mar 16, 2022

I cannot reproduce it. Can you, please, provide details such as sessionInfo() and oclDevices()?

I suspect that the compact representation is a red herring - I recall having seen issues on some GPUs when you try to use integer vectors instead of doubles since only doubles are supported by the hardware (that's why the example uses /2). In your first example you're passing an integer vector, in the second it's a vector of doubles. Try as.double(x).

@mtmorgan
Copy link
Author

Yes, your guess seems better than mine; coercing to double 'fixes' the problem.

> sessionInfo()
R Under development (unstable) (2022-03-07 r81852)
Platform: aarch64-apple-darwin21.3.0 (64-bit)
Running under: macOS Monterey 12.2.1

Matrix products: default
BLAS:   /Users/ma38727/bin/R-devel/lib/libRblas.dylib
LAPACK: /Users/ma38727/bin/R-devel/lib/libRlapack.dylib

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] OpenCL_0.2-2

loaded via a namespace (and not attached):
[1] compiler_4.2.0
> (dev <- oclDevices()); oclInfo(dev[[1]])
[[1]]
OpenCL device 'Apple M1 Pro'

$name
[1] "Apple M1 Pro"

$vendor
[1] "Apple"

$version
[1] "OpenCL 1.2 "

$profile
[1] "FULL_PROFILE"

$exts
 [1] "cl_APPLE_SetMemObjectDestructor"     
 [2] "cl_APPLE_ContextLoggingFunctions"    
 [3] "cl_APPLE_clut"                       
 [4] "cl_APPLE_query_kernel_names"         
 [5] "cl_APPLE_gl_sharing"                 
 [6] "cl_khr_gl_event"                     
 [7] "cl_khr_byte_addressable_store"       
 [8] "cl_khr_global_int32_base_atomics"    
 [9] "cl_khr_global_int32_extended_atomics"
[10] "cl_khr_local_int32_base_atomics"     
[11] "cl_khr_local_int32_extended_atomics" 
[12] "cl_khr_3d_image_writes"              
[13] "cl_khr_image2d_from_buffer"          
[14] "cl_khr_depth_images"                 

$driver.ver
[1] "1.2 1.0"

$max.frequency
[1] 1000

Also, from the above, it is the single-precision version of f() from the example that is being run, since the device does not support cl_khr_fp64

@s-u
Copy link
Owner

s-u commented Mar 16, 2022

@mtmorgan Thanks, I can replicate it on an M1:

> f(0:4)
[1] 0.3989423 0.3989423 0.3989423 0.3989423 0.3989423
> f(as.numeric(0:4))
[1] 0.3989422917 0.2419707328 0.0539909676 0.0044318484 0.0001338302

The problem is that as.clBuffer(x, ctx) has no defined type - the buffer will be either int or double depending what you pass, however the kernel only expects numeric. Therefore the combination is invalid. We should change the example to use as.clBuffer(as.numeric(x), ctx) since it is indeed required.

Alternatively, we may want to add mode = class(vector) to as.clBuffer() and use as.clBuffer(x, ctx, "numeric") since clBuffer() already supports automatic conversion corresponding to the mode.

@s-u s-u changed the title as.clBuffer() does not expand 'compact' integer vectors kernel wrapper example for oclRun does not handle integer input Mar 16, 2022
@s-u s-u closed this as completed in 9535820 Mar 17, 2022
@aaronpuchert
Copy link
Collaborator

To add to this, we currently don't do any type checking when passing arguments to kernels. There is actually an API function to get argument types, clGetKernelArgInfo, which would allow us to do that.

But it's only available with OpenCL 2.0 and newer, as far as I can see. Sadly OpenCL needlessly ties its API version to supported hardware features—there is actually no reason this function couldn't be supported on devices that don't offer the full OpenCL 2.0 functionality, it's purely a question of the software stack.

What I also thought about (briefly) is optionally using libclang, if available, to get that information, but optional linking is not so easy and platform-dependent. (Most platforms that support OpenCL actually use Clang under the hood anyway, but it might not be available as a separate library, so we wouldn't want to require it.)

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

3 participants