pycuda-一些計算函式

雲net發表於2018-07-17

單通自定義表示式評估

評估GPUArray例項上涉及的表示式可能有些低效,因為為每個中間結果建立了一個新的臨時表。模組pycuda.elementwise 中的功能包含有助於生成核心的工具,這些核心在一次傳遞中評估一個或多個運算元上的多階段表示式。

class pycuda.elementwise.ElementwiseKernelargumentsoperationname =“kernel”keep = Falseoptions = []preamble =“” 

如果該引數是向量,則生成一個帶有許多標量或向量引數的核心,並對其引數的每個條目 執行標量運算

arguments被指定為格式化為C引數列表的字串。 operation被指定為C賦值語句,沒有分號。運算中的向量應該由變數i索引。

name指定編譯核心的名稱,keep 和options未經修改地傳遞給pycuda.compiler.SourceModule

preamble指定在元素核心規範之前包含的一些原始碼。您可以使用它來包含其他檔案和/或定義操作使用的函式。

__call__* argsrange = Noneslice = 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.ReductionKerneldtype_outneutralreduce_exprmap_expr = Nonearguments = Nonename =“reduce_kernel”keep = Falseoptions = []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指定編譯核心的名稱,keepoptions未經修改地傳遞給pycuda.compiler.SourceModulepreamble被指定為一串程式碼。

這是一個用法示例:

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()

相關文章