Add support for specialization constants in Level Zero

Change-Id: Ifc1255365f4f25e83c5c6128f2ea4d8994e0ae8b
Signed-off: Jaime Arteaga <jaime.a.arteaga.molina@intel.com>
This commit is contained in:
Jaime Arteaga
2020-05-18 01:38:56 -07:00
committed by sys_ocldev
parent 389e751cc1
commit 5b0a2ee09b
4 changed files with 349 additions and 220 deletions

View File

@@ -6,6 +6,10 @@
*/
#pragma once
#include "shared/test/unit_test/mocks/mock_compiler_interface.h"
#include "opencl/test/unit_test/mocks/mock_cif.h"
#include "level_zero/core/source/module/module_imp.h"
#include "level_zero/core/test/unit_tests/mock.h"
#include "level_zero/core/test/unit_tests/white_box.h"
@@ -22,6 +26,8 @@ template <>
struct WhiteBox<::L0::Module> : public ::L0::ModuleImp {
using BaseClass = ::L0::ModuleImp;
using BaseClass::BaseClass;
using BaseClass::device;
using BaseClass::translationUnit;
};
using Module = WhiteBox<::L0::Module>;
@@ -44,6 +50,49 @@ struct Mock<Module> : public Module {
MOCK_CONST_METHOD0(isDebugEnabled, bool());
};
struct MockModuleTranslationUnit : public L0::ModuleTranslationUnit {
MockModuleTranslationUnit(L0::Device *device) : L0::ModuleTranslationUnit(device) {
}
bool processUnpackedBinary() override {
return true;
}
};
struct MockCompilerInterface : public NEO::CompilerInterface {
MockCompilerInterface(uint32_t moduleNumSpecConstants) : moduleNumSpecConstants(moduleNumSpecConstants) {
}
NEO::TranslationOutput::ErrorCode build(const NEO::Device &device,
const NEO::TranslationInput &input,
NEO::TranslationOutput &output) override {
EXPECT_EQ(moduleNumSpecConstants, input.specializedValues.size());
for (uint32_t i = 0; i < moduleSpecConstantsIds.size(); i++) {
uint32_t specConstantId = moduleSpecConstantsIds[i];
auto it = input.specializedValues.find(specConstantId);
EXPECT_NE(it, input.specializedValues.end());
uint64_t specConstantValue = moduleSpecConstantsValues[i];
EXPECT_EQ(specConstantValue, it->second);
}
return NEO::TranslationOutput::ErrorCode::Success;
}
NEO::TranslationOutput::ErrorCode getSpecConstantsInfo(const NEO::Device &device,
ArrayRef<const char> srcSpirV, NEO::SpecConstantInfo &output) override {
output.idsBuffer.reset(new NEO::MockCIFBuffer());
for (uint32_t i = 0; i < moduleNumSpecConstants; i++) {
output.idsBuffer->PushBackRawCopy(moduleSpecConstantsIds[i]);
}
return NEO::TranslationOutput::ErrorCode::Success;
}
uint32_t moduleNumSpecConstants = 0u;
const std::vector<uint32_t> moduleSpecConstantsIds{0, 1, 2, 3};
const std::vector<uint64_t> moduleSpecConstantsValues{10, 20, 30, 40};
};
} // namespace ult
} // namespace L0

View File

@@ -7,7 +7,9 @@
#include "test.h"
#include "level_zero/core/source/module/module_imp.h"
#include "level_zero/core/test/unit_tests/fixtures/module_fixture.h"
#include "level_zero/core/test/unit_tests/mocks/mock_module.h"
namespace L0 {
namespace ult {
@@ -54,5 +56,63 @@ HWTEST_F(ModuleTest, givenKernelCreateWithIncorrectKernelNameReturnsFailure) {
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, res);
}
struct ModuleSpecConstantsTests : public DeviceFixture,
public ::testing::Test {
void SetUp() override {
DeviceFixture::SetUp();
mockCompiler = new MockCompilerInterface(moduleNumSpecConstants);
auto rootDeviceEnvironment = neoDevice->getExecutionEnvironment()->rootDeviceEnvironments[0].get();
rootDeviceEnvironment->compilerInterface.reset(mockCompiler);
mockTranslationUnit = new MockModuleTranslationUnit(device);
}
void TearDown() override {
DeviceFixture::TearDown();
}
const uint32_t moduleNumSpecConstants = 4;
ze_module_constants_t specConstants;
std::vector<uint64_t> specConstantsPointerValues;
const std::string binaryFilename = "test_kernel";
const std::string kernelName = "test";
MockCompilerInterface *mockCompiler;
MockModuleTranslationUnit *mockTranslationUnit;
};
HWTEST_F(ModuleSpecConstantsTests, givenSpecializationConstantsSetInDescriptorTheModuleCorrectlyPassesThemToTheCompiler) {
std::string testFile;
retrieveBinaryKernelFilename(testFile, binaryFilename + "_", ".spv");
size_t size = 0;
auto src = loadDataFromFile(testFile.c_str(), size);
ASSERT_NE(0u, size);
ASSERT_NE(nullptr, src);
ze_module_desc_t moduleDesc = {ZE_MODULE_DESC_VERSION_CURRENT};
moduleDesc.format = ZE_MODULE_FORMAT_IL_SPIRV;
moduleDesc.pInputModule = reinterpret_cast<const uint8_t *>(src.get());
moduleDesc.inputSize = size;
specConstants.numConstants = mockCompiler->moduleNumSpecConstants;
for (uint32_t i = 0; i < mockCompiler->moduleNumSpecConstants; i++) {
specConstantsPointerValues.push_back(reinterpret_cast<uint64_t>(&mockCompiler->moduleSpecConstantsValues[i]));
}
specConstants.pConstantIds = mockCompiler->moduleSpecConstantsIds.data();
specConstants.pConstantValues = specConstantsPointerValues.data();
moduleDesc.pConstants = &specConstants;
auto module = new Module(device, neoDevice, nullptr);
module->translationUnit.reset(mockTranslationUnit);
bool success = module->initialize(&moduleDesc, neoDevice);
EXPECT_TRUE(success);
module->destroy();
}
} // namespace ult
} // namespace L0