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,33 @@ 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" 
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::KernelInfo<TestKernel>::getName ());
193+   sycl::detail::ProgramManager::getInstance ().getBuiltURProgram (
194+       *sycl::detail::getSyclObjImpl (Ctx), SubSub2,
195+       sycl::detail::KernelInfo<TestKernel>::getName ());
196+ 
197+   //  Check that program is built only once.
198+   EXPECT_EQ (buildCallCount, 1 );
199+ }
0 commit comments