1

有没有办法解决 PyOpenCL 中的限制,即:

array.data

失败了

pyopencl.array.ArrayHasOffsetError:您尝试的操作尚不支持从缓冲区开头偏移的数组。

我试过了:

a.base_data[a.offset: a.offset + a.nbytes]

这似乎有时有效,但其他时候我得到:

pyopencl.LogicError:clCreateSubBuffer 失败:值无效

4

2 回答 2

1

clcreateSubBuffer需要具有origin对齐的偏移量(或者在这种情况下称为 ),并且size+origin必须在缓冲区的范围内。

如果 (origin, size) 指定的区域超出缓冲区的范围,则在 errcode_ret 中返回 CL_INVALID_VALUE。

如果上下文中没有与原始值与 CL_DEVICE_MEM_BASE_ADDR_ALIGN 值对齐的缓冲区关联的设备,则在 errcode_ret 中返回 CL_MISALIGNED_SUB_BUFFER_OFFSET。

对于您看到的特定错误,您的程序或 pyopencl 错误地计算了偏移后数组的大小。即使您解决了这个问题,如果原始偏移量未与CL_DEVICE_MEM_BASE_ADDR_ALIGN.

话虽如此,NVIDIA 似乎打破了规范并允许任意偏移。因此,您的里程可能会因硬件而异。

于 2013-09-03T13:13:21.717 回答
0

如果您只是想获得一个标记数组数据开始的缓冲区,以传递给内核,则不必担心大小。这是一个获取指向偏移数据开始的大小为 1 的缓冲区的函数:

def data_ptr(array):
    if array.offset:
        return array.base_data.get_sub_region(array.offset, 1)
    else:
        return array.data

如果您需要一个指向偏移数据开头的指针,您可以使用它来传递给内核。clV这是一个示例,我想将数组的一个子区域设置clA为值 3。我data_ptr用来获取指向clV数据开头的指针。

import numpy as np
import pyopencl as cl
import pyopencl.array
ctx = cl.create_some_context()
queue = cl.CommandQueue(ctx)

m, n = 5, 5
A = np.random.uniform(size=(m, n)).astype(np.float32)
clA = cl.array.Array(queue, A.shape, A.dtype)
clA.set(A)

clV = clA[1::2, 1::2]

def data(array):
    if array.offset:
        return array.base_data.get_sub_region(array.offset, 1)
    else:
        return array.data

source = """
__kernel void fn(long si, long sj, __global float *Y)
{
    const int i = get_global_id(0);
    const int j = get_global_id(1);
    Y[i*si + j*sj] = 3;
}
"""
kernel = cl.Program(ctx, source).build().fn
gsize = clV.shape
lsize = None

estrides = np.array(clV.strides) / clV.dtype.itemsize
kernel(queue, gsize, lsize, estrides[0], estrides[1], data_ptr(clV))

print(clA.get())
于 2015-09-18T20:26:08.430 回答