Skip to content

Commit 321f649

Browse files
committed
Zebin support
Change-Id: I1e426ee2c5174fd0a4c51c1644cda467c2b88881
1 parent 855c474 commit 321f649

27 files changed

+4763
-18
lines changed

opencl/source/program/program.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,10 @@ void Program::replaceDeviceBinary(std::unique_ptr<char[]> newBinary, size_t newB
441441
this->packedDeviceBinarySize = newBinarySize;
442442
this->unpackedDeviceBinary.reset();
443443
this->unpackedDeviceBinarySize = 0U;
444+
if (isAnySingleDeviceBinaryFormat(ArrayRef<const uint8_t>(reinterpret_cast<uint8_t *>(this->packedDeviceBinary.get()), this->packedDeviceBinarySize))) {
445+
this->unpackedDeviceBinary = makeCopy(packedDeviceBinary.get(), packedDeviceBinarySize);
446+
this->unpackedDeviceBinarySize = packedDeviceBinarySize;
447+
}
444448
} else {
445449
this->packedDeviceBinary.reset();
446450
this->packedDeviceBinarySize = 0U;

opencl/test/unit_test/program/program_tests.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "shared/source/memory_manager/surface.h"
2424
#include "shared/source/os_interface/os_context.h"
2525
#include "shared/test/unit_test/device_binary_format/patchtokens_tests.h"
26+
#include "shared/test/unit_test/device_binary_format/zebin_tests.h"
2627
#include "shared/test/unit_test/helpers/debug_manager_state_restore.h"
2728
#include "shared/test/unit_test/mocks/mock_compiler_interface.h"
2829
#include "shared/test/unit_test/utilities/base_object_utils.h"
@@ -3044,3 +3045,17 @@ TEST_F(ProgramBinTest, GivenSourceKernelWhenLinkingProgramThenGtpinInitInfoIsPas
30443045
EXPECT_EQ(pIgcInitPtr, mockCompilerInterface->gtpinInfoPassed);
30453046
mockCompilerInterface.release();
30463047
}
3048+
3049+
TEST(ProgramReplaceDeviceBinary, GivenBinaryZebinThenUseAsBothPackedAndUnpackedBinaryContainer) {
3050+
MockExecutionEnvironment execEnv;
3051+
ZebinTestData::ValidEmptyProgram zebin;
3052+
std::unique_ptr<char[]> src = makeCopy(zebin.storage.data(), zebin.storage.size());
3053+
MockProgram program{execEnv};
3054+
program.replaceDeviceBinary(std::move(src), zebin.storage.size());
3055+
ASSERT_EQ(zebin.storage.size(), program.packedDeviceBinarySize);
3056+
ASSERT_EQ(zebin.storage.size(), program.unpackedDeviceBinarySize);
3057+
ASSERT_NE(nullptr, program.packedDeviceBinary);
3058+
ASSERT_NE(nullptr, program.unpackedDeviceBinary);
3059+
EXPECT_EQ(0, memcmp(program.packedDeviceBinary.get(), zebin.storage.data(), program.packedDeviceBinarySize));
3060+
EXPECT_EQ(0, memcmp(program.unpackedDeviceBinary.get(), zebin.storage.data(), program.unpackedDeviceBinarySize));
3061+
}

opencl/test/unit_test/test_files/igdrcl.config

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,4 +177,6 @@ ForceCacheFlushForBcs = -1
177177
ForceGpgpuSubmissionForBcsEnqueue = -1
178178
ForceSemaphoreDelayBetweenWaits = -1
179179
ForceLocalMemoryAccessMode = -1
180-
UseLegacyLevelZeroAffinity = 1
180+
UseLegacyLevelZeroAffinity = 1
181+
ZebinAppendElws = 0
182+
ZebinIgnoreIcbeVersion = 0

shared/source/compiler_interface/compiler_interface.inl

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77

88
#pragma once
9+
#include "shared/source/debug_settings/debug_settings_manager.h"
910
#include "shared/source/os_interface/os_library.h"
1011

1112
#include "opencl/source/helpers/validators.h"
@@ -105,7 +106,11 @@ inline bool loadCompiler(const char *libName, std::unique_ptr<OsLibrary> &outLib
105106
return false;
106107
}
107108

108-
if (false == main->IsCompatible<EntryPointT>()) {
109+
std::vector<CIF::InterfaceId_t> interfacesToIgnore;
110+
if (DebugManager.flags.ZebinIgnoreIcbeVersion.get()) {
111+
interfacesToIgnore.push_back(IGC::OclGenBinaryBase::GetInterfaceId());
112+
}
113+
if (false == main->IsCompatible<EntryPointT>(&interfacesToIgnore)) {
109114
DEBUG_BREAK_IF(true); // given compiler library is not compatible
110115
return false;
111116
}

shared/source/debug_settings/debug_variables_base.inl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ DECLARE_DEBUG_VARIABLE(bool, OverrideInvalidEngineWithDefault, false, "When set
7272
DECLARE_DEBUG_VARIABLE(bool, ForceImplicitFlush, false, "Flush after each enqueue. Useful for debugging batched submission logic. ")
7373
DECLARE_DEBUG_VARIABLE(bool, ForcePipeControlPriorToWalker, false, "Allows to force pipe contron prior to walker.")
7474
DECLARE_DEBUG_VARIABLE(bool, UseLegacyLevelZeroAffinity, true, "Use Level Zero affinity mask as bit set, as defined in v0.91 specification")
75+
DECLARE_DEBUG_VARIABLE(bool, ZebinAppendElws, false, "Append crossthread data with enqueue local work size")
76+
DECLARE_DEBUG_VARIABLE(bool, ZebinIgnoreIcbeVersion, false, "Ignore IGC\'s ICBE version")
7577

7678
/*LOGGING FLAGS*/
7779
DECLARE_DEBUG_VARIABLE(bool, PrintDeviceAndEngineIdOnSubmission, false, "print submissions device and engine IDs to standard output")

shared/source/device_binary_format/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ set(NEO_DEVICE_BINARY_FORMAT
1414
${CMAKE_CURRENT_SOURCE_DIR}/device_binary_format_ar.cpp
1515
${CMAKE_CURRENT_SOURCE_DIR}/device_binary_format_ocl_elf.cpp
1616
${CMAKE_CURRENT_SOURCE_DIR}/device_binary_format_patchtokens.cpp
17+
${CMAKE_CURRENT_SOURCE_DIR}/device_binary_format_zebin.cpp
1718
${CMAKE_CURRENT_SOURCE_DIR}/device_binary_formats.cpp
1819
${CMAKE_CURRENT_SOURCE_DIR}/device_binary_formats.h
1920
${CMAKE_CURRENT_SOURCE_DIR}/elf/elf.h
@@ -22,12 +23,15 @@ set(NEO_DEVICE_BINARY_FORMAT
2223
${CMAKE_CURRENT_SOURCE_DIR}/elf/elf_encoder.cpp
2324
${CMAKE_CURRENT_SOURCE_DIR}/elf/elf_encoder.h
2425
${CMAKE_CURRENT_SOURCE_DIR}/elf/ocl_elf.h
26+
${CMAKE_CURRENT_SOURCE_DIR}/elf/zebin_elf.h
2527
${CMAKE_CURRENT_SOURCE_DIR}/patchtokens_decoder.cpp
2628
${CMAKE_CURRENT_SOURCE_DIR}/patchtokens_decoder.h
2729
${CMAKE_CURRENT_SOURCE_DIR}/patchtokens_dumper.cpp
2830
${CMAKE_CURRENT_SOURCE_DIR}/patchtokens_dumper.h
2931
${CMAKE_CURRENT_SOURCE_DIR}/patchtokens_validator.cpp
3032
${CMAKE_CURRENT_SOURCE_DIR}/patchtokens_validator.h
33+
${CMAKE_CURRENT_SOURCE_DIR}/zebin_decoder.cpp
34+
${CMAKE_CURRENT_SOURCE_DIR}/zebin_decoder.h
3135
${CMAKE_CURRENT_SOURCE_DIR}/yaml/yaml_parser.cpp
3236
${CMAKE_CURRENT_SOURCE_DIR}/yaml/yaml_parser.h
3337
)
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright (C) 2020 Intel Corporation
3+
*
4+
* SPDX-License-Identifier: MIT
5+
*
6+
*/
7+
8+
#include "shared/source/compiler_interface/intermediate_representations.h"
9+
#include "shared/source/device_binary_format/device_binary_formats.h"
10+
#include "shared/source/device_binary_format/elf/elf_decoder.h"
11+
#include "shared/source/device_binary_format/elf/elf_encoder.h"
12+
#include "shared/source/device_binary_format/elf/zebin_elf.h"
13+
#include "shared/source/program/program_info.h"
14+
15+
#include <tuple>
16+
17+
namespace NEO {
18+
19+
template <>
20+
bool isDeviceBinaryFormat<NEO::DeviceBinaryFormat::Zebin>(const ArrayRef<const uint8_t> binary) {
21+
auto header = Elf::decodeElfFileHeader<Elf::EI_CLASS_64>(binary);
22+
if (nullptr == header) {
23+
return false;
24+
}
25+
26+
return header->type == NEO::Elf::ET_ZEBIN_EXE;
27+
}
28+
29+
template <>
30+
SingleDeviceBinary unpackSingleDeviceBinary<NEO::DeviceBinaryFormat::Zebin>(const ArrayRef<const uint8_t> archive, const ConstStringRef requestedProductAbbreviation, const TargetDevice &requestedTargetDevice,
31+
std::string &outErrReason, std::string &outWarning) {
32+
auto elf = Elf::decodeElf<Elf::EI_CLASS_64>(archive, outErrReason, outWarning);
33+
if (nullptr == elf.elfFileHeader) {
34+
return {};
35+
}
36+
37+
switch (elf.elfFileHeader->type) {
38+
default:
39+
outErrReason = "Unhandled elf type";
40+
return {};
41+
case NEO::Elf::ET_ZEBIN_EXE:
42+
break;
43+
}
44+
45+
const auto &flags = reinterpret_cast<const NEO::Elf::ZebinTargetFlags &>(elf.elfFileHeader->flags);
46+
bool validForTarget = flags.machineEntryUsesGfxCoreInsteadOfProductFamily
47+
? (requestedTargetDevice.coreFamily == static_cast<GFXCORE_FAMILY>(elf.elfFileHeader->machine))
48+
: (requestedTargetDevice.productFamily == static_cast<PRODUCT_FAMILY>(elf.elfFileHeader->machine));
49+
validForTarget &= (requestedTargetDevice.maxPointerSizeInBytes == 8U);
50+
validForTarget &= (0 == flags.validateRevisionId) | ((requestedTargetDevice.stepping >= flags.minHwRevisionId) & (requestedTargetDevice.stepping <= flags.maxHwRevisionId));
51+
if (false == validForTarget) {
52+
outErrReason = "Unhandled target device";
53+
return {};
54+
}
55+
56+
SingleDeviceBinary ret;
57+
ret.deviceBinary = archive;
58+
ret.format = NEO::DeviceBinaryFormat::Zebin;
59+
ret.targetDevice = requestedTargetDevice;
60+
61+
return ret;
62+
}
63+
64+
} // namespace NEO

shared/source/device_binary_format/device_binary_formats.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
namespace NEO {
1111

1212
std::vector<uint8_t> packDeviceBinary(const SingleDeviceBinary binary, std::string &outErrReason, std::string &outWarning) {
13+
if (NEO::isAnyPackedDeviceBinaryFormat(binary.deviceBinary)) {
14+
return std::vector<uint8_t>(binary.deviceBinary.begin(), binary.deviceBinary.end());
15+
}
1316
return packDeviceBinary<DeviceBinaryFormat::OclElf>(binary, outErrReason, outWarning);
1417
}
1518

shared/source/device_binary_format/device_binary_formats.h

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ enum class DeviceBinaryFormat : uint8_t {
2525
OclLibrary,
2626
OclCompiledObject,
2727
Patchtokens,
28-
Archive
28+
Archive,
29+
Zebin
2930
};
3031

3132
enum class DecodeError : uint8_t {
@@ -54,6 +55,7 @@ inline const char *asString(DecodeError err) {
5455

5556
struct TargetDevice {
5657
GFXCORE_FAMILY coreFamily = IGFX_UNKNOWN_CORE;
58+
PRODUCT_FAMILY productFamily = IGFX_UNKNOWN;
5759
uint32_t stepping = 0U;
5860
uint32_t maxPointerSizeInBytes = 4U;
5961
};
@@ -76,6 +78,8 @@ template <>
7678
bool isDeviceBinaryFormat<DeviceBinaryFormat::Patchtokens>(const ArrayRef<const uint8_t>);
7779
template <>
7880
bool isDeviceBinaryFormat<DeviceBinaryFormat::Archive>(const ArrayRef<const uint8_t>);
81+
template <>
82+
bool isDeviceBinaryFormat<DeviceBinaryFormat::Zebin>(const ArrayRef<const uint8_t>);
7983

8084
inline bool isAnyDeviceBinaryFormat(const ArrayRef<const uint8_t> binary) {
8185
if (isDeviceBinaryFormat<DeviceBinaryFormat::OclElf>(binary)) {
@@ -87,6 +91,9 @@ inline bool isAnyDeviceBinaryFormat(const ArrayRef<const uint8_t> binary) {
8791
if (isDeviceBinaryFormat<DeviceBinaryFormat::Archive>(binary)) {
8892
return true;
8993
}
94+
if (isDeviceBinaryFormat<DeviceBinaryFormat::Zebin>(binary)) {
95+
return true;
96+
}
9097
return false;
9198
}
9299

@@ -100,6 +107,8 @@ template <>
100107
SingleDeviceBinary unpackSingleDeviceBinary<DeviceBinaryFormat::Patchtokens>(const ArrayRef<const uint8_t>, const ConstStringRef, const TargetDevice &, std::string &, std::string &);
101108
template <>
102109
SingleDeviceBinary unpackSingleDeviceBinary<DeviceBinaryFormat::Archive>(const ArrayRef<const uint8_t>, const ConstStringRef, const TargetDevice &, std::string &, std::string &);
110+
template <>
111+
SingleDeviceBinary unpackSingleDeviceBinary<DeviceBinaryFormat::Zebin>(const ArrayRef<const uint8_t>, const ConstStringRef, const TargetDevice &, std::string &, std::string &);
103112

104113
inline SingleDeviceBinary unpackSingleDeviceBinary(const ArrayRef<const uint8_t> archive, const ConstStringRef requestedProductAbbreviation, const TargetDevice &requestedTargetDevice,
105114
std::string &outErrReason, std::string &outWarning) {
@@ -111,6 +120,8 @@ inline SingleDeviceBinary unpackSingleDeviceBinary(const ArrayRef<const uint8_t>
111120
return unpackSingleDeviceBinary<DeviceBinaryFormat::Patchtokens>(archive, requestedProductAbbreviation, requestedTargetDevice, outErrReason, outWarning);
112121
} else if (isDeviceBinaryFormat<DeviceBinaryFormat::Archive>(archive)) {
113122
return unpackSingleDeviceBinary<DeviceBinaryFormat::Archive>(archive, requestedProductAbbreviation, requestedTargetDevice, outErrReason, outWarning);
123+
} else if (isDeviceBinaryFormat<DeviceBinaryFormat::Zebin>(archive)) {
124+
return unpackSingleDeviceBinary<DeviceBinaryFormat::Zebin>(archive, requestedProductAbbreviation, requestedTargetDevice, outErrReason, outWarning);
114125
} else {
115126
outErrReason = "Unknown format";
116127
}
@@ -132,11 +143,14 @@ inline bool isAnyPackedDeviceBinaryFormat(const ArrayRef<const uint8_t> binary)
132143
if (isDeviceBinaryFormat<DeviceBinaryFormat::Archive>(binary)) {
133144
return true;
134145
}
146+
if (isDeviceBinaryFormat<DeviceBinaryFormat::Zebin>(binary)) {
147+
return true;
148+
}
135149
return false;
136150
}
137151

138152
inline bool isAnySingleDeviceBinaryFormat(const ArrayRef<const uint8_t> binary) {
139-
return (false == isAnyPackedDeviceBinaryFormat(binary)) && isAnyDeviceBinaryFormat(binary);
153+
return ((false == isAnyPackedDeviceBinaryFormat(binary)) && isAnyDeviceBinaryFormat(binary)) || isDeviceBinaryFormat<DeviceBinaryFormat::Zebin>(binary);
140154
}
141155

142156
template <DeviceBinaryFormat Format>
@@ -148,6 +162,8 @@ template <>
148162
DecodeError decodeSingleDeviceBinary<DeviceBinaryFormat::Patchtokens>(ProgramInfo &, const SingleDeviceBinary &, std::string &, std::string &);
149163
template <>
150164
DecodeError decodeSingleDeviceBinary<DeviceBinaryFormat::Archive>(ProgramInfo &, const SingleDeviceBinary &, std::string &, std::string &);
165+
template <>
166+
DecodeError decodeSingleDeviceBinary<DeviceBinaryFormat::Zebin>(ProgramInfo &, const SingleDeviceBinary &, std::string &, std::string &);
151167

152168
inline std::pair<DecodeError, DeviceBinaryFormat> decodeSingleDeviceBinary(ProgramInfo &dst, const SingleDeviceBinary &src, std::string &outErrReason, std::string &outWarning) {
153169
std::pair<DecodeError, DeviceBinaryFormat> ret;
@@ -162,6 +178,9 @@ inline std::pair<DecodeError, DeviceBinaryFormat> decodeSingleDeviceBinary(Progr
162178
} else if (isDeviceBinaryFormat<DeviceBinaryFormat::Archive>(src.deviceBinary)) {
163179
ret.second = DeviceBinaryFormat::Archive;
164180
ret.first = decodeSingleDeviceBinary<DeviceBinaryFormat::Archive>(dst, src, outErrReason, outWarning);
181+
} else if (isDeviceBinaryFormat<DeviceBinaryFormat::Zebin>(src.deviceBinary)) {
182+
ret.second = DeviceBinaryFormat::Zebin;
183+
ret.first = decodeSingleDeviceBinary<DeviceBinaryFormat::Zebin>(dst, src, outErrReason, outWarning);
165184
} else {
166185
outErrReason = "Unknown format";
167186
}

shared/source/device_binary_format/elf/elf.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,55 @@ struct ElfFileHeader {
303303
static_assert(sizeof(ElfFileHeader<EI_CLASS_32>) == 0x34, "");
304304
static_assert(sizeof(ElfFileHeader<EI_CLASS_64>) == 0x40, "");
305305

306+
template <int NumBits>
307+
struct ElfSymbolEntryTypes;
308+
309+
template <>
310+
struct ElfSymbolEntryTypes<EI_CLASS_32> {
311+
using Name = uint32_t;
312+
using Info = uint8_t;
313+
using Other = uint8_t;
314+
using Shndx = uint16_t;
315+
using Value = uint32_t;
316+
using Size = uint32_t;
317+
};
318+
319+
template <>
320+
struct ElfSymbolEntryTypes<EI_CLASS_64> {
321+
using Name = uint32_t;
322+
using Info = uint8_t;
323+
using Other = uint8_t;
324+
using Shndx = uint16_t;
325+
using Value = uint64_t;
326+
using Size = uint64_t;
327+
};
328+
329+
template <ELF_IDENTIFIER_CLASS NumBits>
330+
struct ElfSymbolEntry;
331+
332+
template <>
333+
struct ElfSymbolEntry<EI_CLASS_32> {
334+
ElfSymbolEntryTypes<EI_CLASS_32>::Name name;
335+
ElfSymbolEntryTypes<EI_CLASS_32>::Value value;
336+
ElfSymbolEntryTypes<EI_CLASS_32>::Size size;
337+
ElfSymbolEntryTypes<EI_CLASS_32>::Info info;
338+
ElfSymbolEntryTypes<EI_CLASS_32>::Other other;
339+
ElfSymbolEntryTypes<EI_CLASS_32>::Shndx shndx;
340+
};
341+
342+
template <>
343+
struct ElfSymbolEntry<EI_CLASS_64> {
344+
ElfSymbolEntryTypes<EI_CLASS_64>::Name name;
345+
ElfSymbolEntryTypes<EI_CLASS_64>::Info info;
346+
ElfSymbolEntryTypes<EI_CLASS_64>::Other other;
347+
ElfSymbolEntryTypes<EI_CLASS_64>::Shndx shndx;
348+
ElfSymbolEntryTypes<EI_CLASS_64>::Value value;
349+
ElfSymbolEntryTypes<EI_CLASS_64>::Size size;
350+
};
351+
352+
static_assert(sizeof(ElfSymbolEntry<EI_CLASS_32>) == 0x10, "");
353+
static_assert(sizeof(ElfSymbolEntry<EI_CLASS_64>) == 0x18, "");
354+
306355
namespace SpecialSectionNames {
307356
static constexpr ConstStringRef bss = ".bss"; // uninitialized memory
308357
static constexpr ConstStringRef comment = ".comment"; // version control information

0 commit comments

Comments
 (0)