From eff1491f95c78436e33a7ad4d9b2c02dcdebcc76 Mon Sep 17 00:00:00 2001 From: Nikita Sirgienko Date: Mon, 5 Feb 2024 13:04:36 +0100 Subject: [PATCH] Build: Cycles: Backport a DPC++ fix for caching of GPU binaries Since the addition of Meteor Lake binaries, prebuilt GPU binaries are now stored as fatbinaries. When running on a platform for which prebuilt binaries are lacking or considered incompatible, the DPC++ SYCL runtime caching logic failed storing the (re)compiled compatible version. This patch to DPC++ SYCL runtime fixes it. --- .../build_environment/patches/dpcpp.diff | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/build_files/build_environment/patches/dpcpp.diff b/build_files/build_environment/patches/dpcpp.diff index a87d1412caf..5605e550397 100644 --- a/build_files/build_environment/patches/dpcpp.diff +++ b/build_files/build_environment/patches/dpcpp.diff @@ -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 Hdr = 0; +- std::copy(ImgData, ImgData + sizeof(Hdr), reinterpret_cast(&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; + } + -- 2.30.2