Build: Cycles: Backport a DPC++ fix for caching of GPU binaries #117844
|
@ -187,3 +187,93 @@ index 17eeaafae194..09e6d2217aaa 100644
|
|||
return SYCLDeviceImages;
|
||||
}
|
||||
|
||||
diff --git a/sycl/source/detail/pi.cpp b/sycl/source/detail/pi.cpp
|
||||
index fb228cd85979..94e8438ee964 100644
|
||||
--- a/sycl/source/detail/pi.cpp
|
||||
+++ b/sycl/source/detail/pi.cpp
|
||||
@@ -635,45 +635,47 @@ static uint16_t getELFHeaderType(const unsigned char *ImgData, size_t ImgSize) {
|
||||
RT::PiDeviceBinaryType getBinaryImageFormat(const unsigned char *ImgData,
|
||||
size_t ImgSize) {
|
||||
// Top-level magic numbers for the recognized binary image formats.
|
||||
- struct {
|
||||
- RT::PiDeviceBinaryType Fmt;
|
||||
- const uint32_t Magic;
|
||||
- } Fmts[] = {{PI_DEVICE_BINARY_TYPE_SPIRV, 0x07230203},
|
||||
- {PI_DEVICE_BINARY_TYPE_LLVMIR_BITCODE, 0xDEC04342},
|
||||
- // 'I', 'N', 'T', 'C' ; Intel native
|
||||
- {PI_DEVICE_BINARY_TYPE_NATIVE, 0x43544E49}};
|
||||
-
|
||||
- if (ImgSize >= sizeof(Fmts[0].Magic)) {
|
||||
- detail::remove_const_t<decltype(Fmts[0].Magic)> Hdr = 0;
|
||||
- std::copy(ImgData, ImgData + sizeof(Hdr), reinterpret_cast<char *>(&Hdr));
|
||||
-
|
||||
- // Check headers for direct formats.
|
||||
- for (const auto &Fmt : Fmts) {
|
||||
- if (Hdr == Fmt.Magic)
|
||||
- return Fmt.Fmt;
|
||||
- }
|
||||
-
|
||||
- // ELF e_type for recognized binary image formats.
|
||||
- struct {
|
||||
- RT::PiDeviceBinaryType Fmt;
|
||||
- const uint16_t Magic;
|
||||
- } ELFFmts[] = {{PI_DEVICE_BINARY_TYPE_NATIVE, 0xFF04}, // OpenCL executable
|
||||
- {PI_DEVICE_BINARY_TYPE_NATIVE, 0xFF12}}; // ZEBIN executable
|
||||
-
|
||||
- // ELF files need to be parsed separately. The header type ends after 18
|
||||
- // bytes.
|
||||
- if (Hdr == 0x464c457F && ImgSize >= 18) {
|
||||
- uint16_t HdrType = getELFHeaderType(ImgData, ImgSize);
|
||||
- for (const auto &ELFFmt : ELFFmts) {
|
||||
- if (HdrType == ELFFmt.Magic)
|
||||
- return ELFFmt.Fmt;
|
||||
- }
|
||||
- // Newer ZEBIN format does not have a special header type, but can instead
|
||||
- // be identified by having a required .ze_info section.
|
||||
- if (checkELFSectionPresent(".ze_info", ImgData, ImgSize))
|
||||
- return PI_DEVICE_BINARY_TYPE_NATIVE;
|
||||
- }
|
||||
+ auto MatchMagicNumber = [&](auto Number) {
|
||||
+ return ImgSize >= sizeof(Number) &&
|
||||
+ std::memcmp(ImgData, &Number, sizeof(Number)) == 0;
|
||||
+ };
|
||||
+
|
||||
+ if (MatchMagicNumber(uint32_t{0x07230203}))
|
||||
+ return PI_DEVICE_BINARY_TYPE_SPIRV;
|
||||
+
|
||||
+ if (MatchMagicNumber(uint32_t{0xDEC04342}))
|
||||
+ return PI_DEVICE_BINARY_TYPE_LLVMIR_BITCODE;
|
||||
+
|
||||
+ if (MatchMagicNumber(uint32_t{0x43544E49}))
|
||||
+ // 'I', 'N', 'T', 'C' ; Intel native
|
||||
+ return PI_DEVICE_BINARY_TYPE_LLVMIR_BITCODE;
|
||||
+
|
||||
+ // Check for ELF format, size requirements include data we'll read in case of
|
||||
+ // succesful match.
|
||||
+ if (ImgSize >= 18 && MatchMagicNumber(uint32_t{0x464c457F})) {
|
||||
+ uint16_t ELFHdrType = getELFHeaderType(ImgData, ImgSize);
|
||||
+ if (ELFHdrType == 0xFF04)
|
||||
+ // OpenCL executable.
|
||||
+ return PI_DEVICE_BINARY_TYPE_NATIVE;
|
||||
+
|
||||
+ if (ELFHdrType == 0xFF12)
|
||||
+ // ZEBIN executable.
|
||||
+ return PI_DEVICE_BINARY_TYPE_NATIVE;
|
||||
+
|
||||
+ // Newer ZEBIN format does not have a special header type, but can instead
|
||||
+ // be identified by having a required .ze_info section.
|
||||
+ if (checkELFSectionPresent(".ze_info", ImgData, ImgSize))
|
||||
+ return PI_DEVICE_BINARY_TYPE_NATIVE;
|
||||
}
|
||||
+
|
||||
+ // "ar" format is used to pack binaries for multiple devices, e.g. via
|
||||
+ //
|
||||
+ // -Xsycl-target-backend=spir64_gen "-device acm-g10,acm-g11"
|
||||
+ //
|
||||
+ // option.
|
||||
+ if (MatchMagicNumber(std::array{'!', '<', 'a', 'r', 'c', 'h', '>', '\n'}))
|
||||
+ return PI_DEVICE_BINARY_TYPE_NATIVE;
|
||||
+
|
||||
return PI_DEVICE_BINARY_TYPE_NONE;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue