GPUMAGIC 1.12.0
#Intoduction有几个原因可以说服您编写自己的OpenCL代码可能比纯粹依靠包装编译器更具吸引力:
您需要的功能在软件包中不可用
编译代码的性能不符合要求
您对OpenCL很熟悉,并且想直接使用OpenCL代码
与OpenCL语言的传统无聊和痛苦的编程程序相比,在R中编写自己的代码非常简单:只需提供代码包,该软件包就会为您设置所有内容。该软件包还提供了类似模板的功能,以减轻您的烦人参数类型一致性问题。如果您不喜欢OpenCL语言,那么在Internet上有很多很棒的介绍,请先阅读它们,并在阅读下一节之前确保您拥有OpenCL的基本概念。
#示例以最简单的示例启动教程是很好的,假设我们要计算a+b
在哪里一个
和b
都是矢量。如果我们使用本机OpenCL代码编写它,那将是。
#内核代码src =“ kernel void vecadd(global double* a,global double* b,global double* res){uint ID = get_global_id(0); res [id] = a [id] = a [id]+b [id];}“ #check并设置设备getDevicelist()#>找不到设备,请确保计算机具有图形卡或驱动程序已正确安装。#>提示:#>对于CPU,您可以分别为Intel / AMD的CPU安装Intel / ATI的图形驱动程序。#>对于GPU,您需要从供应商的网站下载图形驱动程序。#>找不到设备!#> null setDevice(1)#>找不到设备!#> null #DATA准备n = 1000 a = runif(n)b = runif(n)#将数据汇总到设备#参数类型和设备是可选的a_dev = gpumatrix(a,type =“ double”,设备=“ double”,设备=1)#>找不到设备!b_dev = gpumatrix(b,type =“ double”,设备= 1)#>找不到设备!#创建一个空的矢量来存储结果res_dev = gpuemptmatrix(row = n,col = 1,type =“ double”,double”,device = 1)#>找不到设备! #Call the kernel function to excute the code #No return value .kernel(src = src,kernel="vecAdd",parms=list(A_dev,B_dev,res_dev),.device = 1,.globalThreadNum = n) #> No device has been found! #> NULL #retrieve the data and convert it into a vector res_dev=download(res_dev) res=as.vector(res_dev) #Check the error range(res-A-B) #> [1] NA NA
如您在这里所见,使用GPUMAGIC中的OpenCL代码与在RCPP中使用C ++代码非常相似。主要区别在于,您需要在代码理由之前和之后发送和检索数据。这。核心
由于S4类,功能没有任何返回值gpumatrix
包含一个指针,能够在代码归于代码后检索最终结果。请注意。核心
函数不会阻止您的控制台,因此您只要不调用下载
功能。
#使用模板,您可能会注意到,将R对象转换为gpumatrix
班级。可用类型将在本文档的末尾列出。但是,当您更改变量类型时,您需要确保OPENCL代码中的函数参数也与之匹配,这很笨拙。因此,。核心
功能证明一组宏来处理可变类型。这些宏将自动找到正确的变量类型并提供类似模板的功能,它们是:汽车
,,,,高托
,,,,lauto
。这汽车
宏将找到变量类型;高托
和lauto
矮了全球自动
和本地自动
分别。如果您不知道全球的
和当地的
,请参阅OpenCL地址空间预选赛。在这里,我们使用相同的示例来说明宏的使用。
#use自动宏声明函数参数#第一个参数具有auto1,第二个参数具有auto2等。#gauto是全局自动src =“ kernel void vecadd(gauto1* a,gauto2* b,gauto3* res){uint ID = get_global_id(0); res [id] = a [id] = a [id]+b [id];}“#将数据验证到设备#note,即变量A和B在float类型A_DEV = gpumatrix(a,type =“ float”,device = 1)#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>找不到设备!b_dev = gpumatrix(b,type =“ float”,设备= 1)#>找不到设备!#创建一个空的矢量来存储结果res_dev = gpuemptmatrix(row = n,col = 1,type =“ float”,device = 1)#>找不到设备!#call内核函数要符合代码#no return value .kernel(src = src,kernel =“ vecadd”,parms = list(a_dev,b_dev,res_dev),。设备= 1,.globalthreadnum = n)已找到设备!#> null #retrieve数据并将其转换为vector res_dev = download(res_dev)res = as.vector(res_dev)#check误差范围(res-a-a-b)#> [1]
我们在示例中做出了两个更改。首先,我们使用高托
宏以在OpenCL代码中声明函数参数,因此该函数定义与将传递给该函数的实际数据独立。其次,我们使用Float类型变量存储数据。降低可变精度可以使代码运行速度更快,但是结果不如上一个示例准确。
#附加信息
在这里,我们预示了有关使用的一些其他信息。核心
功能,将读者转介到文档?。核心
查看更多详细信息:
在通过。设备
论点,您需要确保该设备已初始化,请致电setdevice
功能。
这。设备
参数仅允许单个设备ID作为输入,您只能在一个设备上运行代码。核心
功能调用。但是,由于。核心
功能不会阻止控制台,您可以有多个。核心
带有不同设备ID的功能调用以并行化硬件。
您可以将编译标志传递给OpenCL编译器(不是gpumagic
包装编译器,是Vender的编译器)。选项
争论
这src
参数可以是文件目录或代码。
#Appendix ##可用数据类型
整数类型:布尔
,,,,char
,,,,Uint
,,,,int
,,,,乌隆
,,,,长
浮点类型:一半
,,,,漂浮
,,,,双倍的