我正在使用 Luis Cabellos 的 System.GPU.OpenCL 模块来控制 OpenCL 内核。
一切正常,但为了加快速度,我试图将一些全局内存缓存到本地缓冲区中。我刚刚注意到似乎不可能使用 clSetKernelArg 的当前定义传递本地缓冲区,但也许有人可以启发我?

定义是,

clSetKernelArg :: Storable a => CLKernel -> CLuint -> a -> IO ()
clSetKernelArg krn idx val = with val $ \pval -> do
  whenSuccess (raw_clSetKernelArg krn idx (fromIntegral . sizeOf $ val) (castPtr pval))
    $ return ()

其中原始函数定义为,
foreign import CALLCONV "clSetKernelArg" raw_clSetKernelArg ::
  CLKernel -> CLuint -> CSize -> Ptr () -> IO CLint

因此,高级 clSetKernelArg 可以方便地计算出内存的大小并提取指向它的指针。这对于全局内存来说是完美的,但似乎在请求本地内存时使用 clSetKernelArg 的方法是在 CSize 中指定所需内存的大小,并将 Ptr 设置为零。当然,把 nullPtr 放在这里是不行的,那么我该如何规避这个问题呢?我会直接调用 raw_clSetKernelArg ,但它似乎不是由模块导出的。

谢谢。

最佳答案

我认为没有任何方法可以进行黑客攻击,使 pval 最终成为 nullPtr

这似乎是封装 API 中的一个相当简单的遗漏;我建议简单地使用 reporting it 而不是试图破解它:)

10-08 12:35