1414
1515#include < helpers/TestKernel.hpp>
1616
17- static ur_device_handle_t rootDevice;
18- static ur_device_handle_t urSubDev1 = (ur_device_handle_t )0x1 ;
19- static ur_device_handle_t urSubDev2 = (ur_device_handle_t )0x2 ;
17+ static ur_device_handle_t rootDevice = (ur_device_handle_t )0x1 ;
18+ // Sub-devices under rootDevice
19+ static ur_device_handle_t urSubDev1 = (ur_device_handle_t )0x11 ;
20+ static ur_device_handle_t urSubDev2 = (ur_device_handle_t )0x12 ;
21+ // Sub-sub-devices under urSubDev1
22+ static ur_device_handle_t urSubSubDev1 = (ur_device_handle_t )0x111 ;
23+ static ur_device_handle_t urSubSubDev2 = (ur_device_handle_t )0x112 ;
2024
2125namespace {
26+ ur_result_t redefinedDeviceGet (void *pParams) {
27+ auto params = *static_cast <ur_device_get_params_t *>(pParams);
28+ if (*params.ppNumDevices )
29+ **params.ppNumDevices = 1 ;
30+ if (*params.pphDevices )
31+ (*params.pphDevices )[0 ] = rootDevice;
32+ return UR_RESULT_SUCCESS;
33+ }
34+
2235ur_result_t redefinedDeviceGetInfo (void *pParams) {
2336 auto params = *static_cast <ur_device_get_info_params_t *>(pParams);
2437 if (*params.ppropName == UR_DEVICE_INFO_SUPPORTED_PARTITIONS) {
@@ -41,13 +54,32 @@ ur_result_t redefinedDeviceGetInfo(void *pParams) {
4154 }
4255 }
4356 if (*params.ppropName == UR_DEVICE_INFO_PARTITION_MAX_SUB_DEVICES) {
44- ((uint32_t *)*params.ppPropValue )[0 ] = 2 ;
57+ if (!*params.ppPropValue )
58+ **params.ppPropSizeRet = sizeof (uint32_t );
59+ else
60+ ((uint32_t *)*params.ppPropValue )[0 ] = 2 ;
4561 }
4662 if (*params.ppropName == UR_DEVICE_INFO_PARENT_DEVICE) {
47- if (*params.phDevice == urSubDev1 || *params.phDevice == urSubDev2)
48- ((ur_device_handle_t *)*params.ppPropValue )[0 ] = rootDevice;
63+ if (!*params.ppPropValue ) {
64+ **params.ppPropSizeRet = sizeof (ur_device_handle_t );
65+ } else {
66+ ur_device_handle_t &ret =
67+ *static_cast <ur_device_handle_t *>(*params.ppPropValue );
68+ if (*params.phDevice == urSubDev1 || *params.phDevice == urSubDev2) {
69+ ret = rootDevice;
70+ } else if (*params.phDevice == urSubSubDev1 ||
71+ *params.phDevice == urSubSubDev2) {
72+ ret = urSubDev1;
73+ } else {
74+ ret = nullptr ;
75+ }
76+ }
77+ }
78+ if (*params.ppropName == UR_DEVICE_INFO_BUILD_ON_SUBDEVICE) {
79+ if (!*params.ppPropValue )
80+ **params.ppPropSizeRet = sizeof (ur_bool_t );
4981 else
50- ((ur_device_handle_t *)*params.ppPropValue )[0 ] = nullptr ;
82+ ((ur_bool_t *)*params.ppPropValue )[0 ] = false ;
5183 }
5284 return UR_RESULT_SUCCESS;
5385}
@@ -77,6 +109,13 @@ ur_result_t redefinedProgramBuild(void *) {
77109 return UR_RESULT_SUCCESS;
78110}
79111
112+ static int buildCallCount = 0 ;
113+
114+ ur_result_t redefinedProgramBuildExp (void *) {
115+ buildCallCount++;
116+ return UR_RESULT_SUCCESS;
117+ }
118+
80119ur_result_t redefinedContextCreate (void *) { return UR_RESULT_SUCCESS; }
81120} // anonymous namespace
82121
@@ -128,3 +167,32 @@ TEST(SubDevices, DISABLED_BuildProgramForSubdevices) {
128167 *sycl::detail::getSyclObjImpl (Ctx), subDev2,
129168 sycl::detail::KernelInfo<TestKernel>::getName ());
130169}
170+
171+ // Check that program is built once for all sub-sub-devices
172+ TEST (SubDevices, BuildProgramForSubSubDevices) {
173+ sycl::unittest::UrMock<> Mock;
174+ mock::getCallbacks ().set_after_callback (" urDeviceGet" , &redefinedDeviceGet);
175+ mock::getCallbacks ().set_after_callback (" urDeviceGetInfo" ,
176+ &redefinedDeviceGetInfo);
177+ mock::getCallbacks ().set_after_callback (" urProgramBuildExp" ,
178+ &redefinedProgramBuildExp);
179+ sycl::platform Plt = sycl::platform ();
180+ sycl::device root = Plt.get_devices ()[0 ];
181+ sycl::detail::platform_impl &PltImpl = *sycl::detail::getSyclObjImpl (Plt);
182+ // Initialize sub-sub-devices
183+ sycl::detail::device_impl &SubSub1 =
184+ PltImpl.getOrMakeDeviceImpl (urSubSubDev1);
185+ sycl::detail::device_impl &SubSub2 =
186+ PltImpl.getOrMakeDeviceImpl (urSubSubDev2);
187+
188+ sycl::context Ctx{root};
189+ buildCallCount = 0 ;
190+ sycl::detail::ProgramManager::getInstance ().getBuiltURProgram (
191+ *sycl::detail::getSyclObjImpl (Ctx), SubSub1,
192+ sycl::detail::ProgramManager::getInstance ().getBuiltURProgram (
193+ *sycl::detail::getSyclObjImpl (Ctx), SubSub2,
194+ sycl::detail::KernelInfo<TestKernel>::getName ());
195+
196+ // Check that program is built only once.
197+ EXPECT_EQ (buildCallCount, 1 );
198+ }
0 commit comments