Disable zebin on pre-Gen12 platforms when debugger is active

On pre-Gen12 platform we use igfxdcd kernel module for debugging, which
does not support zebinary format.
- When platform is pre-Gen12 an and debugger is
attached, if binary format is zebin and it's not a builtin:
- If SPIR-V is available - force rebuild with zebin disabled
- Otherwise, return an error.
- Minor refactor: extend check for ir presence for each case of
rebuilt in OCL.

Related-To: NEO-7328
Signed-off-by: Kacper Nowak <kacper.nowak@intel.com>
This commit is contained in:
Kacper Nowak
2022-09-27 14:19:01 +00:00
committed by Compute-Runtime-Automation
parent 4eeef388e2
commit 2285772c7e
9 changed files with 183 additions and 6 deletions

View File

@@ -286,6 +286,10 @@ ze_result_t ModuleTranslationUnit::createFromNativeBinary(const char *input, siz
} }
bool rebuild = NEO::DebugManager.flags.RebuildPrecompiledKernels.get() && irBinarySize != 0; bool rebuild = NEO::DebugManager.flags.RebuildPrecompiledKernels.get() && irBinarySize != 0;
rebuild |= NEO::isRebuiltToPatchtokensRequired(device->getNEODevice(), archive, this->options, this->isBuiltIn);
if (rebuild && irBinarySize == 0) {
return ZE_RESULT_ERROR_INVALID_NATIVE_BINARY;
}
if ((false == singleDeviceBinary.deviceBinary.empty()) && (false == rebuild)) { if ((false == singleDeviceBinary.deviceBinary.empty()) && (false == rebuild)) {
this->unpackedDeviceBinary = makeCopy<char>(reinterpret_cast<const char *>(singleDeviceBinary.deviceBinary.begin()), singleDeviceBinary.deviceBinary.size()); this->unpackedDeviceBinary = makeCopy<char>(reinterpret_cast<const char *>(singleDeviceBinary.deviceBinary.begin()), singleDeviceBinary.deviceBinary.size());
this->unpackedDeviceBinarySize = singleDeviceBinary.deviceBinary.size(); this->unpackedDeviceBinarySize = singleDeviceBinary.deviceBinary.size();
@@ -521,6 +525,7 @@ ze_result_t ModuleImp::initialize(const ze_module_desc_t *desc, NEO::Device *neo
} else { } else {
std::string buildFlagsInput{desc->pBuildFlags != nullptr ? desc->pBuildFlags : ""}; std::string buildFlagsInput{desc->pBuildFlags != nullptr ? desc->pBuildFlags : ""};
this->translationUnit->shouldSuppressRebuildWarning = NEO::CompilerOptions::extract(NEO::CompilerOptions::noRecompiledFromIr, buildFlagsInput); this->translationUnit->shouldSuppressRebuildWarning = NEO::CompilerOptions::extract(NEO::CompilerOptions::noRecompiledFromIr, buildFlagsInput);
this->translationUnit->isBuiltIn = this->type == ModuleType::Builtin ? true : false;
this->createBuildOptions(buildFlagsInput.c_str(), buildOptions, internalBuildOptions); this->createBuildOptions(buildFlagsInput.c_str(), buildOptions, internalBuildOptions);
if (type == ModuleType::User) { if (type == ModuleType::User) {

View File

@@ -77,6 +77,7 @@ struct ModuleTranslationUnit {
std::vector<char *> alignedvIsas; std::vector<char *> alignedvIsas;
NEO::specConstValuesMap specConstantsValues; NEO::specConstValuesMap specConstantsValues;
bool isBuiltIn{false};
}; };
struct ModuleImp : public Module { struct ModuleImp : public Module {

View File

@@ -24,6 +24,7 @@
#include "shared/test/common/mocks/mock_elf.h" #include "shared/test/common/mocks/mock_elf.h"
#include "shared/test/common/mocks/mock_graphics_allocation.h" #include "shared/test/common/mocks/mock_graphics_allocation.h"
#include "shared/test/common/mocks/mock_modules_zebin.h" #include "shared/test/common/mocks/mock_modules_zebin.h"
#include "shared/test/common/mocks/mock_source_level_debugger.h"
#include "shared/test/common/test_macros/hw_test.h" #include "shared/test/common/test_macros/hw_test.h"
#include "level_zero/core/source/context/context.h" #include "level_zero/core/source/context/context.h"
@@ -2332,6 +2333,23 @@ HWTEST_F(ModuleTranslationUnitTest, WithNoCompilerWhenCallingStaticLinkSpirVThen
Os::frontEndDllName = oldFclDllName; Os::frontEndDllName = oldFclDllName;
} }
HWTEST_F(ModuleTranslationUnitTest, WhenCreatingFromZeBinaryWithoutSpirvDataIncludedAndLegacyDebuggerAttachedThenReturnError) {
if (false == device->getHwInfo().capabilityTable.debuggerSupported) {
GTEST_SKIP();
}
ZebinTestData::ValidEmptyProgram<> zebin;
const auto &hwInfo = device->getNEODevice()->getHardwareInfo();
zebin.elfHeader->machine = hwInfo.platform.eProductFamily;
neoDevice->executionEnvironment->rootDeviceEnvironments[mockRootDeviceIndex]->debugger.reset(new MockActiveSourceLevelDebugger);
EXPECT_NE(nullptr, neoDevice->getSourceLevelDebugger());
MockModuleTU moduleTu{device};
ASSERT_EQ(0u, moduleTu.irBinarySize);
auto result = moduleTu.createFromNativeBinary(reinterpret_cast<const char *>(zebin.storage.data()), zebin.storage.size());
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_NATIVE_BINARY, result);
}
HWTEST_F(ModuleTranslationUnitTest, WhenBuildOptionsAreNullThenReuseExistingOptions) { HWTEST_F(ModuleTranslationUnitTest, WhenBuildOptionsAreNullThenReuseExistingOptions) {
auto *pMockCompilerInterface = new MockCompilerInterface; auto *pMockCompilerInterface = new MockCompilerInterface;

View File

@@ -192,8 +192,12 @@ cl_int Program::createProgramFromBinary(
this->buildInfos[rootDeviceIndex].debugData = makeCopy(reinterpret_cast<const char *>(singleDeviceBinary.debugData.begin()), singleDeviceBinary.debugData.size()); this->buildInfos[rootDeviceIndex].debugData = makeCopy(reinterpret_cast<const char *>(singleDeviceBinary.debugData.begin()), singleDeviceBinary.debugData.size());
this->buildInfos[rootDeviceIndex].debugDataSize = singleDeviceBinary.debugData.size(); this->buildInfos[rootDeviceIndex].debugDataSize = singleDeviceBinary.debugData.size();
bool forceRebuildBuiltInFromIr = isBuiltIn && DebugManager.flags.RebuildPrecompiledKernels.get(); bool rebuild = isRebuiltToPatchtokensRequired(&clDevice.getDevice(), archive, this->options, this->isBuiltIn);
if ((false == singleDeviceBinary.deviceBinary.empty()) && (false == forceRebuildBuiltInFromIr)) { rebuild |= isBuiltIn && DebugManager.flags.RebuildPrecompiledKernels.get();
if (rebuild && 0u == this->irBinarySize) {
return CL_INVALID_BINARY;
}
if ((false == singleDeviceBinary.deviceBinary.empty()) && (false == rebuild)) {
this->buildInfos[rootDeviceIndex].unpackedDeviceBinary = makeCopy<char>(reinterpret_cast<const char *>(singleDeviceBinary.deviceBinary.begin()), singleDeviceBinary.deviceBinary.size()); this->buildInfos[rootDeviceIndex].unpackedDeviceBinary = makeCopy<char>(reinterpret_cast<const char *>(singleDeviceBinary.deviceBinary.begin()), singleDeviceBinary.deviceBinary.size());
this->buildInfos[rootDeviceIndex].unpackedDeviceBinarySize = singleDeviceBinary.deviceBinary.size(); this->buildInfos[rootDeviceIndex].unpackedDeviceBinarySize = singleDeviceBinary.deviceBinary.size();
this->buildInfos[rootDeviceIndex].packedDeviceBinary = makeCopy<char>(reinterpret_cast<const char *>(archive.begin()), archive.size()); this->buildInfos[rootDeviceIndex].packedDeviceBinary = makeCopy<char>(reinterpret_cast<const char *>(archive.begin()), archive.size());

View File

@@ -13,6 +13,7 @@
#include "shared/source/compiler_interface/compiler_warnings/compiler_warnings.h" #include "shared/source/compiler_interface/compiler_warnings/compiler_warnings.h"
#include "shared/source/compiler_interface/intermediate_representations.h" #include "shared/source/compiler_interface/intermediate_representations.h"
#include "shared/source/device_binary_format/elf/elf_decoder.h" #include "shared/source/device_binary_format/elf/elf_decoder.h"
#include "shared/source/device_binary_format/elf/elf_encoder.h"
#include "shared/source/device_binary_format/elf/ocl_elf.h" #include "shared/source/device_binary_format/elf/ocl_elf.h"
#include "shared/source/device_binary_format/patchtokens_decoder.h" #include "shared/source/device_binary_format/patchtokens_decoder.h"
#include "shared/source/gmm_helper/gmm_helper.h" #include "shared/source/gmm_helper/gmm_helper.h"
@@ -2683,7 +2684,7 @@ TEST_F(ProgramTests, GivenInjectInternalBuildOptionsWhenCompilingBuiltInProgramT
EXPECT_FALSE(CompilerOptions::contains(cip->buildInternalOptions, "-abc")) << cip->buildInternalOptions; EXPECT_FALSE(CompilerOptions::contains(cip->buildInternalOptions, "-abc")) << cip->buildInternalOptions;
} }
TEST(CreateProgramFromBinaryTests, givenBinaryProgramBuiltInWhenKernelRebulildIsForcedThenDeviceBinaryIsNotUsed) { TEST(CreateProgramFromBinaryTests, givenBinaryProgramBuiltInWhenKernelRebulildIsForcedAndIrBinaryIsNotPresentThenErrorIsReturned) {
DebugManagerStateRestore dbgRestorer; DebugManagerStateRestore dbgRestorer;
DebugManager.flags.RebuildPrecompiledKernels.set(true); DebugManager.flags.RebuildPrecompiledKernels.set(true);
cl_int retVal = CL_INVALID_BINARY; cl_int retVal = CL_INVALID_BINARY;
@@ -2695,7 +2696,32 @@ TEST(CreateProgramFromBinaryTests, givenBinaryProgramBuiltInWhenKernelRebulildIs
ASSERT_NE(nullptr, pProgram.get()); ASSERT_NE(nullptr, pProgram.get());
EXPECT_EQ(CL_SUCCESS, retVal); EXPECT_EQ(CL_SUCCESS, retVal);
pProgram->irBinarySize = 0x10;
retVal = pProgram->createProgramFromBinary(programTokens.storage.data(), programTokens.storage.size(), *clDevice);
EXPECT_EQ(CL_INVALID_BINARY, retVal);
}
TEST(CreateProgramFromBinaryTests, givenBinaryProgramBuiltInWhenKernelRebulildIsForcedAndIrBinaryIsPresentThenDeviceBinaryIsNotUsed) {
DebugManagerStateRestore dbgRestorer;
DebugManager.flags.RebuildPrecompiledKernels.set(true);
cl_int retVal = CL_INVALID_BINARY;
PatchTokensTestData::ValidEmptyProgram programTokens;
Elf::ElfEncoder<Elf::EI_CLASS_64> elfEncoder;
elfEncoder.getElfFileHeader().type = Elf::ET_OPENCL_EXECUTABLE;
constexpr auto mockSpirvDataSize = 0x10;
uint8_t mockSpirvData[mockSpirvDataSize]{0};
elfEncoder.appendSection(Elf::SHT_OPENCL_SPIRV, Elf::SectionNamesOpenCl::spirvObject, ArrayRef<const uint8_t>::fromAny(mockSpirvData, mockSpirvDataSize));
programTokens.storage = elfEncoder.encode();
auto clDevice = std::make_unique<MockClDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(nullptr));
std::unique_ptr<MockProgram> pProgram(Program::createBuiltInFromGenBinary<MockProgram>(nullptr, toClDeviceVector(*clDevice), programTokens.storage.data(), programTokens.storage.size(), &retVal));
ASSERT_NE(nullptr, pProgram.get());
EXPECT_EQ(CL_SUCCESS, retVal);
auto rootDeviceIndex = clDevice->getRootDeviceIndex(); auto rootDeviceIndex = clDevice->getRootDeviceIndex();
pProgram->irBinarySize = 0x10;
retVal = pProgram->createProgramFromBinary(programTokens.storage.data(), programTokens.storage.size(), *clDevice); retVal = pProgram->createProgramFromBinary(programTokens.storage.data(), programTokens.storage.size(), *clDevice);
EXPECT_EQ(CL_SUCCESS, retVal); EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(nullptr, pProgram->buildInfos[rootDeviceIndex].unpackedDeviceBinary.get()); EXPECT_EQ(nullptr, pProgram->buildInfos[rootDeviceIndex].unpackedDeviceBinary.get());
@@ -2704,11 +2730,19 @@ TEST(CreateProgramFromBinaryTests, givenBinaryProgramBuiltInWhenKernelRebulildIs
EXPECT_EQ(0U, pProgram->buildInfos[rootDeviceIndex].packedDeviceBinarySize); EXPECT_EQ(0U, pProgram->buildInfos[rootDeviceIndex].packedDeviceBinarySize);
} }
TEST(CreateProgramFromBinaryTests, givenBinaryProgramBuiltInWhenKernelRebulildIsForcedThenRebuildWarningIsEnabled) { TEST(CreateProgramFromBinaryTests, givenBinaryProgramBuiltInWhenKernelRebulildIsForcedAndIrBinaryIsPresentThenRebuildWarningIsEnabled) {
DebugManagerStateRestore dbgRestorer{}; DebugManagerStateRestore dbgRestorer{};
DebugManager.flags.RebuildPrecompiledKernels.set(true); DebugManager.flags.RebuildPrecompiledKernels.set(true);
PatchTokensTestData::ValidEmptyProgram programTokens; PatchTokensTestData::ValidEmptyProgram programTokens;
Elf::ElfEncoder<Elf::EI_CLASS_64> elfEncoder;
elfEncoder.getElfFileHeader().type = Elf::ET_OPENCL_EXECUTABLE;
constexpr auto mockSpirvDataSize = 0x10;
uint8_t mockSpirvData[mockSpirvDataSize]{0};
elfEncoder.appendSection(Elf::SHT_OPENCL_SPIRV, Elf::SectionNamesOpenCl::spirvObject, ArrayRef<const uint8_t>::fromAny(mockSpirvData, mockSpirvDataSize));
programTokens.storage = elfEncoder.encode();
cl_int retVal{CL_INVALID_BINARY}; cl_int retVal{CL_INVALID_BINARY};
const auto clDevice = std::make_unique<MockClDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(nullptr)); const auto clDevice = std::make_unique<MockClDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(nullptr));
@@ -2716,6 +2750,7 @@ TEST(CreateProgramFromBinaryTests, givenBinaryProgramBuiltInWhenKernelRebulildIs
ASSERT_NE(nullptr, pProgram.get()); ASSERT_NE(nullptr, pProgram.get());
ASSERT_EQ(CL_SUCCESS, retVal); ASSERT_EQ(CL_SUCCESS, retVal);
pProgram->irBinarySize = 0x10;
retVal = pProgram->createProgramFromBinary(programTokens.storage.data(), programTokens.storage.size(), *clDevice); retVal = pProgram->createProgramFromBinary(programTokens.storage.data(), programTokens.storage.size(), *clDevice);
ASSERT_EQ(CL_SUCCESS, retVal); ASSERT_EQ(CL_SUCCESS, retVal);

View File

@@ -6,6 +6,7 @@
*/ */
#include "shared/source/compiler_interface/compiler_options.h" #include "shared/source/compiler_interface/compiler_options.h"
#include "shared/source/device_binary_format/elf/elf.h"
#include "shared/source/device_binary_format/patchtokens_decoder.h" #include "shared/source/device_binary_format/patchtokens_decoder.h"
#include "shared/test/common/device_binary_format/elf/elf_tests_data.h" #include "shared/test/common/device_binary_format/elf/elf_tests_data.h"
#include "shared/test/common/helpers/debug_manager_state_restore.h" #include "shared/test/common/helpers/debug_manager_state_restore.h"
@@ -13,7 +14,9 @@
#include "shared/test/common/helpers/kernel_binary_helper.h" #include "shared/test/common/helpers/kernel_binary_helper.h"
#include "shared/test/common/helpers/kernel_filename_helper.h" #include "shared/test/common/helpers/kernel_filename_helper.h"
#include "shared/test/common/libult/global_environment.h" #include "shared/test/common/libult/global_environment.h"
#include "shared/test/common/mocks/mock_modules_zebin.h"
#include "shared/test/common/mocks/mock_source_level_debugger.h" #include "shared/test/common/mocks/mock_source_level_debugger.h"
#include "shared/test/common/test_macros/hw_test.h"
#include "shared/test/common/test_macros/test.h" #include "shared/test/common/test_macros/test.h"
#include "opencl/test/unit_test/fixtures/program_fixture.h" #include "opencl/test/unit_test/fixtures/program_fixture.h"
@@ -42,6 +45,56 @@ TEST_F(ProgramTests, givenProgramObjectWhenEnableKernelDebugIsCalledThenProgramH
EXPECT_TRUE(program.isKernelDebugEnabled()); EXPECT_TRUE(program.isKernelDebugEnabled());
} }
class ZebinFallbackToPatchtokensLegacyDebugger : public ProgramTests {
public:
void SetUp() override {
ProgramTests::SetUp();
device = std::make_unique<MockClDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(nullptr, mockRootDeviceIndex));
const auto &hwInfo = device->getHardwareInfo();
zebin.elfHeader->machine = hwInfo.platform.eProductFamily;
}
void TearDown() override {
ProgramTests::TearDown();
}
ZebinTestData::ValidEmptyProgram<> zebin;
std::unique_ptr<MockClDevice> device;
};
HWTEST_F(ZebinFallbackToPatchtokensLegacyDebugger, WhenCreatingProgramFromNonBuiltinZeBinaryWithSpirvDataIncludedAndLegacyDebuggerAttachedThenSuccessIsReturnedAndRebuildFromPTIsRequired) {
if (sizeof(void *) != 8U) {
GTEST_SKIP();
}
const uint8_t mockSpvData[0x10]{0};
zebin.appendSection(Elf::SHT_ZEBIN_SPIRV, Elf::SectionsNamesZebin::spv, mockSpvData);
std::unique_ptr<MockProgram> program;
device->executionEnvironment->rootDeviceEnvironments[mockRootDeviceIndex]->debugger.reset(new MockActiveSourceLevelDebugger);
ASSERT_NE(nullptr, device->getSourceLevelDebugger());
program = std::make_unique<MockProgram>(toClDeviceVector(*device));
auto retVal = program->createProgramFromBinary(zebin.storage.data(), zebin.storage.size(), *device.get());
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_FALSE(program->isCreatedFromBinary);
EXPECT_TRUE(program->requiresRebuild);
EXPECT_FALSE(CompilerOptions::contains(program->options, CompilerOptions::allowZebin));
}
HWTEST_F(ZebinFallbackToPatchtokensLegacyDebugger, WhenCreatingProgramFromNonBuiltinZeBinaryWithoutSpirvDataIncludedAndLegacyDebuggerAttachedThenErrorIsReturned) {
if (sizeof(void *) != 8U) {
GTEST_SKIP();
}
std::unique_ptr<MockProgram> program;
device->executionEnvironment->rootDeviceEnvironments[mockRootDeviceIndex]->debugger.reset(new MockActiveSourceLevelDebugger);
ASSERT_NE(nullptr, device->getSourceLevelDebugger());
program = std::make_unique<MockProgram>(toClDeviceVector(*device));
ASSERT_EQ(0u, program->irBinarySize);
auto retVal = program->createProgramFromBinary(zebin.storage.data(), zebin.storage.size(), *device.get());
EXPECT_EQ(CL_INVALID_BINARY, retVal);
}
class ProgramWithKernelDebuggingTest : public ProgramFixture, class ProgramWithKernelDebuggingTest : public ProgramFixture,
public ::testing::Test { public ::testing::Test {
public: public:

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2020-2021 Intel Corporation * Copyright (C) 2020-2022 Intel Corporation
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
@@ -7,6 +7,7 @@
#include "shared/source/program/program_info.h" #include "shared/source/program/program_info.h"
#include "shared/source/device/device.h"
#include "shared/source/program/kernel_info.h" #include "shared/source/program/kernel_info.h"
namespace NEO { namespace NEO {
@@ -35,4 +36,19 @@ bool requiresLocalMemoryWindowVA(const ProgramInfo &programInfo) {
return false; return false;
} }
bool isRebuiltToPatchtokensRequired(Device *neoDevice, ArrayRef<const uint8_t> archive, std::string &optionsString, bool isBuiltin) {
if (isBuiltin) {
return false;
}
auto isSourceLevelDebuggerActive = (nullptr != neoDevice->getSourceLevelDebugger());
auto isZebinFormat = NEO::isDeviceBinaryFormat<NEO::DeviceBinaryFormat::Zebin>(archive);
if (isSourceLevelDebuggerActive && isZebinFormat) {
auto pos = optionsString.find(NEO::CompilerOptions::allowZebin.str());
optionsString.erase(pos, pos + NEO::CompilerOptions::allowZebin.length());
optionsString += " " + NEO::CompilerOptions::disableZebin.str();
return true;
}
return false;
}
} // namespace NEO } // namespace NEO

View File

@@ -51,5 +51,6 @@ struct ProgramInfo {
size_t getMaxInlineSlmNeeded(const ProgramInfo &programInfo); size_t getMaxInlineSlmNeeded(const ProgramInfo &programInfo);
bool requiresLocalMemoryWindowVA(const ProgramInfo &programInfo); bool requiresLocalMemoryWindowVA(const ProgramInfo &programInfo);
bool isRebuiltToPatchtokensRequired(Device *neoDevice, ArrayRef<const uint8_t> archive, std::string &optionsString, bool isBuiltin);
} // namespace NEO } // namespace NEO

View File

@@ -7,6 +7,9 @@
#include "shared/source/program/kernel_info.h" #include "shared/source/program/kernel_info.h"
#include "shared/source/program/program_info.h" #include "shared/source/program/program_info.h"
#include "shared/test/common/mocks/mock_device.h"
#include "shared/test/common/mocks/mock_modules_zebin.h"
#include "shared/test/common/mocks/mock_source_level_debugger.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
@@ -57,3 +60,44 @@ TEST(RequiresLocalMemoryWindowVA, GivenProgramWithKernelsWhenSomeOfKernelRequire
programInfo.kernelInfos[1]->kernelDescriptor.payloadMappings.implicitArgs.localMemoryStatelessWindowStartAddres = 0U; programInfo.kernelInfos[1]->kernelDescriptor.payloadMappings.implicitArgs.localMemoryStatelessWindowStartAddres = 0U;
EXPECT_TRUE(NEO::requiresLocalMemoryWindowVA(programInfo)); EXPECT_TRUE(NEO::requiresLocalMemoryWindowVA(programInfo));
} }
TEST(RequiresRebuildWithPatchtokens, givenLegacyDebuggerAttachedAndZebinaryFormatNonBuiltinBinaryWhenCheckingForRebuildRequirementThenReturnTrueAndFallbackToPatchtokens) {
ZebinTestData::ValidEmptyProgram<> zebin;
auto device = std::unique_ptr<MockDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(nullptr));
device->getRootDeviceEnvironmentRef().debugger.reset(new MockActiveSourceLevelDebugger);
std::string options{NEO::CompilerOptions::allowZebin};
bool isBuiltIn{false};
bool rebuildRequired = isRebuiltToPatchtokensRequired(device.get(), ArrayRef<const uint8_t>::fromAny(zebin.storage.data(), zebin.storage.size()), options, isBuiltIn);
EXPECT_TRUE(rebuildRequired);
EXPECT_FALSE(NEO::CompilerOptions::contains(options, NEO::CompilerOptions::allowZebin));
EXPECT_TRUE(NEO::CompilerOptions::contains(options, NEO::CompilerOptions::disableZebin));
}
TEST(RequiresRebuildWithPatchtokens, givenNoLegacyDebuggerAttachedOrNonZebinaryFormatOrBuiltinBinaryWhenCheckingForRebuildRequirementThenReturnFalseAndDoNotFallback) {
ZebinTestData::ValidEmptyProgram<> zebin;
auto device = std::unique_ptr<MockDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(nullptr));
device->getRootDeviceEnvironmentRef().debugger.reset(new MockActiveSourceLevelDebugger);
std::string options{NEO::CompilerOptions::allowZebin};
bool isBuiltIn{true};
bool rebuildRequired = isRebuiltToPatchtokensRequired(device.get(), ArrayRef<const uint8_t>::fromAny(zebin.storage.data(), zebin.storage.size()), options, isBuiltIn);
EXPECT_FALSE(rebuildRequired);
EXPECT_TRUE(NEO::CompilerOptions::contains(options, NEO::CompilerOptions::allowZebin));
isBuiltIn = false;
device->getRootDeviceEnvironmentRef().debugger.reset(nullptr);
rebuildRequired = isRebuiltToPatchtokensRequired(device.get(), ArrayRef<const uint8_t>::fromAny(zebin.storage.data(), zebin.storage.size()), options, isBuiltIn);
EXPECT_FALSE(rebuildRequired);
EXPECT_TRUE(NEO::CompilerOptions::contains(options, NEO::CompilerOptions::allowZebin));
device->getRootDeviceEnvironmentRef().debugger.reset(new MockActiveSourceLevelDebugger);
for (auto idx = 0; idx < 4; idx++) {
zebin.elfHeader->identity.magic[idx] = 0;
} //broken header - zebinary format will not be detected
rebuildRequired = isRebuiltToPatchtokensRequired(device.get(), ArrayRef<const uint8_t>::fromAny(zebin.storage.data(), zebin.storage.size()), options, isBuiltIn);
EXPECT_FALSE(rebuildRequired);
EXPECT_TRUE(NEO::CompilerOptions::contains(options, NEO::CompilerOptions::allowZebin));
}