【问题标题】:image2d_t corrupted when passing to OpenCL kernel传递给 OpenCL 内核时 image2d_t 损坏
【发布时间】:2012-11-30 03:39:10
【问题描述】:

我正在用 Haskell 和 OpenCL 编写路径跟踪器,但在将 image2d_t 传递到内核以将输出写入到时遇到问题。也就是说,在 image2d_t 上调用 OpenCL 中的任何 get_image_* 函数都会返回无意义的值(通常是 0 或 2^24-1),而 write_imagef 什么也不做。这只发生在 GPU 上运行时——CPU 运行良好。在主机上调用clGetImageInfo 会返回正确的值。 OpenCL 的 Haskell 绑定将错误代码转换为异常,因此不必忘记检查错误。 clinfo 将我的版本报告为“OpenCL 1.2 AMD-APP (1084.2)”。我应该注意到我遇到(并报告)了多个导致 OpenCL 编译器出现段错误或无法链接的错误,所以这可能是我的代码中的错误而不是错误的结果。

我这样初始化 OpenCL(希望对不了解 Haskell 的人来说应该比较容易理解):

(platform:_) <- clGetPlatformIDs
(device:_) <- clGetDeviceIDs platform CL_DEVICE_TYPE_GPU
glContext <- glXGetCurrentContext
glDisplay <- glXGetCurrentDisplay
context <- clCreateContext [CL_GL_CONTEXT_KHR glContext, CL_GLX_DISPLAY_KHR glDisplay] [device] putStrLn
queue <- clCreateCommandQueue context device []
source <- readFile "pt.cl"
program <- clCreateProgramWithSource context source
clBuildProgram program [device] "-cl-strict-aliasing"
        `catch` (λe -> case (e :: CLError) of
                            CL_BUILD_PROGRAM_FAILURE -> putStrLn "Building OpenCL program failed:"
                                                     >> clGetProgramBuildLog program device >>= putStrLn
                                                     >> throw e
                            _                        -> return ())
kernel <- clCreateKernel program "sample"
pCorners <- mallocArray 4
buffer <- clCreateBuffer context [CL_MEM_READ_ONLY, CL_MEM_USE_HOST_PTR] (4*sizeOf (undefined :: V.Vec4F), castPtr pCorners)
clSetKernelArgSto kernel 1 buffer
tex@(TextureObject texid) <- head <$> (genObjectNames 1)
activeTexture $= TextureUnit 0
textureBinding Texture2D $= Just tex
textureFilter Texture2D $= ((Nearest, Nothing), Nearest)
textureWrapMode Texture2D S $= (Repeated, Clamp)
textureWrapMode Texture2D T $= (Repeated, Clamp)
texImage2D Nothing NoProxy 0 RGBA′ (TextureSize2D initialWidth initialHeight) 0 (PixelData RGBA UnsignedByte nullPtr)
image <- clCreateFromGLTexture2D context [CL_MEM_READ_WRITE] gl_TEXTURE_2D 0 texid
clSetKernelArgSto kernel 2 image

我称之为(稍微简化)运行内核并渲染结果:

clSetKernelArgSto kernel 0 position
pokeArray pCorners orientedCorners -- update the pCorners array
finish -- This is glFinish()
clEnqueueAcquireGLObjects queue [image] []
clEnqueueNDRangeKernel queue kernel [width, height] [] []
clEnqueueReleaseGLObjects queue [image] []
clFinish queue
drawElements TriangleFan 4 UnsignedInt offset0
swapBuffers

最后是测试内核:

__kernel void sample(float3 position, __constant float3 corner[4], image2d_t output) {
        write_imagef(output, (int2)(get_global_id(0), get_global_id(1)), (float4)(0, 0.5f, 1, 1));
}

它的输出是一个全屏四边形,显示 GPU 内存的一个随机未初始化区域。它应该是全屏青色四边形。我有一些printfs 在那里显示get_image_* 函数的结果,但它们已经开始导致程序挂起。

【问题讨论】:

    标签: opengl haskell opencl


    【解决方案1】:

    OpenCL 规范对此有规定 - image2d_t 对象需要访问限定符。

    有两个这样的限定词:

    • read_only(或__read_only
    • write_only(或__write_only

    它们是互斥的,不能一起使用(因此您不能同时读取和写入纹理 - 如果您打算对图像进行累积工作,这一点很重要,我怀疑这是Monte-Carlo 应用程序,例如路径跟踪)。省略限定符是有效的,因为它只是默认为read_only,但不幸的是,这是输出图像的错误选择。

    解决方案是使用write_only 限定您的图像参数,或者如果您也需要从中读取,请使用某种交换系统(或使用可以在同时,但这会使 CL/GL 互操作更加困难,并且您会丢失采样功能...)。

    我认为它在 CPU 上工作的原因是,因为在 CPU 上没有只读的“纹理内存”,所以即使写入图像在技术上是非法的,它也是可能的,运行时允许你这样做它。另一方面,GPU 确实具有只读内存部分,无论您如何努力(或者您的 GPU 设备的运行时间可能更严格),都无法在内核运行时写入这些部分。

    *当我说运行时,我指的是支持 OpenCL 的设备,当然不是你的程序。

    【讨论】:

    • 谢谢你,我现在添加了一个 __write_only 限定符。不幸的是,这并没有什么不同。
    • @klkblake 该死,这很奇怪。那肯定还有什么问题。您的 GPU 平台/设备/驱动程序是什么?老实说,我也遇到过 GPU 内核的暂时性问题,从一个驱动程序版本到另一个版本,它们会突然无缘无故地失败。
    • 我在 5400 系列中使用移动 radeon(我不知道确切的型号)。我在 linux 上使用 12.11 beta 驱动程序,其中捆绑了最新的 APP sdk。正如我提到的,我在构建内核时遇到了一些段错误(我已向 AMD 报告),我开始认为这可能只是这两个问题背后的一个错误。
    • @klkblake 您是否尝试恢复到某些较旧的驱动程序版本,例如 12.8 或 12.9,并尝试运行代码?如果它有效,那肯定是驱动程序错误。
    • 我现在尝试从 12.6 到现在的每个版本(早期版本与 linux 3.6 不兼容)。 12.10 表现出与当前版本相同的行为。所有其他人都未能运行它 - 段错误或打印“链接失败”。我现在相当确定这是一个驱动程序错误。
    【解决方案2】:

    我遇到了类似的问题。重新排序内核参数后,所有 image2d_t 参数都是第一个参数,它起作用了。特别是调用 get_image_dim 返回了正确的结果。不知道,如果这是一个错误。我的 GPU:ATI Radeon 7950。

    【讨论】:

    • 我在 AMD 上使用 OpenCL 时遇到了其他几个问题,这些问题通过按大小递减顺序排列参数得到了解决,所以我认为它(或者是,我最近没有尝试过)是一个驱动程序错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多