diff --git a/projects/clr/opencl/api/opencl/amdocl/amdocl.def.in b/projects/clr/opencl/api/opencl/amdocl/amdocl.def.in index a475327045..7d789d68fc 100644 --- a/projects/clr/opencl/api/opencl/amdocl/amdocl.def.in +++ b/projects/clr/opencl/api/opencl/amdocl/amdocl.def.in @@ -103,6 +103,7 @@ clUnloadPlatformCompiler #endif #if (OPENCL_MAJOR >= 2) +clCreateProgramWithIL clCreateCommandQueueWithProperties clCreateSamplerWithProperties clCreatePipe diff --git a/projects/clr/opencl/api/opencl/amdocl/amdocl.map.in b/projects/clr/opencl/api/opencl/amdocl/amdocl.map.in index 657446f720..db2dda51f7 100644 --- a/projects/clr/opencl/api/opencl/amdocl/amdocl.map.in +++ b/projects/clr/opencl/api/opencl/amdocl/amdocl.map.in @@ -142,6 +142,7 @@ global: #if (OPENCL_MAJOR >= 2) OPENCL_2.0 { global: + clCreateProgramWithIL; clCreateCommandQueueWithProperties; clCreateSamplerWithProperties; clCreatePipe; diff --git a/projects/clr/opencl/api/opencl/amdocl/cl_icd.cpp b/projects/clr/opencl/api/opencl/amdocl/cl_icd.cpp index 4dd85c2721..f844b32030 100644 --- a/projects/clr/opencl/api/opencl/amdocl/cl_icd.cpp +++ b/projects/clr/opencl/api/opencl/amdocl/cl_icd.cpp @@ -204,7 +204,8 @@ amd::ICDDispatchedObject::icdVendorDispatch_[] = {{ clSetKernelExecInfo, clGetKernelSubGroupInfoKHR, - clTerminateContextKHR + clTerminateContextKHR, + clCreateProgramWithIL }}; CL_API_ENTRY cl_int CL_API_CALL diff --git a/projects/clr/opencl/api/opencl/amdocl/cl_icd_amd.h b/projects/clr/opencl/api/opencl/amdocl/cl_icd_amd.h index 999fd180f7..a41807f8c4 100644 --- a/projects/clr/opencl/api/opencl/amdocl/cl_icd_amd.h +++ b/projects/clr/opencl/api/opencl/amdocl/cl_icd_amd.h @@ -210,6 +210,12 @@ typedef cl_program (CL_API_CALL * clCreateProgramWithSource_fn)( const size_t * /* lengths */, cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; +typedef cl_program (CL_API_CALL * clCreateProgramWithIL_fn)( + cl_context /* context */, + const void * /* il */, + size_t /* length */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + typedef cl_program (CL_API_CALL * clCreateProgramWithBinary_fn)( cl_context /* context */, cl_uint /* num_devices */, @@ -972,6 +978,9 @@ typedef struct _cl_icd_dispatch_table clGetKernelSubGroupInfoKHR_fn GetKernelSubGroupInfoKHR; clTerminateContextKHR_fn TerminateContextKHR; + + /* cl_khr_spirv */ + clCreateProgramWithIL_fn CreateProgramWithIL; } cl_icd_dispatch_table; #ifdef __cplusplus diff --git a/projects/clr/opencl/api/opencl/amdocl/cl_program.cpp b/projects/clr/opencl/api/opencl/amdocl/cl_program.cpp index 39d4a3b890..506ebc8168 100644 --- a/projects/clr/opencl/api/opencl/amdocl/cl_program.cpp +++ b/projects/clr/opencl/api/opencl/amdocl/cl_program.cpp @@ -166,6 +166,73 @@ RUNTIME_ENTRY_RET(cl_program, clCreateProgramWithSource, ( } RUNTIME_EXIT +/*! \brief Create a program object for a context, and loads the IL into the + * program object. + * + * \param context must be a valid OpenCL context. + * + * \param string is a pointer to IL. + * + * \param length is the size in bytes of IL. + * + * \param errcode_ret will return an appropriate error code. If \a errcode_ret + * is NULL, no error code is returned. + * + * \return A valid non-zero program object and errcode_ret is set to + * \a CL_SUCCESS if the program object is created successfully. It returns a + * NULL value with one of the following error values returned in + * \a errcode_ret: + * - CL_INVALID_CONTEXT if \a context is not a valid context. + * - CL_INVALID_VALUE if \a il is NULL or \a length is zero. + * - CL_INVALID_VALUE if the \a length-byte memory pointed to by \a il does + * not contain well-formed intermediate language input appropriate for the + * deployment environment in which the OpenCL platform is running. + * - CL_OUT_OF_RESOURCES if there is a failure to allocate resources required + * by the OpenCL implementation on the device. + * - CL_OUT_OF_HOST_MEMORY if there is a failure to allocate resources + * required by the OpenCL implementation on the host. + * + * \version 1.0r33 + */ +RUNTIME_ENTRY_RET(cl_program, clCreateProgramWithIL, ( + cl_context context, + const void *il, + size_t length, + cl_int *errcode_ret)) +{ + if (!is_valid(context)) { + *not_null(errcode_ret) = CL_INVALID_CONTEXT; + return (cl_program)0; + } + if (length == 0 || il == NULL) { + *not_null(errcode_ret) = CL_INVALID_VALUE; + return (cl_program)0; + } + + // Create the program + amd::Program* program = new amd::Program(*as_amd(context), "", true); + if (program == NULL) { + *not_null(errcode_ret) = CL_OUT_OF_HOST_MEMORY; + return (cl_program)0; + } + + // Add programs for all devices in the context. + const std::vector& devices = as_amd(context)->devices(); + std::vector::const_iterator it; + for (it = devices.begin(); it != devices.end(); ++it) { + if (program->addDeviceProgram(**it, il, length) == + CL_OUT_OF_HOST_MEMORY) { + *not_null(errcode_ret) = CL_OUT_OF_HOST_MEMORY; + program->release(); + return (cl_program)0; + } + } + + *not_null(errcode_ret) = CL_SUCCESS; + return as_cl(program); +} +RUNTIME_EXIT + /*! \brief Create a program object for a context, and loads the binary images * into the program object. * diff --git a/projects/clr/opencl/api/opencl/khronos/headers/opencl2.0/CL/cl.h b/projects/clr/opencl/api/opencl/khronos/headers/opencl2.0/CL/cl.h index 87fd6d7781..983a620052 100644 --- a/projects/clr/opencl/api/opencl/khronos/headers/opencl2.0/CL/cl.h +++ b/projects/clr/opencl/api/opencl/khronos/headers/opencl2.0/CL/cl.h @@ -835,6 +835,12 @@ clCreateProgramWithSource(cl_context /* context */, const size_t * /* lengths */, cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; +extern CL_API_ENTRY cl_program CL_API_CALL +clCreateProgramWithIL(cl_context /* context */, + const void * /* strings */, + size_t /* lengths */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + extern CL_API_ENTRY cl_program CL_API_CALL clCreateProgramWithBinary(cl_context /* context */, cl_uint /* num_devices */, diff --git a/projects/clr/opencl/api/opencl/khronos/icd/icd_dispatch.c b/projects/clr/opencl/api/opencl/khronos/icd/icd_dispatch.c index 113dee5304..96cf4898b8 100644 --- a/projects/clr/opencl/api/opencl/khronos/icd/icd_dispatch.c +++ b/projects/clr/opencl/api/opencl/khronos/icd/icd_dispatch.c @@ -470,6 +470,20 @@ clCreateProgramWithSource(cl_context context, errcode_ret); } +CL_API_ENTRY cl_program CL_API_CALL +clCreateProgramWithIL(cl_context context, + const void * il, + size_t length, + cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0 +{ + KHR_ICD_VALIDATE_HANDLE_RETURN_HANDLE(context, CL_INVALID_CONTEXT); + return context->dispatch->clCreateProgramWithIL( + context, + il, + length, + errcode_ret); +} + CL_API_ENTRY cl_program CL_API_CALL clCreateProgramWithBinary(cl_context context, cl_uint num_devices, diff --git a/projects/clr/opencl/api/opencl/khronos/icd/icd_dispatch.h b/projects/clr/opencl/api/opencl/khronos/icd/icd_dispatch.h index f58c6c0c05..d670a62ac7 100644 --- a/projects/clr/opencl/api/opencl/khronos/icd/icd_dispatch.h +++ b/projects/clr/opencl/api/opencl/khronos/icd/icd_dispatch.h @@ -272,6 +272,12 @@ typedef CL_API_ENTRY cl_program (CL_API_CALL *KHRpfn_clCreateProgramWithSource)( const size_t * lengths, cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0; +typedef CL_API_ENTRY cl_program (CL_API_CALL *KHRpfn_clCreateProgramWithIL)( + cl_context context, + const void * il, + size_t length, + cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0; + typedef CL_API_ENTRY cl_program (CL_API_CALL *KHRpfn_clCreateProgramWithBinary)( cl_context context, cl_uint num_devices, @@ -1411,6 +1417,9 @@ struct KHRicdVendorDispatchRec KHRpfn_clGetKernelSubGroupInfoKHR clGetKernelSubGroupInfoKHR; KHRpfn_clTerminateContextKHR clTerminateContextKHR; + + /* cl_khr_spirv */ + KHRpfn_clCreateProgramWithIL clCreateProgramWithIL; }; #endif // _ICD_DISPATCH_H_