【发布时间】:2021-02-18 17:48:19
【问题描述】:
我发现使用 pyopencl.cltypes.float2 之类的 dtypes 同时使用 structs 和 np.ndarrays 非常方便。这是将结构化数据传递给我的内核的一种清晰且自我记录的方式,而不仅仅是一堆浮点数。
但是我发现某些行为不方便。例如给出:
import numpy as np
import pyopencl.cltypes as cltp
a = np.zeros((3,5), dtype=cltp.float2)
>>> a
array([[(0., 0.), (0., 0.), (0., 0.), (0., 0.), (0., 0.)],
[(0., 0.), (0., 0.), (0., 0.), (0., 0.), (0., 0.)],
[(0., 0.), (0., 0.), (0., 0.), (0., 0.), (0., 0.)]],
dtype=[(('x', 's0'), '<f4'), (('y', 's1'), '<f4')])
我可以在将数据结构传递给内核之前零碎地构建我的数据结构,例如
a[:,1] = (42,-42)
>>> a
array([[( 0., 0.), (42., -42.), ( 0., 0.), ( 0., 0.), ( 0., 0.)],
[( 0., 0.), (42., -42.), ( 0., 0.), ( 0., 0.), ( 0., 0.)],
[( 0., 0.), (42., -42.), ( 0., 0.), ( 0., 0.), ( 0., 0.)]],
dtype=[(('x', 's0'), '<f4'), (('y', 's1'), '<f4')])
这很好。但是我也想将一个大小为 2 的数组分配给 float2,但这失败了。
a[:,1] = np.array((42,-42))
ValueError: could not broadcast input array from shape (2) into shape (3)
我不得不这样做
a[:,1]['x'] = 42
a[:,1]['y'] = -42
这行得通,但有点违背了整个事情的目的。
我是否遗漏了一些明显的语法差异,或者这个功能不应该以这种方式使用?
编辑:在我试图展示最小的例子时,我过度简化了问题。 hpaulj 的答案是正确的,因为如果我在 shape=(2,) 上使用显式 dtype=float2,它将被转换为 dtype=float2 的 shape=(1,)。 然而,我的实际问题更笼统,关于如何从说一个数组(shape=(foo,bar,N),dtype=np.float32)变成一个数组(shape=(foo,bar),dtype=cltp.floatN ) N=2,3,4。
刚刚出现的后续问题:是否一定会出现实际副本,还是可以“就地”转换?乍一看,实际的内存布局看起来是兼容的。
【问题讨论】:
-
structured arrays文档页面指向recfunctions包。其中有一个unstructured_to_structured函数。许多recfunctions通过逐个字段复制值来工作。或者,数据作为元组列表提供给结构化 dtype,就像显示数组一样。