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:
parent
3a75c4fb71
commit
971eb7a1b4
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
|
@ -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]));
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue