我正在使用 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 而不是试图破解它:)