@@ -60,6 +60,51 @@ vector_class<device> device::get_devices(info::device_type deviceType) {
6060 }
6161 }
6262 }
63+
64+ // If SYCL_BE is set and there are multiple devices of the same type
65+ // supported by different BE, and one of the devices is from SYCL_BE
66+ // then only add that (and remove all others). This allows to force
67+ // selection of a specific BE for a target, while running on other
68+ // targets, unsupported by the SYCL_BE, with other BEs.
69+ //
70+ if (std::getenv (" SYCL_BE" )) {
71+ vector_class<device> filtered_devices;
72+ auto SyclBE = detail::pi::getPreferredBE ();
73+
74+ // On the first pass see which device types are supported with SYCL_BE
75+ pi_uint64 TypesSupportedBySyclBE = 0 ; // bit-set of info::device_type
76+ for (const auto &dev : devices) {
77+ if (dev.is_host ())
78+ continue ;
79+ auto BE = detail::getSyclObjImpl (dev)->getPlugin ().getBackend ();
80+ if (BE == SyclBE) {
81+ TypesSupportedBySyclBE |=
82+ (pi_uint64)dev.get_info <info::device::device_type>();
83+ }
84+ }
85+ // On the second pass only add devices that are from SYCL_BE or not
86+ // supported there.
87+ //
88+ for (const auto &dev : devices) {
89+ if (dev.is_host ()) {
90+ // TODO: decide if we really want to add the host here.
91+ // The cons of doing so is that if SYCL_BE is set but that BE
92+ // is unavailable for whatever reason, the execution would silently
93+ // proceed to the host while people may think it is running
94+ // with the SYCL_BE as they wanted.
95+ //
96+ filtered_devices.push_back (dev);
97+ continue ;
98+ }
99+
100+ auto BE = detail::getSyclObjImpl (dev)->getPlugin ().getBackend ();
101+ auto Type = (pi_uint64)dev.get_info <info::device::device_type>();
102+ if (BE == SyclBE || (TypesSupportedBySyclBE & Type) == 0 ) {
103+ filtered_devices.push_back (dev);
104+ }
105+ }
106+ return filtered_devices;
107+ }
63108 return devices;
64109}
65110
0 commit comments