mirror of
https://github.com/intel/compute-runtime.git
synced 2025-09-15 13:01:45 +08:00
Create mock elf for elf process binary ULTs
Instead of using data loaded from the compiled binary, ULTs testing elf binary data processing will use mock elf created for this purpose. This will ensure mentioned ULTs independence from binary format in the context of incoming zebin switch. Related-To: NEO-6646 Signed-off-by: Kacper Nowak <kacper.nowak@intel.com>
This commit is contained in:

committed by
Compute-Runtime-Automation

parent
95ff289bde
commit
ee4a177296
@ -5,6 +5,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "shared/source/compiler_interface/intermediate_representations.h"
|
||||
#include "shared/source/device/device.h"
|
||||
#include "shared/source/device_binary_format/elf/elf.h"
|
||||
#include "shared/source/device_binary_format/elf/elf_decoder.h"
|
||||
@ -13,11 +14,13 @@
|
||||
#include "shared/source/helpers/string.h"
|
||||
#include "shared/test/common/helpers/test_files.h"
|
||||
#include "shared/test/common/mocks/mock_device.h"
|
||||
#include "shared/test/common/mocks/mock_elf.h"
|
||||
#include "shared/test/unit_test/device_binary_format/patchtokens_tests.h"
|
||||
#include "shared/test/unit_test/helpers/gtest_helpers.h"
|
||||
|
||||
#include "opencl/test/unit_test/mocks/mock_cl_device.h"
|
||||
#include "opencl/test/unit_test/mocks/mock_program.h"
|
||||
#include "opencl/test/unit_test/test_files/patch_list.h"
|
||||
|
||||
#include "compiler_options.h"
|
||||
#include "gtest/gtest.h"
|
||||
@ -26,6 +29,52 @@
|
||||
|
||||
using namespace NEO;
|
||||
|
||||
enum class enabledIrFormat {
|
||||
NONE,
|
||||
ENABLE_SPIRV,
|
||||
ENABLE_LLVM
|
||||
};
|
||||
|
||||
template <enabledIrFormat irFormat = enabledIrFormat::NONE>
|
||||
struct MockElfBinaryPatchtokens {
|
||||
MockElfBinaryPatchtokens(const HardwareInfo &hwInfo) : MockElfBinaryPatchtokens(std::string{}, hwInfo){};
|
||||
MockElfBinaryPatchtokens(const std::string &buildOptions, const HardwareInfo &hwInfo) {
|
||||
mockDevBinaryHeader.Device = hwInfo.platform.eRenderCoreFamily;
|
||||
mockDevBinaryHeader.GPUPointerSizeInBytes = sizeof(void *);
|
||||
mockDevBinaryHeader.Version = iOpenCL::CURRENT_ICBE_VERSION;
|
||||
constexpr size_t mockDevBinaryDataSize = sizeof(mockDevBinaryHeader) + mockDataSize;
|
||||
constexpr size_t mockSpirvBinaryDataSize = sizeof(spirvMagic) + mockDataSize;
|
||||
constexpr size_t mockLlvmBinaryDataSize = sizeof(llvmBcMagic) + mockDataSize;
|
||||
|
||||
char mockDevBinaryData[mockDevBinaryDataSize];
|
||||
memcpy_s(mockDevBinaryData, mockDevBinaryDataSize, &mockDevBinaryHeader, sizeof(mockDevBinaryHeader));
|
||||
memset(mockDevBinaryData + sizeof(mockDevBinaryHeader), '\x01', mockDataSize);
|
||||
|
||||
char mockSpirvBinaryData[mockSpirvBinaryDataSize];
|
||||
memcpy_s(mockSpirvBinaryData, mockSpirvBinaryDataSize, spirvMagic.data(), spirvMagic.size());
|
||||
memset(mockSpirvBinaryData + spirvMagic.size(), '\x02', mockDataSize);
|
||||
|
||||
char mockLlvmBinaryData[mockLlvmBinaryDataSize];
|
||||
memcpy_s(mockLlvmBinaryData, mockLlvmBinaryDataSize, llvmBcMagic.data(), llvmBcMagic.size());
|
||||
memset(mockLlvmBinaryData + llvmBcMagic.size(), '\x03', mockDataSize);
|
||||
|
||||
Elf::ElfEncoder<Elf::EI_CLASS_64> enc;
|
||||
enc.getElfFileHeader().identity = Elf::ElfFileHeaderIdentity(Elf::EI_CLASS_64);
|
||||
enc.getElfFileHeader().type = NEO::Elf::ET_OPENCL_EXECUTABLE;
|
||||
enc.appendSection(Elf::SHT_OPENCL_DEV_BINARY, Elf::SectionNamesOpenCl::deviceBinary, ArrayRef<const uint8_t>::fromAny(mockDevBinaryData, mockDevBinaryDataSize));
|
||||
if (irFormat == enabledIrFormat::ENABLE_SPIRV)
|
||||
enc.appendSection(Elf::SHT_OPENCL_SPIRV, Elf::SectionNamesOpenCl::spirvObject, ArrayRef<const uint8_t>::fromAny(mockSpirvBinaryData, mockSpirvBinaryDataSize));
|
||||
else if (irFormat == enabledIrFormat::ENABLE_LLVM)
|
||||
enc.appendSection(Elf::SHT_OPENCL_LLVM_BINARY, Elf::SectionNamesOpenCl::llvmObject, ArrayRef<const uint8_t>::fromAny(mockLlvmBinaryData, mockLlvmBinaryDataSize));
|
||||
if (false == buildOptions.empty())
|
||||
enc.appendSection(Elf::SHT_OPENCL_OPTIONS, Elf::SectionNamesOpenCl::buildOptions, ArrayRef<const uint8_t>::fromAny(buildOptions.data(), buildOptions.size()));
|
||||
storage = enc.encode();
|
||||
}
|
||||
static constexpr size_t mockDataSize = 0x10;
|
||||
SProgramBinaryHeader mockDevBinaryHeader = SProgramBinaryHeader{MAGIC_CL, 0, 0, 0, 0, 0, 0};
|
||||
std::vector<uint8_t> storage;
|
||||
};
|
||||
|
||||
class ProcessElfBinaryTests : public ::testing::Test {
|
||||
public:
|
||||
void SetUp() override {
|
||||
@ -52,15 +101,14 @@ TEST_F(ProcessElfBinaryTests, GivenInvalidBinaryWhenCreatingProgramFromBinaryThe
|
||||
}
|
||||
|
||||
TEST_F(ProcessElfBinaryTests, GivenValidBinaryWhenCreatingProgramFromBinaryThenSuccessIsReturned) {
|
||||
std::string filePath;
|
||||
retrieveBinaryKernelFilename(filePath, "CopyBuffer_simd16_", ".bin");
|
||||
auto mockElf = std::make_unique<MockElfBinaryPatchtokens<>>(device->getHardwareInfo());
|
||||
auto pBinary = mockElf->storage;
|
||||
auto binarySize = mockElf->storage.size();
|
||||
|
||||
size_t binarySize = 0;
|
||||
auto pBinary = loadDataFromFile(filePath.c_str(), binarySize);
|
||||
cl_int retVal = program->createProgramFromBinary(pBinary.get(), binarySize, *device);
|
||||
cl_int retVal = program->createProgramFromBinary(pBinary.data(), binarySize, *device);
|
||||
|
||||
EXPECT_EQ(CL_SUCCESS, retVal);
|
||||
EXPECT_EQ(0, memcmp(pBinary.get(), program->buildInfos[rootDeviceIndex].packedDeviceBinary.get(), binarySize));
|
||||
EXPECT_EQ(0, memcmp(pBinary.data(), program->buildInfos[rootDeviceIndex].packedDeviceBinary.get(), binarySize));
|
||||
}
|
||||
|
||||
TEST_F(ProcessElfBinaryTests, GivenValidSpirBinaryWhenCreatingProgramFromBinaryThenSuccessIsReturned) {
|
||||
@ -119,19 +167,17 @@ class ProcessElfBinaryTestsWithBinaryType : public ::testing::TestWithParam<unsi
|
||||
device = std::make_unique<MockClDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(nullptr, rootDeviceIndex));
|
||||
program = std::make_unique<MockProgram>(nullptr, false, toClDeviceVector(*device));
|
||||
}
|
||||
|
||||
std::unique_ptr<MockProgram> program;
|
||||
std::unique_ptr<ClDevice> device;
|
||||
const uint32_t rootDeviceIndex = 1;
|
||||
};
|
||||
|
||||
TEST_P(ProcessElfBinaryTestsWithBinaryType, GivenBinaryTypeWhenResolveProgramThenProgramIsProperlyResolved) {
|
||||
std::string filePath;
|
||||
retrieveBinaryKernelFilename(filePath, "CopyBuffer_simd16_", ".bin");
|
||||
auto mockElf = std::make_unique<MockElfBinaryPatchtokens<enabledIrFormat::ENABLE_SPIRV>>(device->getHardwareInfo());
|
||||
auto pBinary = mockElf->storage;
|
||||
auto binarySize = mockElf->storage.size();
|
||||
|
||||
size_t binarySize = 0;
|
||||
auto pBinary = loadDataFromFile(filePath.c_str(), binarySize);
|
||||
cl_int retVal = program->createProgramFromBinary(pBinary.get(), binarySize, *device);
|
||||
cl_int retVal = program->createProgramFromBinary(pBinary.data(), binarySize, *device);
|
||||
auto options = program->options;
|
||||
auto genBinary = makeCopy(program->buildInfos[rootDeviceIndex].unpackedDeviceBinary.get(), program->buildInfos[rootDeviceIndex].unpackedDeviceBinarySize);
|
||||
auto genBinarySize = program->buildInfos[rootDeviceIndex].unpackedDeviceBinarySize;
|
||||
@ -140,7 +186,7 @@ TEST_P(ProcessElfBinaryTestsWithBinaryType, GivenBinaryTypeWhenResolveProgramThe
|
||||
|
||||
EXPECT_EQ(CL_SUCCESS, retVal);
|
||||
ASSERT_EQ(binarySize, program->buildInfos[rootDeviceIndex].packedDeviceBinarySize);
|
||||
EXPECT_EQ(0, memcmp(pBinary.get(), program->buildInfos[rootDeviceIndex].packedDeviceBinary.get(), binarySize));
|
||||
EXPECT_EQ(0, memcmp(pBinary.data(), program->buildInfos[rootDeviceIndex].packedDeviceBinary.get(), binarySize));
|
||||
|
||||
// delete program's elf reference to force a resolve
|
||||
program->buildInfos[rootDeviceIndex].packedDeviceBinary.reset();
|
||||
@ -178,7 +224,6 @@ TEST_P(ProcessElfBinaryTestsWithBinaryType, GivenBinaryTypeWhenResolveProgramThe
|
||||
ASSERT_EQ(options.size(), decodedOptions.size());
|
||||
ASSERT_EQ(genBinarySize, decodedDeviceBinary.size());
|
||||
ASSERT_EQ(irBinarySize, decodedIr.size());
|
||||
|
||||
EXPECT_EQ(0, memcmp(genBinary.get(), decodedDeviceBinary.begin(), genBinarySize));
|
||||
EXPECT_EQ(0, memcmp(irBinary.get(), decodedIr.begin(), irBinarySize));
|
||||
}
|
||||
@ -187,34 +232,12 @@ INSTANTIATE_TEST_CASE_P(ResolveBinaryTests,
|
||||
ProcessElfBinaryTestsWithBinaryType,
|
||||
::testing::ValuesIn(BinaryTypeValues));
|
||||
|
||||
TEST_F(ProcessElfBinaryTests, GivenMultipleCallsWhenCreatingProgramFromBinaryThenEachProgramIsCorrect) {
|
||||
std::string filePath;
|
||||
retrieveBinaryKernelFilename(filePath, "CopyBuffer_simd16_", ".bin");
|
||||
|
||||
size_t binarySize = 0;
|
||||
auto pBinary = loadDataFromFile(filePath.c_str(), binarySize);
|
||||
cl_int retVal = program->createProgramFromBinary(pBinary.get(), binarySize, *device);
|
||||
|
||||
EXPECT_EQ(CL_SUCCESS, retVal);
|
||||
EXPECT_EQ(0, memcmp(pBinary.get(), program->buildInfos[rootDeviceIndex].packedDeviceBinary.get(), binarySize));
|
||||
|
||||
std::string filePath2;
|
||||
retrieveBinaryKernelFilename(filePath2, "simple_arg_int_", ".bin");
|
||||
|
||||
pBinary = loadDataFromFile(filePath2.c_str(), binarySize);
|
||||
retVal = program->createProgramFromBinary(pBinary.get(), binarySize, *device);
|
||||
|
||||
EXPECT_EQ(CL_SUCCESS, retVal);
|
||||
EXPECT_EQ(0, memcmp(pBinary.get(), program->buildInfos[rootDeviceIndex].packedDeviceBinary.get(), binarySize));
|
||||
}
|
||||
|
||||
TEST_F(ProcessElfBinaryTests, GivenEmptyBuildOptionsWhenCreatingProgramFromBinaryThenSuccessIsReturned) {
|
||||
std::string filePath;
|
||||
retrieveBinaryKernelFilename(filePath, "simple_kernels_", ".bin");
|
||||
auto mockElf = std::make_unique<MockElfBinaryPatchtokens<>>(device->getHardwareInfo());
|
||||
auto pBinary = mockElf->storage;
|
||||
auto binarySize = mockElf->storage.size();
|
||||
|
||||
size_t binarySize = 0;
|
||||
auto pBinary = loadDataFromFile(filePath.c_str(), binarySize);
|
||||
cl_int retVal = program->createProgramFromBinary(pBinary.get(), binarySize, *device);
|
||||
cl_int retVal = program->createProgramFromBinary(pBinary.data(), binarySize, *device);
|
||||
|
||||
EXPECT_EQ(CL_SUCCESS, retVal);
|
||||
const auto &options = program->getOptions();
|
||||
@ -223,16 +246,15 @@ TEST_F(ProcessElfBinaryTests, GivenEmptyBuildOptionsWhenCreatingProgramFromBinar
|
||||
}
|
||||
|
||||
TEST_F(ProcessElfBinaryTests, GivenNonEmptyBuildOptionsWhenCreatingProgramFromBinaryThenSuccessIsReturned) {
|
||||
std::string filePath;
|
||||
retrieveBinaryKernelFilename(filePath, "simple_kernels_opts_", ".bin");
|
||||
auto buildOptionsNotEmpty = CompilerOptions::concatenate(CompilerOptions::optDisable, "-DDEF_WAS_SPECIFIED=1");
|
||||
auto mockElf = std::make_unique<MockElfBinaryPatchtokens<>>(buildOptionsNotEmpty, device->getHardwareInfo());
|
||||
auto pBinary = mockElf->storage;
|
||||
auto binarySize = mockElf->storage.size();
|
||||
|
||||
size_t binarySize = 0;
|
||||
auto pBinary = loadDataFromFile(filePath.c_str(), binarySize);
|
||||
cl_int retVal = program->createProgramFromBinary(pBinary.get(), binarySize, *device);
|
||||
cl_int retVal = program->createProgramFromBinary(pBinary.data(), binarySize, *device);
|
||||
|
||||
EXPECT_EQ(CL_SUCCESS, retVal);
|
||||
const auto &options = program->getOptions();
|
||||
std::string buildOptionsNotEmpty = CompilerOptions::concatenate(CompilerOptions::optDisable, "-DDEF_WAS_SPECIFIED=1");
|
||||
EXPECT_TRUE(hasSubstr(options, buildOptionsNotEmpty));
|
||||
}
|
||||
|
||||
@ -256,4 +278,4 @@ TEST_F(ProcessElfBinaryTests, GivenBinaryWhenIncompatiblePatchtokenVerionThenPro
|
||||
cl_int retVal = program->createProgramFromBinary(elfBinary.data(), elfBinary.size(), *device);
|
||||
EXPECT_EQ(CL_INVALID_BINARY, retVal);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user