@@ -1589,6 +1589,10 @@ extern "C" {
15891589// Forward declarations
15901590decltype (piEventCreate) piEventCreate;
15911591
1592+ static ze_result_t
1593+ checkUnresolvedSymbols (ze_module_handle_t ZeModule,
1594+ ze_module_build_log_handle_t *ZeBuildLog);
1595+
15921596// This function will ensure compatibility with both Linux and Windows for
15931597// setting environment variables.
15941598static bool setEnvVar (const char *name, const char *value) {
@@ -3887,6 +3891,22 @@ pi_result piProgramLink(pi_context Context, pi_uint32 NumDevices,
38873891 return PiResult;
38883892 }
38893893
3894+ // The call to zeModuleCreate does not report an error if there are
3895+ // unresolved symbols because it thinks these could be resolved later via a
3896+ // call to zeModuleDynamicLink. However, modules created with piProgramLink
3897+ // are supposed to be fully linked and ready to use. Therefore, do an extra
3898+ // check now for unresolved symbols. Note that we still create a
3899+ // _pi_program if there are unresolved symbols because the ZeBuildLog tells
3900+ // which symbols are unresolved.
3901+ if (ZeResult == ZE_RESULT_SUCCESS) {
3902+ ZeResult = checkUnresolvedSymbols (ZeModule, &ZeBuildLog);
3903+ if (ZeResult == ZE_RESULT_ERROR_MODULE_LINK_FAILURE) {
3904+ PiResult = PI_LINK_PROGRAM_FAILURE;
3905+ } else if (ZeResult != ZE_RESULT_SUCCESS) {
3906+ return mapError (ZeResult);
3907+ }
3908+ }
3909+
38903910 _pi_program::state State =
38913911 (PiResult == PI_SUCCESS) ? _pi_program::Exe : _pi_program::Invalid;
38923912 *RetProgram = new _pi_program (State, Context, ZeModule, ZeBuildLog);
@@ -3985,6 +4005,18 @@ pi_result piProgramBuild(pi_program Program, pi_uint32 NumDevices,
39854005 ZE_CALL (zeModuleCreate, (ZeContext, ZeDevice, &ZeModuleDesc, &ZeModule,
39864006 &Program->ZeBuildLog ));
39874007
4008+ // The call to zeModuleCreate does not report an error if there are
4009+ // unresolved symbols because it thinks these could be resolved later via a
4010+ // call to zeModuleDynamicLink. However, modules created with piProgramBuild
4011+ // are supposed to be fully linked and ready to use. Therefore, do an extra
4012+ // check now for unresolved symbols.
4013+ ze_result_t ZeResult = checkUnresolvedSymbols (ZeModule, &Program->ZeBuildLog );
4014+ if (ZeResult == ZE_RESULT_ERROR_MODULE_LINK_FAILURE) {
4015+ return PI_BUILD_PROGRAM_FAILURE;
4016+ } else if (ZeResult != ZE_RESULT_SUCCESS) {
4017+ return mapError (ZeResult);
4018+ }
4019+
39884020 // We no longer need the IL / native code.
39894021 Program->Code .reset ();
39904022
@@ -4111,6 +4143,40 @@ _pi_program::~_pi_program() {
41114143 }
41124144}
41134145
4146+ // Check to see if a Level Zero module has any unresolved symbols.
4147+ //
4148+ // @param ZeModule The module handle to check.
4149+ // @param ZeBuildLog If there are unresolved symbols, this build log handle is
4150+ // modified to receive information telling which symbols
4151+ // are unresolved.
4152+ //
4153+ // @return ZE_RESULT_ERROR_MODULE_LINK_FAILURE indicates there are unresolved
4154+ // symbols. ZE_RESULT_SUCCESS indicates all symbols are resolved. Any other
4155+ // value indicates there was an error and we cannot tell if symbols are
4156+ // resolved.
4157+ static ze_result_t
4158+ checkUnresolvedSymbols (ze_module_handle_t ZeModule,
4159+ ze_module_build_log_handle_t *ZeBuildLog) {
4160+
4161+ // First check to see if the module has any imported symbols. If there are
4162+ // no imported symbols, it's not possible to have any unresolved symbols. We
4163+ // do this check first because we assume it's faster than the call to
4164+ // zeModuleDynamicLink below.
4165+ ZeStruct<ze_module_properties_t > ZeModuleProps;
4166+ ze_result_t ZeResult =
4167+ ZE_CALL_NOCHECK (zeModuleGetProperties, (ZeModule, &ZeModuleProps));
4168+ if (ZeResult != ZE_RESULT_SUCCESS)
4169+ return ZeResult;
4170+
4171+ // If there are imported symbols, attempt to "link" the module with itself.
4172+ // As a side effect, this will return the error
4173+ // ZE_RESULT_ERROR_MODULE_LINK_FAILURE if there are any unresolved symbols.
4174+ if (ZeModuleProps.flags & ZE_MODULE_PROPERTY_FLAG_IMPORTS) {
4175+ return ZE_CALL_NOCHECK (zeModuleDynamicLink, (1 , &ZeModule, ZeBuildLog));
4176+ }
4177+ return ZE_RESULT_SUCCESS;
4178+ }
4179+
41144180pi_result piKernelCreate (pi_program Program, const char *KernelName,
41154181 pi_kernel *RetKernel) {
41164182
0 commit comments