feature: Enabling support for redirecting FCL to IGC for OCLOC

This allows for invoking IGC as OCL C translator in OCLOC paths

Accepted debug env :
NEO_OCLOC_UseIgcAsFcl=1 ; forces IGC
NEO_OCLOC_UseIgcAsFcl=2 ; forces FCL
NEO_OCLOC_UseIgcAsFcl=0 ; use defaults

Related-To: NEO-14473
Signed-off-by: Chodor, Jaroslaw <jaroslaw.chodor@intel.com>
This commit is contained in:
Chodor, Jaroslaw
2025-04-08 14:43:25 +00:00
committed by Compute-Runtime-Automation
parent 5bf8b66498
commit 2ce694c52b
9 changed files with 233 additions and 23 deletions

View File

@@ -76,6 +76,7 @@ class MockOfflineCompiler : public OfflineCompiler {
using OfflineCompiler::storeBinary;
using OfflineCompiler::updateBuildLog;
using OfflineCompiler::useGenFile;
using OfflineCompiler::useIgcAsFcl;
using OfflineCompiler::useOptionsSuffix;
MockOfflineCompiler();

View File

@@ -5649,4 +5649,90 @@ TEST(OclocApiSpecificConfigTests, givenOclocThenDebugKeysAreAllowedOnlyInDebug)
EXPECT_FALSE(NEO::isDebugKeysReadEnabled());
}
TEST_F(OfflineCompilerTests, GivenFclRedirectionEnvSetToForceIgcWhenInitializingOclocThenIgcIsBeingUsedAsFclFacade) {
DebugManagerStateRestore dbgRestore;
debugManager.flags.UseIgcAsFcl.set(1);
std::vector<std::string> argv = {
"ocloc",
"-file",
clCopybufferFilename.c_str(),
"-device",
gEnvironment->devicePrefix.c_str(),
"-spv_only"};
char bin[1] = {7};
auto oldIgcDebugVars = getIgcDebugVars();
auto currIgcDebugVars = oldIgcDebugVars;
currIgcDebugVars.binaryToReturn = bin;
currIgcDebugVars.binaryToReturnSize = 1;
currIgcDebugVars.forceBuildFailure = false;
setIgcDebugVars(currIgcDebugVars);
auto oldFclDebugVars = getFclDebugVars();
auto currFclDebugVars = oldFclDebugVars;
currFclDebugVars.forceBuildFailure = true;
setFclDebugVars(currFclDebugVars);
std::unique_ptr<OfflineCompiler> pOfflineCompiler(OfflineCompiler::create(argv.size(), argv, true, retVal, oclocArgHelperWithoutInput.get()));
ASSERT_NE(nullptr, pOfflineCompiler);
auto ret = pOfflineCompiler->build();
EXPECT_EQ(OCLOC_SUCCESS, ret);
currIgcDebugVars.forceBuildFailure = true;
ret = pOfflineCompiler->build();
EXPECT_EQ(OCLOC_SUCCESS, ret);
setFclDebugVars(oldFclDebugVars);
setIgcDebugVars(oldIgcDebugVars);
}
TEST_F(OfflineCompilerTests, GivenFclRedirectionEnvSetToForceFclWhenInitializingOclocThenFclIsBeingUsedAsFclFacade) {
DebugManagerStateRestore dbgRestore;
debugManager.flags.UseIgcAsFcl.set(2);
std::vector<std::string> argv = {
"ocloc",
"-file",
clCopybufferFilename.c_str(),
"-device",
gEnvironment->devicePrefix.c_str(),
"-spv_only"};
char bin[1] = {7};
auto oldIgcDebugVars = getIgcDebugVars();
auto currIgcDebugVars = oldIgcDebugVars;
currIgcDebugVars.forceBuildFailure = true;
setIgcDebugVars(currIgcDebugVars);
auto oldFclDebugVars = getFclDebugVars();
auto currFclDebugVars = oldFclDebugVars;
currFclDebugVars.binaryToReturn = bin;
currFclDebugVars.binaryToReturnSize = 1;
currFclDebugVars.forceBuildFailure = false;
setFclDebugVars(currFclDebugVars);
std::unique_ptr<OfflineCompiler> pOfflineCompiler(OfflineCompiler::create(argv.size(), argv, true, retVal, oclocArgHelperWithoutInput.get()));
ASSERT_NE(nullptr, pOfflineCompiler);
auto ret = pOfflineCompiler->build();
EXPECT_EQ(OCLOC_SUCCESS, ret);
currFclDebugVars.forceBuildFailure = true;
ret = pOfflineCompiler->build();
setFclDebugVars(oldFclDebugVars);
setIgcDebugVars(oldIgcDebugVars);
}
TEST_F(OfflineCompilerTests, GivenFclRedirectionDefaultSettingWhenCompilingToIrThenUseCompilerProductHelperDefaults) {
std::vector<std::string> argv = {
"ocloc",
"-file",
clCopybufferFilename.c_str(),
"-device",
gEnvironment->devicePrefix.c_str()};
MockOfflineCompiler mockOfflineCompiler{};
mockOfflineCompiler.initialize(argv.size(), argv);
EXPECT_EQ(mockOfflineCompiler.compilerProductHelper->useIgcAsFcl(), mockOfflineCompiler.useIgcAsFcl());
mockOfflineCompiler.compilerProductHelper.reset();
EXPECT_EQ(false, mockOfflineCompiler.useIgcAsFcl());
}
} // namespace NEO

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2022-2024 Intel Corporation
* Copyright (C) 2022-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -124,6 +124,22 @@ CIF::RAII::UPtr_t<CIF::Builtins::BufferLatest> OclocFclFacade::createConstBuffer
return CIF::Builtins::CreateConstBuffer(fclMain.get(), data, size);
}
CIF::RAII::UPtr_t<IGC::OclTranslationOutputTagOCL> OclocFclFacade::translate(IGC::CodeType::CodeType_t inType, IGC::CodeType::CodeType_t outType, CIF::Builtins::BufferLatest *error,
CIF::Builtins::BufferSimple *src,
CIF::Builtins::BufferSimple *options,
CIF::Builtins::BufferSimple *internalOptions,
CIF::Builtins::BufferSimple *tracingOptions,
uint32_t tracingOptionsCount) {
auto fclTranslationCtx = this->createTranslationContext(inType, outType, error);
if ((nullptr != error->GetMemory<char>()) || (nullptr == fclTranslationCtx)) {
return nullptr;
}
return fclTranslationCtx->Translate(src, options, internalOptions, nullptr, 0);
}
CIF::RAII::UPtr_t<IGC::FclOclTranslationCtxTagOCL> OclocFclFacade::createTranslationContext(IGC::CodeType::CodeType_t inType, IGC::CodeType::CodeType_t outType, CIF::Builtins::BufferLatest *error) {
return fclDeviceCtx->CreateTranslationCtx(inType, outType, error);
}

View File

@@ -27,18 +27,44 @@ class OsLibrary;
struct HardwareInfo;
class OclocFclFacade : NEO::NonCopyableAndNonMovableClass {
class OclocFclFacadeBase : NEO::NonCopyableAndNonMovableClass {
protected:
OclocFclFacadeBase() = default;
public:
virtual ~OclocFclFacadeBase() = default;
virtual int initialize(const HardwareInfo &hwInfo) = 0;
virtual bool isInitialized() const = 0;
virtual IGC::CodeType::CodeType_t getPreferredIntermediateRepresentation() const = 0;
virtual CIF::RAII::UPtr_t<CIF::Builtins::BufferLatest> createConstBuffer(const void *data, size_t size) = 0;
virtual CIF::RAII::UPtr_t<IGC::OclTranslationOutputTagOCL> translate(IGC::CodeType::CodeType_t inType, IGC::CodeType::CodeType_t outType, CIF::Builtins::BufferLatest *error,
CIF::Builtins::BufferSimple *src,
CIF::Builtins::BufferSimple *options,
CIF::Builtins::BufferSimple *internalOptions,
CIF::Builtins::BufferSimple *tracingOptions,
uint32_t tracingOptionsCount) = 0;
};
static_assert(NEO::NonCopyableAndNonMovable<OclocFclFacadeBase>);
class OclocFclFacade : public OclocFclFacadeBase {
public:
OclocFclFacade(OclocArgHelper *argHelper);
MOCKABLE_VIRTUAL ~OclocFclFacade();
~OclocFclFacade() override;
int initialize(const HardwareInfo &hwInfo);
bool isInitialized() const;
IGC::CodeType::CodeType_t getPreferredIntermediateRepresentation() const;
CIF::RAII::UPtr_t<CIF::Builtins::BufferLatest> createConstBuffer(const void *data, size_t size);
CIF::RAII::UPtr_t<IGC::FclOclTranslationCtxTagOCL> createTranslationContext(IGC::CodeType::CodeType_t inType, IGC::CodeType::CodeType_t outType, CIF::Builtins::BufferLatest *error);
int initialize(const HardwareInfo &hwInfo) override;
bool isInitialized() const override;
IGC::CodeType::CodeType_t getPreferredIntermediateRepresentation() const override;
CIF::RAII::UPtr_t<CIF::Builtins::BufferLatest> createConstBuffer(const void *data, size_t size) override;
CIF::RAII::UPtr_t<IGC::OclTranslationOutputTagOCL> translate(IGC::CodeType::CodeType_t inType, IGC::CodeType::CodeType_t outType, CIF::Builtins::BufferLatest *error,
CIF::Builtins::BufferSimple *src,
CIF::Builtins::BufferSimple *options,
CIF::Builtins::BufferSimple *internalOptions,
CIF::Builtins::BufferSimple *tracingOptions,
uint32_t tracingOptionsCount) override;
protected:
MOCKABLE_VIRTUAL CIF::RAII::UPtr_t<IGC::FclOclTranslationCtxTagOCL> createTranslationContext(IGC::CodeType::CodeType_t inType, IGC::CodeType::CodeType_t outType, CIF::Builtins::BufferLatest *error);
MOCKABLE_VIRTUAL std::unique_ptr<OsLibrary> loadFclLibrary() const;
MOCKABLE_VIRTUAL CIF::CreateCIFMainFunc_t loadCreateFclMainFunction() const;
MOCKABLE_VIRTUAL CIF::RAII::UPtr_t<CIF::CIFMain> createFclMain(CIF::CreateCIFMainFunc_t createMainFunction) const;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2022-2024 Intel Corporation
* Copyright (C) 2022-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -191,4 +191,44 @@ bool OclocIgcFacade::isInitialized() const {
return initialized;
}
OclocIgcAsFcl::OclocIgcAsFcl(OclocArgHelper *argHelper) : igc(std::make_unique<OclocIgcFacade>(argHelper)) {}
OclocIgcAsFcl::~OclocIgcAsFcl() = default;
int OclocIgcAsFcl::initialize(const HardwareInfo &hwInfo) {
auto ret = igc->initialize(hwInfo);
if (OCLOC_SUCCESS != ret) {
return ret;
}
auto compilerProductHelper = NEO::CompilerProductHelper::create(hwInfo.platform.eProductFamily);
this->preferredIntermediateRepresentation = compilerProductHelper->getPreferredIntermediateRepresentation();
return OCLOC_SUCCESS;
}
bool OclocIgcAsFcl::isInitialized() const {
return igc->isInitialized();
}
IGC::CodeType::CodeType_t OclocIgcAsFcl::getPreferredIntermediateRepresentation() const {
return this->preferredIntermediateRepresentation;
}
CIF::RAII::UPtr_t<CIF::Builtins::BufferLatest> OclocIgcAsFcl::createConstBuffer(const void *data, size_t size) {
return igc->createConstBuffer(data, size);
}
CIF::RAII::UPtr_t<IGC::OclTranslationOutputTagOCL> OclocIgcAsFcl::translate(IGC::CodeType::CodeType_t inType, IGC::CodeType::CodeType_t outType, CIF::Builtins::BufferLatest *error,
CIF::Builtins::BufferSimple *src,
CIF::Builtins::BufferSimple *options,
CIF::Builtins::BufferSimple *internalOptions,
CIF::Builtins::BufferSimple *tracingOptions,
uint32_t tracingOptionsCount) {
auto translationCtx = igc->createTranslationContext(inType, outType);
if ((nullptr != error->GetMemory<char>()) || (nullptr == translationCtx)) {
return nullptr;
}
return translationCtx->Translate(src, options, internalOptions, nullptr, 0);
}
} // namespace NEO

View File

@@ -7,6 +7,7 @@
#pragma once
#include "shared/offline_compiler/source/ocloc_fcl_facade.h"
#include "shared/source/helpers/non_copyable_or_moveable.h"
#include "cif/common/cif_main.h"
@@ -65,4 +66,27 @@ class OclocIgcFacade : NEO::NonCopyableAndNonMovableClass {
static_assert(NEO::NonCopyableAndNonMovable<OclocIgcFacade>);
class OclocIgcAsFcl : public OclocFclFacadeBase {
public:
OclocIgcAsFcl(OclocArgHelper *argHelper);
~OclocIgcAsFcl() override;
int initialize(const HardwareInfo &hwInfo) override;
bool isInitialized() const override;
IGC::CodeType::CodeType_t getPreferredIntermediateRepresentation() const override;
CIF::RAII::UPtr_t<CIF::Builtins::BufferLatest> createConstBuffer(const void *data, size_t size) override;
CIF::RAII::UPtr_t<IGC::OclTranslationOutputTagOCL> translate(IGC::CodeType::CodeType_t inType, IGC::CodeType::CodeType_t outType, CIF::Builtins::BufferLatest *error,
CIF::Builtins::BufferSimple *src,
CIF::Builtins::BufferSimple *options,
CIF::Builtins::BufferSimple *internalOptions,
CIF::Builtins::BufferSimple *tracingOptions,
uint32_t tracingOptionsCount) override;
protected:
IGC::CodeType::CodeType_t preferredIntermediateRepresentation = IGC::CodeType::undefined;
std::unique_ptr<OclocIgcFacade> igc;
};
static_assert(NEO::NonCopyableAndNonMovable<OclocIgcAsFcl>);
} // namespace NEO

View File

@@ -100,6 +100,9 @@ OfflineCompiler *OfflineCompiler::create(size_t numArgs, const std::vector<std::
pOffCompiler->fclFacade = std::make_unique<OclocFclFacade>(helper);
pOffCompiler->igcFacade = std::make_unique<OclocIgcFacade>(helper);
retVal = pOffCompiler->initialize(numArgs, allArgs, dumpFiles);
if (pOffCompiler->useIgcAsFcl()) {
pOffCompiler->fclFacade = std::make_unique<OclocIgcAsFcl>(helper);
}
}
if (retVal != OCLOC_SUCCESS) {
@@ -536,7 +539,14 @@ int OfflineCompiler::buildToIrBinary() {
fclSrc = fclFacade->createConstBuffer(sourceCode.c_str(), sourceCode.size() + 1);
}
auto fclTranslationCtx = fclFacade->createTranslationContext(srcType, intermediateRepresentation, err.get());
if (false == NEO::areNotNullptr(fclSrc.get(), pBuildInfo->fclOptions.get(), pBuildInfo->fclInternalOptions.get())) {
retVal = OCLOC_OUT_OF_HOST_MEMORY;
return retVal;
}
pBuildInfo->fclOutput = fclFacade->translate(srcType, intermediateRepresentation, err.get(),
fclSrc.get(), pBuildInfo->fclOptions.get(),
pBuildInfo->fclInternalOptions.get(), nullptr, 0);
if (true == NEO::areNotNullptr(err->GetMemory<char>())) {
updateBuildLog(err->GetMemory<char>(), err->GetSizeRaw());
@@ -544,15 +554,6 @@ int OfflineCompiler::buildToIrBinary() {
return retVal;
}
if (false == NEO::areNotNullptr(fclSrc.get(), pBuildInfo->fclOptions.get(), pBuildInfo->fclInternalOptions.get(),
fclTranslationCtx.get())) {
retVal = OCLOC_OUT_OF_HOST_MEMORY;
return retVal;
}
pBuildInfo->fclOutput = fclTranslationCtx->Translate(fclSrc.get(), pBuildInfo->fclOptions.get(),
pBuildInfo->fclInternalOptions.get(), nullptr, 0);
if (pBuildInfo->fclOutput == nullptr) {
retVal = OCLOC_OUT_OF_HOST_MEMORY;
return retVal;
@@ -1705,4 +1706,19 @@ std::string generateFilePath(const std::string &directory, const std::string &fi
return ret;
}
} // namespace NEO
bool OfflineCompiler::useIgcAsFcl() {
if (0 != debugManager.flags.UseIgcAsFcl.get()) {
if (1 == debugManager.flags.UseIgcAsFcl.get()) {
return true;
} else if (2 == debugManager.flags.UseIgcAsFcl.get()) {
return false;
}
}
if (nullptr == compilerProductHelper) {
return false;
}
return compilerProductHelper->useIgcAsFcl();
}
} // namespace NEO

View File

@@ -31,7 +31,7 @@ namespace NEO {
class CompilerCache;
class CompilerProductHelper;
class OclocFclFacade;
class OclocFclFacadeBase;
class OclocIgcFacade;
std::string convertToPascalCase(const std::string &inString);
@@ -198,6 +198,7 @@ All supported acronyms: %s.
MOCKABLE_VIRTUAL void writeOutAllFiles();
MOCKABLE_VIRTUAL void createDir(const std::string &path);
bool useIgcAsFcl();
void unifyExcludeIrFlags();
void enforceFormat(std::string &format);
HardwareInfo hwInfo{};
@@ -260,7 +261,7 @@ All supported acronyms: %s.
uint64_t hwInfoConfig = 0u;
std::unique_ptr<OclocIgcFacade> igcFacade;
std::unique_ptr<OclocFclFacade> fclFacade;
std::unique_ptr<OclocFclFacadeBase> fclFacade;
std::unique_ptr<CompilerCache> cache;
std::unique_ptr<CompilerProductHelper> compilerProductHelper;
std::unique_ptr<ReleaseHelper> releaseHelper;

View File

@@ -680,7 +680,7 @@ DECLARE_DEBUG_VARIABLE(int64_t, ReadOnlyAllocationsTypeMask, 0, "0: default, >0
DECLARE_DEBUG_VARIABLE(bool, IgnoreZebinUnknownAttributes, false, "enable to treat unknown zebin attributes as warning instead of error");
DECLARE_DEBUG_VARIABLE(int64_t, FinalizerInputType, 0, "0: default (N/A), input type for finalizer")
DECLARE_DEBUG_VARIABLE(std::string, FinalizerLibraryName, std::string("unk"), "Library name for finalizer")
DECLARE_DEBUG_SCOPED_V(int32_t, UseIgcAsFcl, 0, S_RT, "0: platform default, 1: force use IGC, 2: force use FCL")
DECLARE_DEBUG_SCOPED_V(int32_t, UseIgcAsFcl, 0, S_RT | S_OCLOC, "0: platform default, 1: force use IGC, 2: force use FCL")
DECLARE_DEBUG_VARIABLE(int32_t, EnableGlobalTimestampViaSubmission, -1, "-1: OS Interface, 0: OS Interface, 1: Submission. This flag sets the type of method to get timestamp for getGlobalTimestamps");
/* Binary Cache */