@@ -298,6 +298,146 @@ void assertion(bool Condition, const char *Message) {
298
298
die (Message);
299
299
}
300
300
301
+ std::ostream &operator <<(std::ostream &Out, const DeviceBinaryProperty &P) {
302
+ switch (P.Prop ->Type ) {
303
+ case PI_PROPERTY_TYPE_UINT32:
304
+ Out << " [UINT32] " ;
305
+ break ;
306
+ case PI_PROPERTY_TYPE_STRING:
307
+ Out << " [String] " ;
308
+ break ;
309
+ default :
310
+ assert (" unsupported property" );
311
+ return Out;
312
+ }
313
+ Out << P.Prop ->Name << " =" ;
314
+
315
+ switch (P.Prop ->Type ) {
316
+ case PI_PROPERTY_TYPE_UINT32:
317
+ Out << P.asUint32 ();
318
+ break ;
319
+ case PI_PROPERTY_TYPE_STRING:
320
+ Out << P.asCString ();
321
+ break ;
322
+ default :
323
+ assert (" unsupported property" );
324
+ return Out;
325
+ }
326
+ return Out;
327
+ }
328
+
329
+ void DeviceBinaryImage::print () const {
330
+ std::cerr << " --- Image " << Bin << " \n " ;
331
+ if (!Bin)
332
+ return ;
333
+ std::cerr << " Version : " << (int )Bin->Version << " \n " ;
334
+ std::cerr << " Kind : " << (int )Bin->Kind << " \n " ;
335
+ std::cerr << " Format : " << (int )Bin->Format << " \n " ;
336
+ std::cerr << " Target : " << Bin->DeviceTargetSpec << " \n " ;
337
+ std::cerr << " Bin size : "
338
+ << ((intptr_t )Bin->BinaryEnd - (intptr_t )Bin->BinaryStart ) << " \n " ;
339
+ std::cerr << " Compile options : "
340
+ << (Bin->CompileOptions ? Bin->CompileOptions : " NULL" ) << " \n " ;
341
+ std::cerr << " Link options : "
342
+ << (Bin->LinkOptions ? Bin->LinkOptions : " NULL" ) << " \n " ;
343
+ std::cerr << " Entries : " ;
344
+ for (_pi_offload_entry EntriesIt = Bin->EntriesBegin ;
345
+ EntriesIt != Bin->EntriesEnd ; ++EntriesIt)
346
+ std::cerr << EntriesIt->name << " " ;
347
+ std::cerr << " \n " ;
348
+ std::cerr << " Properties [" << Bin->PropertySetsBegin << " -"
349
+ << Bin->PropertySetsEnd << " ]:\n " ;
350
+
351
+ for (pi_device_binary_property_set PS = Bin->PropertySetsBegin ;
352
+ PS != Bin->PropertySetsEnd ; ++PS) {
353
+ std::cerr << " Category " << PS->Name << " [" << PS->PropertiesBegin
354
+ << " -" << PS->PropertiesEnd << " ]:\n " ;
355
+
356
+ for (pi_device_binary_property P = PS->PropertiesBegin ;
357
+ P != PS->PropertiesEnd ; ++P) {
358
+ std::cerr << " " << DeviceBinaryProperty (P) << " \n " ;
359
+ }
360
+ }
361
+ }
362
+
363
+ void DeviceBinaryImage::dump (std::ostream &Out) const {
364
+ size_t ImgSize = getSize ();
365
+ Out.write (reinterpret_cast <const char *>(Bin->BinaryStart ), ImgSize);
366
+ }
367
+
368
+ static pi_uint32 asUint32 (const void *Addr) {
369
+ assert (Addr && " Addr is NULL" );
370
+ const auto *P = reinterpret_cast <const unsigned char *>(Addr);
371
+ return (*P) | (*(P + 1 ) << 8 ) | (*(P + 2 ) << 16 ) | (*(P + 3 ) << 24 );
372
+ }
373
+
374
+ pi_uint32 DeviceBinaryProperty::asUint32 () const {
375
+ assert (Prop->Type == PI_PROPERTY_TYPE_UINT32 && " property type mismatch" );
376
+ // if type fits into the ValSize - it is used to store the property value
377
+ assert (Prop->ValAddr == nullptr && " primitive types must be stored inline" );
378
+ return sycl::detail::pi::asUint32 (&Prop->ValSize );
379
+ }
380
+
381
+ const char *DeviceBinaryProperty::asCString () const {
382
+ assert (Prop->Type == PI_PROPERTY_TYPE_STRING && " property type mismatch" );
383
+ assert (Prop->ValSize > 0 && " property size mismatch" );
384
+ return pi::cast<const char *>(Prop->ValAddr );
385
+ }
386
+
387
+ void DeviceBinaryImage::PropertyRange::init (pi_device_binary Bin,
388
+ const char *PropSetName) {
389
+ assert (!this ->Begin && !this ->End && " already initialized" );
390
+ pi_device_binary_property_set PS = nullptr ;
391
+
392
+ for (PS = Bin->PropertySetsBegin ; PS != Bin->PropertySetsEnd ; ++PS) {
393
+ assert (PS->Name && " nameless property set - bug in the offload wrapper?" );
394
+ if (!strcmp (PropSetName, PS->Name ))
395
+ break ;
396
+ }
397
+ if (PS == Bin->PropertySetsEnd ) {
398
+ Begin = End = nullptr ;
399
+ return ;
400
+ }
401
+ Begin = PS->PropertiesBegin ;
402
+ End = Begin ? PS->PropertiesEnd : nullptr ;
403
+ }
404
+
405
+ RT::PiDeviceBinaryType getBinaryImageFormat (const unsigned char *ImgData,
406
+ size_t ImgSize) {
407
+ struct {
408
+ RT::PiDeviceBinaryType Fmt;
409
+ const uint32_t Magic;
410
+ } Fmts[] = {{PI_DEVICE_BINARY_TYPE_SPIRV, 0x07230203 },
411
+ {PI_DEVICE_BINARY_TYPE_LLVMIR_BITCODE, 0xDEC04342 }};
412
+
413
+ if (ImgSize >= sizeof (Fmts[0 ].Magic )) {
414
+ std::remove_const<decltype (Fmts[0 ].Magic )>::type Hdr = 0 ;
415
+ std::copy (ImgData, ImgData + sizeof (Hdr), reinterpret_cast <char *>(&Hdr));
416
+
417
+ for (const auto &Fmt : Fmts) {
418
+ if (Hdr == Fmt.Magic )
419
+ return Fmt.Fmt ;
420
+ }
421
+ }
422
+ return PI_DEVICE_BINARY_TYPE_NONE;
423
+ }
424
+
425
+ void DeviceBinaryImage::init (pi_device_binary Bin) {
426
+ this ->Bin = Bin;
427
+ // If device binary image format wasn't set by its producer, then can't change
428
+ // now, because 'Bin' data is part of the executable image loaded into memory
429
+ // which can't be modified (easily).
430
+ // TODO clang driver + ClangOffloadWrapper can figure out the format and set
431
+ // it when invoking the offload wrapper job
432
+ Format = static_cast <pi::PiDeviceBinaryType>(Bin->Format );
433
+
434
+ if (Format == PI_DEVICE_BINARY_TYPE_NONE)
435
+ // try to determine the format; may remain "NONE"
436
+ Format = getBinaryImageFormat (Bin->BinaryStart , getSize ());
437
+
438
+ SpecConstIDMap.init (Bin, PI_PROPERTY_SET_SPEC_CONST_MAP);
439
+ }
440
+
301
441
} // namespace pi
302
442
} // namespace detail
303
443
} // namespace sycl
0 commit comments