@@ -180,8 +180,6 @@ __urdlllocal ur_result_t UR_APICALL urProgramBuild(
180180
181181// /////////////////////////////////////////////////////////////////////////////
182182// / @brief Intercept function for urProgramLink
183- // / TODO: It is technically possible that user directly calls urProgramLinkExp
184- // / instead of urProgramLink, intercept urProgramLinkExp if that happens.
185183__urdlllocal ur_result_t UR_APICALL urProgramLink (
186184 ur_context_handle_t hContext, // /< [in] handle of the context instance.
187185 uint32_t count, // /< [in] number of program handles in `phPrograms`.
@@ -207,6 +205,37 @@ __urdlllocal ur_result_t UR_APICALL urProgramLink(
207205 return UR_RESULT_SUCCESS;
208206}
209207
208+ // /////////////////////////////////////////////////////////////////////////////
209+ // / @brief Intercept function for urProgramLinkExp
210+ ur_result_t UR_APICALL urProgramLinkExp (
211+ ur_context_handle_t hContext, // /< [in] handle of the context instance.
212+ uint32_t numDevices, // /< [in] number of devices
213+ ur_device_handle_t *
214+ phDevices, // /< [in][range(0, numDevices)] pointer to array of device handles
215+ uint32_t count, // /< [in] number of program handles in `phPrograms`.
216+ const ur_program_handle_t *
217+ phPrograms, // /< [in][range(0, count)] pointer to array of program handles.
218+ const char *
219+ pOptions, // /< [in][optional] pointer to linker options null-terminated string.
220+ ur_program_handle_t
221+ *phProgram // /< [out] pointer to handle of program object created.
222+ ) {
223+ auto pfnProgramLinkExp = context.urDdiTable .ProgramExp .pfnLinkExp ;
224+
225+ if (nullptr == pfnProgramLinkExp) {
226+ return UR_RESULT_ERROR_UNSUPPORTED_FEATURE;
227+ }
228+
229+ context.logger .debug (" ==== urProgramLinkExp" );
230+
231+ UR_CALL (pfnProgramLinkExp (hContext, numDevices, phDevices, count,
232+ phPrograms, pOptions, phProgram));
233+
234+ UR_CALL (context.interceptor ->registerDeviceGlobals (hContext, *phProgram));
235+
236+ return UR_RESULT_SUCCESS;
237+ }
238+
210239// /////////////////////////////////////////////////////////////////////////////
211240// / @brief Intercept function for urEnqueueKernelLaunch
212241__urdlllocal ur_result_t UR_APICALL urEnqueueKernelLaunch (
@@ -455,6 +484,38 @@ __urdlllocal ur_result_t UR_APICALL urGetProgramProcAddrTable(
455484
456485 return UR_RESULT_SUCCESS;
457486}
487+
488+ // /////////////////////////////////////////////////////////////////////////////
489+ // / @brief Exported function for filling application's ProgramExp table
490+ // / with current process' addresses
491+ // /
492+ // / @returns
493+ // / - ::UR_RESULT_SUCCESS
494+ // / - ::UR_RESULT_ERROR_INVALID_NULL_POINTER
495+ // / - ::UR_RESULT_ERROR_UNSUPPORTED_VERSION
496+ __urdlllocal ur_result_t UR_APICALL urGetProgramExpProcAddrTable (
497+ ur_api_version_t version, // /< [in] API version requested
498+ ur_program_exp_dditable_t
499+ *pDdiTable // /< [in,out] pointer to table of DDI function pointers
500+ ) {
501+ if (nullptr == pDdiTable) {
502+ return UR_RESULT_ERROR_INVALID_NULL_POINTER;
503+ }
504+
505+ if (UR_MAJOR_VERSION (ur_sanitizer_layer::context.version ) !=
506+ UR_MAJOR_VERSION (version) ||
507+ UR_MINOR_VERSION (ur_sanitizer_layer::context.version ) >
508+ UR_MINOR_VERSION (version)) {
509+ return UR_RESULT_ERROR_UNSUPPORTED_VERSION;
510+ }
511+
512+ ur_result_t result = UR_RESULT_SUCCESS;
513+
514+ pDdiTable->pfnLinkExp = ur_sanitizer_layer::urProgramLinkExp;
515+
516+ return result;
517+ }
518+
458519// /////////////////////////////////////////////////////////////////////////////
459520// / @brief Exported function for filling application's Enqueue table
460521// / with current process' addresses
0 commit comments