From 9c3d9d803ffff885cf9a877dbdcc3d1c68172184 Mon Sep 17 00:00:00 2001 From: "Chodor, Jaroslaw" Date: Fri, 10 Oct 2025 14:00:20 +0000 Subject: [PATCH] feature: Support for OCL C in L0 runtime Prototype support for OCL C in L0 runtime Can be used with zeModuleCreate and ze_module_format_t=3 Related-To: GSD-11827 Signed-off-by: Chodor, Jaroslaw --- level_zero/core/source/module/module_imp.cpp | 28 +++++++++++++++++++ level_zero/core/source/module/module_imp.h | 1 + .../sources/device/test_l0_device.cpp | 21 -------------- opencl/test/unit_test/device/device_tests.cpp | 13 --------- .../compiler_interface/compiler_interface.cpp | 6 ++-- .../root_device_environment.cpp | 2 +- .../compiler_interface_tests.cpp | 4 +-- 7 files changed, 36 insertions(+), 39 deletions(-) diff --git a/level_zero/core/source/module/module_imp.cpp b/level_zero/core/source/module/module_imp.cpp index 720ab15fce..6e9eaa8f79 100644 --- a/level_zero/core/source/module/module_imp.cpp +++ b/level_zero/core/source/module/module_imp.cpp @@ -56,6 +56,8 @@ #include #include +#define ZE_MODULE_FORMAT_OCLC (ze_module_format_t)3U + namespace L0 { namespace BuildOptions { @@ -272,6 +274,25 @@ ze_result_t ModuleTranslationUnit::staticLinkSpirV(std::vector inp return this->compileGenBinary(linkInputArgs, true); } +ze_result_t ModuleTranslationUnit::buildFromSource(ze_module_format_t inputFormat, const char *input, uint32_t inputSize, const char *buildOptions, const char *internalBuildOptions) { + const auto &neoDevice = device->getNEODevice(); + auto compilerInterface = neoDevice->getCompilerInterface(); + const auto driverHandle = static_cast(device->getDriverHandle()); + if (!compilerInterface) { + driverHandle->clearErrorDescription(); + return ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE; + } + + std::string internalOptions = this->generateCompilerOptions(buildOptions, internalBuildOptions); + + NEO::TranslationInput inputArgs = {IGC::CodeType::oclC, IGC::CodeType::oclGenBin}; + + inputArgs.src = ArrayRef(input, inputSize); + inputArgs.apiOptions = ArrayRef(this->options.c_str(), this->options.length()); + inputArgs.internalOptions = ArrayRef(internalOptions.c_str(), internalOptions.length()); + return this->compileGenBinary(inputArgs, false); +} + ze_result_t ModuleTranslationUnit::buildFromIntermediate(IGC::CodeType::CodeType_t intermediateType, const char *input, uint32_t inputSize, const char *buildOptions, const char *internalBuildOptions, const ze_module_constants_t *pConstants) { const auto &neoDevice = device->getNEODevice(); @@ -776,6 +797,13 @@ inline ze_result_t ModuleImp::initializeTranslationUnit(const ze_module_desc_t * buildOptions.c_str(), internalBuildOptions.c_str(), desc->pConstants); + } else if (desc->format == ZE_MODULE_FORMAT_OCLC) { + this->precompiled = false; + return this->translationUnit->buildFromSource(desc->format, + reinterpret_cast(desc->pInputModule), + static_cast(desc->inputSize), + buildOptions.c_str(), + internalBuildOptions.c_str()); } else { this->precompiled = false; this->isFunctionSymbolExportEnabled = true; diff --git a/level_zero/core/source/module/module_imp.h b/level_zero/core/source/module/module_imp.h index 358f76c91f..d959f46154 100644 --- a/level_zero/core/source/module/module_imp.h +++ b/level_zero/core/source/module/module_imp.h @@ -57,6 +57,7 @@ struct ModuleTranslationUnit { return buildFromIntermediate(IGC::CodeType::spirV, input, inputSize, buildOptions, internalBuildOptions, pConstants); } + MOCKABLE_VIRTUAL ze_result_t buildFromSource(ze_module_format_t inputFormat, const char *input, uint32_t inputSize, const char *buildOptions, const char *internalBuildOptions); MOCKABLE_VIRTUAL ze_result_t buildExt(ze_module_format_t inputFormat, const char *input, uint32_t inputSize, const char *buildOptions, const char *internalBuildOptions); MOCKABLE_VIRTUAL ze_result_t buildFromIntermediate(IGC::CodeType::CodeType_t intermediateType, const char *input, uint32_t inputSize, const char *buildOptions, const char *internalBuildOptions, diff --git a/level_zero/core/test/unit_tests/sources/device/test_l0_device.cpp b/level_zero/core/test/unit_tests/sources/device/test_l0_device.cpp index 435da90618..7b33747255 100644 --- a/level_zero/core/test/unit_tests/sources/device/test_l0_device.cpp +++ b/level_zero/core/test/unit_tests/sources/device/test_l0_device.cpp @@ -73,27 +73,6 @@ extern GfxCoreHelperCreateFunctionType gfxCoreHelperFactory[IGFX_MAX_CORE]; namespace L0 { namespace ult { -TEST(L0DeviceTest, givenNonExistingFclWhenCreatingDeviceThenCompilerInterfaceIsCreated) { - - VariableBackup frontEndDllName(&Os::frontEndDllName); - Os::frontEndDllName = "_fake_fcl1_so"; - - ze_result_t returnValue = ZE_RESULT_SUCCESS; - - std::unique_ptr driverHandle(new DriverHandleImp); - auto hwInfo = *NEO::defaultHwInfo; - - auto neoDevice = std::unique_ptr(NEO::MockDevice::createWithNewExecutionEnvironment(&hwInfo, 0)); - ASSERT_NE(nullptr, neoDevice); - - auto device = std::unique_ptr(Device::create(driverHandle.get(), neoDevice.release(), false, &returnValue)); - ASSERT_NE(nullptr, device); - EXPECT_EQ(returnValue, ZE_RESULT_SUCCESS); - - auto compilerInterface = device->getNEODevice()->getCompilerInterface(); - ASSERT_NE(nullptr, compilerInterface); -} - TEST(L0DeviceTest, GivenCreatedDeviceHandleWhenCallingdeviceReinitThenNewDeviceHandleIsNotCreated) { ze_result_t returnValue = ZE_RESULT_SUCCESS; std::unique_ptr driverHandle(new DriverHandleImp); diff --git a/opencl/test/unit_test/device/device_tests.cpp b/opencl/test/unit_test/device/device_tests.cpp index caf95ddf84..0aae8949e2 100644 --- a/opencl/test/unit_test/device/device_tests.cpp +++ b/opencl/test/unit_test/device/device_tests.cpp @@ -249,19 +249,6 @@ TEST(DeviceCleanup, givenDeviceWhenItIsDestroyedThenFlushBatchedSubmissionsIsCal EXPECT_EQ(1, flushedBatchedSubmissionsCalledCount); } -TEST(DeviceCreation, GiveNonExistingFclWhenCreatingDeviceThenCompilerInterfaceIsNotCreated) { - DebugManagerStateRestore restore{}; - debugManager.flags.ForcePreemptionMode.set(PreemptionMode::Disabled); - VariableBackup frontEndDllName(&Os::frontEndDllName); - Os::frontEndDllName = "_fake_fcl1_so"; - - auto mockDevice = std::unique_ptr(MockDevice::createWithNewExecutionEnvironment(nullptr)); - ASSERT_NE(nullptr, mockDevice); - - auto compilerInterface = mockDevice->getCompilerInterface(); - ASSERT_EQ(nullptr, compilerInterface); -} - TEST(DeviceCreation, givenDeviceWhenItIsCreatedThenOsContextIsRegisteredInMemoryManager) { auto hwInfo = *defaultHwInfo; hwInfo.capabilityTable.blitterOperationsSupported = true; diff --git a/shared/source/compiler_interface/compiler_interface.cpp b/shared/source/compiler_interface/compiler_interface.cpp index 6da44b4b47..8f4ba47baa 100644 --- a/shared/source/compiler_interface/compiler_interface.cpp +++ b/shared/source/compiler_interface/compiler_interface.cpp @@ -436,12 +436,14 @@ bool CompilerInterface::loadIgcBasedCompiler(CompilerLibraryEntry &entry, const } bool CompilerInterface::initialize(std::unique_ptr &&cache, bool requireFcl) { - bool fclAvailable = requireFcl ? this->loadFcl() : false; + if (requireFcl) { + this->loadFcl(); + } bool igcAvailable = this->loadIgcBasedCompiler(defaultIgc, Os::igcDllName); this->cache.swap(cache); - return this->cache && igcAvailable && (fclAvailable || (false == requireFcl)); + return this->cache && igcAvailable; } IGC::FclOclDeviceCtxTagOCL *CompilerInterface::getFclDeviceCtx(const Device &device) { diff --git a/shared/source/execution_environment/root_device_environment.cpp b/shared/source/execution_environment/root_device_environment.cpp index b9fe3d8e29..7bf6a67002 100644 --- a/shared/source/execution_environment/root_device_environment.cpp +++ b/shared/source/execution_environment/root_device_environment.cpp @@ -159,7 +159,7 @@ CompilerInterface *RootDeviceEnvironment::getCompilerInterface() { std::lock_guard autolock(this->mtx); if (this->compilerInterface.get() == nullptr) { auto cache = std::make_unique(getDefaultCompilerCacheConfig()); - this->compilerInterface.reset(CompilerInterface::createInstance(std::move(cache), ApiSpecificConfig::getApiType() == ApiSpecificConfig::ApiType::OCL)); + this->compilerInterface.reset(CompilerInterface::createInstance(std::move(cache), true)); } } return this->compilerInterface.get(); diff --git a/shared/test/unit_test/compiler_interface/compiler_interface_tests.cpp b/shared/test/unit_test/compiler_interface/compiler_interface_tests.cpp index 594caff9f9..cc4b87c8a0 100644 --- a/shared/test/unit_test/compiler_interface/compiler_interface_tests.cpp +++ b/shared/test/unit_test/compiler_interface/compiler_interface_tests.cpp @@ -88,7 +88,7 @@ TEST(CompilerInterface, WhenInitializeIsCalledThenFailIfCompilerCacheHandlerIsEm EXPECT_FALSE(initSuccess); } -TEST(CompilerInterface, WhenInitializeIsCalledThenFailIfOneOfRequiredCompilersIsUnavailable) { +TEST(CompilerInterface, WhenInitializeIsCalledThenFailIfIgcIsUnavailable) { bool initSuccess = false; bool requireFcl = true; MockCompilerInterface ci; @@ -115,7 +115,7 @@ TEST(CompilerInterface, WhenInitializeIsCalledThenFailIfOneOfRequiredCompilersIs ci.failLoadIgc = false; requireFcl = true; initSuccess = ci.initialize(std::make_unique(CompilerCacheConfig{}), requireFcl); - EXPECT_FALSE(initSuccess); + EXPECT_TRUE(initSuccess); ci.failLoadFcl = false; ci.failLoadIgc = true;