内置公用设施#

内存池#

内存分配(例如,以 pyopencl.Buffer() 构造函数)如果频繁使用可能会很昂贵。例如,基于 pyopencl.array.Array 很容易遇到这个问题,因为为每个中间结果分配了一个新的内存区。根据观察,许多块分配的大小通常与以前使用的块分配的大小相同,因此内存池是解决此问题的一种方法。

然后,该池保留内存并使用它来满足将来类似大小的块的分配,而不是将内存完全返回给系统并产生相关的重新分配开销。只要所有内存分配都是通过池进行的,池就会对内存不足的情况做出适当的反应。由于池拥有大量或全部可用内存,从池外部执行的分配可能会遇到虚假的内存不足情况。

有两种类型的分配器和内存池:

vbl.使用 pyopencl.array.Array S可以直接与内存池一起使用:

mem_pool = pyopencl.tools.MemoryPool(pyopencl.tools.ImmediateAllocator(queue))
a_dev = cl_array.arange(queue, 2000, dtype=np.float32, allocator=mem_pool)

同样,基于支持向量机的分配器可直接用于 pyopencl.array.Array

Buffer -基于分配器和内存池#

class pyopencl.tools.PooledBuffer#

一个对象,表示 MemoryPool -基于资源的分配 Buffer -风格的设备内存。类似于 Buffer 但是,一旦删除此对象,其关联的设备内存就会返回到池中。

是一种 pyopencl.MemoryObject

class pyopencl.tools.AllocatorBase#

中的各种内存分配函数实现的接口 pyopencl

__call__(self: pyopencl._cl.AllocatorBase, size: int) pyopencl._cl.Buffer#

分配并返回一个 pyopencl.Buffer 给出的 size

class pyopencl.tools.DeferredAllocator#

mem_flags 它的价值来自 pyopencl.mem_flags 并对应于 flags 的论点 pyopencl.Buffer 。DeferredAllocator具有与常规OpenCL缓冲区分配相同的语义,即它可能承诺有可用内存(在对使用缓冲区的CL函数的任何调用中)稍后可能不存在。(CL中的分配与上下文绑定,而不是与设备绑定,内存可用性取决于使用缓冲区的设备。)

机具 AllocatorBase

在 2013.1 版本发生变更: CLAllocator 已弃用,取而代之的 DeferredAllocator

__init__(context, mem_flags=pyopencl.mem_flags.READ_WRITE)#
__call__(self: pyopencl._cl.AllocatorBase, size: int) pyopencl._cl.Buffer#

分配一个 pyopencl.Buffer 给出的 size

在 2020.2 版本发生变更: 即使对于大小为零的分配,分配器也会成功,返回 None

class pyopencl.tools.ImmediateAllocator#

mem_flags 它的价值来自 pyopencl.mem_flags 并对应于 flags 的论点 pyopencl.BufferImmediateAllocator 将尝试在分配时确保分配的内存实际可用。如果没有可用的内存,则在分配时会报告内存不足错误。

机具 AllocatorBase

在 2013.1 版本加入.

__init__(queue, mem_flags=pyopencl.mem_flags.READ_WRITE)#
__call__(self: pyopencl._cl.AllocatorBase, size: int) pyopencl._cl.Buffer#

分配一个 pyopencl.Buffer 给出的 size

在 2020.2 版本发生变更: 即使对于大小为零的分配,分配器也会成功,返回 None

class pyopencl.tools.MemoryPool#

中用于OpenCL设备内存的内存池 pyopencl.Buffer 形式。 allocator 必须是上述类之一的实例,并且应该是 ImmediateAllocator 。内存池假定分配器立即报告分配失败,而不是以OpenCL典型的延迟方式。

机具 AllocatorBase

在 2019.1 版本发生变更: 记录了当前仓位分配行为, leading_bits_in_bin_id 添加了。

__init__(self: pyopencl._cl.MemoryPool, allocator: pyopencl._cl.AllocatorBase, leading_bits_in_bin_id: int = 4) None#
allocate(self: pyopencl._cl.MemoryPool, size: int) pyopencl._cl.PooledBuffer#

返回一个 PooledBuffer 给出的 size

__call__(self: pyopencl._cl.MemoryPool, size: int) pyopencl._cl.PooledBuffer#

的同义词 allocate() 匹配 AllocatorBase

在 2011.2 版本加入.

备注

内存池的当前实现将在应用程序返回内存后保留分配的内存,并将其保存在由主要 leading_bits_in_bin_id 分配大小的位。为了确保每个库中的分配是可互换的,分配大小被向上舍入到共享所请求的分配大小的前导比特的最大大小。

的当前缺省值 leading_bits_in_bin_id 是四,但这可能会在未来的版本中更改,并且不能保证。

leading_bits_in_bin_id 必须通过关键字传递,其作用纯粹是建议。不能保证池的未来版本将使用相同的分配方案和/或遵守 leading_bits_in_bin_id

held_blocks#

此池持有的未使用数据块数。

active_blocks#

已通过此池分配的处于活动状态的数据块数。

managed_bytes#

“托管”内存是“活动的”和“保持的”内存。

在 2021.1.2 版本加入.

active_bytes#

“活动”字节是在应用程序控制下的字节。这可能小于反映在 managed_bytes

在 2021.1.2 版本加入.

free_held()#

释放池当前持有的所有未使用的内存。

stop_holding()#

指示内存立即开始释放返回给它的内存,而不是保留它以供将来分配。隐式调用 free_held() 。当内存池停止使用时,这作为清理操作非常有用。

SVM -基于分配器和内存池#

支持向量机功能需要OpenCL 2.0。

class pyopencl.tools.PooledSVM#

一个对象,表示 SVMPool -基于资源的分配 共享虚拟内存(SVM) 。类似于 SVMAllocation 但是,一旦此对象被删除,其关联的设备内存就会返回到它所在的池。

在 2022.2 版本加入.

备注

如果 SVMAllocator 对于 SVMPool 分配了此类型对象的对象与(按顺序) CommandQueue 提供了充分的同步,以确保在释放完成之前排队的操作在允许来自不同用途(可能在不同队列中)的操作开始之前。这适用于以下情况 release 当垃圾回收器自动释放对象时,也会调用。

是一种 pyopencl.SVMPointer

支持结构平等和哈希。

release(self: pyopencl._cl.PooledSVM) None#

将保留的内存返还给池。请参阅上面关于释放期间的同步行为的说明。

enqueue_release(self: pyopencl._cl.PooledSVM) None#

同义词 release() ,以保持与 SVMAllocation 。请注意,与 pyopencl.SVMAllocation.enqueue_release() 不支持指定要等待的队列或事件。

bind_to_queue(self: pyopencl._cl.PooledSVM, arg0: pyopencl._cl.CommandQueue) None#

类似于 pyopencl.SVMAllocation.bind_to_queue()

unbind_from_queue(self: pyopencl._cl.PooledSVM) None#

类似于 pyopencl.SVMAllocation.unbind_from_queue()

class pyopencl.tools.SVMAllocator#

在 2022.2 版本加入.

__init__(self: pyopencl._cl.SVMAllocator, context: pyopencl._cl.Context, *, alignment: int = 0, flags: int = 1, queue: pyopencl._cl.CommandQueue = None) None#
参数:
  • flags -- 看见 svm_mem_flags

  • queue -- 如果未指定,则无论挂起/入队的操作是否仍在使用内存,都将立即释放分配。如果指定,则内存释放将与给定队列一起入队,并且只有在队列中先前入队的操作完成后才会执行。指定无序队列是错误的。。。警告::不指定队列通常会导致意外行为,包括崩溃和内存损坏。请参阅中的警告 共享虚拟内存(SVM)

__call__(self: pyopencl._cl.SVMAllocator, size: int) pyopencl._cl.SVMAllocation#

返回一个 SVMAllocation 给出的 size

class pyopencl.tools.SVMPool#

中用于OpenCL设备内存的内存池 SVM 形式。 allocator 必须是 SVMAllocator

在 2022.2 版本加入.

__init__(self: pyopencl._cl.SVMPool, allocator: pyopencl._cl.SVMAllocator, *, leading_bits_in_bin_id: int = 4) None#
__call__(self: pyopencl._cl.SVMPool, size: int) pyopencl._cl.PooledSVM#

返回一个 PooledSVM 给出的 size

备注

内存池的当前实现将在应用程序返回内存后保留分配的内存,并将其保存在由主要 leading_bits_in_bin_id 分配大小的位。为了确保每个库中的分配是可互换的,分配大小被向上舍入到共享所请求的分配大小的前导比特的最大大小。

的当前缺省值 leading_bits_in_bin_id 是四,但这可能会在未来的版本中更改,并且不能保证。

leading_bits_in_bin_id 必须通过关键字传递,其作用纯粹是建议。不能保证池的未来版本将使用相同的分配方案和/或遵守 leading_bits_in_bin_id

held_blocks#

此池持有的未使用数据块数。

active_blocks#

已通过此池分配的处于活动状态的数据块数。

managed_bytes#

“托管”内存是“活动的”和“保持的”内存。

在 2021.1.2 版本加入.

active_bytes#

“活动”字节是在应用程序控制下的字节。这可能小于反映在 managed_bytes

在 2021.1.2 版本加入.

free_held()#

释放池当前持有的所有未使用的内存。

stop_holding()#

指示内存立即开始释放返回给它的内存,而不是保留它以供将来分配。隐式调用 free_held() 。当内存池停止使用时,这作为清理操作非常有用。

CL-依赖对象的缓存#

pyopencl.tools.first_arg_dependent_memoize(func)[源代码]#
pyopencl.tools.clear_first_arg_caches()[源代码]#

清空所有依赖于第一个参数的备忘缓存。还会释放所有保留的参照上下文。如果程序脱离其上下文对您来说很重要,您可能需要调用此函数来释放对上下文的所有剩余引用。

在 2011.2 版本加入.

测试#

pyopencl.tools.pytest_generate_tests_for_pyopencl(metafunc)[源代码]#

使用行::

from pyopencl.tools import pytest_generate_tests_for_pyopencl
        as pytest_generate_tests

在你的 pytest 测试脚本允许您使用参数 ctx_factorydevice ,或 platform 在您的测试函数中,它们将根据需要为系统中的每个OpenCL设备/平台自动运行。

还支持以下两个环境变量来控制设备/平台选择:

PYOPENCL_TEST=0:0,1;intel=i5,i7

参数类型#

class pyopencl.tools.Argument[源代码]#
abstract declarator() str[源代码]#
class pyopencl.tools.DtypedArgument(dtype: Any, name: str)[源代码]#
name#
dtype#
class pyopencl.tools.VectorArg(dtype: Any, name: str, with_offset: bool = False)[源代码]#

继承自 DtypedArgument

__init__(dtype: Any, name: str, with_offset: bool = False) None[源代码]#
class pyopencl.tools.ScalarArg(dtype: Any, name: str)[源代码]#

继承自 DtypedArgument

class pyopencl.tools.OtherArg(declarator: str, name: str)[源代码]#
pyopencl.tools.parse_arg_list(arguments: str | List[str] | List[DtypedArgument], with_offset: bool = False) List[DtypedArgument][源代码]#

解析内核参数列表。 arguments 可以是字符串中以逗号分隔的C声明符列表、表示C声明符的字符串列表,或者 Argument 物体。

设备特性#

exception pyopencl.characterize.CLCharacterizationWarning[源代码]#
pyopencl.characterize.get_fast_inaccurate_build_options(dev)[源代码]#

返回设备上有效的标志列表 dev 这使得浮点运算速度很快,但可能不准确。

pyopencl.characterize.get_simd_group_size(dev, type_size)[源代码]#

返回将跨SIMD通道执行的工作项数的估计值。这将返回NVIDIA所称的翘曲和AMD所称的波前的大小。

仅指隐式SIMD。

参数:

type_size -- 向量条目类型中的字节数。

pyopencl.characterize.has_amd_double_support(dev)[源代码]#

“修复以允许低端电路板中的不完整和双支撑

pyopencl.characterize.has_struct_arg_count_bug(dev, ctx=None)[源代码]#

检查设备是否应具有 argument counting bug

pyopencl.characterize.local_memory_access_granularity(dev)[源代码]#

返回本地内存中每个库的字节数。

pyopencl.characterize.local_memory_bank_count(dev)[源代码]#

返回本地内存中存在的存储体的数量。

pyopencl.characterize.nv_compute_capability(dev)[源代码]#

如果 dev 是NVIDIA图形处理器 pyopencl.Device ,返回一个元组 (major, minor) 指示设备的计算能力。

pyopencl.characterize.simultaneous_work_items_on_local_access(dev)[源代码]#

返回同时访问本地内存并因此可能相互冲突的工作项的数量。

pyopencl.characterize.usable_local_mem_size(dev, nargs=None)[源代码]#

返回可用本地内存大小的估计值。用法:arg Nargs:传递的32位参数的数量。

pyopencl.characterize.why_not_local_access_conflict_free(dev, itemsize, array_shape, array_stored_shape=None)[源代码]#
参数:
  • itemsize -- 访问的数据大小(以字节为单位

  • array_shape -- 数组维度,移动最快的最后一个(C顺序)

返回:

元组(多重性,解释),其中 multiplicity 是在访问本地内存时将在库上发生冲突的工作项数。 explanation 是详细描述发现的冲突的字符串。

类型别名#

class pyopencl._cl.AllocatorBase#

看见 pyopencl.tools.AllocatorBase