Add initial implementation of specialization constants

Related-To: NEO-2260

Change-Id: Ib722109039555a028eb4ec0862e9de72342f9730
Signed-off-by: Jobczyk, Lukasz <lukasz.jobczyk@intel.com>
This commit is contained in:
Jobczyk, Lukasz 2019-04-25 12:46:43 +02:00 committed by sys_ocldev
parent 3a75c4fb71
commit 971eb7a1b4
16 changed files with 561 additions and 42 deletions

View File

@ -165,7 +165,7 @@ if(NOT DEFINED KHRONOS_HEADERS_DIR)
get_filename_component(DIR_tmp "${CMAKE_CURRENT_SOURCE_DIR}/third_party/opencl_headers" ABSOLUTE)
if(IS_DIRECTORY ${DIR_tmp})
set(KHRONOS_HEADERS_DIR ${DIR_tmp})
add_definitions(-DCL_TARGET_OPENCL_VERSION=210)
add_definitions(-DCL_TARGET_OPENCL_VERSION=220)
else()
message(FATAL_ERROR "Khronos OpenCL headers not available!")
endif()

View File

@ -4659,3 +4659,21 @@ cl_int CL_API_CALL clAddCommentINTEL(cl_platform_id platform, const char *commen
return retVal;
}
cl_int CL_API_CALL clSetProgramSpecializationConstant(cl_program program, cl_uint specId, size_t specSize, const void *specValue) {
cl_int retVal = CL_SUCCESS;
API_ENTER(&retVal);
DBG_LOG_INPUTS("program", program,
"specId", specId,
"specSize", specSize,
"specValue", specValue);
Program *pProgram = nullptr;
retVal = validateObjects(WithCastToInternal(program, &pProgram), specValue);
if (retVal == CL_SUCCESS) {
retVal = pProgram->setProgramSpecializationConstant(specId, specSize, specValue);
}
return retVal;
}

View File

@ -916,3 +916,11 @@ extern CL_API_ENTRY cl_program CL_API_CALL clCreateProgramWithILKHR(
size_t length,
cl_int *errcodeRet) CL_API_SUFFIX__VERSION_1_2;
}
// OpenCL 2.2
cl_int CL_API_CALL clSetProgramSpecializationConstant(
cl_program program,
cl_uint specId,
size_t specSize,
const void *specValue);

View File

@ -131,7 +131,7 @@ cl_int CompilerInterface::build(
if (!binaryLoaded) {
auto igcTranslationCtx = createIgcTranslationCtx(device, intermediateCodeType, IGC::CodeType::oclGenBin);
auto igcOutput = translate(igcTranslationCtx.get(), intermediateRepresentation.get(),
auto igcOutput = translate(igcTranslationCtx.get(), intermediateRepresentation.get(), program.getSpecConstIdsBuffer().get(), program.getSpecConstValuesBuffer().get(),
fclOptions.get(), fclInternalOptions.get(), inputArgs.GTPinInput);
if (igcOutput == nullptr) {
@ -272,6 +272,27 @@ cl_int CompilerInterface::link(
return CL_SUCCESS;
}
cl_int CompilerInterface::getSpecConstantsInfo(Program &program, const TranslationArgs &inputArgs) {
if (false == isCompilerAvailable()) {
return CL_COMPILER_NOT_AVAILABLE;
}
auto igcTranslationCtx = createIgcTranslationCtx(program.getDevice(0), IGC::CodeType::spirV, IGC::CodeType::oclGenBin);
auto inSrc = CIF::Builtins::CreateConstBuffer(igcMain.get(), inputArgs.pInput, inputArgs.InputSize);
program.getSpecConstIdsBuffer() = CIF::Builtins::CreateConstBuffer(igcMain.get(), nullptr, 0);
program.getSpecConstSizesBuffer() = CIF::Builtins::CreateConstBuffer(igcMain.get(), nullptr, 0);
program.getSpecConstValuesBuffer() = CIF::Builtins::CreateConstBuffer(igcMain.get(), nullptr, 0);
auto retVal = getSpecConstantsInfoImpl(igcTranslationCtx.get(), inSrc.get(), program.getSpecConstIdsBuffer().get(), program.getSpecConstSizesBuffer().get(), program.getSpecConstValuesBuffer().get());
if (!retVal) {
return CL_OUT_OF_HOST_MEMORY;
}
return CL_SUCCESS;
}
cl_int CompilerInterface::createLibrary(
Program &program,
const TranslationArgs &inputArgs) {

View File

@ -57,6 +57,8 @@ class CompilerInterface {
MOCKABLE_VIRTUAL cl_int link(Program &program, const TranslationArgs &pInputArgs);
MOCKABLE_VIRTUAL cl_int getSpecConstantsInfo(Program &program, const TranslationArgs &inputArgs);
cl_int createLibrary(Program &program, const TranslationArgs &pInputArgs);
MOCKABLE_VIRTUAL cl_int getSipKernelBinary(SipKernelType kernel, const Device &device, std::vector<char> &retBinary);

View File

@ -54,6 +54,37 @@ inline CIF::RAII::UPtr_t<IGC::OclTranslationOutputTagOCL> translate(TranslationC
return ret;
}
template <typename TranslationCtx>
inline bool getSpecConstantsInfoImpl(TranslationCtx *tCtx,
CIFBuffer *src,
CIFBuffer *outSpecConstantsIds,
CIFBuffer *outSpecConstantsSizes,
CIFBuffer *outSpecConstantsValues) {
if (!NEO::areNotNullptr(tCtx, src, outSpecConstantsIds, outSpecConstantsSizes, outSpecConstantsValues)) {
return false;
}
return tCtx->GetSpecConstantsInfoImpl(src, outSpecConstantsIds, outSpecConstantsSizes);
}
template <typename TranslationCtx>
inline CIF::RAII::UPtr_t<IGC::OclTranslationOutputTagOCL> translate(TranslationCtx *tCtx, CIFBuffer *src, CIFBuffer *specConstantsIds, CIFBuffer *specConstantsValues, CIFBuffer *options,
CIFBuffer *internalOptions, void *gtpinInit) {
if (false == NEO::areNotNullptr(tCtx, src, options, internalOptions)) {
return nullptr;
}
auto ret = tCtx->Translate(src, specConstantsIds, specConstantsValues, options, internalOptions, nullptr, 0, gtpinInit);
if (ret == nullptr) {
return nullptr; // assume OOM or internal error
}
if (!NEO::areNotNullptr(ret->GetOutput(), ret->GetBuildLog(), ret->GetDebugData())) {
return nullptr; // assume OOM or internal error
}
return ret;
}
CIF::CIFMain *createMainNoSanitize(CIF::CreateCIFMainFunc_t createFunc);
template <template <CIF::Version_t> class EntryPointT>

View File

@ -210,6 +210,56 @@ cl_int Program::rebuildProgramFromIr() {
return retVal;
}
cl_int Program::setProgramSpecializationConstant(cl_uint specId, size_t specSize, const void *specValue) {
if (!isSpirV) {
return CL_INVALID_PROGRAM;
}
static std::mutex mutex;
std::lock_guard<std::mutex> lock(mutex);
if (!areSpecializationConstantsInitialized) {
auto pCompilerInterface = this->executionEnvironment.getCompilerInterface();
if (nullptr == pCompilerInterface) {
return CL_OUT_OF_HOST_MEMORY;
}
TranslationArgs inputArgs = {};
inputArgs.pInput = const_cast<char *>(sourceCode.c_str());
inputArgs.InputSize = static_cast<uint32_t>(sourceCode.size());
inputArgs.pOptions = options.c_str();
inputArgs.OptionsSize = static_cast<uint32_t>(options.length());
inputArgs.pInternalOptions = internalOptions.c_str();
inputArgs.InternalOptionsSize = static_cast<uint32_t>(internalOptions.length());
inputArgs.pTracingOptions = nullptr;
inputArgs.TracingOptionsCount = 0;
auto retVal = pCompilerInterface->getSpecConstantsInfo(*this, inputArgs);
if (retVal != CL_SUCCESS) {
return retVal;
}
areSpecializationConstantsInitialized = true;
}
return updateSpecializationConstant(specId, specSize, specValue);
}
cl_int Program::updateSpecializationConstant(cl_uint specId, size_t specSize, const void *specValue) {
for (uint32_t i = 0; i < specConstantsIds->GetSize<cl_uint>(); i++) {
if (specConstantsIds->GetMemory<cl_uint>()[i] == specId) {
if (specConstantsSizes->GetMemory<size_t>()[i] == specSize) {
specConstantsValues->GetMemoryWriteable<const void *>()[i] = specValue;
return CL_SUCCESS;
} else {
return CL_INVALID_VALUE;
}
}
}
return CL_INVALID_SPEC_ID;
}
void Program::getProgramCompilerVersion(
SProgramBinaryHeader *pSectionData,
uint32_t &binaryVersion) const {

View File

@ -15,6 +15,7 @@
#include "runtime/helpers/string_helpers.h"
#include "block_kernel_manager.h"
#include "cif/builtins/memory/buffer/buffer.h"
#include "igfxfmid.h"
#include "kernel_info.h"
#include "patch_list.h"
@ -117,6 +118,9 @@ class Program : public BaseObject<_cl_program> {
void(CL_CALLBACK *funcNotify)(cl_program program, void *userData),
void *userData);
cl_int setProgramSpecializationConstant(cl_uint specId, size_t specSize, const void *specValue);
MOCKABLE_VIRTUAL cl_int updateSpecializationConstant(cl_uint specId, size_t specSize, const void *specValue);
size_t getNumKernels() const;
const KernelInfo *getKernelInfo(const char *kernelName) const;
const KernelInfo *getKernelInfo(size_t ordinal) const;
@ -242,6 +246,18 @@ class Program : public BaseObject<_cl_program> {
return debugDataSize;
}
CIF::RAII::UPtr_t<CIF::Builtins::BufferSimple> &getSpecConstIdsBuffer() {
return this->specConstantsIds;
}
CIF::RAII::UPtr_t<CIF::Builtins::BufferSimple> &getSpecConstValuesBuffer() {
return this->specConstantsValues;
}
CIF::RAII::UPtr_t<CIF::Builtins::BufferSimple> &getSpecConstSizesBuffer() {
return this->specConstantsSizes;
}
protected:
Program(ExecutionEnvironment &executionEnvironment);
@ -286,60 +302,64 @@ class Program : public BaseObject<_cl_program> {
static const std::string clOptNameClVer;
static const std::string clOptNameUniformWgs;
// clang-format off
cl_program_binary_type programBinaryType;
bool isSpirV = false;
cl_program_binary_type programBinaryType;
bool isSpirV = false;
CLElfLib::ElfBinaryStorage elfBinary;
size_t elfBinarySize;
size_t elfBinarySize;
char* genBinary;
size_t genBinarySize;
char *genBinary;
size_t genBinarySize;
char* irBinary;
size_t irBinarySize;
char *irBinary;
size_t irBinarySize;
char* debugData;
size_t debugDataSize;
char *debugData;
size_t debugDataSize;
CreatedFrom createdFrom = CreatedFrom::UNKNOWN;
CreatedFrom createdFrom = CreatedFrom::UNKNOWN;
std::vector<KernelInfo*> kernelInfoArray;
std::vector<KernelInfo*> parentKernelInfoArray;
std::vector<KernelInfo*> subgroupKernelInfoArray;
BlockKernelManager * blockKernelManager;
std::vector<KernelInfo *> kernelInfoArray;
std::vector<KernelInfo *> parentKernelInfoArray;
std::vector<KernelInfo *> subgroupKernelInfoArray;
BlockKernelManager *blockKernelManager;
const void* programScopePatchList;
size_t programScopePatchListSize;
const void *programScopePatchList;
size_t programScopePatchListSize;
GraphicsAllocation* constantSurface;
GraphicsAllocation* globalSurface;
GraphicsAllocation *constantSurface;
GraphicsAllocation *globalSurface;
size_t globalVarTotalSize;
size_t globalVarTotalSize;
cl_build_status buildStatus;
bool isCreatedFromBinary;
bool isProgramBinaryResolved;
cl_build_status buildStatus;
bool isCreatedFromBinary;
bool isProgramBinaryResolved;
std::string sourceCode;
std::string options;
std::string internalOptions;
std::string sourceCode;
std::string options;
std::string internalOptions;
static const std::vector<std::string> internalOptionsToExtract;
std::string hashFileName;
std::string hashFilePath;
std::string hashFileName;
std::string hashFilePath;
uint32_t programOptionVersion;
bool allowNonUniform;
uint32_t programOptionVersion;
bool allowNonUniform;
std::map<const Device*, std::string> buildLog;
std::map<const Device *, std::string> buildLog;
ExecutionEnvironment& executionEnvironment;
Context* context;
Device* pDevice;
cl_uint numDevices;
bool areSpecializationConstantsInitialized = false;
CIF::RAII::UPtr_t<CIF::Builtins::BufferSimple> specConstantsIds;
CIF::RAII::UPtr_t<CIF::Builtins::BufferSimple> specConstantsSizes;
CIF::RAII::UPtr_t<CIF::Builtins::BufferSimple> specConstantsValues;
bool isBuiltIn;
bool kernelDebugEnabled = false;
ExecutionEnvironment &executionEnvironment;
Context *context;
Device *pDevice;
cl_uint numDevices;
bool isBuiltIn;
bool kernelDebugEnabled = false;
friend class OfflineCompiler;
// clang-format on
};
} // namespace NEO

View File

@ -114,6 +114,7 @@ set(IGDRCL_SRCS_tests_api
${CMAKE_CURRENT_SOURCE_DIR}/cl_set_mem_object_destructor_callback_tests.inl
${CMAKE_CURRENT_SOURCE_DIR}/cl_set_mem_object_destructor_callback_tests_mt.cpp
${CMAKE_CURRENT_SOURCE_DIR}/cl_set_performance_configuration_tests.inl
${CMAKE_CURRENT_SOURCE_DIR}/cl_set_program_specialization_constant_tests.inl
${CMAKE_CURRENT_SOURCE_DIR}/cl_svm_alloc_tests.inl
${CMAKE_CURRENT_SOURCE_DIR}/cl_svm_free_tests.inl
${CMAKE_CURRENT_SOURCE_DIR}/cl_unload_compiler_tests.inl

View File

@ -34,6 +34,7 @@
#include "unit_tests/api/cl_set_kernel_exec_info_tests.inl"
#include "unit_tests/api/cl_set_mem_object_destructor_callback_tests.inl"
#include "unit_tests/api/cl_set_performance_configuration_tests.inl"
#include "unit_tests/api/cl_set_program_specialization_constant_tests.inl"
#include "unit_tests/api/cl_svm_alloc_tests.inl"
#include "unit_tests/api/cl_svm_free_tests.inl"
#include "unit_tests/api/cl_unload_compiler_tests.inl"

View File

@ -0,0 +1,35 @@
/*
* Copyright (C) 2019 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "unit_tests/api/cl_api_tests.h"
using namespace NEO;
namespace ULT {
TEST(clSetProgramSpecializationConstantTest, givenNullptrProgramWhenSetProgramSpecializationConstantThenErrorIsReturned) {
auto retVal = clSetProgramSpecializationConstant(nullptr, 1, 1, nullptr);
EXPECT_EQ(CL_INVALID_PROGRAM, retVal);
}
using clSetProgramSpecializationConstantTests = api_tests;
TEST_F(clSetProgramSpecializationConstantTests, givenNonSpirVProgramWhenSetProgramSpecializationConstantThenErrorIsReturned) {
pProgram->isSpirV = false;
int specValue = 1;
auto retVal = clSetProgramSpecializationConstant(pProgram, 1, sizeof(int), &specValue);
EXPECT_EQ(CL_INVALID_PROGRAM, retVal);
}
TEST_F(clSetProgramSpecializationConstantTests, givenProperProgramAndNullptrSpecValueWhenSetProgramSpecializationConstantThenErrorIsReturned) {
pProgram->isSpirV = true;
auto retVal = clSetProgramSpecializationConstant(pProgram, 1, 1, nullptr);
EXPECT_EQ(CL_INVALID_VALUE, retVal);
}
} // namespace ULT

View File

@ -572,7 +572,18 @@ struct TranslationCtxMock {
CIF::Builtins::BufferSimple *options,
CIF::Builtins::BufferSimple *internalOptions,
CIF::Builtins::BufferSimple *tracingOptions,
uint32_t tracingOptionsCount, void *gtpinInit) {
uint32_t tracingOptionsCount,
void *gtpinInit) {
return this->Translate(src, options, internalOptions, tracingOptions, tracingOptionsCount);
}
CIF::RAII::UPtr_t<IGC::OclTranslationOutputTagOCL> Translate(CIF::Builtins::BufferSimple *src,
CIF::Builtins::BufferSimple *specConstantsIds,
CIF::Builtins::BufferSimple *specConstantsValues,
CIF::Builtins::BufferSimple *options,
CIF::Builtins::BufferSimple *internalOptions,
CIF::Builtins::BufferSimple *tracingOptions,
uint32_t tracingOptionsCount,
void *gtPinInput) {
return this->Translate(src, options, internalOptions, tracingOptions, tracingOptionsCount);
}
};
@ -591,6 +602,40 @@ TEST(TranslateTest, whenArgsAreValidAndTranslatorReturnsValidOutputThenValidOutp
EXPECT_EQ(mockIntOpt.get(), mockTranslationCtx.receivedIntOpt);
}
TEST(TranslateTest, givenGtPinInputWhenArgsAreValidAndTranslatorReturnsValidOutputThenValidOutputIsReturned) {
TranslationCtxMock mockTranslationCtx;
auto mockSrc = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
auto mockOpt = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
auto mockIntOpt = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
auto ret = NEO::translate(&mockTranslationCtx, mockSrc.get(), mockOpt.get(), mockIntOpt.get(), nullptr);
EXPECT_NE(nullptr, ret);
EXPECT_EQ(mockSrc.get(), mockTranslationCtx.receivedSrc);
EXPECT_EQ(mockOpt.get(), mockTranslationCtx.receivedOpt);
EXPECT_EQ(mockIntOpt.get(), mockTranslationCtx.receivedIntOpt);
}
TEST(TranslateTest, whenArgsAreInvalidThenNullptrIsReturned) {
auto mockSrc = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
auto mockOpt = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
auto mockIntOpt = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
auto ret = NEO::translate<TranslationCtxMock>(nullptr, mockSrc.get(), mockOpt.get(), mockIntOpt.get());
EXPECT_EQ(nullptr, ret);
}
TEST(TranslateTest, givenGtPinInputWhenArgsAreInvalidThenNullptrIsReturned) {
auto mockSrc = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
auto mockOpt = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
auto mockIntOpt = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
auto ret = NEO::translate<TranslationCtxMock>(nullptr, mockSrc.get(), mockOpt.get(), mockIntOpt.get(), nullptr);
EXPECT_EQ(nullptr, ret);
}
TEST(TranslateTest, whenTranslatorReturnsNullptrThenNullptrIsReturned) {
TranslationCtxMock mockTranslationCtx;
mockTranslationCtx.returnNullptr = true;
@ -600,6 +645,15 @@ TEST(TranslateTest, whenTranslatorReturnsNullptrThenNullptrIsReturned) {
EXPECT_EQ(nullptr, ret);
}
TEST(TranslateTest, givenSpecConstantsBuffersWhenTranslatorReturnsNullptrThenNullptrIsReturned) {
TranslationCtxMock mockTranslationCtx;
mockTranslationCtx.returnNullptr = true;
auto mockCifBuffer = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
auto ret = NEO::translate(&mockTranslationCtx, mockCifBuffer.get(), mockCifBuffer.get(), mockCifBuffer.get(), mockCifBuffer.get(), mockCifBuffer.get(), nullptr);
EXPECT_EQ(nullptr, ret);
}
TEST(TranslateTest, givenNullPtrAsGtPinInputWhenTranslatorReturnsNullptrThenNullptrIsReturned) {
TranslationCtxMock mockTranslationCtx;
mockTranslationCtx.returnNullptr = true;
@ -633,6 +687,18 @@ TEST(TranslateTest, givenNullPtrAsGtPinInputWhenTranslatorReturnsInvalidOutputTh
}
}
TEST(TranslateTest, givenSpecConstantsBuffersAndNullPtrAsGtPinInputWhenTranslatorReturnsInvalidOutputThenNullptrIsReturned) {
TranslationCtxMock mockTranslationCtx;
auto mockCifBuffer = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
for (uint32_t i = 1; i <= (1 << 3) - 1; ++i) {
mockTranslationCtx.returnNullptrDebugData = (i & 1) != 0;
mockTranslationCtx.returnNullptrLog = (i & (1 << 1)) != 0;
mockTranslationCtx.returnNullptrOutput = (i & (1 << 2)) != 0;
auto ret = NEO::translate(&mockTranslationCtx, mockCifBuffer.get(), mockCifBuffer.get(), mockCifBuffer.get(), mockCifBuffer.get(), mockCifBuffer.get(), nullptr);
EXPECT_EQ(nullptr, ret);
}
}
TEST(TranslateTest, whenAnyArgIsNullThenNullptrIsReturnedAndTranslatorIsNotInvoked) {
TranslationCtxMock mockTranslationCtx;
auto mockCifBuffer = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
@ -961,3 +1027,142 @@ TEST_F(CompilerInterfaceTest, whenRequestingSipKernelBinaryThenProperInternalOpt
gEnvironment->igcPopDebugVars();
}
TEST_F(CompilerInterfaceTest, whenCompilerIsNotAvailableThenGetSpecializationConstantsFails) {
pCompilerInterface->GetIgcMain()->Release();
pCompilerInterface->SetIgcMain(nullptr);
TranslationArgs inputArgs;
retVal = pCompilerInterface->getSpecConstantsInfo(*pProgram, inputArgs);
EXPECT_EQ(CL_COMPILER_NOT_AVAILABLE, retVal);
}
struct SpecConstantsTranslationCtxMock {
bool returnFalse = false;
CIF::Builtins::BufferSimple *receivedSrc = nullptr;
CIF::Builtins::BufferSimple *receivedOutSpecConstantsIds = nullptr;
CIF::Builtins::BufferSimple *receivedOutSpecConstantsSizes = nullptr;
bool GetSpecConstantsInfoImpl(CIFBuffer *src, CIFBuffer *outSpecConstantsIds, CIFBuffer *outSpecConstantsSizes) {
this->receivedSrc = src;
this->receivedOutSpecConstantsIds = outSpecConstantsIds;
this->receivedOutSpecConstantsSizes = outSpecConstantsSizes;
return !returnFalse;
}
};
TEST(GetSpecConstantsTest, givenNullptrTranslationContextAndBuffersWhenGetSpecializationConstantsThenErrorIsReturned) {
EXPECT_FALSE(NEO::getSpecConstantsInfoImpl<SpecConstantsTranslationCtxMock>(nullptr, nullptr, nullptr, nullptr, nullptr));
}
TEST(GetSpecConstantsTest, whenGetSpecializationConstantsSuccedThenSuccessIsReturnedAndBuffersArePassed) {
SpecConstantsTranslationCtxMock tCtxMock;
auto mockSrc = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
auto mockIds = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
auto mockSizes = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
auto mockValues = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
auto ret = NEO::getSpecConstantsInfoImpl(&tCtxMock, mockSrc.get(), mockIds.get(), mockSizes.get(), mockValues.get());
EXPECT_TRUE(ret);
EXPECT_EQ(mockSrc.get(), tCtxMock.receivedSrc);
EXPECT_EQ(mockIds.get(), tCtxMock.receivedOutSpecConstantsIds);
EXPECT_EQ(mockSizes.get(), tCtxMock.receivedOutSpecConstantsSizes);
}
TEST(GetSpecConstantsTest, whenGetSpecializationConstantsFailThenErrorIsReturnedAndBuffersArePassed) {
SpecConstantsTranslationCtxMock tCtxMock;
tCtxMock.returnFalse = true;
auto mockSrc = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
auto mockIds = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
auto mockSizes = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
auto mockValues = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
auto ret = NEO::getSpecConstantsInfoImpl(&tCtxMock, mockSrc.get(), mockIds.get(), mockSizes.get(), mockValues.get());
EXPECT_FALSE(ret);
EXPECT_EQ(mockSrc.get(), tCtxMock.receivedSrc);
EXPECT_EQ(mockIds.get(), tCtxMock.receivedOutSpecConstantsIds);
EXPECT_EQ(mockSizes.get(), tCtxMock.receivedOutSpecConstantsSizes);
}
TEST_F(CompilerInterfaceTest, whenIgcTranlationContextCreationFailsThenErrorIsReturned) {
pCompilerInterface->failCreateIgcTranslationCtx = true;
retVal = pCompilerInterface->getSpecConstantsInfo(*pProgram, inputArgs);
EXPECT_EQ(CL_OUT_OF_HOST_MEMORY, retVal);
}
TEST_F(CompilerInterfaceTest, givenCompilerInterfaceWhenGetSpecializationConstantsThenSuccesIsReturned) {
retVal = pCompilerInterface->getSpecConstantsInfo(*pProgram, inputArgs);
EXPECT_EQ(CL_SUCCESS, retVal);
}
struct UpdateSpecConstantsTest : public ::testing::Test {
void SetUp() override {
mockProgram.reset(new MockProgram(executionEnvironment));
mockProgram->specConstantsIds.reset(new MockCIFBuffer());
mockProgram->specConstantsSizes.reset(new MockCIFBuffer());
mockProgram->specConstantsValues.reset(new MockCIFBuffer());
mockProgram->specConstantsIds->PushBackRawCopy(1);
mockProgram->specConstantsIds->PushBackRawCopy(2);
mockProgram->specConstantsIds->PushBackRawCopy(3);
mockProgram->specConstantsSizes->PushBackRawCopy(sizeof(char));
mockProgram->specConstantsSizes->PushBackRawCopy(sizeof(uint16_t));
mockProgram->specConstantsSizes->PushBackRawCopy(sizeof(int));
mockProgram->specConstantsValues->PushBackRawCopy(&val1);
mockProgram->specConstantsValues->PushBackRawCopy(&val2);
mockProgram->specConstantsValues->PushBackRawCopy(&val3);
values = mockProgram->specConstantsValues->GetMemory<const void *>();
EXPECT_EQ(val1, *reinterpret_cast<const char *>(values[0]));
EXPECT_EQ(val2, *reinterpret_cast<const uint16_t *>(values[1]));
EXPECT_EQ(val3, *reinterpret_cast<const int *>(values[2]));
}
ExecutionEnvironment executionEnvironment;
std::unique_ptr<MockProgram> mockProgram;
char val1 = 5;
uint16_t val2 = 50;
int val3 = 500;
const void *const *values;
};
TEST_F(UpdateSpecConstantsTest, givenNewSpecConstValueWhenUpdateSpecializationConstantThenProperValueIsUpdated) {
int newSpecConstVal3 = 5000;
auto ret = mockProgram->updateSpecializationConstant(3, sizeof(int), &newSpecConstVal3);
EXPECT_EQ(CL_SUCCESS, ret);
EXPECT_EQ(val1, *reinterpret_cast<const char *>(values[0]));
EXPECT_EQ(val2, *reinterpret_cast<const uint16_t *>(values[1]));
EXPECT_EQ(newSpecConstVal3, *reinterpret_cast<const int *>(values[2]));
}
TEST_F(UpdateSpecConstantsTest, givenNewSpecConstValueWithUnproperSizeWhenUpdateSpecializationConstantThenErrorIsReturned) {
int newSpecConstVal3 = 5000;
auto ret = mockProgram->updateSpecializationConstant(3, 10 * sizeof(int), &newSpecConstVal3);
EXPECT_EQ(CL_INVALID_VALUE, ret);
EXPECT_EQ(val1, *reinterpret_cast<const char *>(values[0]));
EXPECT_EQ(val2, *reinterpret_cast<const uint16_t *>(values[1]));
EXPECT_EQ(val3, *reinterpret_cast<const int *>(values[2]));
}
TEST_F(UpdateSpecConstantsTest, givenNewSpecConstValueWithUnproperIdAndSizeWhenUpdateSpecializationConstantThenErrorIsReturned) {
int newSpecConstVal3 = 5000;
auto ret = mockProgram->updateSpecializationConstant(4, sizeof(int), &newSpecConstVal3);
EXPECT_EQ(CL_INVALID_SPEC_ID, ret);
EXPECT_EQ(val1, *reinterpret_cast<const char *>(values[0]));
EXPECT_EQ(val2, *reinterpret_cast<const uint16_t *>(values[1]));
EXPECT_EQ(val3, *reinterpret_cast<const int *>(values[2]));
}

View File

@ -5,13 +5,14 @@
*
*/
#include "unit_tests/mocks/mock_compilers.h"
#include "mock_compilers.h"
#include "runtime/helpers/file_io.h"
#include "runtime/helpers/hw_info.h"
#include "runtime/helpers/options.h"
#include "runtime/os_interface/os_inc_base.h"
#include "unit_tests/helpers/test_files.h"
#include "unit_tests/mocks/mock_compilers.h"
#include "unit_tests/mocks/mock_sip.h"
#include "cif/macros/enable.h"
@ -491,6 +492,28 @@ IGC::OclTranslationOutputBase *MockIgcOclTranslationCtx::TranslateImpl(
return out;
}
bool MockIgcOclTranslationCtx::GetSpecConstantsInfoImpl(
CIF::Builtins::BufferSimple *src,
CIF::Builtins::BufferSimple *outSpecConstantsIds,
CIF::Builtins::BufferSimple *outSpecConstantsSizes) {
return true;
}
IGC::OclTranslationOutputBase *MockIgcOclTranslationCtx::TranslateImpl(
CIF::Version_t outVersion,
CIF::Builtins::BufferSimple *src,
CIF::Builtins::BufferSimple *specConstantsIds,
CIF::Builtins::BufferSimple *specConstantsValues,
CIF::Builtins::BufferSimple *options,
CIF::Builtins::BufferSimple *internalOptions,
CIF::Builtins::BufferSimple *tracingOptions,
uint32_t tracingOptionsCount,
void *gtPinInput) {
auto out = new MockOclTranslationOutput();
translate(true, src, options, internalOptions, out);
return out;
}
MockOclTranslationOutput::MockOclTranslationOutput() {
this->log = new MockCIFBuffer();
this->output = new MockCIFBuffer();

View File

@ -136,6 +136,22 @@ struct MockIgcOclTranslationCtx : MockCIF<IGC::IgcOclTranslationCtxTagOCL> {
CIF::Builtins::BufferSimple *tracingOptions,
uint32_t tracingOptionsCount,
void *gtpinInput) override;
bool GetSpecConstantsInfoImpl(
CIF::Builtins::BufferSimple *src,
CIF::Builtins::BufferSimple *outSpecConstantsIds,
CIF::Builtins::BufferSimple *outSpecConstantsSizes) override;
IGC::OclTranslationOutputBase *TranslateImpl(
CIF::Version_t outVersion,
CIF::Builtins::BufferSimple *src,
CIF::Builtins::BufferSimple *specConstantsIds,
CIF::Builtins::BufferSimple *specConstantsValues,
CIF::Builtins::BufferSimple *options,
CIF::Builtins::BufferSimple *internalOptions,
CIF::Builtins::BufferSimple *tracingOptions,
uint32_t tracingOptionsCount,
void *gtPinInput) override;
};
struct MockOclTranslationOutput : MockCIF<IGC::OclTranslationOutputTagOCL> {

View File

@ -31,6 +31,7 @@ class MockProgram : public Program {
using Program::resolveProgramBinary;
using Program::updateNonUniformFlag;
using Program::areSpecializationConstantsInitialized;
using Program::elfBinary;
using Program::elfBinarySize;
using Program::genBinary;
@ -40,6 +41,9 @@ class MockProgram : public Program {
using Program::isProgramBinaryResolved;
using Program::isSpirV;
using Program::programBinaryType;
using Program::specConstantsIds;
using Program::specConstantsSizes;
using Program::specConstantsValues;
using Program::sourceCode;

View File

@ -3013,3 +3013,87 @@ TEST(RebuildProgramFromIrTests, givenBinaryProgramWhenKernelRebulildIsNotForcedT
EXPECT_TRUE(pProgram->processElfBinaryCalled);
EXPECT_FALSE(pProgram->rebuildProgramFromIrCalled);
}
struct SpecializationConstantProgramMock : public MockProgram {
using MockProgram::MockProgram;
cl_int updateSpecializationConstant(cl_uint specId, size_t specSize, const void *specValue) override {
return CL_SUCCESS;
}
};
struct SpecializationConstantCompilerInterfaceMock : public CompilerInterface {
int retVal = CL_SUCCESS;
int counter = 0;
cl_int getSpecConstantsInfo(Program &program, const TranslationArgs &pInputArgs) override {
counter++;
return retVal;
}
void returnError() {
retVal = CL_INVALID_VALUE;
}
};
struct SpecializationConstantExecutionEnvironmentMock : public ExecutionEnvironment {
SpecializationConstantExecutionEnvironmentMock() {
compilerInterface.reset(new SpecializationConstantCompilerInterfaceMock());
}
CompilerInterface *getCompilerInterface() override {
return compilerInterface.get();
}
};
struct setProgramSpecializationConstantTests : public ::testing::Test {
void SetUp() override {
mockProgram.reset(new SpecializationConstantProgramMock(executionEnvironment));
mockProgram->isSpirV = true;
EXPECT_FALSE(mockProgram->areSpecializationConstantsInitialized);
EXPECT_EQ(0, mockCompiler->counter);
}
SpecializationConstantExecutionEnvironmentMock executionEnvironment;
SpecializationConstantCompilerInterfaceMock *mockCompiler = reinterpret_cast<SpecializationConstantCompilerInterfaceMock *>(executionEnvironment.getCompilerInterface());
std::unique_ptr<SpecializationConstantProgramMock> mockProgram;
int specValue = 1;
};
TEST_F(setProgramSpecializationConstantTests, whenSetProgramSpecializationConstantMultipleTimesThenSpecializationConstantsAreInitializedOnce) {
auto retVal = mockProgram->setProgramSpecializationConstant(1, sizeof(int), &specValue);
EXPECT_EQ(1, mockCompiler->counter);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_TRUE(mockProgram->areSpecializationConstantsInitialized);
retVal = mockProgram->setProgramSpecializationConstant(1, sizeof(int), &specValue);
EXPECT_EQ(1, mockCompiler->counter);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_TRUE(mockProgram->areSpecializationConstantsInitialized);
}
TEST_F(setProgramSpecializationConstantTests, givenInvalidGetSpecConstantsInfoReturnValueWhenSetProgramSpecializationConstantThenErrorIsReturned) {
reinterpret_cast<SpecializationConstantCompilerInterfaceMock *>(executionEnvironment.getCompilerInterface())->returnError();
auto retVal = mockProgram->setProgramSpecializationConstant(1, sizeof(int), &specValue);
EXPECT_EQ(1, mockCompiler->counter);
EXPECT_EQ(CL_INVALID_VALUE, retVal);
EXPECT_FALSE(mockProgram->areSpecializationConstantsInitialized);
}
TEST(setProgramSpecializationConstantTest, givenUninitializedCompilerinterfaceWhenSetProgramSpecializationConstantThenErrorIsReturned) {
struct MockExecutionEnvironment : public ExecutionEnvironment {
CompilerInterface *getCompilerInterface() override {
return compilerInterface.get();
}
};
MockExecutionEnvironment executionEnvironment;
SpecializationConstantProgramMock mockProgram(executionEnvironment);
mockProgram.isSpirV = true;
int specValue = 1;
auto retVal = mockProgram.setProgramSpecializationConstant(1, sizeof(int), &specValue);
EXPECT_EQ(CL_OUT_OF_HOST_MEMORY, retVal);
}