Files
compute-runtime/opencl/test/unit_test/offline_compiler/ocloc_concat_tests.cpp
Krystian Chmielewski 7982e26ae7 feat(ocloc concat): allow device binary
Allow for use of device binary in ocloc concat. Previously only
AR files could be concatenated.
This feature only works for zebin with AOT Product Config note.

Signed-off-by: Krystian Chmielewski <krystian.chmielewski@intel.com>
2023-02-10 17:45:00 +01:00

181 lines
8.2 KiB
C++

/*
* Copyright (C) 2022-2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/offline_compiler/source/ocloc_error_code.h"
#include "shared/source/device_binary_format/ar/ar_encoder.h"
#include "shared/source/device_binary_format/elf/elf_encoder.h"
#include "shared/test/common/mocks/mock_modules_zebin.h"
#include "gtest/gtest.h"
#include "mock/mock_argument_helper.h"
#include "mock/mock_ocloc_concat.h"
#include "platforms.h"
#include <array>
namespace NEO {
TEST(OclocConcatTest, GivenNoArgumentsWhenInitializingThenErrorIsReturned) {
MockOclocArgHelper::FilesMap mockArgHelperFilesMap{};
MockOclocArgHelper mockArgHelper{mockArgHelperFilesMap};
auto oclocConcat = MockOclocConcat(&mockArgHelper);
std::vector<std::string> args = {"ocloc", "concat"};
::testing::internal::CaptureStdout();
auto error = oclocConcat.initialize(args);
const auto output = ::testing::internal::GetCapturedStdout();
EXPECT_EQ(static_cast<uint32_t>(OclocErrorCode::INVALID_COMMAND_LINE), error);
const std::string expectedOutput = "No files to concatenate were provided.\n";
EXPECT_EQ(expectedOutput, output);
}
TEST(OclocConcatTest, GivenMissingFilesWhenInitializingThenErrorIsReturned) {
MockOclocArgHelper::FilesMap mockArgHelperFilesMap{};
MockOclocArgHelper mockArgHelper{mockArgHelperFilesMap};
auto oclocConcat = MockOclocConcat(&mockArgHelper);
std::vector<std::string> args = {"ocloc", "concat", "fatBinary1.ar", "fatBinary2.ar"};
::testing::internal::CaptureStdout();
auto error = oclocConcat.initialize(args);
const auto output = ::testing::internal::GetCapturedStdout();
EXPECT_EQ(static_cast<uint32_t>(OclocErrorCode::INVALID_COMMAND_LINE), error);
const std::string expectedOutput = "fatBinary1.ar doesn't exist!\nfatBinary2.ar doesn't exist!\n";
EXPECT_EQ(expectedOutput, output);
}
TEST(OclocConcatTest, GivenValidArgsWhenInitializingThenFileNamesToConcatAndOutputFileNameAreSetCorrectlyAndSuccessIsReturned) {
MockOclocArgHelper::FilesMap mockArgHelperFilesMap{
{"fatBinary1.ar", "fatBinary1Data"},
{"fatBinary2.ar", "fatBinary2Data"}};
MockOclocArgHelper mockArgHelper{mockArgHelperFilesMap};
auto oclocConcat = MockOclocConcat(&mockArgHelper);
std::vector<std::string> args = {"ocloc", "concat", "fatBinary1.ar", "fatBinary2.ar", "-out", "fatBinary.ar"};
::testing::internal::CaptureStdout();
auto error = oclocConcat.initialize(args);
const auto output = ::testing::internal::GetCapturedStdout();
EXPECT_EQ(static_cast<uint32_t>(OclocErrorCode::SUCCESS), error);
EXPECT_TRUE(output.empty());
EXPECT_EQ(args[2], oclocConcat.fileNamesToConcat[0]);
EXPECT_EQ(args[3], oclocConcat.fileNamesToConcat[1]);
EXPECT_EQ(args[5], oclocConcat.fatBinaryName);
}
TEST(OclocConcatTest, GivenMissingOutFileNameAfterOutArgumentWhenInitalizingThenErrorIsReturned) {
MockOclocArgHelper::FilesMap mockArgHelperFilesMap{};
MockOclocArgHelper mockArgHelper{mockArgHelperFilesMap};
auto oclocConcat = MockOclocConcat(&mockArgHelper);
std::vector<std::string> args = {"ocloc", "concat", "fatBinary1.ar", "fatBinary2.ar", "-out"};
::testing::internal::CaptureStdout();
auto error = oclocConcat.initialize(args);
const auto output = ::testing::internal::GetCapturedStdout();
EXPECT_EQ(static_cast<uint32_t>(OclocErrorCode::INVALID_COMMAND_LINE), error);
const std::string expectedOutput = "Missing out file name after \"-out\" argument\n";
EXPECT_EQ(expectedOutput, output);
}
TEST(OclocConcatTest, GivenErrorDuringDecodingArWhenConcatenatingThenErrorIsReturned) {
MockOclocArgHelper::FilesMap mockArgHelperFilesMap{
{"fatBinary1.ar", "!<arch>\nInvalidAr"},
{"fatBinary2.ar", "!<arch>\nfatBinary2Data"}};
MockOclocArgHelper mockArgHelper{mockArgHelperFilesMap};
auto oclocConcat = MockOclocConcat(&mockArgHelper);
mockArgHelper.messagePrinter = new MessagePrinter(true);
oclocConcat.shouldFailDecodingAr = true;
oclocConcat.fileNamesToConcat = {"fatBinary1.ar",
"fatBinary2.ar"};
auto error = oclocConcat.concatenate();
const auto output = mockArgHelper.messagePrinter.getLog().str();
EXPECT_EQ(static_cast<uint32_t>(OclocErrorCode::INVALID_FILE), error);
EXPECT_EQ("fatBinary1.ar : Error while decoding AR file\n", output);
}
TEST(OclocConcatTest, GivenBinaryFileNonZebinWhenConcatenatingThenErrorIsReturned) {
MockOclocArgHelper::FilesMap mockArgHelperFilesMap{
{"binary.bin", "NOT Zebin"}};
MockOclocArgHelper mockArgHelper{mockArgHelperFilesMap};
auto oclocConcat = MockOclocConcat(&mockArgHelper);
mockArgHelper.messagePrinter = new MessagePrinter(true);
oclocConcat.fileNamesToConcat = {"binary.bin"};
auto error = oclocConcat.concatenate();
const auto output = mockArgHelper.messagePrinter.getLog().str();
EXPECT_EQ(static_cast<uint32_t>(OclocErrorCode::INVALID_FILE), error);
EXPECT_EQ("binary.bin : Not a zebin file\n", output);
}
TEST(OclocConcatTest, GivenZebinWithoutAOTProductConfigWhenConcatenatingThenErrorIsReturned) {
ZebinTestData::ValidEmptyProgram zebin64;
ZebinTestData::ValidEmptyProgram<Elf::EI_CLASS_32> zebin32;
for (auto zebin : {&zebin64.storage, &zebin32.storage}) {
MockOclocArgHelper::FilesMap mockArgHelperFilesMap{
{"zebin.bin", std::string(reinterpret_cast<const char *>(zebin->data()), zebin->size())}};
MockOclocArgHelper mockArgHelper{mockArgHelperFilesMap};
auto oclocConcat = MockOclocConcat(&mockArgHelper);
mockArgHelper.messagePrinter = new MessagePrinter(true);
oclocConcat.fileNamesToConcat = {"zebin.bin"};
auto error = oclocConcat.concatenate();
const auto output = mockArgHelper.messagePrinter.getLog().str();
EXPECT_EQ(static_cast<uint32_t>(OclocErrorCode::INVALID_FILE), error);
EXPECT_EQ("zebin.bin : Couldn't find AOT product configuration in intelGTNotes section.\n", output);
}
}
TEST(OclocConcatTest, GivenZebinWithAOTNoteAndFatBinaryWhenConcatenatingThenCorrectFatBinaryIsProduced) {
std::vector<uint8_t> fatBinary;
{
std::array<uint8_t, 32> file{0};
NEO::Ar::ArEncoder arEncoder(true);
arEncoder.appendFileEntry("10.0.0", ArrayRef<const uint8_t>::fromAny(file.data(), file.size()));
arEncoder.appendFileEntry("11.0.0", ArrayRef<const uint8_t>::fromAny(file.data(), file.size()));
fatBinary = arEncoder.encode();
}
ZebinTestData::ValidEmptyProgram zebin;
{
AOT::PRODUCT_CONFIG productConfig = AOT::PRODUCT_CONFIG::TGL; // 12.0.0
zebin.appendSection(Elf::SHT_NOTE, Elf::SectionsNamesZebin::noteIntelGT,
ZebinTestData::createIntelGTNoteSection(versionToString(NEO::zeInfoDecoderVersion), productConfig));
}
MockOclocArgHelper::FilesMap mockArgHelperFilesMap{
{"binary.bin", std::string(reinterpret_cast<const char *>(zebin.storage.data()), zebin.storage.size())},
{"fatBinary.ar", std::string(reinterpret_cast<const char *>(fatBinary.data()), fatBinary.size())}};
MockOclocArgHelper mockArgHelper{mockArgHelperFilesMap};
mockArgHelper.interceptOutput = true;
mockArgHelper.messagePrinter = new MessagePrinter(true);
auto oclocConcat = MockOclocConcat(&mockArgHelper);
oclocConcat.fileNamesToConcat = {
"fatBinary.ar",
"binary.bin",
};
auto error = oclocConcat.concatenate();
const auto output = mockArgHelper.messagePrinter.getLog().str();
EXPECT_EQ(static_cast<uint32_t>(OclocErrorCode::SUCCESS), error);
EXPECT_TRUE(output.empty());
EXPECT_EQ(1U, mockArgHelper.interceptedFiles.size());
std::string errors, warnings;
auto &concatedFatBinary = mockArgHelper.interceptedFiles["concat.ar"];
auto concatedAr = NEO::Ar::decodeAr(ArrayRef<const uint8_t>::fromAny(reinterpret_cast<const uint8_t *>(concatedFatBinary.data()), concatedFatBinary.size()), errors, warnings);
EXPECT_TRUE(errors.empty());
EXPECT_TRUE(warnings.empty());
ASSERT_EQ(6U, concatedAr.files.size());
EXPECT_EQ("10.0.0", concatedAr.files[1].fileName);
EXPECT_EQ("11.0.0", concatedAr.files[3].fileName);
EXPECT_EQ("12.0.0", concatedAr.files[5].fileName);
}
} // namespace NEO