mirror of
https://github.com/intel/compute-runtime.git
synced 2025-12-18 22:08:53 +08:00
fix(ocl): Force rebuild if binary contains bindless kernel
Related-To: NEO-7063 Signed-off-by: Fabian Zwoliński <fabian.zwolinski@intel.com>
This commit is contained in:
committed by
Compute-Runtime-Automation
parent
90927135f9
commit
59829aeb11
@@ -216,29 +216,30 @@ cl_int Program::processGenBinary(const ClDevice &clDevice) {
|
||||
buildInfo.globalSurface = nullptr;
|
||||
}
|
||||
|
||||
ProgramInfo programInfo;
|
||||
auto blob = ArrayRef<const uint8_t>(reinterpret_cast<const uint8_t *>(buildInfo.unpackedDeviceBinary.get()), buildInfo.unpackedDeviceBinarySize);
|
||||
SingleDeviceBinary binary = {};
|
||||
binary.deviceBinary = blob;
|
||||
binary.targetDevice = NEO::getTargetDevice(clDevice.getRootDeviceEnvironment());
|
||||
std::string decodeErrors;
|
||||
std::string decodeWarnings;
|
||||
if (!decodedSingleDeviceBinary.isSet) {
|
||||
decodedSingleDeviceBinary.programInfo = {};
|
||||
|
||||
DecodeError decodeError;
|
||||
DeviceBinaryFormat singleDeviceBinaryFormat;
|
||||
auto &gfxCoreHelper = clDevice.getGfxCoreHelper();
|
||||
std::tie(decodeError, singleDeviceBinaryFormat) = NEO::decodeSingleDeviceBinary(programInfo, binary, decodeErrors, decodeWarnings, gfxCoreHelper);
|
||||
auto blob = ArrayRef<const uint8_t>(reinterpret_cast<const uint8_t *>(buildInfo.unpackedDeviceBinary.get()), buildInfo.unpackedDeviceBinarySize);
|
||||
SingleDeviceBinary binary = {};
|
||||
binary.deviceBinary = blob;
|
||||
binary.targetDevice = NEO::getTargetDevice(clDevice.getRootDeviceEnvironment());
|
||||
|
||||
if (decodeWarnings.empty() == false) {
|
||||
PRINT_DEBUG_STRING(debugManager.flags.PrintDebugMessages.get(), stderr, "%s\n", decodeWarnings.c_str());
|
||||
auto &gfxCoreHelper = clDevice.getGfxCoreHelper();
|
||||
std::tie(decodedSingleDeviceBinary.decodeError, std::ignore) = NEO::decodeSingleDeviceBinary(decodedSingleDeviceBinary.programInfo, binary, decodedSingleDeviceBinary.decodeErrors, decodedSingleDeviceBinary.decodeWarnings, gfxCoreHelper);
|
||||
} else {
|
||||
decodedSingleDeviceBinary.isSet = false;
|
||||
}
|
||||
|
||||
if (DecodeError::success != decodeError) {
|
||||
PRINT_DEBUG_STRING(debugManager.flags.PrintDebugMessages.get(), stderr, "%s\n", decodeErrors.c_str());
|
||||
if (decodedSingleDeviceBinary.decodeWarnings.empty() == false) {
|
||||
PRINT_DEBUG_STRING(debugManager.flags.PrintDebugMessages.get(), stderr, "%s\n", decodedSingleDeviceBinary.decodeWarnings.c_str());
|
||||
}
|
||||
|
||||
if (DecodeError::success != decodedSingleDeviceBinary.decodeError) {
|
||||
PRINT_DEBUG_STRING(debugManager.flags.PrintDebugMessages.get(), stderr, "%s\n", decodedSingleDeviceBinary.decodeErrors.c_str());
|
||||
return CL_INVALID_BINARY;
|
||||
}
|
||||
|
||||
return this->processProgramInfo(programInfo, clDevice);
|
||||
return this->processProgramInfo(decodedSingleDeviceBinary.programInfo, clDevice);
|
||||
}
|
||||
|
||||
cl_int Program::processProgramInfo(ProgramInfo &src, const ClDevice &clDevice) {
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "shared/source/device_binary_format/elf/ocl_elf.h"
|
||||
#include "shared/source/execution_environment/execution_environment.h"
|
||||
#include "shared/source/execution_environment/root_device_environment.h"
|
||||
#include "shared/source/helpers/addressing_mode_helper.h"
|
||||
#include "shared/source/helpers/api_specific_config.h"
|
||||
#include "shared/source/helpers/compiler_options_parser.h"
|
||||
#include "shared/source/helpers/compiler_product_helper.h"
|
||||
@@ -196,6 +197,19 @@ cl_int Program::createProgramFromBinary(
|
||||
this->options += " " + NEO::CompilerOptions::enableZebin.str();
|
||||
}
|
||||
|
||||
auto deviceBinary = makeCopy<char>(reinterpret_cast<const char *>(singleDeviceBinary.deviceBinary.begin()), singleDeviceBinary.deviceBinary.size());
|
||||
auto blob = ArrayRef<const uint8_t>(reinterpret_cast<const uint8_t *>(deviceBinary.get()), singleDeviceBinary.deviceBinary.size());
|
||||
SingleDeviceBinary binary = {};
|
||||
binary.deviceBinary = blob;
|
||||
binary.targetDevice = NEO::getTargetDevice(clDevice.getRootDeviceEnvironment());
|
||||
|
||||
auto &gfxCoreHelper = clDevice.getGfxCoreHelper();
|
||||
std::tie(decodedSingleDeviceBinary.decodeError, std::ignore) = NEO::decodeSingleDeviceBinary(decodedSingleDeviceBinary.programInfo,
|
||||
binary,
|
||||
decodedSingleDeviceBinary.decodeErrors,
|
||||
decodedSingleDeviceBinary.decodeWarnings,
|
||||
gfxCoreHelper);
|
||||
|
||||
this->buildInfos[rootDeviceIndex].debugData = makeCopy(reinterpret_cast<const char *>(singleDeviceBinary.debugData.begin()), singleDeviceBinary.debugData.size());
|
||||
this->buildInfos[rootDeviceIndex].debugDataSize = singleDeviceBinary.debugData.size();
|
||||
|
||||
@@ -203,7 +217,9 @@ cl_int Program::createProgramFromBinary(
|
||||
this->indirectDetectionVersion = singleDeviceBinary.generatorFeatureVersions.indirectMemoryAccessDetection;
|
||||
|
||||
auto isVmeUsed = containsVmeUsage(this->buildInfos[rootDeviceIndex].kernelInfoArray);
|
||||
bool rebuild = isRebuiltToPatchtokensRequired(&clDevice.getDevice(), archive, this->options, this->isBuiltIn, isVmeUsed);
|
||||
bool rebuild = isRebuiltToPatchtokensRequired(&clDevice.getDevice(), archive, this->options, this->isBuiltIn, isVmeUsed) ||
|
||||
AddressingModeHelper::containsBindlessKernel(decodedSingleDeviceBinary.programInfo.kernelInfos);
|
||||
|
||||
bool flagRebuild = debugManager.flags.RebuildPrecompiledKernels.get();
|
||||
|
||||
if (0u == this->irBinarySize) {
|
||||
@@ -219,12 +235,13 @@ cl_int Program::createProgramFromBinary(
|
||||
}
|
||||
|
||||
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 = std::move(deviceBinary);
|
||||
this->buildInfos[rootDeviceIndex].unpackedDeviceBinarySize = singleDeviceBinary.deviceBinary.size();
|
||||
this->buildInfos[rootDeviceIndex].packedDeviceBinary = makeCopy<char>(reinterpret_cast<const char *>(archive.begin()), archive.size());
|
||||
this->buildInfos[rootDeviceIndex].packedDeviceBinarySize = archive.size();
|
||||
|
||||
this->decodedSingleDeviceBinary.isSet = true;
|
||||
} else {
|
||||
this->decodedSingleDeviceBinary.isSet = false;
|
||||
this->isCreatedFromBinary = false;
|
||||
this->requiresRebuild = true;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#pragma once
|
||||
#include "shared/source/compiler_interface/compiler_interface.h"
|
||||
#include "shared/source/compiler_interface/linker.h"
|
||||
#include "shared/source/device_binary_format/device_binary_formats.h"
|
||||
#include "shared/source/helpers/non_copyable_or_moveable.h"
|
||||
#include "shared/source/program/program_info.h"
|
||||
|
||||
@@ -388,6 +389,14 @@ class Program : public BaseObject<_cl_program> {
|
||||
std::once_flag generateDefaultMetadataOnce;
|
||||
};
|
||||
std::unique_ptr<MetadataGenerationFlags> metadataGenerationFlags;
|
||||
|
||||
struct DecodedSingleDeviceBinary {
|
||||
bool isSet = false;
|
||||
ProgramInfo programInfo;
|
||||
DecodeError decodeError;
|
||||
std::string decodeErrors;
|
||||
std::string decodeWarnings;
|
||||
} decodedSingleDeviceBinary;
|
||||
};
|
||||
|
||||
} // namespace NEO
|
||||
|
||||
@@ -2904,6 +2904,50 @@ TEST(CreateProgramFromBinaryTests, givenBinaryProgramNotBuiltInWhenBuiltInKernel
|
||||
EXPECT_EQ(0U, pProgram->buildInfos[rootDeviceIndex].packedDeviceBinarySize);
|
||||
}
|
||||
|
||||
TEST(CreateProgramFromBinaryTests, givenBinaryWithBindlessKernelWhenCreateProgramFromBinaryThenDeviceBinaryIsNotUsedAndRebuildIsRequired) {
|
||||
std::string validZeInfo = std::string("version :\'") + versionToString(NEO::Zebin::ZeInfo::zeInfoDecoderVersion) + R"===('
|
||||
kernels:
|
||||
- name : kernel_bindless
|
||||
execution_env:
|
||||
simd_size: 8
|
||||
payload_arguments:
|
||||
- arg_type: arg_bypointer
|
||||
offset: 0
|
||||
size: 4
|
||||
arg_index: 0
|
||||
addrmode: bindless
|
||||
addrspace: global
|
||||
access_type: readwrite
|
||||
...
|
||||
)===";
|
||||
|
||||
uint8_t kernelIsa[8]{0U};
|
||||
ZebinTestData::ValidEmptyProgram zebin;
|
||||
zebin.removeSection(NEO::Zebin::Elf::SectionHeaderTypeZebin::SHT_ZEBIN_ZEINFO, NEO::Zebin::Elf::SectionNames::zeInfo);
|
||||
zebin.appendSection(NEO::Zebin::Elf::SectionHeaderTypeZebin::SHT_ZEBIN_ZEINFO, NEO::Zebin::Elf::SectionNames::zeInfo, ArrayRef<const uint8_t>::fromAny(validZeInfo.data(), validZeInfo.size()));
|
||||
zebin.appendSection(NEO::Elf::SHT_PROGBITS, NEO::Zebin::Elf::SectionNames::textPrefix.str() + "kernel_bindless", {kernelIsa, sizeof(kernelIsa)});
|
||||
constexpr auto mockSpirvDataSize = 0x10;
|
||||
uint8_t mockSpirvData[mockSpirvDataSize]{0};
|
||||
zebin.appendSection(Elf::SHT_OPENCL_SPIRV, Elf::SectionNamesOpenCl::spirvObject, ArrayRef<const uint8_t>::fromAny(mockSpirvData, mockSpirvDataSize));
|
||||
zebin.elfHeader->machine = NEO::defaultHwInfo->platform.eProductFamily;
|
||||
|
||||
cl_int retVal = CL_INVALID_BINARY;
|
||||
|
||||
auto clDevice = std::make_unique<MockClDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(nullptr));
|
||||
std::unique_ptr<MockProgram> pProgram(Program::createBuiltInFromGenBinary<MockProgram>(nullptr, toClDeviceVector(*clDevice), zebin.storage.data(), zebin.storage.size(), &retVal));
|
||||
ASSERT_NE(nullptr, pProgram.get());
|
||||
EXPECT_EQ(CL_SUCCESS, retVal);
|
||||
|
||||
auto rootDeviceIndex = clDevice->getRootDeviceIndex();
|
||||
retVal = pProgram->createProgramFromBinary(zebin.storage.data(), zebin.storage.size(), *clDevice);
|
||||
EXPECT_EQ(CL_SUCCESS, retVal);
|
||||
EXPECT_EQ(nullptr, pProgram->buildInfos[rootDeviceIndex].unpackedDeviceBinary.get());
|
||||
EXPECT_EQ(0U, pProgram->buildInfos[rootDeviceIndex].unpackedDeviceBinarySize);
|
||||
EXPECT_EQ(nullptr, pProgram->buildInfos[rootDeviceIndex].packedDeviceBinary);
|
||||
EXPECT_EQ(0U, pProgram->buildInfos[rootDeviceIndex].packedDeviceBinarySize);
|
||||
ASSERT_TRUE(pProgram->requiresRebuild);
|
||||
}
|
||||
|
||||
TEST(CreateProgramFromBinaryTests, givenBinaryProgramWhenKernelRebulildIsNotForcedThenDeviceBinaryIsUsed) {
|
||||
cl_int retVal = CL_INVALID_BINARY;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022-2023 Intel Corporation
|
||||
* Copyright (C) 2022-2024 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
@@ -55,4 +55,13 @@ bool containsStatefulAccess(const std::vector<KernelInfo *> &kernelInfos, bool s
|
||||
return false;
|
||||
}
|
||||
|
||||
bool containsBindlessKernel(const std::vector<KernelInfo *> &kernelInfos) {
|
||||
for (const auto &kernelInfo : kernelInfos) {
|
||||
if (NEO::KernelDescriptor::isBindlessAddressingKernel(kernelInfo->kernelDescriptor)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace NEO::AddressingModeHelper
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022-2023 Intel Corporation
|
||||
* Copyright (C) 2022-2024 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
@@ -17,6 +17,7 @@ namespace AddressingModeHelper {
|
||||
bool failBuildProgramWithStatefulAccess(const RootDeviceEnvironment &rootDeviceEnvironment);
|
||||
bool containsStatefulAccess(const KernelDescriptor &kernelDescriptor, bool skipLastExplicitArg);
|
||||
bool containsStatefulAccess(const std::vector<KernelInfo *> &kernelInfos, bool skipLastExplicitArg);
|
||||
bool containsBindlessKernel(const std::vector<KernelInfo *> &kernelInfos);
|
||||
|
||||
} // namespace AddressingModeHelper
|
||||
} // namespace NEO
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Intel Corporation
|
||||
* Copyright (C) 2023-2024 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
@@ -64,3 +64,33 @@ TEST(AddressingModeHelperTest, GivenLastArgIsPointerWithValidBindlessOffsetWhenI
|
||||
|
||||
EXPECT_FALSE(AddressingModeHelper::containsStatefulAccess(kernelDescriptor, true));
|
||||
}
|
||||
|
||||
TEST(AddressingModeHelperTest, GivenKernelInfosWhenCheckingForBindlessKernelThenReturnCorrectValue) {
|
||||
KernelInfo kernelInfo1{};
|
||||
KernelInfo kernelInfo2{};
|
||||
|
||||
{
|
||||
kernelInfo1.kernelDescriptor.kernelAttributes.bufferAddressingMode = KernelDescriptor::Bindless;
|
||||
std::vector<KernelInfo *> kernelInfos{&kernelInfo1};
|
||||
EXPECT_TRUE(AddressingModeHelper::containsBindlessKernel(kernelInfos));
|
||||
}
|
||||
|
||||
{
|
||||
kernelInfo1.kernelDescriptor.kernelAttributes.bufferAddressingMode = KernelDescriptor::Bindful;
|
||||
std::vector<KernelInfo *> kernelInfos{&kernelInfo1};
|
||||
EXPECT_FALSE(AddressingModeHelper::containsBindlessKernel(kernelInfos));
|
||||
}
|
||||
|
||||
{
|
||||
kernelInfo1.kernelDescriptor.kernelAttributes.bufferAddressingMode = KernelDescriptor::Bindful;
|
||||
std::vector<KernelInfo *> kernelInfos{&kernelInfo1};
|
||||
EXPECT_FALSE(AddressingModeHelper::containsBindlessKernel(kernelInfos));
|
||||
}
|
||||
|
||||
{
|
||||
kernelInfo1.kernelDescriptor.kernelAttributes.bufferAddressingMode = KernelDescriptor::Bindful;
|
||||
kernelInfo2.kernelDescriptor.kernelAttributes.bufferAddressingMode = KernelDescriptor::Bindless;
|
||||
std::vector<KernelInfo *> kernelInfos{&kernelInfo1, &kernelInfo2};
|
||||
EXPECT_TRUE(AddressingModeHelper::containsBindlessKernel(kernelInfos));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user