2

I'm a new one working on OpenCL. I have some weird trouble when I try to compile the kernel.

On Nvidia platform, no matter what code in the source, it always show me cl_success and the log is only "\n"; On Intel platform, no matter what code in the source, clBuildProgram returns CL_INVALID_BINARY, clGetProgramBuildInfo with CL_PROGRAM_BUILD_STATUS returns CL_ERROR and the log looks find no mistake:

fcl build 1 succeeded.\n fcl build 2 succeeded.\n bcl build succeeded.\n.

Due to this is my first piece of complicated kernel codes, I know it fills tons of mistakes. However, this doesn't look like an error of codes. Why the compiler shows some contradictory information?

Here is my code: The Codes are long, I just post parts that might be associated with. "..." means something skipped. Ask the rest if you need. 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);
...

And Here is my kernel: Renderer.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

Don't need care too much about kernel. All wrong...

And my hardware: my desktop:

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

my laptop:

  • NVIDIA GeForce GT 750M
  • Intel(R) HD Graphics 4600
  • Intel(R) Core(TM) i7-4712HQ CPU @2.30GHz
  • Windows 8.1

Another question: When I run the program on my desktop, only Nvidia platform can be detected. OpenCL is also able to run on CPU, isn't it? Why Intel platform cannot be detected?

Soban
  • 81
  • 5
  • Absolute guess: Your intel and your nvidia drivers have different driver versions.... Or the ICD-driver is b0rked. – Mats Petersson Sep 22 '15 at 07:17
  • 1
    And for a simple test, that's a very long kernel. I'm pretty sure it works just as well/bad with `__kernel void k() { }` [And is it really valid to have just `global` as argument, or are you not actually compiling the code you have posted here?] – Mats Petersson Sep 22 '15 at 07:20

1 Answers1

0

I am not sure, however, the second argument in clCreateProgramWithSource looks strange:

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

It should be a number of lines in your source code, so I suggest trying

cl_program VertexProgram=clCreateProgramWithSource(Context,sizeof(Cartography)/sizeof(Cartography[0]),Cartography,NULL,NULL);
Alex
  • 612
  • 3
  • 9
  • Yes, you are right. I solved this problem like 10 days ago, but I forgot checking Stack Overflow. Sorry about that. `cl_program K_Program=clCreateProgramWithSource(Context,113,Cartography,NULL,&status);` Setting the second argument to 1 makes the compiler can only read the first line of the source code. – Soban Nov 12 '15 at 06:33