【问题标题】:How do get to the bottom with a OpenCL kernel build error using Cloo with .NET?如何使用 Cloo 和 .NET 解决 OpenCL 内核构建错误?
【发布时间】:2017-12-26 17:18:51
【问题描述】:

我目前正在使用 VS2013。我创建了一个非常简单的 C# 解决方案,旨在将 Cloo 与一个简单的类一起使用:

    using System;
using System.Collections.Concurrent;
using System.Threading.Tasks;
using System.IO;
using Cloo;

namespace ClooTest
{
    class Test
    {
        public static void main_entry(byte[] args)
        {
            ComputePlatform platform = ComputePlatform.Platforms[0];

            ComputeContext context = new ComputeContext(ComputeDeviceTypes.Gpu,
            new ComputeContextPropertyList(platform), null, IntPtr.Zero);

            ComputeCommandQueue queue = new ComputeCommandQueue(context,
            context.Devices[0], ComputeCommandQueueFlags.None);

            // get and build the source code
            ComputeProgram program = new ComputeProgram(context, new string[] { kernelCode });
            program.Build(null, null, null, IntPtr.Zero);

            // pick the fucntion
            ComputeKernel kernel = program.CreateKernel("add_data");

            // create a ten integer array and its length
            byte[] data1 = new byte[] { 1, 2, 3, 4, 5 };
            byte[] data2 = new byte[] { 1, 2, 3, 4, 5 };
            int size = data1.Length;

            /* allocate memory */
            ComputeBuffer<byte> data1buffer = new ComputeBuffer<byte>(context,
            ComputeMemoryFlags.ReadWrite, data1);

            ComputeBuffer<byte> data2buffer = new ComputeBuffer<byte>(context,
            ComputeMemoryFlags.ReadWrite, data2);

            kernel.SetMemoryArgument(0, data1buffer); // set the byte array
            kernel.SetMemoryArgument(1, data2buffer); // set the byte array
            kernel.SetValueArgument(2, size); // set third argument as size;

            // execute
            queue.ExecuteTask(kernel, null);

            // wait for completion
            queue.Finish();

            // output results
            for (int i = 0; i < size; i++)
                Console.WriteLine(data1[i].ToString());
        }
        #region Kernels
        private static string kernelCode = @"__kernel void add_data(__local char* data1, __local char* data2, __local int n)
                        {
                            data1[0]=data1[0]+data2[0];
                        }";

        #endregion

    }
}

虽然我在 Visual Studio 中构建解决方案没有任何问题,但我不断收到“检测到 OpenCL 错误代码:BuildProgramFailure”。尝试使用“program.Build(null, null, null, IntPtr.Zero)”构建程序时。内核代码看起来不错,但我已经在这工作了几个晚上,似乎无法弄清楚发生了什么。你可能会说我对 Cloo 很陌生,我从网上的例子中得到了一些想法,但我可能在一个非常简单的层面上做错了。任何建议都会很棒。

我已经为我的显卡下载了所有最新的 OpenCL 驱动程序。

谢谢

【问题讨论】:

    标签: c# opencl cloo


    【解决方案1】:

    您应该检查来自program.Build 的错误返回代码(如果它返回一个;我不知道您的框架包装了 OpenCL API)。

    要获取有关构建失败原因的更多详细信息,您需要调用您的框架在clGetProgramBuildInfo 周围放置的任何内容,并将cl_program_build_info 参数设置为CL_PROGRAM_BUILD_LOG。这将告诉你编译错误是什么以及它发生在哪一行。

    只是猜测错误:

    1. 我觉得__local int n 不对,应该是int n

    2. 我也不认为__local char* data1, __local char* data2 是正确的;这些应该是__global char* data1, __global char* data2(本地内存是一个高级主题)。

    【讨论】:

    • 我尝试将内核函数剥离为一个简单的 int add_data(){ return 0; } 仍然没有喜悦。
    【解决方案2】:

    要获取特定的内核错误,您应该尝试捕获 program.Build 并调用 GetBuildLog。 像这样的:

    try{
       program.Build(null, null, null, IntPtr.Zero);
    }
    catch (Exception ex)
    {
       String buildLog = program.GetBuildLog(context.Devices[0]);
       Console.WriteLine("\n********** Build Log **********\n" + buildLog + "\n*************************");
    }
    

    【讨论】:

      猜你喜欢
      • 2017-11-25
      • 2019-03-02
      • 2016-07-17
      • 1970-01-01
      • 2014-03-24
      • 2013-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多