Skip to content

Commit e5df409

Browse files
igchorkbenzie
authored andcommitted
[UR][L0] Add support for passing device list to urProgramBuild
piProgramBuild receives a list of devices, while urProgramBuild does not. This produces a series of issues when a UR program needs to be created for a specific device. So define a new API, called urProgramBuildExp to pass this list. Authored-by: [email protected]
1 parent a2d23dc commit e5df409

File tree

13 files changed

+591
-3
lines changed

13 files changed

+591
-3
lines changed

include/ur.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,8 @@ class ur_function_v(IntEnum):
202202
KERNEL_SUGGEST_MAX_COOPERATIVE_GROUP_COUNT_EXP = 194## Enumerator for ::urKernelSuggestMaxCooperativeGroupCountExp
203203
COMMAND_BUFFER_APPEND_USM_PREFETCH_EXP = 195 ## Enumerator for ::urCommandBufferAppendUSMPrefetchExp
204204
COMMAND_BUFFER_APPEND_USM_ADVISE_EXP = 196 ## Enumerator for ::urCommandBufferAppendUSMAdviseExp
205-
LOADER_CONFIG_SET_CODE_LOCATION_CALLBACK = 197 ## Enumerator for ::urLoaderConfigSetCodeLocationCallback
205+
PROGRAM_BUILD_EXP = 197 ## Enumerator for ::urProgramBuildExp
206+
LOADER_CONFIG_SET_CODE_LOCATION_CALLBACK = 198 ## Enumerator for ::urLoaderConfigSetCodeLocationCallback
206207

207208
class ur_function_t(c_int):
208209
def __str__(self):
@@ -2631,6 +2632,21 @@ class ur_program_dditable_t(Structure):
26312632
("pfnCreateWithNativeHandle", c_void_p) ## _urProgramCreateWithNativeHandle_t
26322633
]
26332634

2635+
###############################################################################
2636+
## @brief Function-pointer for urProgramBuildExp
2637+
if __use_win_types:
2638+
_urProgramBuildExp_t = WINFUNCTYPE( ur_result_t, ur_context_handle_t, ur_program_handle_t, c_ulong, POINTER(ur_device_handle_t), c_char_p )
2639+
else:
2640+
_urProgramBuildExp_t = CFUNCTYPE( ur_result_t, ur_context_handle_t, ur_program_handle_t, c_ulong, POINTER(ur_device_handle_t), c_char_p )
2641+
2642+
2643+
###############################################################################
2644+
## @brief Table of ProgramExp functions pointers
2645+
class ur_program_exp_dditable_t(Structure):
2646+
_fields_ = [
2647+
("pfnBuildExp", c_void_p) ## _urProgramBuildExp_t
2648+
]
2649+
26342650
###############################################################################
26352651
## @brief Function-pointer for urKernelCreate
26362652
if __use_win_types:
@@ -3862,6 +3878,7 @@ class ur_dditable_t(Structure):
38623878
("Context", ur_context_dditable_t),
38633879
("Event", ur_event_dditable_t),
38643880
("Program", ur_program_dditable_t),
3881+
("ProgramExp", ur_program_exp_dditable_t),
38653882
("Kernel", ur_kernel_dditable_t),
38663883
("KernelExp", ur_kernel_exp_dditable_t),
38673884
("Sampler", ur_sampler_dditable_t),
@@ -3966,6 +3983,16 @@ def __init__(self, version : ur_api_version_t):
39663983
self.urProgramGetNativeHandle = _urProgramGetNativeHandle_t(self.__dditable.Program.pfnGetNativeHandle)
39673984
self.urProgramCreateWithNativeHandle = _urProgramCreateWithNativeHandle_t(self.__dditable.Program.pfnCreateWithNativeHandle)
39683985

3986+
# call driver to get function pointers
3987+
ProgramExp = ur_program_exp_dditable_t()
3988+
r = ur_result_v(self.__dll.urGetProgramExpProcAddrTable(version, byref(ProgramExp)))
3989+
if r != ur_result_v.SUCCESS:
3990+
raise Exception(r)
3991+
self.__dditable.ProgramExp = ProgramExp
3992+
3993+
# attach function interface to function address
3994+
self.urProgramBuildExp = _urProgramBuildExp_t(self.__dditable.ProgramExp.pfnBuildExp)
3995+
39693996
# call driver to get function pointers
39703997
Kernel = ur_kernel_dditable_t()
39713998
r = ur_result_v(self.__dll.urGetKernelProcAddrTable(version, byref(Kernel)))

include/ur_api.h

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,8 @@ typedef enum ur_function_t {
211211
UR_FUNCTION_KERNEL_SUGGEST_MAX_COOPERATIVE_GROUP_COUNT_EXP = 194, ///< Enumerator for ::urKernelSuggestMaxCooperativeGroupCountExp
212212
UR_FUNCTION_COMMAND_BUFFER_APPEND_USM_PREFETCH_EXP = 195, ///< Enumerator for ::urCommandBufferAppendUSMPrefetchExp
213213
UR_FUNCTION_COMMAND_BUFFER_APPEND_USM_ADVISE_EXP = 196, ///< Enumerator for ::urCommandBufferAppendUSMAdviseExp
214-
UR_FUNCTION_LOADER_CONFIG_SET_CODE_LOCATION_CALLBACK = 197, ///< Enumerator for ::urLoaderConfigSetCodeLocationCallback
214+
UR_FUNCTION_PROGRAM_BUILD_EXP = 197, ///< Enumerator for ::urProgramBuildExp
215+
UR_FUNCTION_LOADER_CONFIG_SET_CODE_LOCATION_CALLBACK = 198, ///< Enumerator for ::urLoaderConfigSetCodeLocationCallback
215216
/// @cond
216217
UR_FUNCTION_FORCE_UINT32 = 0x7fffffff
217218
/// @endcond
@@ -4075,6 +4076,43 @@ urProgramBuild(
40754076
const char *pOptions ///< [in][optional] pointer to build options null-terminated string.
40764077
);
40774078

4079+
///////////////////////////////////////////////////////////////////////////////
4080+
/// @brief Produces an executable program from one program, negates need for the
4081+
/// linking step.
4082+
///
4083+
/// @details
4084+
/// - The application may call this function from simultaneous threads.
4085+
/// - Following a successful call to this entry point, the program passed
4086+
/// will contain a binary of the ::UR_PROGRAM_BINARY_TYPE_EXECUTABLE type
4087+
/// for each device in `hContext`.
4088+
///
4089+
/// @remarks
4090+
/// _Analogues_
4091+
/// - **clBuildProgram**
4092+
///
4093+
/// @returns
4094+
/// - ::UR_RESULT_SUCCESS
4095+
/// - ::UR_RESULT_ERROR_UNINITIALIZED
4096+
/// - ::UR_RESULT_ERROR_DEVICE_LOST
4097+
/// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC
4098+
/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE
4099+
/// + `NULL == hContext`
4100+
/// + `NULL == hProgram`
4101+
/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER
4102+
/// + `NULL == phDevices`
4103+
/// - ::UR_RESULT_ERROR_INVALID_PROGRAM
4104+
/// + If `hProgram` isn't a valid program object.
4105+
/// - ::UR_RESULT_ERROR_PROGRAM_BUILD_FAILURE
4106+
/// + If an error occurred when building `hProgram`.
4107+
UR_APIEXPORT ur_result_t UR_APICALL
4108+
urProgramBuildExp(
4109+
ur_context_handle_t hContext, ///< [in] handle of the context instance.
4110+
ur_program_handle_t hProgram, ///< [in] Handle of the program to build.
4111+
uint32_t numDevices, ///< [in] number of devices
4112+
ur_device_handle_t *phDevices, ///< [in][range(0, numDevices)] pointer to array of device handles
4113+
const char *pOptions ///< [in][optional] pointer to build options null-terminated string.
4114+
);
4115+
40784116
///////////////////////////////////////////////////////////////////////////////
40794117
/// @brief Produces an executable program from one or more programs.
40804118
///
@@ -8919,6 +8957,18 @@ typedef struct ur_program_build_params_t {
89198957
const char **ppOptions;
89208958
} ur_program_build_params_t;
89218959

8960+
///////////////////////////////////////////////////////////////////////////////
8961+
/// @brief Function parameters for urProgramBuildExp
8962+
/// @details Each entry is a pointer to the parameter passed to the function;
8963+
/// allowing the callback the ability to modify the parameter's value
8964+
typedef struct ur_program_build_exp_params_t {
8965+
ur_context_handle_t *phContext;
8966+
ur_program_handle_t *phProgram;
8967+
uint32_t *pnumDevices;
8968+
ur_device_handle_t **pphDevices;
8969+
const char **ppOptions;
8970+
} ur_program_build_exp_params_t;
8971+
89228972
///////////////////////////////////////////////////////////////////////////////
89238973
/// @brief Function parameters for urProgramCompile
89248974
/// @details Each entry is a pointer to the parameter passed to the function;

include/ur_ddi.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,42 @@ typedef ur_result_t(UR_APICALL *ur_pfnGetProgramProcAddrTable_t)(
408408
ur_api_version_t,
409409
ur_program_dditable_t *);
410410

411+
///////////////////////////////////////////////////////////////////////////////
412+
/// @brief Function-pointer for urProgramBuildExp
413+
typedef ur_result_t(UR_APICALL *ur_pfnProgramBuildExp_t)(
414+
ur_context_handle_t,
415+
ur_program_handle_t,
416+
uint32_t,
417+
ur_device_handle_t *,
418+
const char *);
419+
420+
///////////////////////////////////////////////////////////////////////////////
421+
/// @brief Table of ProgramExp functions pointers
422+
typedef struct ur_program_exp_dditable_t {
423+
ur_pfnProgramBuildExp_t pfnBuildExp;
424+
} ur_program_exp_dditable_t;
425+
426+
///////////////////////////////////////////////////////////////////////////////
427+
/// @brief Exported function for filling application's ProgramExp table
428+
/// with current process' addresses
429+
///
430+
/// @returns
431+
/// - ::UR_RESULT_SUCCESS
432+
/// - ::UR_RESULT_ERROR_UNINITIALIZED
433+
/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER
434+
/// - ::UR_RESULT_ERROR_UNSUPPORTED_VERSION
435+
UR_DLLEXPORT ur_result_t UR_APICALL
436+
urGetProgramExpProcAddrTable(
437+
ur_api_version_t version, ///< [in] API version requested
438+
ur_program_exp_dditable_t *pDdiTable ///< [in,out] pointer to table of DDI function pointers
439+
);
440+
441+
///////////////////////////////////////////////////////////////////////////////
442+
/// @brief Function-pointer for urGetProgramExpProcAddrTable
443+
typedef ur_result_t(UR_APICALL *ur_pfnGetProgramExpProcAddrTable_t)(
444+
ur_api_version_t,
445+
ur_program_exp_dditable_t *);
446+
411447
///////////////////////////////////////////////////////////////////////////////
412448
/// @brief Function-pointer for urKernelCreate
413449
typedef ur_result_t(UR_APICALL *ur_pfnKernelCreate_t)(
@@ -2250,6 +2286,7 @@ typedef struct ur_dditable_t {
22502286
ur_context_dditable_t Context;
22512287
ur_event_dditable_t Event;
22522288
ur_program_dditable_t Program;
2289+
ur_program_exp_dditable_t ProgramExp;
22532290
ur_kernel_dditable_t Kernel;
22542291
ur_kernel_exp_dditable_t KernelExp;
22552292
ur_sampler_dditable_t Sampler;

include/ur_print.hpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -869,6 +869,9 @@ inline std::ostream &operator<<(std::ostream &os, ur_function_t value) {
869869
case UR_FUNCTION_COMMAND_BUFFER_APPEND_USM_ADVISE_EXP:
870870
os << "UR_FUNCTION_COMMAND_BUFFER_APPEND_USM_ADVISE_EXP";
871871
break;
872+
case UR_FUNCTION_PROGRAM_BUILD_EXP:
873+
os << "UR_FUNCTION_PROGRAM_BUILD_EXP";
874+
break;
872875
case UR_FUNCTION_LOADER_CONFIG_SET_CODE_LOCATION_CALLBACK:
873876
os << "UR_FUNCTION_LOADER_CONFIG_SET_CODE_LOCATION_CALLBACK";
874877
break;
@@ -9987,6 +9990,49 @@ inline std::ostream &operator<<(std::ostream &os, [[maybe_unused]] const struct
99879990
return os;
99889991
}
99899992

9993+
///////////////////////////////////////////////////////////////////////////////
9994+
/// @brief Print operator for the ur_program_build_exp_params_t type
9995+
/// @returns
9996+
/// std::ostream &
9997+
inline std::ostream &operator<<(std::ostream &os, [[maybe_unused]] const struct ur_program_build_exp_params_t *params) {
9998+
9999+
os << ".hContext = ";
10000+
10001+
details::printPtr(os,
10002+
*(params->phContext));
10003+
10004+
os << ", ";
10005+
os << ".hProgram = ";
10006+
10007+
details::printPtr(os,
10008+
*(params->phProgram));
10009+
10010+
os << ", ";
10011+
os << ".numDevices = ";
10012+
10013+
os << *(params->pnumDevices);
10014+
10015+
os << ", ";
10016+
os << ".phDevices = {";
10017+
for (size_t i = 0; *(params->pphDevices) != NULL && i < *params->pnumDevices; ++i) {
10018+
if (i != 0) {
10019+
os << ", ";
10020+
}
10021+
10022+
details::printPtr(os,
10023+
(*(params->pphDevices))[i]);
10024+
}
10025+
os << "}";
10026+
10027+
os << ", ";
10028+
os << ".pOptions = ";
10029+
10030+
details::printPtr(os,
10031+
*(params->ppOptions));
10032+
10033+
return os;
10034+
}
10035+
999010036
///////////////////////////////////////////////////////////////////////////////
999110037
/// @brief Print operator for the ur_program_compile_params_t type
999210038
/// @returns
@@ -15830,6 +15876,9 @@ UR_APIEXPORT inline ur_result_t UR_APICALL printFunctionParams(std::ostream &os,
1583015876
case UR_FUNCTION_PROGRAM_BUILD: {
1583115877
os << (const struct ur_program_build_params_t *)params;
1583215878
} break;
15879+
case UR_FUNCTION_PROGRAM_BUILD_EXP: {
15880+
os << (const struct ur_program_build_exp_params_t *)params;
15881+
} break;
1583315882
case UR_FUNCTION_PROGRAM_COMPILE: {
1583415883
os << (const struct ur_program_compile_params_t *)params;
1583515884
} break;

scripts/core/program.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,39 @@ returns:
182182
- "If an error occurred when building `hProgram`."
183183
--- #--------------------------------------------------------------------------
184184
type: function
185+
desc: "Produces an executable program from one program, negates need for the linking step."
186+
class: $xProgram
187+
name: BuildExp
188+
ordinal: "2"
189+
decl: static
190+
analogue:
191+
- "**clBuildProgram**"
192+
details:
193+
- "The application may call this function from simultaneous threads."
194+
- "Following a successful call to this entry point, the program passed will contain a binary of the $X_PROGRAM_BINARY_TYPE_EXECUTABLE type for each device in `hContext`."
195+
params:
196+
- type: $x_context_handle_t
197+
name: hContext
198+
desc: "[in] handle of the context instance."
199+
- type: $x_program_handle_t
200+
name: hProgram
201+
desc: "[in] Handle of the program to build."
202+
- type: uint32_t
203+
name: numDevices
204+
desc: "[in] number of devices"
205+
- type: $x_device_handle_t*
206+
name: phDevices
207+
desc: "[in][range(0, numDevices)] pointer to array of device handles"
208+
- type: const char*
209+
name: pOptions
210+
desc: "[in][optional] pointer to build options null-terminated string."
211+
returns:
212+
- $X_RESULT_ERROR_INVALID_PROGRAM:
213+
- "If `hProgram` isn't a valid program object."
214+
- $X_RESULT_ERROR_PROGRAM_BUILD_FAILURE:
215+
- "If an error occurred when building `hProgram`."
216+
--- #--------------------------------------------------------------------------
217+
type: function
185218
desc: "Produces an executable program from one or more programs."
186219
class: $xProgram
187220
name: Compile

scripts/core/registry.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -547,9 +547,12 @@ etors:
547547
- name: COMMAND_BUFFER_APPEND_USM_ADVISE_EXP
548548
desc: Enumerator for $xCommandBufferAppendUSMAdviseExp
549549
value: '196'
550+
- name: PROGRAM_BUILD_EXP
551+
desc: Enumerator for $xProgramBuildExp
552+
value: '197'
550553
- name: LOADER_CONFIG_SET_CODE_LOCATION_CALLBACK
551554
desc: Enumerator for $xLoaderConfigSetCodeLocationCallback
552-
value: '197'
555+
value: '198'
553556
---
554557
type: enum
555558
desc: Defines structure types

source/adapters/null/ur_nullddi.cpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1749,6 +1749,33 @@ __urdlllocal ur_result_t UR_APICALL urProgramBuild(
17491749
return exceptionToResult(std::current_exception());
17501750
}
17511751

1752+
///////////////////////////////////////////////////////////////////////////////
1753+
/// @brief Intercept function for urProgramBuildExp
1754+
__urdlllocal ur_result_t UR_APICALL urProgramBuildExp(
1755+
ur_context_handle_t hContext, ///< [in] handle of the context instance.
1756+
ur_program_handle_t hProgram, ///< [in] Handle of the program to build.
1757+
uint32_t numDevices, ///< [in] number of devices
1758+
ur_device_handle_t *
1759+
phDevices, ///< [in][range(0, numDevices)] pointer to array of device handles
1760+
const char *
1761+
pOptions ///< [in][optional] pointer to build options null-terminated string.
1762+
) try {
1763+
ur_result_t result = UR_RESULT_SUCCESS;
1764+
1765+
// if the driver has created a custom function, then call it instead of using the generic path
1766+
auto pfnBuildExp = d_context.urDdiTable.ProgramExp.pfnBuildExp;
1767+
if (nullptr != pfnBuildExp) {
1768+
result =
1769+
pfnBuildExp(hContext, hProgram, numDevices, phDevices, pOptions);
1770+
} else {
1771+
// generic implementation
1772+
}
1773+
1774+
return result;
1775+
} catch (...) {
1776+
return exceptionToResult(std::current_exception());
1777+
}
1778+
17521779
///////////////////////////////////////////////////////////////////////////////
17531780
/// @brief Intercept function for urProgramCompile
17541781
__urdlllocal ur_result_t UR_APICALL urProgramCompile(
@@ -5853,6 +5880,36 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetProgramProcAddrTable(
58535880
return exceptionToResult(std::current_exception());
58545881
}
58555882

5883+
///////////////////////////////////////////////////////////////////////////////
5884+
/// @brief Exported function for filling application's ProgramExp table
5885+
/// with current process' addresses
5886+
///
5887+
/// @returns
5888+
/// - ::UR_RESULT_SUCCESS
5889+
/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER
5890+
/// - ::UR_RESULT_ERROR_UNSUPPORTED_VERSION
5891+
UR_DLLEXPORT ur_result_t UR_APICALL urGetProgramExpProcAddrTable(
5892+
ur_api_version_t version, ///< [in] API version requested
5893+
ur_program_exp_dditable_t
5894+
*pDdiTable ///< [in,out] pointer to table of DDI function pointers
5895+
) try {
5896+
if (nullptr == pDdiTable) {
5897+
return UR_RESULT_ERROR_INVALID_NULL_POINTER;
5898+
}
5899+
5900+
if (driver::d_context.version < version) {
5901+
return UR_RESULT_ERROR_UNSUPPORTED_VERSION;
5902+
}
5903+
5904+
ur_result_t result = UR_RESULT_SUCCESS;
5905+
5906+
pDdiTable->pfnBuildExp = driver::urProgramBuildExp;
5907+
5908+
return result;
5909+
} catch (...) {
5910+
return exceptionToResult(std::current_exception());
5911+
}
5912+
58565913
///////////////////////////////////////////////////////////////////////////////
58575914
/// @brief Exported function for filling application's Queue table
58585915
/// with current process' addresses

0 commit comments

Comments
 (0)