clarify behavior of clLinkProgram when linking fails
Creating an issue based on discussion in PR https://github.com/KhronosGroup/OpenCL-Docs/pull/798.
The behavior of clLinkProgram does not seem to be precisely described and as a result implementations are behaving differently. We need to determine what we can fix now, and if we cannot fix everything, what we would like to fix in a future spec version.
Notes:
clLinkProgramcreates a new program object, unlikeclCompileProgramandclBuildProgram, which operate on program objects that have already been created.clLinkProgrammay (or may not!) link asynchronously if a callback function pfn_notify is passed to the function.- The spec defines conditions when "the linking operation can begin": if the context, list of devices, input programs and linker options specified are all valid and appropriate host and device resources needed to perform the link are available.
Some things we need to decide where implementations are behaving differently are:
- What are the situations when
clLinkProgrammust return aNULLprogram object and an error code in errcode_ret? Are these all of the cases where "the linking operation cannot begin", or are there other cases that must return aNULLprogram object and an error code also? - Are there scenarios when
clLinkProgrammay return both a new non-NULLprogram object and an error code in errcode_ret? Or, if an error code is generated, willclLinkProgramalso return aNULLprogram object? - If a callback function is provided, will it always be called, even if an error occurs? If an error occurs, what program object is passed to the callback function?
(If you're curious to see how your implementation behaves, I put my tester here: https://github.com/bashbaug/SimpleOpenCLSamples/tree/link-program-error-behavior/samples/99_linkprogramerror.)
rusticl:
Running on platform: rusticl
Running on device: Mesa Intel(R) UHD Graphics (CML GT2)
Compiling program object 0x379c3d8...
In program_callback: program = 0x379c3d8, user_data = (nil)
Program build status: 0
Program build log:
End of program callback.
clCompileProgram() returned 0
Program compile log for device Mesa Intel(R) UHD Graphics (CML GT2):
Linking program...
In program_callback: program = 0x379c818, user_data = (nil)
Program build status: -2
Program build log:
(file=input,line=0,column=0,index=0): Unresolved external reference to "func".
End of program callback.
(file=input,line=0,column=0,index=0): Unresolved external reference to "func".
clLinkProgram() returned -17
clLinkProgram() created program object 0x379c818.
Program link log for device Mesa Intel(R) UHD Graphics (CML GT2):
(file=input,line=0,column=0,index=0): Unresolved external reference to "func".
All done.
but asynchronous compilation/linking hasn't been implemented yet.
some of my thoughts:
- a
cl_programobject is the only reliable way to fetch program logs. So I'd say it should depend on that. Usually the CL API returnsNULLon errorsNULL, butcl_programis special due to this reason and I'd prefer it stays the only reason. - same as 1. I guess
- I think the spec is clear enough on that:
pfn_notify is a function pointer to a notification routine. The notification routine is a callback function that an application can register and which will be called when the program executable has been built (successfully or unsuccessfully).So given the reason stated in 1. there will always be acl_programobject, therefore by deduction an attempted build also guarantees a validcl_programobject existing as you have no way to retrieve logs otherwise. The question remains if the callback should be called besides attempted compilations/linkings, but that would be a breaking change as applications might run into crashes if they receive aNULLcl_programobject now and don't handleCL_INVALID_PROGRAMbeing returned or other error handling they deemed not necessary.
Are you saying clLinkProgram should return a non-NULL program object even if the linking operation cannot begin, for instance in case CL_INVALID_CONTEXT is returned from the errcode_ret parameter?
In #798 I made it so a non-NULL program object is only returned (and passed to callback) if errcode_ret is either CL_SUCCESS or CL_LINK_PROGRAM_FAILURE.
That would be enough to always fetch logs, but always returning a non-NULL program object also sounds good. I guess this way is more consistent.
no, I didn't. I only meant that in the callback it won't be NULL.