【问题标题】:OpenCL Compiler Weird ConditionOpenCL 编译器异常情况
【发布时间】:2015-09-22 06:26:00
【问题描述】:

我是一名从事 OpenCL 的新人。当我尝试编译内核时,我遇到了一些奇怪的问题。

在Nvidia平台上,无论源代码中的什么代码,它总是显示cl_success,并且日志只有“\n”;在Intel平台上,无论源码中什么代码,clBuildProgram返回CL_INVALID_BINARY,clGetProgramBuildInfo with CL_PROGRAM_BUILD_STATUS返回CL_ERROR,看日志没发现错误:

fcl 构建 1 成功。\n fcl 构建 2 成功。\n bcl 构建成功。\n.

由于这是我的第一段复杂的内核代码,我知道它填补了很多错误。但是,这看起来不像是代码错误。为什么编译器会显示一些矛盾的信息?

这是我的代码: 代码很长,我只是发布可能与之相关的部分。 “...”表示跳过的内容。如果需要,请询问其余部分。 DrawProcess.ccp

#include <stdlib.h>
#include "Console.h"
#include "Renderer.h"
#include "Object.h"
#include "TertiaryArithmeticAlgorithms.h"
#define CL_USE_DEPRECATED_OPENCL_2_0_APIS
#if defined(__APPLE__) || defined(__MACOSX)
#include <OpenCL/cl.hpp>
#else
#include <CL/cl.h>
#endif

#include "Camera.h"

cl_command_queue CommandQueue;
cl_mem BufIdx[8];
cl_kernel Rasterization;
bool Initialization()
{
    ConWrite("======== OpenCL Initializing ========\n");
    //
    cl_platform_id ThePlatformID=NULL;
    cl_uint NumPlatforms;
    cl_int status;
    if(CL_INVALID_VALUE==clGetPlatformIDs(NULL,NULL,&NumPlatforms))
    {
        ConWrite("ERROR: Fail to Get the Number of Available Items in Platform List! The Number of Available Items in Platform List Equal to 0 and Platform List is NULL OR Both Platform List and the Exact Number of Items in Platform List are NULL.\n");
        ConWrite("=== OpenCL Initialization Failed! ===\n");
        return 1;
    }
    else
    {
        ConWrite("The Number of Items in Platform List is ");
        ConWrite(&NumPlatforms);
        ConWrite(".\n");
    }

    //
    cl_platform_id *PlatformList;
    if(NumPlatforms>0)
    {
        PlatformList=(cl_platform_id*)malloc(NumPlatforms*sizeof(cl_platform_id));
        if(CL_INVALID_VALUE==clGetPlatformIDs(NumPlatforms,PlatformList,NULL))
        {
            ConWrite("ERROR: Fail to Get the Platform List! The Number of Available Items in Platform List Equal to 0 and Platform List is NULL OR Both Platform List and the Exact Number of Items in Platform List are NULL.\n");
            ConWrite("=== OpenCL Initialization Failed! ===\n");
            return 1;
        }
        else
        {
            ConWrite("Platform List Obtained.\n");
        }
    }
    else
    {
        ConWrite("ERROR: The Number of Available Items in Platform List is not Greater than 0!\n");
        ConWrite("=== OpenCL Initialization Failed! ===\n");
        return 1;
    }
...
    cl_program VertexProgram=clCreateProgramWithSource(Context,1,Cartography,NULL,NULL);
    status=clBuildProgram(VertexProgram,LengthOfDevices/sizeof(cl_device_id*),DeviceList,NULL,NULL,NULL);
    if(CL_SUCCESS==status)
    {
        ConWrite("CODE: CL_SUCCESS. OpenCL Program Built.\n");
    }
    else
    {
        switch(status)
        {
            case CL_INVALID_PROGRAM:
                ConWrite("CODE: CL_INVALID_PROGRAM. ERROR: The Program is an Invalid Program Object!\n");
                break;
            case CL_INVALID_VALUE:
                ConWrite("CODE: CL_INVALID_VALUE. ERROR: Device List is Unavailable and the Number of Devices is Greater Than Zero, OR Device List is NOT NULL and the Number of Devices is Zero, OR the Pointer to Notify is NULL But User Data is NOT NULL!\n");
                break;
            case CL_INVALID_DEVICE:
                ConWrite("CODE: CL_INVALID_DEVICE. ERROR: OpenCL Devices listed in the Device List are NOT in the List of Devices Associated with the Program!\n");
            break;
            case CL_INVALID_BINARY:
            ConWrite("CODE: CL_INVALID_BINARY. ERROR: The Program was Created with Binary and Devices Listed in the Device List do NOT Have a Valid Binary Program!\n");
                break;
            case CL_INVALID_BUILD_OPTIONS:
                ConWrite("CODE: CL_INVALID_BUILD_OPTIONS. ERROR: The Build Options Specified by Options are Invalid!\n");
                break;
            case CL_INVALID_OPERATION:
                ConWrite("CODE: CL_INVALID_OPERATION. ERROR: The Build of the Program Executable for Any of the Devices Listed in the Device List by a Previous Call to the Function for the Program has NOT Completed!\n");
                break;
            //case CL_COMPILER_NOT_AVAILABLE: if program is created with clCreateProgramWithSource and a compiler is not available i.e. CL_DEVICE_COMPILER_AVAILABLE specified in the table of OpenCL Device Queries for clGetDeviceInfo is set to CL_FALSE. 
            //case CL_BUILD_PROGRAM_FAILURE: if there is a failure to build the program executable. This error will be returned if clBuildProgram does not return until the build has completed. 
            //case CL_INVALID_OPERATION: if there are kernel objects attached to program. 
            //case CL_OUT_OF_HOST_MEMORY: if there is a failure to allocate resources required by the OpenCL implementation on the host. 
        }
    }
    cl_build_status *BudStat;
    size_t StatusSize;
    clGetProgramBuildInfo(VertexProgram,DeviceList[0],CL_PROGRAM_BUILD_STATUS,0,NULL,&StatusSize);
    BudStat=(cl_build_status*)malloc(StatusSize);
    clGetProgramBuildInfo(VertexProgram,DeviceList[0],CL_PROGRAM_BUILD_STATUS,StatusSize,BudStat,NULL);
    switch (*BudStat)
    {
    case CL_BUILD_NONE:
        ConWrite("CODE: CL_BUILD_NONE.\n");
        break;
    case CL_BUILD_ERROR:
        ConWrite("CODE: CL_BUILD_ERROR.\n");
        break;
    case CL_BUILD_SUCCESS:
        ConWrite("CODE: CL_BUILD_SUCCESS.\n");
        break;
    case CL_BUILD_IN_PROGRESS:
        ConWrite("CODE: CL_BUILD_IN_PROGRESS.\n");
    default:
        break;
    }

    char *Log;
    size_t LogSize;
      status=clGetProgramBuildInfo(VertexProgram,DeviceList[0],CL_PROGRAM_BUILD_LOG,0,NULL,&LogSize);
    if(status==CL_SUCCESS)
    {
        ConWrite("CODE: CL_SUCCESS. OpenCL Program Build Infomation Obtained.\n");
    }
    else
    {
        switch(status)
        {
            case CL_INVALID_DEVICE:
                ConWrite("CODE: CL_INVALID_DEVICE. ERROR: The Device is NOT in the List of Devices Associated with the Program.\n");
                break;
            case CL_INVALID_VALUE:
                ConWrite("CODE: CL_INVALID_VALUE. ERROR: The Parameter Name is Invalid, OR the Size in Bytes Specified by Parameter's Value Size is Less Than Size of Return Type and Parameter Value is NOT NULL.\n");
                break;
            case CL_INVALID_PROGRAM:
                ConWrite("CODE: CL_INVALID_PROGRAM. ERROR: The Program is an Invalid Program Object.\n");
                break;
        }
    }
    Log=(char*)malloc(LogSize+1);
    Log[LogSize]='0';
    clGetProgramBuildInfo(VertexProgram,DeviceList[0],CL_PROGRAM_BUILD_LOG,LogSize+1,Log,NULL);
    ConWrite(Log);

    Rasterization=clCreateKernel(VertexProgram,"VertexRenderer",NULL);
...

这是我的内核: 渲染器.h

#ifndef _1174_Renderer
#define _1174_Renderer
//------------------------------
const char *Cartography[]=
{
    "#define COUNTER IdxVert\n",
    "__kernel void VertexRenderer(",
    "global float4 CamPos,",                //X coordinate, Y coordinate, Z coordinate, SectorID
    "global float4 CamAng,",                //Horizontal Angle, Vertical Angle, Inclined Angle, Sight Angle
    "global float4 CamNorV1,",              //W represents horizontal resolution.
    "global float4 CamNorV2,",              //W represents vertical resolution.
    "global float4 CamNorV3,",              //W represents diagonal resolution.
    "global float4 *Vertex,",               //
    "global uint IdxVert,",
    "global uchar2 *ScrPos)\n",             //
    "{",
    "   half4 CpToV[COUNTER];",             //CpToV.w is useless.
    "   int GID=(int)get_global_id(0);",
    "   mem_fence(CLK_GLOBAL_MEM_FENCE);",

    "   CpToV[GID].xyz=Vertex[GID].xyz-CamPos.xyz;",
    "   half Distance[COUNTER];",
    "   mem_fence(CLK_GLOBAL_MEM_FENCE);",

    "   Distance[GID]=tan(acos((CamNorV1.x*CpToV[GID].x+CamNorV1.y*CpToV[GID].y+CamNorV1.z*CpToV[GID].z)*rsqrt(CamNorV1.x*CamNorV1.x+CamNorV1.y*CamNorV1.y+CamNorV1.z*CamNorV1.z)*rsqrt(CpToV[GID].x*CpToV[GID].x+CpToV[GID].y*CpToV[GID].y+CpToV[GID].z*CpToV[GID].z)))/tan(CamAng.w)*CamNorV3.w;",
    "   half Scale[COUNTER];",
    "   mem_fence(CLK_GLOBAL_MEM_FENCE);",

    "   Scale[GID]=(CamNorV1.x*CpToV[GID].x+CamNorV1.y*CpToV[GID].y+CamNorV1.z*CpToV[GID].z)/(CamNorV1.x*CamNorV1.x+CamNorV1.y*CamNorV1.y+CamNorV1.z*CamNorV1.z);",
    "   half4 MapVect[COUNTER];",
    "   mem_fence(CLK_GLOBAL_MEM_FENCE);",

    "   MapVect[GID].xyz=CpToV[GID].xyz-Scale*CamNorV1.xyz;",
    "   half Theta1[COUNTER];",
    "   half Theta2[COUNTER];",
    "   mem_fence(CLK_GLOBAL_MEM_FENCE);",

    "   Theta1[GID]=acos((CamNorV2.x*MapVect[GID].x+CamNorV2.y*MapVect[GID].y+CamNorV2.z*MapVect[GID].z)*rsqrt(CamNorV2.x*CamNorV2.x+CamNorV2.y*CamNorV2.y+CamNorV2.z*CamNorV2.z)*rsqrt(MapVect[GID].x*MapVect[GID].x+MapVect[GID].y*MapVect[GID].y+MapVect[GID].z*MapVect[GID].z));",
    "   Theta2[GID]=acos((CamNorV3.x*MapVect[GID].x+CamNorV3.y*MapVect[GID].y+CamNorV3.z*MapVect[GID].z)*rsqrt(CamNorV3.x*CamNorV3.x+CamNorV3.y*CamNorV3.y+CamNorV3.z*CamNorV3.z)*rsqrt(MapVect[GID].x*MapVect[GID].x+MapVect[GID].y*MapVect[GID].y+MapVect[GID].z*MapVect[GID].z));",
    "   half Theta[COUNTER];",
    "   constant half Pi=(half)3.1415926f;",
    "   mem_fence(CLK_GLOBAL_MEM_FENCE);",

    "   (Theta1[GID]<=Pi/2)?(Theta[GID]=Theta2[GID]):(Theta[GID]=2*Pi-Theta2[GID]);",
    "   mem_fence(CLK_GLOBAL_MEM_FENCE);",

    "   ScrPos[GID].x=(uchar)cos(Theta[GID])*Distance[GID]+CamNorV1.w;",
    "   ScrPos[GID].y=(uchar)sin(Theta[GID])*Distance[GID]+CamNorV2.w;",
    "}"



    "#define COUNTER Dlt\n",
    "__kernel void Polarization(",
    "global float4 *NmVect,",
    "global float4 *AllVert,",
    "global ushort4 *DltIdx,",      //W represents the index of planar vectors of primarch.
    "global uint Dlt)\n",
    "{",
    "   int GID=(int)get_global_id(0);",
    "   half4 SPToCam[COUNTER];",
    "   mem_fence(CLK_GLOBAL_MEM_FENCE);",

    "   SPToCam[GID].xyz=CamPos.xyz-AllVert[DltIdx[GID].x].xyz;",
    "   half m[COUNTER];",
    "   mem_fence(CLK_GLOBAL_MEM_FENCE);",

    "   m[GID]=SPToCam[GID].x*NmVect[DltIdx[GID].w].x+SPToCam[GID].y*NmVect[DltIdx[GID].w].y+SPToCam[GID].z*NmVect[DltIdx[GID].w].z;",
    "   bool Polar[COUNTER];",
    "   mem_fence(CLK_GLOBAL_MEM_FENCE);",

    "   (m>0)?(Polar=true):(Polar=false);",
    "   mem_fence(CLK_GLOBAL_MEM_FENCE);",

    "   ",
    "}",



    "__kernel void Hierarchization(",
    "global ",
    ")\n",
    "{",
    "   for(uint i=0;i<NumOfObj;i++){",
    "       for(uint k=0;k<NumOfLvInObj[IdxOfObj[i]];k++){",
    "           for(uint j=0;j<NumOfVtxInLv[k+IdxOfLv[IdxOfObj[i]]]-1;j++){",
    "               uint m=0;",
    "               (k==0)?():()",
    "               "
};


//------------------------------
#endif

不需要过多关心内核。都错了……

还有我的硬件: 我的桌面:

  • NVIDIA GeForce GTX 770
  • Intel(R) Core(TM) i7-4770 CPU @3.40GHz
  • 窗口 10

我的笔记本电脑:

  • NVIDIA GeForce GT 750M
  • 英特尔(R) 高清显卡 4600
  • Intel(R) Core(TM) i7-4712HQ CPU @2.30GHz
  • Windows 8.1

另一个问题:当我在桌面上运行程序时,只能检测到 Nvidia 平台。 OpenCL 也可以在 CPU 上运行,不是吗?为什么无法检测到 Intel 平台?

【问题讨论】:

  • 绝对猜测:您的英特尔和您的 nvidia 驱动程序有不同的驱动程序版本.... 或者 ICD 驱动程序是 b0rked。
  • 对于一个简单的测试,这是一个非常长的内核。我很确定它与__kernel void k() { } 一样好/不好[并且仅将global 作为参数是否真的有效,或者您实际上并没有编译您在此处发布的代码?]

标签: c++ c windows compiler-errors opencl


【解决方案1】:

不过,我不确定clCreateProgramWithSource 中的第二个参数看起来很奇怪:

cl_program VertexProgram=clCreateProgramWithSource(Context,1,Cartography,NULL,NULL);

应该是你的源代码中的多行,所以我建议尝试

cl_program VertexProgram=clCreateProgramWithSource(Context,sizeof(Cartography)/sizeof(Cartography[0]),Cartography,NULL,NULL);

【讨论】:

  • 是的,你是对的。我在 10 天前解决了这个问题,但我忘了检查 Stack Overflow。对于那个很抱歉。 cl_program K_Program=clCreateProgramWithSource(Context,113,Cartography,NULL,&amp;status);将第二个参数设置为1,使得编译器只能读取源代码的第一行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-25
  • 2015-11-23
  • 1970-01-01
  • 2021-11-14
  • 1970-01-01
  • 2023-03-20
相关资源
最近更新 更多