/* * Copyright (C) 2022-2025 Intel Corporation * * SPDX-License-Identifier: MIT * */ #include "shared/offline_compiler/source/ocloc_igc_facade.h" #include "shared/offline_compiler/source/ocloc_api.h" #include "shared/offline_compiler/source/ocloc_arg_helper.h" #include "shared/source/compiler_interface/igc_platform_helper.h" #include "shared/source/compiler_interface/os_compiler_cache_helper.h" #include "shared/source/helpers/compiler_product_helper.h" #include "shared/source/helpers/constants.h" #include "shared/source/helpers/debug_helpers.h" #include "shared/source/helpers/hw_info.h" #include "shared/source/helpers/string.h" #include "shared/source/os_interface/os_inc_base.h" #include "shared/source/os_interface/os_library.h" #include "ocl_igc_interface/platform_helper.h" #include namespace NEO { CIF::CIFMain *createMainNoSanitize(CIF::CreateCIFMainFunc_t createFunc); OclocIgcFacade::OclocIgcFacade(OclocArgHelper *argHelper) : argHelper{argHelper} { } OclocIgcFacade::~OclocIgcFacade() = default; int OclocIgcFacade::initialize(const HardwareInfo &hwInfo) { if (initialized) { return OCLOC_SUCCESS; } auto compilerProductHelper = NEO::CompilerProductHelper::create(hwInfo.platform.eProductFamily); igcLib = loadIgcLibrary(compilerProductHelper ? compilerProductHelper->getCustomIgcLibraryName() : nullptr); if (!igcLib) { argHelper->printf("Error! Loading of IGC library has failed! Filename: %s\n", (compilerProductHelper && compilerProductHelper->getCustomIgcLibraryName()) ? compilerProductHelper->getCustomIgcLibraryName() : Os::igcDllName); return OCLOC_OUT_OF_HOST_MEMORY; } std::string igcPath = igcLib->getFullPath(); igcLibSize = NEO::getFileSize(igcPath); igcLibMTime = NEO::getFileModificationTime(igcPath); const auto igcCreateMainFunction = loadCreateIgcMainFunction(); if (!igcCreateMainFunction) { argHelper->printf("Error! Cannot load required functions from IGC library.\n"); return OCLOC_OUT_OF_HOST_MEMORY; } igcMain = createIgcMain(igcCreateMainFunction); if (!igcMain) { argHelper->printf("Error! Cannot create IGC main component!\n"); return OCLOC_OUT_OF_HOST_MEMORY; } const std::vector interfacesToIgnore = {IGC::OclGenBinaryBase::GetInterfaceId()}; if (!isIgcInterfaceCompatible(interfacesToIgnore)) { const auto incompatibleInterface{getIncompatibleInterface(interfacesToIgnore)}; argHelper->printf("Error! Incompatible interface in IGC: %s\n", incompatibleInterface.c_str()); DEBUG_BREAK_IF(true); return OCLOC_OUT_OF_HOST_MEMORY; } if (!isPatchtokenInterfaceSupported()) { argHelper->printf("Error! Patchtoken interface is missing.\n"); return OCLOC_OUT_OF_HOST_MEMORY; } { // revision is sha-1 hash igcRevision.resize(41); igcRevision[0] = '\0'; auto igcDeviceCtx3 = createIgcDeviceContext3(); if (igcDeviceCtx3) { const char *revision = igcDeviceCtx3->GetIGCRevision(); strncpy_s(igcRevision.data(), 41, revision, 40); } } igcDeviceCtx = createIgcDeviceContext(); if (!igcDeviceCtx) { argHelper->printf("Error! Cannot create IGC device context!\n"); return OCLOC_OUT_OF_HOST_MEMORY; } igcDeviceCtx->SetProfilingTimerResolution(static_cast(CommonConstants::defaultProfilingTimerResolution)); const auto igcPlatform = getIgcPlatformHandle(); const auto igcGtSystemInfo = getGTSystemInfoHandle(); const auto igcFtrWa = getIgcFeaturesAndWorkaroundsHandle(); if (!igcPlatform || !igcGtSystemInfo || !igcFtrWa) { argHelper->printf("Error! IGC device context has not been properly created!\n"); return OCLOC_OUT_OF_HOST_MEMORY; } populateIgcPlatform(*igcPlatform, hwInfo); IGC::GtSysInfoHelper::PopulateInterfaceWith(*igcGtSystemInfo.get(), hwInfo.gtSystemInfo); populateWithFeatures(igcFtrWa.get(), hwInfo, compilerProductHelper.get()); initialized = true; return OCLOC_SUCCESS; } std::unique_ptr OclocIgcFacade::loadIgcLibrary(const char *libName) const { auto effectiveLibName = libName ? libName : Os::igcDllName; return std::unique_ptr{OsLibrary::loadFunc({effectiveLibName})}; } CIF::CreateCIFMainFunc_t OclocIgcFacade::loadCreateIgcMainFunction() const { return reinterpret_cast(igcLib->getProcAddress(CIF::CreateCIFMainFuncName)); } CIF::RAII::UPtr_t OclocIgcFacade::createIgcMain(CIF::CreateCIFMainFunc_t createMainFunction) const { return CIF::RAII::UPtr(createMainNoSanitize(createMainFunction)); } bool OclocIgcFacade::isIgcInterfaceCompatible(const std::vector &interfacesToIgnore) const { return igcMain->IsCompatible(&interfacesToIgnore); } std::string OclocIgcFacade::getIncompatibleInterface(const std::vector &interfacesToIgnore) const { return CIF::InterfaceIdCoder::Dec(igcMain->FindIncompatible(&interfacesToIgnore)); } bool OclocIgcFacade::isPatchtokenInterfaceSupported() const { CIF::Version_t verMin = 0, verMax = 0; return igcMain->FindSupportedVersions(IGC::OclGenBinaryBase::GetInterfaceId(), verMin, verMax); } CIF::RAII::UPtr_t OclocIgcFacade::createIgcDeviceContext() const { return igcMain->CreateInterface(); } CIF::RAII::UPtr_t> OclocIgcFacade::createIgcDeviceContext3() const { return igcMain->CreateInterface>(); } CIF::RAII::UPtr_t OclocIgcFacade::getIgcPlatformHandle() const { return igcDeviceCtx->GetPlatformHandle(); } CIF::RAII::UPtr_t OclocIgcFacade::getGTSystemInfoHandle() const { return igcDeviceCtx->GetGTSystemInfoHandle(); } CIF::RAII::UPtr_t OclocIgcFacade::getIgcFeaturesAndWorkaroundsHandle() const { return igcDeviceCtx->GetIgcFeaturesAndWorkaroundsHandle(); } void OclocIgcFacade::populateWithFeatures(IGC::IgcFeaturesAndWorkaroundsTagOCL *handle, const HardwareInfo &hwInfo, const CompilerProductHelper *compilerProductHelper) const { if (compilerProductHelper) { handle->SetFtrGpGpuMidThreadLevelPreempt(compilerProductHelper->isMidThreadPreemptionSupported(hwInfo)); } handle->SetFtrWddm2Svm(hwInfo.featureTable.flags.ftrWddm2Svm); handle->SetFtrPooledEuEnabled(hwInfo.featureTable.flags.ftrPooledEuEnabled); } const char *OclocIgcFacade::getIgcRevision() { return igcRevision.data(); } size_t OclocIgcFacade::getIgcLibSize() { return igcLibSize; } time_t OclocIgcFacade::getIgcLibMTime() { return igcLibMTime; } CIF::RAII::UPtr_t OclocIgcFacade::createConstBuffer(const void *data, size_t size) { return CIF::Builtins::CreateConstBuffer(igcMain.get(), data, size); } CIF::RAII::UPtr_t OclocIgcFacade::createTranslationContext(IGC::CodeType::CodeType_t inType, IGC::CodeType::CodeType_t outType) { return igcDeviceCtx->CreateTranslationCtx(inType, outType); } bool OclocIgcFacade::isInitialized() const { return initialized; } OclocIgcAsFcl::OclocIgcAsFcl(OclocArgHelper *argHelper) : igc(std::make_unique(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 OclocIgcAsFcl::createConstBuffer(const void *data, size_t size) { return igc->createConstBuffer(data, size); } CIF::RAII::UPtr_t 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()) || (nullptr == translationCtx)) { return nullptr; } return translationCtx->Translate(src, options, internalOptions, nullptr, 0); } } // namespace NEO