@@ -279,6 +279,35 @@ UR_APIEXPORT ur_result_t UR_APICALL urQueueCreate(
279
279
ur_queue_handle_t
280
280
*Queue // /< [out] pointer to handle of queue object created
281
281
) {
282
+
283
+ // Make the Device appear as the first device in the context since this
284
+ // is where the urProgramBuild will only build the module to. Also, if
285
+ // the Device is a sub-device then see if there is a also its root-device
286
+ // in the context and make that go first instead (because sub-device can
287
+ // run code built for its root-device).
288
+ //
289
+ // TODO: this is all hacky and should be removed when we add support
290
+ // for building to all the devices in the context.
291
+ //
292
+ { // Lock context for thread-safe update
293
+ std::scoped_lock Lock (Context->Mutex );
294
+ UR_ASSERT (Context->isValidDevice (Device), UR_RESULT_ERROR_INVALID_DEVICE);
295
+
296
+ auto MakeFirst = Context->Devices .begin ();
297
+ for (auto I = Context->Devices .begin (); I != Context->Devices .end (); ++I) {
298
+ if (*I == Device) {
299
+ MakeFirst = I;
300
+ if (!Device->RootDevice )
301
+ break ;
302
+ // continue the search for possible root-device in the context
303
+ } else if (*I == Device->RootDevice ) {
304
+ MakeFirst = I;
305
+ break ; // stop the search
306
+ }
307
+ }
308
+ if (MakeFirst != Context->Devices .begin ())
309
+ std::iter_swap (MakeFirst, Context->Devices .begin ());
310
+ }
282
311
ur_queue_flags_t Flags{};
283
312
if (Props) {
284
313
Flags = Props->flags ;
@@ -297,8 +326,6 @@ UR_APIEXPORT ur_result_t UR_APICALL urQueueCreate(
297
326
}
298
327
}
299
328
300
- UR_ASSERT (Context->isValidDevice (Device), UR_RESULT_ERROR_INVALID_DEVICE);
301
-
302
329
// Create placeholder queues in the compute queue group.
303
330
// Actual L0 queues will be created at first use.
304
331
std::vector<ze_command_queue_handle_t > ZeComputeCommandQueues (
0 commit comments