CUDA Ufunc 和广义 Ufunc

CUDA 内置目标弃用通知

Numba 内置的 CUDA 目标已弃用,后续开发已移至 NVIDIA numba-cuda 包。请参阅 内置 CUDA 目标的弃用和维护状态

本页描述了 CUDA 类 ufunc 对象。

为支持 CUDA 程序的编程模式,CUDA Vectorize 和 GUVectorize 无法生成常规的 ufunc。相反,会返回一个类 ufunc 对象。该对象与常规 NumPy ufunc 类似,但并非完全兼容。CUDA ufunc 增加了对传递设备内数组(已在 GPU 设备上)的支持,以减少 PCI-express 总线上的流量。它还接受一个 stream 关键字,用于在异步模式下启动。

示例:基本示例

import math
from numba import vectorize, cuda
import numpy as np

@vectorize(['float32(float32, float32, float32)',
            'float64(float64, float64, float64)'],
           target='cuda')
def cu_discriminant(a, b, c):
    return math.sqrt(b ** 2 - 4 * a * c)

N = 10000
dtype = np.float32

# prepare the input
A = np.array(np.random.sample(N), dtype=dtype)
B = np.array(np.random.sample(N) + 10, dtype=dtype)
C = np.array(np.random.sample(N), dtype=dtype)

D = cu_discriminant(A, B, C)

print(D)  # print result

示例:调用设备函数

所有 CUDA ufunc 内核都能够调用其他 CUDA 设备函数

from numba import vectorize, cuda

# define a device function
@cuda.jit('float32(float32, float32, float32)', device=True, inline=True)
def cu_device_fn(x, y, z):
    return x ** y / z

# define a ufunc that calls our device function
@vectorize(['float32(float32, float32, float32)'], target='cuda')
def cu_ufunc(x, y, z):
    return cu_device_fn(x, y, z)

广义 CUDA Ufunc

广义 ufunc 可以在 GPU 上使用 CUDA 执行,类似于 CUDA ufunc 功能。这可以通过以下方式实现

from numba import guvectorize

@guvectorize(['void(float32[:,:], float32[:,:], float32[:,:])'],
             '(m,n),(n,p)->(m,p)', target='cuda')
def matmulcore(A, B, C):
    ...