CUDA 主机 API
设备管理
设备检测与查询
以下函数可用于查询可用的硬件:
上下文管理
CUDA Python 函数在 CUDA 上下文中执行。系统中的每个 CUDA 设备都有一个关联的 CUDA 上下文,而 Numba 目前每个线程只允许一个上下文。有关 CUDA 上下文的更多详细信息,请参阅 CUDA 驱动 API 文档中的上下文管理 和 CUDA C 编程指南上下文文档。CUDA 上下文是 Context
类的实例:
以下函数可用于获取或选择上下文:
- numba.cuda.current_context(devnum=None)
获取当前设备或通过设备编号使用设备,并返回CUDA上下文。
以下函数影响当前上下文:
设备管理
Numba 维护了一个支持 CUDA 的设备列表:
- numba.cuda.gpus
一个可索引的支持CUDA设备的列表。此列表按整数设备ID索引。
或者,可以获取当前设备:
- numba.cuda.gpus.current
当前选中的设备。
通过 numba.cuda.gpus
获取设备总是提供一个 numba.cuda.cudadrv.devices._DeviceContextManager
的实例,它作为所选设备的上下文管理器:
- class numba.cuda.cudadrv.devices._DeviceContextManager(device)[源代码]
提供一个上下文管理器,用于在选定设备的上下文中执行。这种类型的实例的正常使用是从
numba.cuda.gpus
中。例如,要在设备2上执行:with numba.cuda.gpus[2]: d_a = numba.cuda.to_device(a)
将数组 a 复制到设备 2 上,设备 2 由 d_a 引用。
也可以通过以下三种函数选择上下文和设备,或获取当前设备:
可以使用 numba.cuda.cudadrv.driver.Device
类来查询所选设备的功能:
- class numba.cuda.cudadrv.driver.Device
与特定上下文关联的设备。
- compute_capability
一个元组 (major, minor) ,表示支持的计算能力。
- id
设备的整数ID。
- name
设备的名称(例如“GeForce GTX 970”)。
- uuid
设备的UUID(例如“GPU-e6489c45-5b68-3b03-bab7-0e7c8e809643”)。
- reset()
删除设备的上下文。这将销毁在上下文中创建的所有内存分配、事件和流。
- supports_float16
如果设备支持 float16 操作,则返回
True
,否则返回False
。
编译
Numba 提供了一个入口点,用于编译 Python 函数而不调用任何驱动程序 API。这可以用于:
生成要内联到其他 PTX 代码中的 PTX(例如来自 Numba / Python 生态系统之外的代码)。
生成PTX或LTO-IR以与来自非Python翻译单元的对象链接。
在没有设备时生成代码。
在分叉之前生成代码而不初始化CUDA。
备注
用户需自行管理由于编译为PTX/LTO-IR而产生的任何ABI问题。传递``abi=”c”``关键字参数可以解决大多数可能出现的问题 - 参见 cuda-使用C-ABI。
- numba.cuda.compile(pyfunc, sig, debug=False, lineinfo=False, device=True, fastmath=False, cc=None, opt=True, abi='c', abi_info=None, output='ptx')[源代码]
为给定的一组参数类型,将Python函数编译为PTX或LTO-IR。
- 参数:
pyfunc – 要编译的Python函数。
sig – 表示函数输入和输出类型的签名。如果这是一个不带返回类型的参数类型元组,则此函数推断的返回类型为返回类型。如果传递了包含返回类型的签名,编译后的代码将包括从推断的返回类型到指定返回类型的强制转换,并且此函数将返回指定的返回类型。
debug (bool) – 是否在编译代码中包含调试信息。
lineinfo (bool) – 是否在编译后的代码中包含源代码的行映射。通常这用于优化代码(因为调试模式会自动包含此功能),因此我们希望在LLVM IR中包含调试信息,但在最终输出中仅包含行映射。
device (bool) – 是否编译设备函数。
fastmath (bool) – 是否启用快速数学标志(ftz=1, prec_sqrt=0, prec_div=, 和 fma=1)
cc (tuple) – 要编译的计算能力,以元组
(MAJOR, MINOR)
形式表示。默认为(5, 0)
。opt (bool) – 启用优化。默认为
True
。abi (str) – 编译函数的 ABI - 可以是
"numba"
或"c"
。请注意,Numba ABI 不被认为是稳定的。目前仅支持设备函数的 C ABI。abi_info (dict) – 一组特定于 ABI 的选项。
"c"
ABI 支持一个选项,"abi_name"
,用于提供包装函数的名称。"numba"
ABI 没有选项。output (str) – 要生成的输出类型,可以是
"ptx"
或"ltoir"
。
- 返回:
(代码, 推断返回类型): 编译后的代码和推断的返回类型
- 返回类型:
环境变量 NUMBA_CUDA_DEFAULT_PTX_CC
可以设置来控制 compile
所针对的默认计算能力 - 参见 GPU 支持。如果需要当前设备的计算能力的代码,可以使用 compile_for_current_device
函数:
- numba.cuda.compile_for_current_device(pyfunc, sig, debug=False, lineinfo=False, device=True, fastmath=False, opt=True, abi='c', abi_info=None, output='ptx')[源代码]
为当前设备的计算能力编译一个Python函数为PTX或LTO-IR,给定一个签名。这将调用
compile()
并传入当前设备合适的cc
值。
Numba 还提供了两个函数,这些函数可能用于专门编译为 PTX 的遗留代码中:
- numba.cuda.compile_ptx(pyfunc, sig, debug=False, lineinfo=False, device=False, fastmath=False, cc=None, opt=True, abi='numba', abi_info=None)[源代码]
根据给定的签名将Python函数编译为PTX。参见
compile()
。此函数的默认设置是编译一个符合Numba ABI的内核,而不是compile()
的默认设置,即编译一个符合C ABI的设备函数。
- numba.cuda.compile_ptx_for_current_device(pyfunc, sig, debug=False, lineinfo=False, device=False, fastmath=False, opt=True, abi='numba', abi_info=None)[源代码]
为当前设备的计算能力编译一个具有给定签名的Python函数到PTX。参见
compile_ptx()
。
测量
性能分析
Nvidia Visual Profiler 可以直接用于执行 CUDA Python 代码 - 不需要在用户代码中插入这些函数的调用。然而,这些函数可以用来允许对代码的特定部分进行选择性分析。有关分析的更多信息,请参阅 Nvidia Profiler 用户指南。
事件
事件可用于监控执行进度并记录到达特定点的时戳。事件创建会立即返回,并且可以查询创建的事件以确定是否已到达。更多信息,请参阅 CUDA C 编程指南事件部分。
以下函数用于创建和测量事件之间的时间:
事件是 numba.cuda.cudadrv.driver.Event
类的实例:
流管理
流允许在给定上下文中的单个设备上执行并发操作。同一流中的排队工作项按顺序执行,但不同流中的工作项可能并发执行。涉及CUDA设备的大多数操作都可以使用流进行异步执行,包括数据传输和内核执行。有关流的更多详细信息,请参阅 CUDA C编程指南流部分。
Numba 默认使用遗留默认流作为默认流。可以通过将环境变量 NUMBA_CUDA_PER_THREAD_DEFAULT_STREAM
设置为 1
来使每个线程的默认流成为默认流(参见 CUDA 环境变量部分)。无论此设置如何,都可以使用以下函数构造表示遗留和每个线程默认流的对象。
流是 numba.cuda.cudadrv.driver.Stream
的实例:
- class numba.cuda.cudadrv.driver.Stream(context, handle, finalizer, external=False)[源代码]
- add_callback(callback, arg=None)[源代码]
向计算流添加回调。用户提供的函数将在所有前面的流操作完成后,由驱动线程调用。
回调函数是从CUDA驱动线程调用的,而不是从调用 add_callback 的线程调用的。在回调函数内部不能调用任何CUDA API函数。
回调函数的持续时间应保持较短,因为回调会阻塞流中的后续工作,并可能阻塞其他回调的执行。
注意:此方法底层使用的驱动函数已被标记为最终弃用,并可能在未来的CUDA版本中被替换。
- 参数:
callback – 带参数的回调函数 (stream, status, arg)。
arg – 可选的用户数据,传递给回调函数。
要创建一个新的流:
要获取默认流:
- numba.cuda.default_stream()[源代码]
获取默认的 CUDA 流。一般来说,CUDA 的语义是默认流要么是遗留默认流,要么是每个线程的默认流,这取决于使用的是哪些 CUDA API。在 Numba 中,总是使用遗留默认流的 API,但将来可能会提供使用每个线程默认流 API 的选项。
要获取默认流并明确选择它是遗留的还是每个线程的默认流:
要使用在其他地方分配的流构造一个 Numba Stream
对象,提供了 external_stream
函数。请注意,外部流的生存期必须由用户管理 - Numba 不会释放外部流,并且在使用 Numba Stream
对象时,流必须保持有效。
运行时
Numba 通常使用 Driver API,但它提供了一个简单的 Runtime API 包装器,以便可以查询正在使用的运行时版本。这是通过 cuda.runtime
访问的,它是 numba.cuda.cudadrv.runtime.Runtime
类的一个实例:
- class numba.cuda.cudadrv.runtime.Runtime[源代码]
延迟绑定运行时API函数的运行时对象。
- property supported_versions
所有支持的 CUDA 工具包版本的元组。版本以
(主版本, 次版本)
的形式给出。
当前运行时是否与当前版本的 Numba 正式支持并经过测试,也可以进行查询: