评估GPUArray
实例上涉及的表达式可能有些低效,因为为每个中间结果创建了一个新的临时表。模块pycuda.elementwise
中的功能包含有助于生成内核的工具,这些内核在一次传递中评估一个或多个操作数上的多阶段表达式。
class pycuda.elementwise.
ElementwiseKernel
(arguments,operation,name =“kernel”,keep = False,options = [],preamble =“” )
如果该参数是向量,则生成一个带有许多标量或向量参数的内核,并对其参数的每个条目 执行标量运算。
arguments被指定为格式化为C参数列表的字符串。 operation被指定为C赋值语句,没有分号。运算中的向量应该由变量i索引。
name指定编译内核的名称,keep 和options未经修改地传递给pycuda.compiler.SourceModule
。
preamble指定在元素内核规范之前包含的一些源代码。您可以使用它来包含其他文件和/或定义操作使用的函数。
__call__
(* args,range = None,slice = None )
调用生成的标量内核。参数可以是标量或 GPUArray
实例。
如果范围给出,它必须是一个slice
对象,并指定索引的范围我的量,操作被执行。
如果切片中给出,它必须是一个slice
对象,并指定索引的范围我的量,操作进行时,截断到容器上。此外,slice可能包含相对于数组末尾的索引的负索引。
如果给出了stream,它必须是一个pycuda.driver.Stream
对象,执行将被序列化。
这是一个用法示例:
import pycuda.gpuarray as gpuarray import pycuda.driver as cuda import pycuda.autoinit import numpy from pycuda.curandom import rand as curand a_gpu = curand((50,)) b_gpu = curand((50,)) from pycuda.elementwise import ElementwiseKernel lin_comb = ElementwiseKernel( "float a, float *x, float b, float *y, float *z", "z[i] = a*x[i] + b*y[i]", "linear_combination") c_gpu = gpuarray.empty_like(a_gpu) lin_comb(5, a_gpu, 6, b_gpu, c_gpu) import numpy.linalg as la assert la.norm((c_gpu - (5*a_gpu+6*b_gpu)).get()) < 1e-5
(您可以examples/demo_elementwise.py
在PyCuda发行版中找到此示例。)
class pycuda.reduction.
ReductionKernel
(dtype_out,neutral,reduce_expr,map_expr = None,arguments = None,name =“reduce_kernel”,keep = False,options = [],preamble =“”,allocator = None )
生成一个带有多个标量或向量参数 (至少一个向量参数)的内核,对vector参数的每个条目执行map_expr,然后对其结果执行reduce_expr。 中性作为初始值。preamble提供了在实际的简化内核代码之前添加预处理程序指令和其他代码(如辅助函数)的可能性。
map_expr中的向量应该由变量i索引。reduce_expr 使用形式值“a”和“b”来指示二进制缩减操作的两个操作数。如果未指定map_expr,则会自动假定“in [i]” - 因此只存在一个输入参数。
dtype_out指定numpy.dtype
执行缩减的位置以及返回结果的位置。中性被指定为float或整数,格式为string。reduce_expr和 map_expr被指定为字符串格式化的操作,参数 被指定为格式化为C参数列表的字符串。name指定编译内核的名称,keep和options未经修改地传递给pycuda.compiler.SourceModule
。preamble被指定为一串代码。
这是一个用法示例:
a = gpuarray.arange(400, dtype=numpy.float32) b = gpuarray.arange(400, dtype=numpy.float32) krnl = ReductionKernel(numpy.float32, neutral="0", reduce_expr="a+b", map_expr="x[i]*y[i]", arguments="float *x, float *y") my_dot_prod = krnl(a, b).get()