并行算法#
基于元素的表达式求值(“map”)#
计算上涉及的表达式 pyopencl.array.Array
使用重载运算符的实例可能会有些低效,因为会为每个中间结果创建一个新的临时实例。模块中的功能 pyopencl.elementwise
包含有助于生成内核的工具,这些内核在一次传递中对一个或多个操作数计算多级表达式。
- class pyopencl.elementwise.ElementwiseKernel(context: Context, arguments: str | List[DtypedArgument], operation: str, name: str = 'elwise_kernel', options: Any = None, **kwargs: Any)[源代码]#
接受多个标量或向量的内核 arguments 并执行 operation 指定为这些参数上的C代码片断。
- 参数:
arguments -- 格式为C参数列表的字符串。
operation -- 执行所需“map”操作的C代码片段。当前索引可用作变量 i 。 operation 可以包含以下语句
PYOPENCL_ELWISE_CONTINUE
,这将终止对当前元素的处理。name -- 编译内核时使用的函数名
options -- 未修改地传递给
pyopencl.Program.build()
。preamble -- 在基本操作的内核源代码中的函数上下文之外插入的一段C源代码。
警告
使用
return
中的语句 operation 将导致不正确的结果,因为某些元素可能永远不会被处理。使用PYOPENCL_ELWISE_CONTINUE
取而代之的是。在 2013.1 版本发生变更: 增列
PYOPENCL_ELWISE_CONTINUE
。- __call__(*args, **kwargs) Event [源代码]#
调用生成的标量内核。
参数可以是标量或
pyopencl.array.Array
实例。Returns a new
pyopencl.Event
. wait_for may either be None or a list ofpyopencl.Event
instances for whose completion this command waits before starting exeuction.
下面是一个使用示例:
#!/usr/bin/env python
import numpy as np
import pyopencl as cl
import pyopencl.array
from pyopencl.elementwise import ElementwiseKernel
n = 10
a_np = np.random.randn(n).astype(np.float32)
b_np = np.random.randn(n).astype(np.float32)
ctx = cl.create_some_context()
queue = cl.CommandQueue(ctx)
a_g = cl.array.to_device(queue, a_np)
b_g = cl.array.to_device(queue, b_np)
lin_comb = ElementwiseKernel(ctx,
"float k1, float *a_g, float k2, float *b_g, float *res_g",
"res_g[i] = k1 * a_g[i] + k2 * b_g[i]",
"lin_comb")
res_g = cl.array.empty_like(a_g)
lin_comb(2, a_g, 3, b_g, res_g)
# Check on GPU with PyOpenCL Array:
print((res_g - (2 * a_g + 3 * b_g)).get())
# Check on CPU with Numpy:
res_np = res_g.get()
print(res_np - (2 * a_np + 3 * b_np))
print(np.linalg.norm(res_np - (2 * a_np + 3 * b_np)))
(你可以找到这个例子 examples/demo_elementwise.py
在PyOpenCL发行版中。)
总和和计数(“减少”)#
- class pyopencl.reduction.ReductionKernel(ctx: Context, dtype_out: Any, neutral: str, reduce_expr: str, map_expr: str | None = None, arguments: str | List[DtypedArgument] | None = None, name: str = 'reduce_kernel', options: Any = None, preamble: str = '')[源代码]#
对数组执行一般约简的内核。
生成一个采用多个标量或向量的内核 arguments (至少一个向量参数),执行 map_expr 在向量参数的每一项上,然后 reduce_expr 关于这一结果。 neutral 用作初始值。 preamble 提供了在实际缩减内核代码之前添加预处理器指令和其他代码(如帮助器函数)的可能性。
中的矢量 map_expr 应按变量进行索引 i 。 reduce_expr 使用形式值“a”和“b”表示二进制归约运算的两个操作数。如果您不指定 map_expr ,
in[i]
被自动假定并被视为唯一的一个输入参数。dtype_out 指定
numpy.dtype
其中执行约简并返回结果。 neutral 指定为浮点型或格式化为字符串的整型。 reduce_expr 和 map_expr 被指定为字符串格式的操作,并且 arguments 被指定为格式化为C参数列表的字符串。 name 指定编译内核时使用的名称。 options 原封不动地传递给pyopencl.Program.build()
。 preamble 指定在实际内核之前插入的代码字符串。- __init__(ctx: Context, dtype_out: Any, neutral: str, reduce_expr: str, map_expr: str | None = None, arguments: str | List[DtypedArgument] | None = None, name: str = 'reduce_kernel', options: Any = None, preamble: str = '') None [源代码]#
- __call__(*args: Any, **kwargs: Any) Event [源代码]#
调用生成的内核。
wait_for may either be None or a list of
pyopencl.Event
instances for whose completion this command waits before starting exeuction.使用 out 由此产生的单项
pyopencl.array.Array
可以指定。因为支持偏移量,所以可以将结果存储在任何地方(例如out=a[3]
)。备注
归来的人
pyopencl.Event
仅对应于缩减的部分执行。它不适合用于剖析。在 2011.1 版本加入.
在 2014.2 版本发生变更: 增列 out 参数。
在 2016.2 版本发生变更: range_ 和 slice_ 添加了。
- 参数:
- 返回:
作为单条目的结果标量
pyopencl.array.Array
如果 return_event 是 False ,否则为元组(scalar_array, event)
。
下面是一个用法示例:
a = pyopencl.array.arange(queue, 400, dtype=numpy.float32)
b = pyopencl.array.arange(queue, 400, dtype=numpy.float32)
krnl = ReductionKernel(ctx, numpy.float32, neutral="0",
reduce_expr="a+b", map_expr="x[i]*y[i]",
arguments="__global float *x, __global float *y")
my_dot_prod = krnl(a, b).get()
前缀和(“扫描”)#
前缀和是数组的运行和,例如。 numpy.cumsum()
::
>>> import numpy as np
>>> a = [1,1,1,1,1,2,2,2,2,2]
>>> np.cumsum(a)
array([ 1, 2, 3, 4, 5, 7, 9, 11, 13, 15])
这是一个非常简单的扫描示例。结果表明,扫描的功能明显更为广泛。它们是许多非平凡并行算法的基本构造块。由于循环携带的依赖关系,许多由扫描启用的操作似乎很难并行化。
参见
- Prefix sums and their applications 作者:Guy Blelloch。
本文概述了一些令人惊讶的扫描应用。
- 简单/传统界面
这些内置到PyOpenCL中的操作是通过
GenericScanKernel
.
使用示例#
此示例演示了的简化版本的实现 pyopencl.algorithm.copy_if()
,如果整数大于300,则将其从数组复制到(可变大小)输出:
knl = GenericScanKernel(
ctx, np.int32,
arguments="__global int *ary, __global int *out",
input_expr="(ary[i] > 300) ? 1 : 0",
scan_expr="a+b", neutral="0",
output_statement="""
if (prev_item != item) out[item-1] = ary[i];
""")
out = a.copy()
knl(a, out)
a_host = a.get()
out_host = a_host[a_host > 300]
assert (out_host == out.get()[:len(out_host)]).all()
被扫描的值是指示每个数组元素是否大于300的多个标志。这些标志由以下公式计算 input_expr 。此数组上的前缀sum给出了大于300的数组项的运行计数。这个 output_statement 比较 prev_item
(上一项的扫描结果,即索引)至 item
(当前项目的扫描结果,即索引)。如果它们不同,即如果谓词在此位置得到满足,则该项将存储在输出中的计算索引处。
此示例没有使用PyOpenCL中也提供的以下高级功能:
分段扫描
访问中的上一项 input_expr (例如,用于比较)请参阅 implementation 的
pyopencl.algorithm.unique()
举个例子。
定制扫描内核#
在 2013.1 版本加入.
- class pyopencl.scan.GenericScanKernel(ctx: Context, dtype: Any, arguments: str | List[DtypedArgument], input_expr: str, scan_expr: str, neutral: str | None, output_statement: str, is_segment_start_expr: str | None = None, input_fetch_exprs: List[Tuple[str, str, int]] | None = None, index_dtype: Any = None, name_prefix: str = 'scan', options: Any = None, preamble: str = '', devices: Device | None = None)[源代码]#
生成并执行对任意类型执行前缀求和(“扫描”)的代码,并进行许多可能的调整。
使用示例::
from pyopencl.scan import GenericScanKernel knl = GenericScanKernel( context, np.int32, arguments="__global int *ary", input_expr="ary[i]", scan_expr="a+b", neutral="0", output_statement="ary[i+1] = item;") a = cl.array.arange(queue, 10000, dtype=np.int32) knl(a, queue=queue)
- __init__(ctx: Context, dtype: Any, arguments: str | List[DtypedArgument], input_expr: str, scan_expr: str, neutral: str | None, output_statement: str, is_segment_start_expr: str | None = None, input_fetch_exprs: List[Tuple[str, str, int]] | None = None, index_dtype: Any = None, name_prefix: str = 'scan', options: Any = None, preamble: str = '', devices: Device | None = None) None [源代码]#
- 参数:
ctx -- 一个
pyopencl.Context
在其中将生成用于该扫描内核的代码。dtype -- 这个
numpy.dtype
将用它来执行扫描。可以是结构化类型,如果该类型是通过pyopencl.tools.get_or_register_dtype()
。arguments -- 逗号分隔的C参数声明字符串。如果 arguments 是指定的,则 input_expr 还必须指定。此处使用的所有类型必须为PyOpenCL所知。(见
pyopencl.tools.get_or_register_dtype()
)。scan_expr -- 执行扫描的关联二进制操作,表示为C字符串。它的两个论点如下所示
a
和b
当它被评估时。b
被保证为“正在更新的元素”,并且a
是增量。因此,如果某些数据应该只是传播而不被扫描修改,那么它应该驻留在b
。此表达式可以调用 preamble 。此表达式的另一个可用值为across_seg_boundary
、A、C bool 指示此扫描更新是否正在跨越段边界,如is_segment_start_expr
。扫描例程本身并不实现分段语义。它依赖于scan_expr
来做这件事。该值可用(但始终可用false
),即使对于非分段扫描也是如此。。。注意:在分段扫描的早期预发布中,实现了分段语义 without 依赖于scan_expr
。input_expr -- 编码为字符串的C表达式,生成要应用扫描的值。这可用于将映射应用于存储在中的值 arguments 在被扫描之前。此表达式的结果必须匹配 dtype 。要映射的索引可通过以下方式获得
i
在这个表达中。此表达式还可以使用定义的变量 input_fetch_expr 。此表达式还可以调用 preamble 。output_statement -- 写入扫描输出的C语句。它可以通过以下方式访问扫描结果
item
,前面的扫描结果项为prev_item
,当前索引为i
。prev_item
在分段扫描中,将是分段边界处的中性元素,而不是紧随其后的项目。vbl.使用 prev_item In OUTPUT语句的运行时开销很小。prev_item
允许构建独占扫描。对于非分段扫描, output_statement 也可以参考last_item
,其计算结果为最后一个数组条目的扫描结果。is_segment_start_expr -- 编码为字符串的C表达式,结果是C
bool
值,该值确定新的扫描段是否从索引开始 i 。如果给定,则使扫描成为分段扫描。有权访问当前索引i
,结果是 input_expr ASa
,此外还可以使用 arguments 和 input_fetch_expr 变量就像 input_expr 。如果返回TRUE,则以前的总和不会溢出到带有索引的项中 i 或随后的物品。input_fetch_exprs -- 元组列表 (NAME, ARG_NAME, OFFSET) 。此处的条目的效果相当于在INPUT_EXPR::ARG_NAME_TYPE NAME=ARG_NAME之前执行以下操作 [i+OFFSET] ;
OFFSET
允许为0或-1,并且ARG_NAME_TYPE
是一种ARG_NAME
。preamble -- A snippet of C that is inserted into the compiled kernel before the actual kernel function. May be used for, e.g. type definitions or include statements.
参数列表中的第一个数组确定在其上执行扫描的索引空间的大小,从而确定在其上执行索引的值 i 在上述参数中出现的多个代码片段将有所不同。
所有代码段还可以访问N,即扫描中处理的元素的数量。
- __call__(*args: Any, **kwargs: Any) Event [源代码]#
Returns a new
pyopencl.Event
. wait_for may either be None or a list ofpyopencl.Event
instances for whose completion this command waits before starting exeuction.备注
归来的人
pyopencl.Event
仅对应于扫描执行的一部分。它不适合用于剖析。- 参数:
queue -- 要对其执行扫描的队列。如果未给出,则第一个
pyopencl.array.Array
在……里面 args 使用的是allocator -- 临时数组和结果的分配器。如果未给出,则第一个
pyopencl.array.Array
在……里面 args 使用的是。size -- 指定要执行的扫描的长度。如果未指定,则从第一个参数推断此长度
wait_for -- 一个
list
需要等待的事件。
调试辅助工具#
- class pyopencl.scan.GenericDebugScanKernel(ctx: Context, dtype: Any, arguments: str | List[DtypedArgument], input_expr: str, scan_expr: str, neutral: str | None, output_statement: str, is_segment_start_expr: str | None = None, input_fetch_exprs: List[Tuple[str, str, int]] | None = None, index_dtype: Any = None, name_prefix: str = 'scan', options: Any = None, preamble: str = '', devices: Device | None = None)[源代码]#
执行相同的功能,并具有与相同的接口
GenericScanKernel
,但使用非常简单的顺序扫描。在CPU平台上工作得最好,并通过消除并行执行中可能产生的问题来帮助隔离扫描中的错误。
简单/传统界面#
- class pyopencl.scan.ExclusiveScanKernel(ctx, dtype, scan_expr, neutral, name_prefix='scan', options=[], preamble='', devices=None)[源代码]#
生成一个可以计算 prefix sum 使用给出的任何关联运算 scan_expr 。 scan_expr 使用形式值“a”和“b”表示关联二进制运算的两个操作数。 neutral 是的中性元素 scan_expr ,服从 scan_expr(a, neutral) == a 。
D型 指定要操作的数组的类型。 name_prefix 用于内核名称,以确保配置文件和日志中的可识别性。 选项 是生成时要使用的编译器选项的列表。 序言 指定在实际内核之前插入的代码字符串。 设备 可用于限制内核要在其上运行的设备集。(默认为上下文中的所有设备) ctx .
- class pyopencl.scan.InclusiveScanKernel(ctx, dtype, scan_expr, neutral=None, name_prefix='scan', options=[], preamble='', devices=None)[源代码]#
作品像
ExclusiveScanKernel
.在 2013.1 版本发生变更: 中立的 现在总是需要。
对于阵列 [1, 2, 3]
,包含扫描结果为 [1, 3, 6]
,并且独占扫描将导致 [0, 1, 3]
。
下面是一个用法示例:
knl = InclusiveScanKernel(context, np.int32, "a+b")
n = 2**20-2**18+5
rng = np.random.default_rng(seed=42)
host_data = rng.integers(0, 10, size=n, dtype=np.int32)
dev_data = cl_array.to_device(queue, host_data)
knl(dev_data)
assert (dev_data.get() == np.cumsum(host_data, axis=0)).all()
谓词副本(“partition”,“unique”,…)#
- pyopencl.algorithm.copy_if(ary, predicate, extra_args=None, preamble='', queue=None, wait_for=None)[源代码]#
复制的元素 ary 满足感 predicate 转换为输出数组。
- 参数:
predicate -- A C表达式求值为
bool
,表示为字符串。要测试的值如下所示ary[i]
,并且如果该表达式的计算结果为true
,则该值最终显示在输出中。extra_args -- a list of tuples (name, value) specifying extra arguments to pass to the scan procedure. For version 2013.1, value must be a of a
numpy
sized scalar type. As of version 2013.2, value may also be apyopencl.array.Array
.preamble -- A snippet of C that is inserted into the compiled kernel before the actual kernel function. May be used for, e.g. type definitions or include statements.
wait_for -- wait_for may either be None or a list of
pyopencl.Event
instances for whose completion this command waits before starting exeuction.
- 返回:
元组 (out, count, event) 哪里 out 是输出数组, count 是设备上标量(使用读取到主机
count.get()
)表示满足多少个元素 predicate ,以及 event 是一种pyopencl.Event
用于依赖关系管理。 out 被分配的长度与 ary ,但只有第一个 count 条目具有意义。
在 2013.1 版本加入.
- pyopencl.algorithm.remove_if(ary, predicate, extra_args=None, preamble='', queue=None, wait_for=None)[源代码]#
复制的元素 ary 不令人满意 predicate 转换为输出数组。
- 参数:
predicate -- A C表达式求值为
bool
,表示为字符串。要测试的值如下所示ary[i]
,并且如果该表达式的计算结果为false
,则该值最终显示在输出中。extra_args -- a list of tuples (name, value) specifying extra arguments to pass to the scan procedure. For version 2013.1, value must be a of a
numpy
sized scalar type. As of version 2013.2, value may also be apyopencl.array.Array
.preamble -- A snippet of C that is inserted into the compiled kernel before the actual kernel function. May be used for, e.g. type definitions or include statements.
wait_for -- wait_for may either be None or a list of
pyopencl.Event
instances for whose completion this command waits before starting exeuction.
- 返回:
元组 (out, count, event) 哪里 out 是输出数组, count 是设备上标量(使用读取到主机
count.get()
)表示有多少元素不满足 predicate ,以及 event 是一种pyopencl.Event
用于依赖关系管理。
在 2013.1 版本加入.
- pyopencl.algorithm.partition(ary, predicate, extra_args=None, preamble='', queue=None, wait_for=None)[源代码]#
复制的元素 ary 两个数组中的一个,具体取决于它们是否满足 predicate 。
- 参数:
predicate -- A C表达式求值为
bool
,表示为字符串。要测试的值如下所示ary[i]
。extra_args -- a list of tuples (name, value) specifying extra arguments to pass to the scan procedure. For version 2013.1, value must be a of a
numpy
sized scalar type. As of version 2013.2, value may also be apyopencl.array.Array
.preamble -- A snippet of C that is inserted into the compiled kernel before the actual kernel function. May be used for, e.g. type definitions or include statements.
wait_for -- wait_for may either be None or a list of
pyopencl.Event
instances for whose completion this command waits before starting exeuction.
- 返回:
元组 (out_true, out_false, count, event) 哪里 count 是设备上标量(使用读取到主机
count.get()
)表示有多少元素满足该谓词,以及 event 是一种pyopencl.Event
用于依赖关系管理。
在 2013.1 版本加入.
- pyopencl.algorithm.unique(ary, is_equal_expr='a == b', extra_args=None, preamble='', queue=None, wait_for=None)[源代码]#
复制的元素 ary 输入到输出中,如果 is_equal_expr 应用于数组元素及其前置元素,则会生成FALSE。
工作方式类似于Unix命令 uniq ,具有潜在的自定义比较。此操作通常用于已排序的序列。
- 参数:
is_equal_expr -- A C表达式求值为
bool
,表示为字符串。被比较的元素如下所示a
和b
。如果此表达式产生false
,这两者被认为是截然不同的。extra_args -- a list of tuples (name, value) specifying extra arguments to pass to the scan procedure. For version 2013.1, value must be a of a
numpy
sized scalar type. As of version 2013.2, value may also be apyopencl.array.Array
.preamble -- A snippet of C that is inserted into the compiled kernel before the actual kernel function. May be used for, e.g. type definitions or include statements.
wait_for -- wait_for may either be None or a list of
pyopencl.Event
instances for whose completion this command waits before starting exeuction.
- 返回:
元组 (out, count, event) 哪里 out 是输出数组, count 是设备上标量(使用读取到主机
count.get()
)表示有多少元素满足该谓词,以及 event 是一种pyopencl.Event
用于依赖关系管理。
在 2013.1 版本加入.
排序(基数排序)#
- class pyopencl.algorithm.RadixSort(context, arguments, key_expr, sort_arg_names, bits_at_a_time=2, index_dtype=<class 'numpy.int32'>, key_dtype=<class 'numpy.uint32'>, scan_kernel=<class 'pyopencl.scan.GenericScanKernel'>, options=None)[源代码]#
提供了一个通用的 radix sort 在计算设备上。
在 2013.1 版本加入.
- __call__(*args, **kwargs)[源代码]#
运行基数排序。除了……之外 args 它必须与 arguments 规范,则支持以下关键字参数:
- 参数:
key_bits -- 指定密钥中有多少位(从最低有效位开始)。
allocator -- 请参阅 allocator 的论点
pyopencl.array.empty()
。queue -- A
pyopencl.CommandQueue
,默认为第一个参数数组中的一个。wait_for -- wait_for may either be None or a list of
pyopencl.Event
instances for whose completion this command waits before starting exeuction.
- 返回:
元组
(sorted, event)
。 sorted 中命名的数组的排序副本 sorted_args ,按照该列表的顺序。 event 是一种pyopencl.Event
用于依赖关系管理。
构建许多可变大小的列表#
- class pyopencl.algorithm.ListOfListsBuilder(context, list_names_and_dtypes, generate_template, arg_decls, count_sharing=None, devices=None, name_prefix='plb_build_list', options=None, preamble='', debug=False, complex_kernel=False, eliminate_empty_output_lists=False)[源代码]#
简单地生成并执行代码以生成大量可变大小的列表。
备注
此功能是作为预览提供的。在本通知被删除之前,其界面可能会更改。
在 2013.1 版本加入.
下面是一个用法示例:
from pyopencl.algorithm import ListOfListsBuilder builder = ListOfListsBuilder(context, [("mylist", np.int32)], """ void generate(LIST_ARG_DECL USER_ARG_DECL index_type i) { int count = i % 4; for (int j = 0; j < count; ++j) { APPEND_mylist(count); } } """, arg_decls=[]) result, event = builder(queue, 2000) inf = result["mylist"] assert inf.count == 3000 assert (inf.list.get()[-6:] == [1, 2, 2, 3, 3, 3]).all()
该功能
generate
为每个“输入对象”调用一次。然后,每个输入对象可以生成零个或多个列表条目。这些输入对象的数量被给定给__call__()
AS n_objects 。列表条目是通过调用APPEND_<list name>(value)
。可以一次生成多个列表。- __init__(context, list_names_and_dtypes, generate_template, arg_decls, count_sharing=None, devices=None, name_prefix='plb_build_list', options=None, preamble='', debug=False, complex_kernel=False, eliminate_empty_output_lists=False)[源代码]#
- 参数:
context -- A
pyopencl.Context
。list_names_and_dtypes -- 一份名单
(name, dtype)
指示要构建的列表的元组。generate_template -- 如下所述的C代码片段
arg_decls -- 逗号分隔的C参数声明字符串。
count_sharing -- 由以下内容组成的映射
(child, mother)
这表明mother
和child
将始终具有相同数量的索引,并且APPEND
至mother
总是会发生的 before 这个APPEND
对孩子来说。name_prefix -- 用于编译内核的名称前缀
options -- 使用内核的OpenCL编译选项 generate_template 。
complex_kernel -- 如果 True ,防止CPU上的矢量化。
eliminate_empty_output_lists -- 消除了空输出列表的列表名的Python列表。
generate_template 可以使用以下C宏/标识:
index_type
:展开为用于计算的索引类型的C标识符USER_ARG_DECL
: expands to the C declarator forarg_decls
USER_ARGS
: a list of C argument values corresponding touser_arg_decl
LIST_ARG_DECL
:展开为C参数列表,表示输出列表的数据。这些字符的前缀为转义"plg_"
以便不会干扰用户提供的名称。LIST_ARGS
: a list of C argument values corresponding toLIST_ARG_DECL
APPEND_name(entry)
:插页entry
进入名单name
。 entry 必须是正确类型的有效C表达式。
所有与参数列表相关的宏都有一个尾随逗号,如果它们是非空的。
generate_template 必须提供一个函数:
void generate(USER_ARG_DECL LIST_ARG_DECL index_type i) { APPEND_mylist(5); }
在内部,
kernel_template
被扩展(至少)两次。一次用于确定所有列表的大小的“计数”阶段,第二次用于实际填充列表的“生成”阶段。一个generate
具有超出调用的副作用的函数append
因此是不完善的。在 2018.1 版本发生变更: 变化 eliminate_empty_output_lists 参数类型来自
bool
至list
。
- __call__(queue, n_objects, *args, **kwargs)[源代码]#
- 参数:
args -- 与以下内容对应的参数
arg_decls
在构造函数中。类似数组的参数必须是1Dpyopencl.array.Array
对象或pyopencl.MemoryObject
对象,其中后者可以从pyopencl.array.Array
使用pyopencl.array.Array.data
属性。allocator -- 可选)用于分配新数组的分配器。
omit_lists -- 列表名称的可迭代,应为 not 将使用此调用进行构建。内核代码可以 not 打电话
APPEND_name
对于这些遗漏的名单。如果是这样的话,将导致未定义的行为。归来的人 lists 词典将不包含以下名称的条目 omit_lists 。wait_for -- wait_for may either be None or a list of
pyopencl.Event
instances for whose completion this command waits before starting exeuction.
- 返回:
元组
(lists, event)
,在哪里lists
是从(构建的)列表名称到具有属性的对象的映射 *count
for the total number of entries in all lists combined *lists
用于包含所有列表的数组。 *starts
for the array of starting indices inlists
.starts
is built so that it has n+1 entries, so that the * 我 *'th entry is the start of the * 我 *'th list, and the * 我 *'th entry is the index one past the * 我 *'th list's end, even for the last list. This implies that all lists are contiguous. If the list name is specified in * eliminate_empty_output_lists * constructor argument, * 列表 * has two additional attributesnum_nonempty_lists
andnonempty_indices
*num_nonempty_lists
用于非空列表数。 *nonempty_indices
for the index of nonempty list in input objects. In this case,starts
hasnum_nonempty_lists + 1
entries. The * 我 *'s entry is the start of the * 我 *'th nonempty list, which is generated by the object with indexnonempty_indices[i]
. * 活动*是一项pyopencl.Event
用于依赖关系管理。
在 2016.2 版本发生变更: 添加了省略列表。
双调排序#
- class pyopencl.bitonic_sort.BitonicSort(context)[源代码]#
使用排序网络对数组(或一个数组的一个轴)进行排序。
仅当要排序的数组的轴的长度是2的幂时才起作用。
在 2015.2 版本加入.
- __call__(arr, idx=None, queue=None, wait_for=None, axis=0)[源代码]#
- 参数:
arr -- 要排序的数组。将被排序的数组覆盖。
idx -- 要跟踪的索引数组以及 arr
queue -- 一个
pyopencl.CommandQueue
,如果没有,则默认为数组的队列wait_for -- 一份名单
pyopencl.Event
实例或无axis -- 用于排序的数组的轴
- 返回:
一个tuple(排序数组,事件)