77#include < algorithm>
88
99namespace {
10- const auto COMPOSITE_DEVICE = reinterpret_cast <pi_device>(1u );
10+ const auto COMPOSITE_DEVICE_0 = reinterpret_cast <pi_device>(1u );
1111const auto COMPONENT_DEVICE_A = reinterpret_cast <pi_device>(2u );
1212const auto COMPONENT_DEVICE_B = reinterpret_cast <pi_device>(3u );
1313
14+ // We do not report COMPONENT_DEVICE_D through mocked piDevicesGet to emulate
15+ // that it is not available to ensure that COMPOSITE_DEVICE_1 is not returned
16+ // through platform::ext_oneapi_get_composite_devices and
17+ // sycl:ext::oneapi::experimental::get_composite_devices APIs
18+ const auto COMPOSITE_DEVICE_1 = reinterpret_cast <pi_device>(4u );
19+ const auto COMPONENT_DEVICE_C = reinterpret_cast <pi_device>(5u );
20+ const auto COMPONENT_DEVICE_D = reinterpret_cast <pi_device>(6u );
21+
1422pi_result redefine_piDevicesGet (pi_platform platform, pi_device_type,
1523 pi_uint32 num_entries, pi_device *devices,
1624 pi_uint32 *num_devices) {
1725 if (num_devices)
18- *num_devices = 2 ;
26+ *num_devices = 3 ;
1927 if (devices) {
2028 if (num_entries > 0 )
2129 devices[0 ] = COMPONENT_DEVICE_A;
2230 if (num_entries > 1 )
2331 devices[1 ] = COMPONENT_DEVICE_B;
32+ if (num_entries > 2 )
33+ devices[2 ] = COMPONENT_DEVICE_C;
2434 }
2535 return PI_SUCCESS;
2636}
@@ -34,15 +44,17 @@ pi_result after_piDeviceGetInfo(pi_device device, pi_device_info param_name,
3444 *param_value_size_ret = sizeof (pi_device);
3545 if (param_value) {
3646 if (device == COMPONENT_DEVICE_A || device == COMPONENT_DEVICE_B) {
37- *static_cast <pi_device *>(param_value) = COMPOSITE_DEVICE;
47+ *static_cast <pi_device *>(param_value) = COMPOSITE_DEVICE_0;
48+ } else if (device == COMPONENT_DEVICE_C || device == COMPONENT_DEVICE_D) {
49+ *static_cast <pi_device *>(param_value) = COMPOSITE_DEVICE_1;
3850 } else
3951 *static_cast <pi_device *>(param_value) = nullptr ;
4052 }
4153
4254 return PI_SUCCESS;
4355
4456 case PI_EXT_ONEAPI_DEVICE_INFO_COMPONENT_DEVICES:
45- if (device == COMPOSITE_DEVICE ) {
57+ if (device == COMPOSITE_DEVICE_0 ) {
4658 if (param_value_size_ret)
4759 *param_value_size_ret = 2 * sizeof (pi_device);
4860 if (param_value) {
@@ -51,7 +63,15 @@ pi_result after_piDeviceGetInfo(pi_device device, pi_device_info param_name,
5163 if (param_value_size >= 2 * sizeof (pi_device))
5264 static_cast <pi_device *>(param_value)[1 ] = COMPONENT_DEVICE_B;
5365 }
54-
66+ } else if (device == COMPOSITE_DEVICE_1) {
67+ if (param_value_size_ret)
68+ *param_value_size_ret = 2 * sizeof (pi_device);
69+ if (param_value) {
70+ if (param_value_size >= sizeof (pi_device))
71+ static_cast <pi_device *>(param_value)[0 ] = COMPONENT_DEVICE_C;
72+ if (param_value_size >= 2 * sizeof (pi_device))
73+ static_cast <pi_device *>(param_value)[1 ] = COMPONENT_DEVICE_D;
74+ }
5575 } else {
5676 if (param_value_size_ret)
5777 *param_value_size_ret = 0 ;
@@ -110,6 +130,41 @@ pi_result after_piContextCreate(const pi_context_properties *,
110130
111131} // namespace
112132
133+ TEST (CompositeDeviceTest, PlatformExtOneAPIGetCompositeDevices) {
134+ sycl::unittest::PiMock Mock;
135+ Mock.redefine <sycl::detail::PiApiKind::piDevicesGet>(redefine_piDevicesGet);
136+ Mock.redefineAfter <sycl::detail::PiApiKind::piDeviceGetInfo>(
137+ after_piDeviceGetInfo);
138+
139+ sycl::platform Plt = Mock.getPlatform ();
140+
141+ std::vector<sycl::device> Composites = Plt.ext_oneapi_get_composite_devices ();
142+ // We don't expect to see COMPOSITE_DEVICE_1 here, because one of its
143+ // components (COMPONENT_DEVICE_D) is not available.
144+ ASSERT_EQ (Composites.size (), 1u );
145+ ASSERT_EQ (sycl::bit_cast<pi_device>(
146+ sycl::get_native<sycl::backend::opencl>(Composites.front ())),
147+ COMPOSITE_DEVICE_0);
148+ }
149+
150+ TEST (CompositeDeviceTest, SYCLExtOneAPIExperimentalGetCompositeDevices) {
151+ sycl::unittest::PiMock Mock;
152+ Mock.redefine <sycl::detail::PiApiKind::piDevicesGet>(redefine_piDevicesGet);
153+ Mock.redefineAfter <sycl::detail::PiApiKind::piDeviceGetInfo>(
154+ after_piDeviceGetInfo);
155+
156+ sycl::platform Plt = Mock.getPlatform ();
157+
158+ std::vector<sycl::device> Composites =
159+ sycl::ext::oneapi::experimental::get_composite_devices ();
160+ // We don't expect to see COMPOSITE_DEVICE_1 here, because one of its
161+ // components (COMPONENT_DEVICE_D) is not available.
162+ ASSERT_EQ (Composites.size (), 1u );
163+ ASSERT_EQ (sycl::bit_cast<pi_device>(
164+ sycl::get_native<sycl::backend::opencl>(Composites.front ())),
165+ COMPOSITE_DEVICE_0);
166+ }
167+
113168TEST (CompositeDeviceTest, DescendentDeviceSupportInContext) {
114169 sycl::unittest::PiMock Mock;
115170 Mock.redefine <sycl::detail::PiApiKind::piDevicesGet>(redefine_piDevicesGet);
@@ -133,9 +188,9 @@ TEST(CompositeDeviceTest, DescendentDeviceSupportInContext) {
133188 // created for a composite device, we expect them to be implicitly added to
134189 // the context under the hood.
135190 ASSERT_EQ (DevicesUsedInContextCreation.size (), 3u );
136- ASSERT_TRUE (std::any_of (DevicesUsedInContextCreation. begin (),
137- DevicesUsedInContextCreation.end (),
138- [=](pi_device D) { return D == COMPOSITE_DEVICE ; }));
191+ ASSERT_TRUE (std::any_of (
192+ DevicesUsedInContextCreation. begin (), DevicesUsedInContextCreation.end (),
193+ [=](pi_device D) { return D == COMPOSITE_DEVICE_0 ; }));
139194 ASSERT_TRUE (std::any_of (
140195 DevicesUsedInContextCreation.begin (), DevicesUsedInContextCreation.end (),
141196 [=](pi_device D) { return D == COMPONENT_DEVICE_A; }));
0 commit comments