OpenCL* for CPU
Ask questions and share information on Intel® SDK for OpenCL™ Applications and OpenCL™ implementations for Intel® CPU.
Announcements
This forum covers OpenCL* for CPU only. OpenCL* for GPU questions can be asked in the GPU Compute Software forum. Intel® FPGA SDK for OpenCL™ questions can be ask in the FPGA Intel® High Level Design forum.

is this a bug? clCreateProgramWithBinary failed from ir file

Weibin_T_
Beginner
752 Views
comile command:
/opt/intel/bin/icpc -g -o test  -I/opt/intel/opencl-sdk/include -L/opt/intel/opencl/lib64 -lOpenCL *.cpp

run command: ./test test.cl -debug
output:
 CL_PLATFORM_NAME:      Intel(R) OpenCL
 CL_PLATFORM_VERSION:   OpenCL 1.2 LINUX

run command: ./test test.ir
output:
 CL_PLATFORM_NAME:      Intel(R) OpenCL
 CL_PLATFORM_VERSION:   OpenCL 1.2 LINUX
 Error CL_INVALID_PROGRAM in oclLogBuildInfo Call !!!



// oclTest.cpp 
//

#include<stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
// All OpenCL headers
#if defined (__APPLE__) || defined(MACOSX)
#include <OpenCL/opencl.h>
#else
#include <CL/opencl.h>
#endif

#define VENDOR_INTEL "Intel(R)"


cl_int oclGetPlatformID(cl_platform_id* clSelectedPlatformID)
{
	char chBuffer[1024];
	cl_uint num_platforms; 
	cl_platform_id* clPlatformIDs;
	cl_int ciErrNum;
	*clSelectedPlatformID = NULL;

	// Get OpenCL platform count
	ciErrNum = clGetPlatformIDs (0, NULL, &num_platforms);
	if (ciErrNum != CL_SUCCESS)
	{
		printf(" Error %i in clGetPlatformIDs Call !!!\n\n", ciErrNum);
		return -1000;
	}
	else 
	{
		if(num_platforms == 0)
		{
			printf("No OpenCL platform found!\n\n");
			return -2000;
		}
		else 
		{
			// if there's a platform or more, make space for ID's
			if ((clPlatformIDs = (cl_platform_id*)malloc(num_platforms * sizeof(cl_platform_id))) == NULL)
			{
				printf("Failed to allocate memory for cl_platform ID's!\n\n");
				return -3000;
			}

			// get platform info for each platform and trap the NVIDIA platform if found
			ciErrNum = clGetPlatformIDs (num_platforms, clPlatformIDs, NULL);
			for(cl_uint i = 0; i < num_platforms; ++i)
			{
				ciErrNum = clGetPlatformInfo (clPlatformIDs, CL_PLATFORM_NAME, 1024, &chBuffer, NULL);
				if(ciErrNum == CL_SUCCESS)
				{
					if(strstr(chBuffer, VENDOR_INTEL) != NULL)
					{
						*clSelectedPlatformID = clPlatformIDs;
						break;
					}
				}
			}

			// default to zeroeth platform if NVIDIA not found
			if(*clSelectedPlatformID == NULL)
			{
				printf("WARNING: NVIDIA OpenCL platform not found - defaulting to first platform!\n\n");
				*clSelectedPlatformID = clPlatformIDs[0];
			}

			free(clPlatformIDs);
		}
	}

	return CL_SUCCESS;
}

char* oclLoadProgSource(const char* cFilename, size_t* szFinalLength)
{
	// locals 
	FILE* pFileStream = NULL;
	size_t szSourceLength;

	// open the OpenCL source code file
#ifdef _WIN32   // Windows version
	if(fopen_s(&pFileStream, cFilename, "rb") != 0) 
	{       
		return NULL;
	}
#else           // Linux version
	pFileStream = fopen(cFilename, "rb");
	if(pFileStream == 0) 
	{       
		return NULL;
	}
#endif

	// get the length of the source code
	fseek(pFileStream, 0, SEEK_END); 
	szSourceLength = ftell(pFileStream);
	fseek(pFileStream, 0, SEEK_SET); 

	// allocate a buffer for the source code string and read it in
	char* cSourceString = (char *)malloc(szSourceLength + 1); 

	if (fread((cSourceString), szSourceLength, 1, pFileStream) != 1)
	{
		fclose(pFileStream);
		free(cSourceString);
		return 0;
	}

	// close the file and return the total length of the combined (preamble + source) string
	fclose(pFileStream);
	if(szFinalLength != 0)
	{
		*szFinalLength = szSourceLength ;
	}
	cSourceString[szSourceLength] = '\0';

	return cSourceString;
}

const char* oclErrorString(cl_int error)
{
	static const char* errorString[] = {
		"CL_SUCCESS",
		"CL_DEVICE_NOT_FOUND",
		"CL_DEVICE_NOT_AVAILABLE",
		"CL_COMPILER_NOT_AVAILABLE",
		"CL_MEM_OBJECT_ALLOCATION_FAILURE",
		"CL_OUT_OF_RESOURCES",
		"CL_OUT_OF_HOST_MEMORY",
		"CL_PROFILING_INFO_NOT_AVAILABLE",
		"CL_MEM_COPY_OVERLAP",
		"CL_IMAGE_FORMAT_MISMATCH",
		"CL_IMAGE_FORMAT_NOT_SUPPORTED",
		"CL_BUILD_PROGRAM_FAILURE",
		"CL_MAP_FAILURE",
		"",
		"",
		"",
		"",
		"",
		"",
		"",
		"",
		"",
		"",
		"",
		"",
		"",
		"",
		"",
		"",
		"",
		"CL_INVALID_VALUE",
		"CL_INVALID_DEVICE_TYPE",
		"CL_INVALID_PLATFORM",
		"CL_INVALID_DEVICE",
		"CL_INVALID_CONTEXT",
		"CL_INVALID_QUEUE_PROPERTIES",
		"CL_INVALID_COMMAND_QUEUE",
		"CL_INVALID_HOST_PTR",
		"CL_INVALID_MEM_OBJECT",
		"CL_INVALID_IMAGE_FORMAT_DESCRIPTOR",
		"CL_INVALID_IMAGE_SIZE",
		"CL_INVALID_SAMPLER",
		"CL_INVALID_BINARY",
		"CL_INVALID_BUILD_OPTIONS",
		"CL_INVALID_PROGRAM",
		"CL_INVALID_PROGRAM_EXECUTABLE",
		"CL_INVALID_KERNEL_NAME",
		"CL_INVALID_KERNEL_DEFINITION",
		"CL_INVALID_KERNEL",
		"CL_INVALID_ARG_INDEX",
		"CL_INVALID_ARG_VALUE",
		"CL_INVALID_ARG_SIZE",
		"CL_INVALID_KERNEL_ARGS",
		"CL_INVALID_WORK_DIMENSION",
		"CL_INVALID_WORK_GROUP_SIZE",
		"CL_INVALID_WORK_ITEM_SIZE",
		"CL_INVALID_GLOBAL_OFFSET",
		"CL_INVALID_EVENT_WAIT_LIST",
		"CL_INVALID_EVENT",
		"CL_INVALID_OPERATION",
		"CL_INVALID_GL_OBJECT",
		"CL_INVALID_BUFFER_SIZE",
		"CL_INVALID_MIP_LEVEL",
		"CL_INVALID_GLOBAL_WORK_SIZE",
	};

	const int errorCount = sizeof(errorString) / sizeof(errorString[0]);

	const int index = -error;

	return (index >= 0 && index < errorCount) ? errorString[index] : "Unspecified Error";
}

#define HDASHLINE "-----------------------------------------------------------\n"
void oclLogBuildInfo(cl_program cpProgram, cl_device_id cdDevice)
{
	// write out the build log and ptx, then exit
	char cBuildLog[10240]={0};
	cl_int ciErrNum =clGetProgramBuildInfo(cpProgram, cdDevice, CL_PROGRAM_BUILD_LOG, sizeof(cBuildLog), cBuildLog, NULL );
	if(ciErrNum!=CL_SUCCESS)
		printf(" Error %s in oclLogBuildInfo Call !!!\n\n", oclErrorString(ciErrNum));
	else
	{
		printf("\n%s\nBuild Log:\n%s\n%s\n", HDASHLINE, cBuildLog, HDASHLINE);
		FILE *stream = fopen( "BuildInfo.log", "w" );
		if (stream==NULL)
		{
			return;
		}
		fprintf( stream, "%s", cBuildLog);
		fclose( stream );
	}
}

int main(int argc, char** argvs)
{
	cl_platform_id clSelectedPlatformID=NULL;
	char *pOclSource=NULL;
	char cBuffer[1024];
	cl_uint num_platforms; 
	cl_uint ciDeviceCount;
	cl_platform_id* clPlatformIDs;
	cl_int ciErrNum;
	cl_device_id devices[8];
	cl_context contexts[8];
	cl_program programs[8];
	cl_command_queue commandQueues[8];
	size_t srcLen=0;
	pOclSource=oclLoadProgSource(argvs[1],&srcLen);
	ciErrNum = oclGetPlatformID (&clSelectedPlatformID);

	ciErrNum = clGetPlatformInfo (clSelectedPlatformID, CL_PLATFORM_NAME, sizeof(cBuffer), cBuffer, NULL);
	if (ciErrNum == CL_SUCCESS)
		printf(" CL_PLATFORM_NAME: \t%s\n", cBuffer);
	ciErrNum = clGetPlatformInfo (clSelectedPlatformID, CL_PLATFORM_VERSION, sizeof(cBuffer), cBuffer, NULL);
	if (ciErrNum == CL_SUCCESS)
	{
		printf(" CL_PLATFORM_VERSION: \t%s\n", cBuffer);
	} 

	ciErrNum = clGetDeviceIDs (clSelectedPlatformID, CL_DEVICE_TYPE_ACCELERATOR|CL_DEVICE_TYPE_GPU, 0, NULL, &ciDeviceCount);
	ciErrNum = clGetDeviceIDs (clSelectedPlatformID, CL_DEVICE_TYPE_ACCELERATOR|CL_DEVICE_TYPE_GPU, ciDeviceCount, devices, &ciDeviceCount);

	for(unsigned int i = 0; i < ciDeviceCount; ++i ) 
	{  
		contexts = clCreateContext(0, 1, &devices, NULL, NULL, &ciErrNum);
		if (ciErrNum != CL_SUCCESS)
		{
			printf("Error %s in clCreateContext call !!!\n\n", oclErrorString(ciErrNum));
			break;
		}
		commandQueues=clCreateCommandQueue(contexts,devices,0,&ciErrNum);
		if (ciErrNum != CL_SUCCESS)
		{
			printf("Error %s in clCreateCommandQueue call !!!\n\n", oclErrorString(ciErrNum));
			break;
		}
		if((argc>2)&&(memcmp(argvs[2],"-debug",strlen("-debug"))==0))
		{
			programs=clCreateProgramWithSource(contexts,1,(const char**)&pOclSource,&srcLen,&ciErrNum);
			if (ciErrNum != CL_SUCCESS)
			{
				printf("Error %s in clCreateProgramWithSource call !!!\n\n", oclErrorString(ciErrNum));
				break;
			}
			ciErrNum=clBuildProgram(programs,1,&(devices),NULL,NULL,NULL);
			if (ciErrNum != CL_SUCCESS)
			{
				printf("Error %s in clBuildProgram call !!!\n\n", oclErrorString(ciErrNum));
				oclLogBuildInfo(programs,devices);
				break;
			}
			size_t binary_size=0;
			ciErrNum=clGetProgramInfo(programs,CL_PROGRAM_BINARY_SIZES,sizeof(size_t),&binary_size,NULL);
			binary_size++;
			char *binary=new char[binary_size];
			memset(binary,0,binary_size);
			ciErrNum=clGetProgramInfo(programs,CL_PROGRAM_BINARIES,sizeof(size_t),&binary,NULL);
			char filename[256]="test.ir";
			FILE *fp=fopen(filename,"wb");
			fwrite(binary,1,binary_size,fp);
			fclose(fp);
			delete binary;
			
		}

		else
		{
			programs=clCreateProgramWithBinary(contexts,1,&devices,&srcLen,(const unsigned char**)&pOclSource,&ciErrNum,NULL);
			if (ciErrNum != CL_SUCCESS)
			{
				printf("Error %s in clCreateProgramWithBinary call !!!\n\n", oclErrorString(ciErrNum));

				break;
			}
			ciErrNum=clBuildProgram(programs,1,&(devices),NULL,NULL,NULL);
			if (ciErrNum != CL_SUCCESS)
			{
				oclLogBuildInfo(programs,devices);
				break;
			}
		}
		//#endif



		printf(" ---------------------------------\n");
		//clGetDeviceInfo(devices, CL_DEVICE_NAME, sizeof(oclDevInfo.deviceName), &oclDevInfo.deviceName, NULL);
		//printf(" Device: %s\n", deviceName);
		printf(" ---------------------------------\n");
		//oclPrintDevInfo(devices);			
	}
	return 0;
}

 

0 Kudos
1 Reply
Weibin_T_
Beginner
752 Views

summary missing....

post again:

My project work well if i compile it from opencl source file(test.cl) with clCreateProgramWithSource function. and save the cl program binary into an ir file(test.ir).
When i recompile the cl program with clCreateProgramWithBinary , it gets an error while clBuildProgram is called.
The same code works well on NVIDIA and AMD GPU platforms, except the intel mic card(5110p).
Is there something wrong with my code or intel opencl sdk?
This problem has trapped me for servel days, can anyone help me?

 

0 Kudos
Reply