对于OpenCL中的不同内核/程序,缓冲区的设备地址是否相同

时间:2014-10-10 16:28:03

标签: opencl pyopencl

当将缓冲区作为参数传递给OpenCL内核时,内核代码看到的缓冲区地址是否会对同一个缓冲区保持相同?

我使用下面的代码进行检查,看起来地址确实相同。但是,我无法在标准中找到任何保证这一点。

import pyopencl as cl
import numpy as np

def main():
    ctx = cl.create_some_context()
    queue = cl.CommandQueue(ctx)
    mf = cl.mem_flags
    buf = cl.Buffer(ctx, mf.READ_ONLY, 1000)
    buf2 = cl.Buffer(ctx, mf.READ_WRITE, 8)
    prg = cl.Program(ctx, """
    __kernel void
    get_addr(__global const int *in, __global long *out)
    {
        *out = (long)in;
    }
    """).build()

    knl = prg.get_addr
    knl.set_args(buf, buf2)
    cl.enqueue_task(queue, knl)

    b = np.empty([1], dtype=np.int64)
    cl.enqueue_copy(queue, b, buf2).wait()
    print(b[0])

    prg = cl.Program(ctx, """
    __kernel void
    get_addr(__global const int *in, __global long *out)
    {
        *out = (long)in;
    }
    """).build()
    knl = prg.get_addr
    knl.set_args(buf, buf2)
    cl.enqueue_task(queue, knl)

    b = np.empty([1], dtype=np.int64)
    cl.enqueue_copy(queue, b, buf2).wait()
    print(b[0])

if __name__ == '__main__':
    main()

用例是我使用OpenCL运行模拟,OpenCL有许多(数组)参数。为了不必将这些数组作为参数传递,我将它们填入结构中并将指针传递给结构。由于这个结构将被多次使用(并且被所有工作项使用),我不希望在每个内核的每次运行中都填写它,并且想知道指针是否会在不同的运行/工作项之间发生变化。

1 个答案:

答案 0 :(得分:1)

OpenCL 1.x无法保证。这就是将指针存储在缓冲区中不安全的原因。允许运行时为每次内核启动移动分配。不能保证它会移动它,当然可以合理地预期缓冲区通常不需要移动,所以你看到你看到的结果并不令人惊讶。如果你分配了更多的缓冲区并循环遍历它们以强制运行时移动它们,你将更有可能看到这个问题。

对于OpenCL 2.0,共享虚拟内存功能保证了这一点:如果地址不断变化,地址将无法共享。