安装了 R 的 OpenCL 包,但得到了奇怪的结果

OpenCL package for R installed, but got strange results

我在 Linux 系统上使用 运行 R 3.4.3。由于我有 Radeon (R9 380X) 卡,我决定尝试 OpenCL 包(我知道有 gpuR 包,但它对我不起作用)。所以:

我按照软件包页面 (here) 上的建议做了 install.packages('OpenCL',,'http://www.rforge.net/'),并获得了版本 0.1-4:

Installing package into ‘/home/jeronimo/R/x86_64-pc-linux-gnu-library/3.4’
(as ‘lib’ is unspecified)
trying URL 'http://www.rforge.net/src/contrib/OpenCL_0.1-4.tar.gz'
Content type 'application/x-gzip' length 14933 bytes (14 KB)
==================================================
downloaded 14 KB

* installing *source* package ‘OpenCL’ ...
** libs
gcc -std=gnu99 -I/usr/share/R/include -DNDEBUG      -fpic  -g -O2 -fdebug-prefix-map=/build/r-base-3.4.3=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -g  -c ocl.c -o ocl.o
ocl.c: In function ‘ocl_call’:
ocl.c:440:5: warning: ‘clCreateCommandQueue’ is deprecated [-Wdeprecated-declarations]
     occ->commands = commands = clCreateCommandQueue(context, device_id, 0, &last_ocl_error);
     ^~~
In file included from /usr/include/CL/opencl.h:47:0,
                 from ocl.c:6:
/usr/include/CL/cl.h:1427:1: note: declared here
 clCreateCommandQueue(cl_context                     /* context */,
 ^~~~~~~~~~~~~~~~~~~~
gcc -std=gnu99 -I/usr/share/R/include -DNDEBUG      -fpic  -g -O2 -fdebug-prefix-map=/build/r-base-3.4.3=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -g  -c tools.c -o tools.o
gcc -std=gnu99 -shared -L/usr/lib/R/lib -Wl,-z,relro -o OpenCL.so ocl.o tools.o -lOpenCL -L/usr/lib/R/lib -lR
installing to /home/jeronimo/R/x86_64-pc-linux-gnu-library/3.4/OpenCL/libs
** R
** preparing package for lazy loading
** help
*** installing help indices
** building package indices
** testing if installed package can be loaded
* DONE (OpenCL)

The downloaded source packages are in
    ‘/tmp/user/1000/Rtmpkdhno7/downloaded_packages’

该库似乎可以正确检测到我的 GPU:

> library(OpenCL)
> p = oclPlatforms()
> d = oclDevices(p[[1]])
> p
[[1]]
 OpenCL platform 'Clover'

[[2]]
 OpenCL platform 'Portable Computing Language'

> d
[[1]]
 OpenCL device 'AMD Radeon (TM) R9 380 Series (TONGA / DRM 3.19.0 / 4.14.0-3-amd64, LLVM 5.0.1)'

只是检查 -- 它还检测多核 CPU:

> oclDevices(p[[2]])
[[1]]
 OpenCL device 'pthread-AMD FX-8320E Eight-Core Processor'

现在我创建一个简单的 OpenCL 内核,它将获得一个向量,乘以 -1 并将 3.0 与其所有元素相加:

code = c("
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
__kernel void countit(
      __global double* output,
      const unsigned int count,
      __global double* input) 
{
    int i = get_global_id(0);
    if (i<count)
            output[i] = -(input[i]) + (3.0);
};")

> f_kernel <- oclSimpleKernel(d[[1]], "countit", code, "double")
> 
> f<-function(ve)
+         oclRun(f_kernel,length(ve),ve, wait=TRUE)
>

但是输入向量 input 似乎总是用零填充:

> f(1:5)
[1] 3 3 3 3 3

但我希望这是向量 4 5 6 7 8,因为我将 3 添加到 1:5

这是会话信息:

> sessionInfo()
R version 3.4.3 (2017-11-30)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Debian GNU/Linux buster/sid

Matrix products: default
BLAS: /usr/lib/x86_64-linux-gnu/openblas/libblas.so.3
LAPACK: /usr/lib/x86_64-linux-gnu/libopenblasp-r0.2.20.so

locale:
 [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C         LC_TIME=C           
 [4] LC_COLLATE=C         LC_MONETARY=C        LC_MESSAGES=C       
 [7] LC_PAPER=C           LC_NAME=C            LC_ADDRESS=C        
[10] LC_TELEPHONE=C       LC_MEASUREMENT=C     LC_IDENTIFICATION=C 

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

other attached packages:
[1] devtools_1.13.1 OpenCL_0.1-4   

loaded via a namespace (and not attached):
[1] compiler_3.4.3 tools_3.4.3    withr_1.0.2    rstudioapi_0.6 memoise_1.1.0 
[6] digest_0.6.13 

我错过了什么?这看起来像是我的一个简单错误,但我看不到。 如果有任何提示,我将不胜感激!

问题是 1:5 的类型是 integer。您必须将其转换为 numeric 才能将其作为 double 向量传递:

library(OpenCL)
p = oclPlatforms()
d = oclDevices(p[[1]])

code = c("
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
__kernel void countit(
      __global double* output,
      const unsigned int count,
      __global double* input) {
    int i = get_global_id(0);
    if (i<count)
            output[i] = -(input[i]) + (3.0);
};")

f_kernel <- oclSimpleKernel(d[[1]], "countit", code, "double")

f<-function(ve)
         oclRun(f_kernel,length(ve),ve, wait=TRUE)

f(as.numeric(1:5))
#> [1]  2  1  0 -1 -2