2020-07-30 19:18:54 +08:00
/*
2021-01-12 01:29:55 +08:00
* Copyright ( C ) 2020 - 2021 Intel Corporation
2020-07-30 19:18:54 +08:00
*
* SPDX - License - Identifier : MIT
*
*/
# include "shared/source/device_binary_format/zebin_decoder.h"
# include "shared/source/compiler_interface/intermediate_representations.h"
# include "shared/source/debug_settings/debug_settings_manager.h"
# include "shared/source/device_binary_format/device_binary_formats.h"
# include "shared/source/device_binary_format/elf/elf_decoder.h"
# include "shared/source/device_binary_format/elf/elf_encoder.h"
# include "shared/source/device_binary_format/elf/zebin_elf.h"
# include "shared/source/device_binary_format/yaml/yaml_parser.h"
# include "shared/source/program/program_info.h"
# include "shared/source/utilities/compiler_support.h"
# include "shared/source/utilities/stackvec.h"
# include "opencl/source/program/kernel_info.h"
# include <tuple>
namespace NEO {
2021-07-02 22:28:08 +08:00
bool validateTargetDevice ( const Elf : : Elf < Elf : : EI_CLASS_64 > & elf , const TargetDevice & targetDevice ) {
GFXCORE_FAMILY gfxCore = IGFX_UNKNOWN_CORE ;
PRODUCT_FAMILY productFamily = IGFX_UNKNOWN ;
Elf : : ZebinTargetMetadata targetMetadata = { } ;
auto intelGTNotes = getIntelGTNotes ( elf ) ;
for ( const auto & intelGTNote : intelGTNotes ) {
switch ( intelGTNote - > type ) {
case Elf : : IntelGTSectionType : : ProductFamily :
productFamily = static_cast < PRODUCT_FAMILY > ( intelGTNote - > desc ) ;
break ;
case Elf : : IntelGTSectionType : : GfxCore :
gfxCore = static_cast < GFXCORE_FAMILY > ( intelGTNote - > desc ) ;
break ;
case Elf : : IntelGTSectionType : : TargetMetadata :
targetMetadata . packed = intelGTNote - > desc ;
break ;
default :
return false ;
}
}
bool validForTarget = ( gfxCore ! = IGFX_UNKNOWN_CORE ) | ( productFamily ! = IGFX_UNKNOWN ) ;
validForTarget & = ( gfxCore ! = IGFX_UNKNOWN_CORE ) ? targetDevice . coreFamily = = gfxCore : true ;
validForTarget & = ( productFamily ! = IGFX_UNKNOWN ) ? targetDevice . productFamily = = productFamily : true ;
validForTarget & = ( 0 = = targetMetadata . validateRevisionId ) | ( ( targetDevice . stepping > = targetMetadata . minHwRevisionId ) & ( targetDevice . stepping < = targetMetadata . maxHwRevisionId ) ) ;
validForTarget & = ( 8U = = targetDevice . maxPointerSizeInBytes ) ;
return validForTarget ;
}
std : : vector < const Elf : : IntelGTNote * > getIntelGTNotes ( const Elf : : Elf < Elf : : EI_CLASS_64 > & elf ) {
std : : vector < const Elf : : IntelGTNote * > intelGTNotes ;
for ( size_t i = 0 ; i < elf . sectionHeaders . size ( ) ; i + + ) {
auto section = elf . sectionHeaders [ i ] ;
if ( Elf : : SHT_NOTE = = section . header - > type & & Elf : : SectionsNamesZebin : : noteIntelGT = = elf . getSectionName ( static_cast < uint32_t > ( i ) ) ) {
auto numEntries = elf . sectionHeaders [ i ] . header - > size / sizeof ( Elf : : IntelGTNote ) ;
for ( uint32_t i = 0 ; i < numEntries ; + + i ) {
auto intelGTNote = reinterpret_cast < const Elf : : IntelGTNote * > ( section . data . begin ( ) + i * sizeof ( Elf : : IntelGTNote ) ) ;
bool isValidGTNote = sizeof ( uint32_t ) = = intelGTNote - > descSize ;
isValidGTNote & = Elf : : IntelGtNoteOwnerName . size ( ) + 1 = = intelGTNote - > nameSize ;
isValidGTNote & = Elf : : IntelGtNoteOwnerName = = ConstStringRef ( intelGTNote - > ownerName ) ;
if ( isValidGTNote ) {
intelGTNotes . push_back ( intelGTNote ) ;
} else {
continue ;
}
}
}
}
return intelGTNotes ;
}
2020-07-30 19:18:54 +08:00
DecodeError extractZebinSections ( NEO : : Elf : : Elf < Elf : : EI_CLASS_64 > & elf , ZebinSections & out , std : : string & outErrReason , std : : string & outWarning ) {
if ( ( elf . elfFileHeader - > shStrNdx > = elf . sectionHeaders . size ( ) ) | | ( NEO : : Elf : : SHN_UNDEF = = elf . elfFileHeader - > shStrNdx ) ) {
outErrReason . append ( " DeviceBinaryFormat::Zebin : Invalid or missing shStrNdx in elf header \n " ) ;
return DecodeError : : InvalidBinary ;
}
2021-01-20 00:29:20 +08:00
2020-07-30 19:18:54 +08:00
auto sectionHeaderNamesData = elf . sectionHeaders [ elf . elfFileHeader - > shStrNdx ] . data ;
ConstStringRef sectionHeaderNamesString ( reinterpret_cast < const char * > ( sectionHeaderNamesData . begin ( ) ) , sectionHeaderNamesData . size ( ) ) ;
for ( auto & elfSectionHeader : elf . sectionHeaders ) {
ConstStringRef sectionName = ConstStringRef ( sectionHeaderNamesString . begin ( ) + elfSectionHeader . header - > name ) ;
switch ( elfSectionHeader . header - > type ) {
default :
outErrReason . append ( " DeviceBinaryFormat::Zebin : Unhandled ELF section header type : " + std : : to_string ( elfSectionHeader . header - > type ) + " \n " ) ;
return DecodeError : : InvalidBinary ;
case Elf : : SHT_PROGBITS :
if ( sectionName . startsWith ( NEO : : Elf : : SectionsNamesZebin : : textPrefix . data ( ) ) ) {
out . textKernelSections . push_back ( & elfSectionHeader ) ;
} else if ( sectionName = = NEO : : Elf : : SectionsNamesZebin : : dataConst ) {
out . constDataSections . push_back ( & elfSectionHeader ) ;
2021-01-20 00:29:20 +08:00
} else if ( sectionName = = NEO : : Elf : : SectionsNamesZebin : : dataGlobalConst ) {
2020-07-30 19:18:54 +08:00
outWarning . append ( " Misspelled section name : " + sectionName . str ( ) + " , should be : " + NEO : : Elf : : SectionsNamesZebin : : dataConst . str ( ) + " \n " ) ;
out . constDataSections . push_back ( & elfSectionHeader ) ;
} else if ( sectionName = = NEO : : Elf : : SectionsNamesZebin : : dataGlobal ) {
out . globalDataSections . push_back ( & elfSectionHeader ) ;
2021-07-15 22:32:33 +08:00
} else if ( sectionName . startsWith ( NEO : : Elf : : SectionsNamesZebin : : debugPrefix . data ( ) ) ) {
// ignoring intentionally
2020-07-30 19:18:54 +08:00
} else {
2021-07-15 22:32:33 +08:00
outErrReason . append ( " DeviceBinaryFormat::Zebin : Unhandled SHT_PROGBITS section : " + sectionName . str ( ) + " currently supports only : " + NEO : : Elf : : SectionsNamesZebin : : textPrefix . str ( ) + " KERNEL_NAME, " + NEO : : Elf : : SectionsNamesZebin : : dataConst . str ( ) + " , " + NEO : : Elf : : SectionsNamesZebin : : dataGlobal . str ( ) + " and " + NEO : : Elf : : SectionsNamesZebin : : debugPrefix . str ( ) + " * . \n " ) ;
2020-07-30 19:18:54 +08:00
return DecodeError : : InvalidBinary ;
}
break ;
case NEO : : Elf : : SHT_ZEBIN_ZEINFO :
out . zeInfoSections . push_back ( & elfSectionHeader ) ;
break ;
case NEO : : Elf : : SHT_SYMTAB :
out . symtabSections . push_back ( & elfSectionHeader ) ;
break ;
case NEO : : Elf : : SHT_ZEBIN_SPIRV :
out . spirvSections . push_back ( & elfSectionHeader ) ;
break ;
2021-07-02 22:28:08 +08:00
case NEO : : Elf : : SHT_NOTE :
if ( sectionName = = NEO : : Elf : : SectionsNamesZebin : : noteIntelGT ) {
out . noteIntelGTSections . push_back ( & elfSectionHeader ) ;
} else {
outWarning . append ( " DeviceBinaryFormat::Zebin : Unhandled SHT_NOTE section : " + sectionName . str ( ) + " currently supports only : " + NEO : : Elf : : SectionsNamesZebin : : noteIntelGT . str ( ) + " . \n " ) ;
}
break ;
2020-07-30 19:18:54 +08:00
case NEO : : Elf : : SHT_STRTAB :
// ignoring intentionally - section header names
continue ;
2021-01-20 00:29:20 +08:00
case NEO : : Elf : : SHT_REL :
case NEO : : Elf : : SHT_RELA :
// ignoring intentionally - rel/rela sections handled by Elf decoder
continue ;
2020-09-07 09:05:13 +08:00
case NEO : : Elf : : SHT_ZEBIN_GTPIN_INFO :
// ignoring intentionally - gtpin internal data
continue ;
2020-07-30 19:18:54 +08:00
case NEO : : Elf : : SHT_NULL :
// ignoring intentionally, inactive section, probably UNDEF
continue ;
}
}
return DecodeError : : Success ;
}
template < typename ContainerT >
bool validateZebinSectionsCountAtMost ( const ContainerT & sectionsContainer , ConstStringRef sectionName , uint32_t max , std : : string & outErrReason , std : : string & outWarning ) {
if ( sectionsContainer . size ( ) < = max ) {
return true ;
}
outErrReason . append ( " DeviceBinaryFormat::Zebin : Expected at most " + std : : to_string ( max ) + " of " + sectionName . str ( ) + " section, got : " + std : : to_string ( sectionsContainer . size ( ) ) + " \n " ) ;
return false ;
}
template < typename ContainerT >
bool validateZebinSectionsCountExactly ( const ContainerT & sectionsContainer , ConstStringRef sectionName , uint32_t num , std : : string & outErrReason , std : : string & outWarning ) {
if ( sectionsContainer . size ( ) = = num ) {
return true ;
}
outErrReason . append ( " DeviceBinaryFormat::Zebin : Expected exactly " + std : : to_string ( num ) + " of " + sectionName . str ( ) + " section, got : " + std : : to_string ( sectionsContainer . size ( ) ) + " \n " ) ;
return false ;
}
DecodeError validateZebinSectionsCount ( const ZebinSections & sections , std : : string & outErrReason , std : : string & outWarning ) {
bool valid = validateZebinSectionsCountAtMost ( sections . zeInfoSections , NEO : : Elf : : SectionsNamesZebin : : zeInfo , 1U , outErrReason , outWarning ) ;
valid & = validateZebinSectionsCountAtMost ( sections . globalDataSections , NEO : : Elf : : SectionsNamesZebin : : dataGlobal , 1U , outErrReason , outWarning ) ;
valid & = validateZebinSectionsCountAtMost ( sections . constDataSections , NEO : : Elf : : SectionsNamesZebin : : dataConst , 1U , outErrReason , outWarning ) ;
valid & = validateZebinSectionsCountAtMost ( sections . symtabSections , NEO : : Elf : : SectionsNamesZebin : : symtab , 1U , outErrReason , outWarning ) ;
valid & = validateZebinSectionsCountAtMost ( sections . spirvSections , NEO : : Elf : : SectionsNamesZebin : : spv , 1U , outErrReason , outWarning ) ;
2021-07-02 22:28:08 +08:00
valid & = validateZebinSectionsCountAtMost ( sections . noteIntelGTSections , NEO : : Elf : : SectionsNamesZebin : : noteIntelGT , 1U , outErrReason , outWarning ) ;
2020-07-30 19:18:54 +08:00
return valid ? DecodeError : : Success : DecodeError : : InvalidBinary ;
}
void extractZeInfoKernelSections ( const NEO : : Yaml : : YamlParser & parser , const NEO : : Yaml : : Node & kernelNd , ZeInfoKernelSections & outZeInfoKernelSections , ConstStringRef context , std : : string & outWarning ) {
for ( const auto & kernelMetadataNd : parser . createChildrenRange ( kernelNd ) ) {
auto key = parser . readKey ( kernelMetadataNd ) ;
if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : name = = key ) {
outZeInfoKernelSections . nameNd . push_back ( & kernelMetadataNd ) ;
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : executionEnv = = key ) {
outZeInfoKernelSections . executionEnvNd . push_back ( & kernelMetadataNd ) ;
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : payloadArguments = = key ) {
outZeInfoKernelSections . payloadArgumentsNd . push_back ( & kernelMetadataNd ) ;
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : perThreadPayloadArguments = = key ) {
outZeInfoKernelSections . perThreadPayloadArgumentsNd . push_back ( & kernelMetadataNd ) ;
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : bindingTableIndices = = key ) {
outZeInfoKernelSections . bindingTableIndicesNd . push_back ( & kernelMetadataNd ) ;
2020-08-30 14:50:00 +08:00
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : perThreadMemoryBuffers = = key ) {
outZeInfoKernelSections . perThreadMemoryBuffersNd . push_back ( & kernelMetadataNd ) ;
2021-01-14 09:19:44 +08:00
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : experimentalProperties = = key ) {
outZeInfoKernelSections . experimentalPropertiesNd . push_back ( & kernelMetadataNd ) ;
2020-07-30 19:18:54 +08:00
} else {
outWarning . append ( " DeviceBinaryFormat::Zebin:: " + NEO : : Elf : : SectionsNamesZebin : : zeInfo . str ( ) + " : Unknown entry \" " + parser . readKey ( kernelMetadataNd ) . str ( ) + " \" in context of : " + context . str ( ) + " \n " ) ;
}
}
}
DecodeError validateZeInfoKernelSectionsCount ( const ZeInfoKernelSections & outZeInfoKernelSections , std : : string & outErrReason , std : : string & outWarning ) {
bool valid = validateZebinSectionsCountExactly ( outZeInfoKernelSections . nameNd , NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : name , 1U , outErrReason , outWarning ) ;
valid & = validateZebinSectionsCountExactly ( outZeInfoKernelSections . executionEnvNd , NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : executionEnv , 1U , outErrReason , outWarning ) ;
valid & = validateZebinSectionsCountAtMost ( outZeInfoKernelSections . payloadArgumentsNd , NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : payloadArguments , 1U , outErrReason , outWarning ) ;
valid & = validateZebinSectionsCountAtMost ( outZeInfoKernelSections . perThreadPayloadArgumentsNd , NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : perThreadPayloadArguments , 1U , outErrReason , outWarning ) ;
valid & = validateZebinSectionsCountAtMost ( outZeInfoKernelSections . bindingTableIndicesNd , NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : bindingTableIndices , 1U , outErrReason , outWarning ) ;
2020-08-30 14:50:00 +08:00
valid & = validateZebinSectionsCountAtMost ( outZeInfoKernelSections . perThreadMemoryBuffersNd , NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : perThreadMemoryBuffers , 1U , outErrReason , outWarning ) ;
2021-01-14 09:19:44 +08:00
valid & = validateZebinSectionsCountAtMost ( outZeInfoKernelSections . experimentalPropertiesNd , NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : experimentalProperties , 1U , outErrReason , outWarning ) ;
2020-07-30 19:18:54 +08:00
return valid ? DecodeError : : Success : DecodeError : : InvalidBinary ;
}
template < typename T >
bool readZeInfoValueChecked ( const NEO : : Yaml : : YamlParser & parser , const NEO : : Yaml : : Node & node , T & outValue , ConstStringRef context , std : : string & outErrReason ) {
if ( parser . readValueChecked ( node , outValue ) ) {
return true ;
}
outErrReason . append ( " DeviceBinaryFormat::Zebin:: " + NEO : : Elf : : SectionsNamesZebin : : zeInfo . str ( ) + " : could not read " + parser . readKey ( node ) . str ( ) + " from : [ " + parser . readValue ( node ) . str ( ) + " ] in context of : " + context . str ( ) + " \n " ) ;
return false ;
}
DecodeError readZeInfoExecutionEnvironment ( const NEO : : Yaml : : YamlParser & parser , const NEO : : Yaml : : Node & node ,
NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ExecutionEnv : : ExecutionEnvBaseT & outExecEnv ,
ConstStringRef context ,
std : : string & outErrReason , std : : string & outWarning ) {
bool validExecEnv = true ;
for ( const auto & execEnvMetadataNd : parser . createChildrenRange ( node ) ) {
auto key = parser . readKey ( execEnvMetadataNd ) ;
if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : ExecutionEnv : : actualKernelStartOffset = = key ) {
validExecEnv = validExecEnv & readZeInfoValueChecked ( parser , execEnvMetadataNd , outExecEnv . actualKernelStartOffset , context , outErrReason ) ;
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : ExecutionEnv : : barrierCount = = key ) {
validExecEnv = validExecEnv & readZeInfoValueChecked ( parser , execEnvMetadataNd , outExecEnv . barrierCount , context , outErrReason ) ;
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : ExecutionEnv : : disableMidThreadPreemption = = key ) {
validExecEnv = validExecEnv & readZeInfoValueChecked ( parser , execEnvMetadataNd , outExecEnv . disableMidThreadPreemption , context , outErrReason ) ;
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : ExecutionEnv : : grfCount = = key ) {
validExecEnv = validExecEnv & readZeInfoValueChecked ( parser , execEnvMetadataNd , outExecEnv . grfCount , context , outErrReason ) ;
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : ExecutionEnv : : has4gbBuffers = = key ) {
validExecEnv = validExecEnv & readZeInfoValueChecked ( parser , execEnvMetadataNd , outExecEnv . has4GBBuffers , context , outErrReason ) ;
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : ExecutionEnv : : hasDeviceEnqueue = = key ) {
validExecEnv = validExecEnv & readZeInfoValueChecked ( parser , execEnvMetadataNd , outExecEnv . hasDeviceEnqueue , context , outErrReason ) ;
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : ExecutionEnv : : hasFenceForImageAccess = = key ) {
validExecEnv = validExecEnv & readZeInfoValueChecked ( parser , execEnvMetadataNd , outExecEnv . hasFenceForImageAccess , context , outErrReason ) ;
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : ExecutionEnv : : hasGlobalAtomics = = key ) {
validExecEnv = validExecEnv & readZeInfoValueChecked ( parser , execEnvMetadataNd , outExecEnv . hasGlobalAtomics , context , outErrReason ) ;
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : ExecutionEnv : : hasMultiScratchSpaces = = key ) {
validExecEnv = validExecEnv & readZeInfoValueChecked ( parser , execEnvMetadataNd , outExecEnv . hasMultiScratchSpaces , context , outErrReason ) ;
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : ExecutionEnv : : hasNoStatelessWrite = = key ) {
validExecEnv = validExecEnv & readZeInfoValueChecked ( parser , execEnvMetadataNd , outExecEnv . hasNoStatelessWrite , context , outErrReason ) ;
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : ExecutionEnv : : hwPreemptionMode = = key ) {
validExecEnv = validExecEnv & readZeInfoValueChecked ( parser , execEnvMetadataNd , outExecEnv . hwPreemptionMode , context , outErrReason ) ;
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : ExecutionEnv : : offsetToSkipPerThreadDataLoad = = key ) {
validExecEnv = validExecEnv & readZeInfoValueChecked ( parser , execEnvMetadataNd , outExecEnv . offsetToSkipPerThreadDataLoad , context , outErrReason ) ;
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : ExecutionEnv : : offsetToSkipSetFfidGp = = key ) {
validExecEnv = validExecEnv & readZeInfoValueChecked ( parser , execEnvMetadataNd , outExecEnv . offsetToSkipSetFfidGp , context , outErrReason ) ;
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : ExecutionEnv : : requiredSubGroupSize = = key ) {
validExecEnv = validExecEnv & readZeInfoValueChecked ( parser , execEnvMetadataNd , outExecEnv . requiredSubGroupSize , context , outErrReason ) ;
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : ExecutionEnv : : simdSize = = key ) {
validExecEnv = validExecEnv & readZeInfoValueChecked ( parser , execEnvMetadataNd , outExecEnv . simdSize , context , outErrReason ) ;
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : ExecutionEnv : : slmSize = = key ) {
validExecEnv = validExecEnv & readZeInfoValueChecked ( parser , execEnvMetadataNd , outExecEnv . slmSize , context , outErrReason ) ;
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : ExecutionEnv : : subgroupIndependentForwardProgress = = key ) {
validExecEnv = validExecEnv & readZeInfoValueChecked ( parser , execEnvMetadataNd , outExecEnv . subgroupIndependentForwardProgress , context , outErrReason ) ;
} else {
outWarning . append ( " DeviceBinaryFormat::Zebin:: " + NEO : : Elf : : SectionsNamesZebin : : zeInfo . str ( ) + " : Unknown entry \" " + key . str ( ) + " \" in context of " + context . str ( ) + " \n " ) ;
}
}
return validExecEnv ? DecodeError : : Success : DecodeError : : InvalidBinary ;
}
2021-01-14 09:19:44 +08:00
DecodeError readZeInfoExperimentalProperties ( const NEO : : Yaml : : YamlParser & parser , const NEO : : Yaml : : Node & node ,
NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ExecutionEnv : : ExperimentalPropertiesBaseT & outExperimentalProperties ,
ConstStringRef context ,
std : : string & outErrReason , std : : string & outWarning ) {
bool validExperimentalProperty = true ;
for ( const auto & experimentalPropertyNd : parser . createChildrenRange ( node ) ) {
for ( const auto & experimentalPropertyMemberNd : parser . createChildrenRange ( experimentalPropertyNd ) ) {
auto key = parser . readKey ( experimentalPropertyMemberNd ) ;
if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : ExperimentalProperties : : hasNonKernelArgLoad = = key ) {
validExperimentalProperty = validExperimentalProperty & readZeInfoValueChecked ( parser , experimentalPropertyMemberNd ,
outExperimentalProperties . hasNonKernelArgLoad , context , outErrReason ) ;
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : ExperimentalProperties : : hasNonKernelArgStore = = key ) {
validExperimentalProperty = validExperimentalProperty & readZeInfoValueChecked ( parser , experimentalPropertyMemberNd ,
outExperimentalProperties . hasNonKernelArgStore , context , outErrReason ) ;
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : ExperimentalProperties : : hasNonKernelArgAtomic = = key ) {
validExperimentalProperty = validExperimentalProperty & readZeInfoValueChecked ( parser , experimentalPropertyMemberNd ,
outExperimentalProperties . hasNonKernelArgAtomic , context , outErrReason ) ;
} else {
outWarning . append ( " DeviceBinaryFormat::Zebin:: " + NEO : : Elf : : SectionsNamesZebin : : zeInfo . str ( ) + " : Unknown entry \" " + key . str ( ) + " \" in context of " + context . str ( ) + " \n " ) ;
validExperimentalProperty = false ;
}
}
}
return validExperimentalProperty ? DecodeError : : Success : DecodeError : : InvalidBinary ;
}
2020-07-30 19:18:54 +08:00
bool readEnumChecked ( const Yaml : : Token * token , NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ArgType & out , ConstStringRef context , std : : string & outErrReason ) {
if ( nullptr = = token ) {
return false ;
}
using namespace NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel ;
using ArgTypeT = NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ArgType ;
auto tokenValue = token - > cstrref ( ) ;
if ( tokenValue = = PerThreadPayloadArgument : : ArgType : : packedLocalIds ) {
out = ArgTypeT : : ArgTypePackedLocalIds ;
} else if ( tokenValue = = PerThreadPayloadArgument : : ArgType : : localId ) {
out = ArgTypeT : : ArgTypeLocalId ;
} else if ( tokenValue = = PayloadArgument : : ArgType : : localSize ) {
out = ArgTypeT : : ArgTypeLocalSize ;
2020-08-19 19:07:34 +08:00
} else if ( tokenValue = = PayloadArgument : : ArgType : : groupCount ) {
out = ArgTypeT : : ArgTypeGroupCount ;
} else if ( tokenValue = = PayloadArgument : : ArgType : : globalSize ) {
out = ArgTypeT : : ArgTypeGlobalSize ;
} else if ( tokenValue = = PayloadArgument : : ArgType : : enqueuedLocalSize ) {
out = ArgTypeT : : ArgTypeEnqueuedLocalSize ;
2020-07-30 19:18:54 +08:00
} else if ( tokenValue = = PayloadArgument : : ArgType : : globalIdOffset ) {
out = ArgTypeT : : ArgTypeGlobalIdOffset ;
} else if ( tokenValue = = PayloadArgument : : ArgType : : privateBaseStateless ) {
out = ArgTypeT : : ArgTypePrivateBaseStateless ;
} else if ( tokenValue = = PayloadArgument : : ArgType : : argByvalue ) {
out = ArgTypeT : : ArgTypeArgByvalue ;
} else if ( tokenValue = = PayloadArgument : : ArgType : : argBypointer ) {
out = ArgTypeT : : ArgTypeArgBypointer ;
2021-03-15 23:51:56 +08:00
} else if ( tokenValue = = PayloadArgument : : ArgType : : bufferOffset ) {
out = ArgTypeT : : ArgTypeBufferOffset ;
2021-03-17 22:31:36 +08:00
} else if ( tokenValue = = PayloadArgument : : ArgType : : printfBuffer ) {
out = ArgTypeT : : ArgTypePrintfBuffer ;
2020-07-30 19:18:54 +08:00
} else {
outErrReason . append ( " DeviceBinaryFormat::Zebin:: " + NEO : : Elf : : SectionsNamesZebin : : zeInfo . str ( ) + " : Unhandled \" " + tokenValue . str ( ) + " \" argument type in context of " + context . str ( ) + " \n " ) ;
return false ;
}
return true ;
}
bool readEnumChecked ( const Yaml : : Token * token , NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PayloadArgument : : MemoryAddressingMode & out ,
ConstStringRef context , std : : string & outErrReason ) {
if ( nullptr = = token ) {
return false ;
}
using namespace NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PayloadArgument : : MemoryAddressingMode ;
using AddrMode = NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PayloadArgument : : MemoryAddressingMode ;
auto tokenValue = token - > cstrref ( ) ;
if ( stateless = = tokenValue ) {
out = AddrMode : : MemoryAddressingModeStateless ;
} else if ( stateful = = tokenValue ) {
out = AddrMode : : MemoryAddressingModeStateful ;
} else if ( bindless = = tokenValue ) {
out = AddrMode : : MemoryAddressingModeBindless ;
} else if ( sharedLocalMemory = = tokenValue ) {
out = AddrMode : : MemoryAddressingModeSharedLocalMemory ;
} else {
outErrReason . append ( " DeviceBinaryFormat::Zebin:: " + NEO : : Elf : : SectionsNamesZebin : : zeInfo . str ( ) + " : Unhandled \" " + tokenValue . str ( ) + " \" memory addressing mode in context of " + context . str ( ) + " \n " ) ;
return false ;
}
return true ;
}
bool readEnumChecked ( const Yaml : : Token * token , NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PayloadArgument : : AddressSpace & out ,
ConstStringRef context , std : : string & outErrReason ) {
if ( nullptr = = token ) {
return false ;
}
using namespace NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PayloadArgument : : AddrSpace ;
using AddrSpace = NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PayloadArgument : : AddressSpace ;
auto tokenValue = token - > cstrref ( ) ;
if ( global = = tokenValue ) {
out = AddrSpace : : AddressSpaceGlobal ;
} else if ( local = = tokenValue ) {
out = AddrSpace : : AddressSpaceLocal ;
} else if ( constant = = tokenValue ) {
out = AddrSpace : : AddressSpaceConstant ;
} else if ( image = = tokenValue ) {
out = AddrSpace : : AddressSpaceImage ;
} else if ( sampler = = tokenValue ) {
out = AddrSpace : : AddressSpaceSampler ;
} else {
outErrReason . append ( " DeviceBinaryFormat::Zebin:: " + NEO : : Elf : : SectionsNamesZebin : : zeInfo . str ( ) + " : Unhandled \" " + tokenValue . str ( ) + " \" address space in context of " + context . str ( ) + " \n " ) ;
return false ;
}
return true ;
}
bool readEnumChecked ( const Yaml : : Token * token , NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PayloadArgument : : AccessType & out ,
ConstStringRef context , std : : string & outErrReason ) {
if ( nullptr = = token ) {
return false ;
}
using namespace NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PayloadArgument : : AccessType ;
using AccessType = NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PayloadArgument : : AccessType ;
auto tokenValue = token - > cstrref ( ) ;
static constexpr ConstStringRef readonly ( " readonly " ) ;
static constexpr ConstStringRef writeonly ( " writeonly " ) ;
static constexpr ConstStringRef readwrite ( " readwrite " ) ;
if ( readonly = = tokenValue ) {
out = AccessType : : AccessTypeReadonly ;
} else if ( writeonly = = tokenValue ) {
out = AccessType : : AccessTypeWriteonly ;
} else if ( readwrite = = tokenValue ) {
out = AccessType : : AccessTypeReadwrite ;
} else {
outErrReason . append ( " DeviceBinaryFormat::Zebin:: " + NEO : : Elf : : SectionsNamesZebin : : zeInfo . str ( ) + " : Unhandled \" " + tokenValue . str ( ) + " \" access type in context of " + context . str ( ) + " \n " ) ;
return false ;
}
return true ;
}
2020-08-30 14:50:00 +08:00
bool readEnumChecked ( const Yaml : : Token * token , NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PerThreadMemoryBuffer : : AllocationType & out ,
ConstStringRef context , std : : string & outErrReason ) {
if ( nullptr = = token ) {
return false ;
}
using namespace NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PerThreadMemoryBuffer : : AllocationType ;
using AllocType = NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PerThreadMemoryBuffer : : AllocationType ;
auto tokenValue = token - > cstrref ( ) ;
if ( global = = tokenValue ) {
out = AllocType : : AllocationTypeGlobal ;
} else if ( scratch = = tokenValue ) {
out = AllocType : : AllocationTypeScratch ;
} else if ( slm = = tokenValue ) {
out = AllocType : : AllocationTypeSlm ;
} else {
outErrReason . append ( " DeviceBinaryFormat::Zebin:: " + NEO : : Elf : : SectionsNamesZebin : : zeInfo . str ( ) + " : Unhandled \" " + tokenValue . str ( ) + " \" per-thread memory buffer allocation type in context of " + context . str ( ) + " \n " ) ;
return false ;
}
return true ;
}
bool readEnumChecked ( const Yaml : : Token * token , NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PerThreadMemoryBuffer : : MemoryUsage & out ,
ConstStringRef context , std : : string & outErrReason ) {
if ( nullptr = = token ) {
return false ;
}
using namespace NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PerThreadMemoryBuffer : : MemoryUsage ;
using Usage = NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PerThreadMemoryBuffer : : MemoryUsage ;
auto tokenValue = token - > cstrref ( ) ;
if ( privateSpace = = tokenValue ) {
out = Usage : : MemoryUsagePrivateSpace ;
} else if ( spillFillSpace = = tokenValue ) {
out = Usage : : MemoryUsageSpillFillSpace ;
} else if ( singleSpace = = tokenValue ) {
out = Usage : : MemoryUsageSingleSpace ;
} else {
outErrReason . append ( " DeviceBinaryFormat::Zebin:: " + NEO : : Elf : : SectionsNamesZebin : : zeInfo . str ( ) + " : Unhandled \" " + tokenValue . str ( ) + " \" per-thread memory buffer usage type in context of " + context . str ( ) + " \n " ) ;
return false ;
}
return true ;
}
2020-07-30 19:18:54 +08:00
DecodeError readZeInfoPerThreadPayloadArguments ( const NEO : : Yaml : : YamlParser & parser , const NEO : : Yaml : : Node & node ,
ZeInfoPerThreadPayloadArguments & outPerThreadPayloadArguments ,
ConstStringRef context ,
std : : string & outErrReason , std : : string & outWarning ) {
bool validPerThreadPayload = true ;
for ( const auto & perThredPayloadArgumentNd : parser . createChildrenRange ( node ) ) {
outPerThreadPayloadArguments . resize ( outPerThreadPayloadArguments . size ( ) + 1 ) ;
auto & perThreadPayloadArgMetadata = * outPerThreadPayloadArguments . rbegin ( ) ;
ConstStringRef argTypeStr ;
for ( const auto & perThreadPayloadArgumentMemberNd : parser . createChildrenRange ( perThredPayloadArgumentNd ) ) {
auto key = parser . readKey ( perThreadPayloadArgumentMemberNd ) ;
if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PerThreadPayloadArgument : : argType = = key ) {
auto argTypeToken = parser . getValueToken ( perThreadPayloadArgumentMemberNd ) ;
argTypeStr = parser . readValue ( perThreadPayloadArgumentMemberNd ) ;
validPerThreadPayload & = readEnumChecked ( argTypeToken , perThreadPayloadArgMetadata . argType , context , outErrReason ) ;
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PerThreadPayloadArgument : : size = = key ) {
validPerThreadPayload & = readZeInfoValueChecked ( parser , perThreadPayloadArgumentMemberNd , perThreadPayloadArgMetadata . size , context , outErrReason ) ;
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PerThreadPayloadArgument : : offset = = key ) {
validPerThreadPayload & = readZeInfoValueChecked ( parser , perThreadPayloadArgumentMemberNd , perThreadPayloadArgMetadata . offset , context , outErrReason ) ;
} else {
outWarning . append ( " DeviceBinaryFormat::Zebin:: " + NEO : : Elf : : SectionsNamesZebin : : zeInfo . str ( ) + " : Unknown entry \" " + key . str ( ) + " \" for per-thread payload argument in context of " + context . str ( ) + " \n " ) ;
}
}
if ( 0 = = perThreadPayloadArgMetadata . size ) {
outWarning . append ( " DeviceBinaryFormat::Zebin:: " + NEO : : Elf : : SectionsNamesZebin : : zeInfo . str ( ) + " : Skippinig 0-size per-thread argument of type : " + argTypeStr . str ( ) + " in context of " + context . str ( ) + " \n " ) ;
outPerThreadPayloadArguments . pop_back ( ) ;
}
}
return validPerThreadPayload ? DecodeError : : Success : DecodeError : : InvalidBinary ;
}
DecodeError readZeInfoPayloadArguments ( const NEO : : Yaml : : YamlParser & parser , const NEO : : Yaml : : Node & node ,
ZeInfoPayloadArguments & ouPayloadArguments ,
uint32_t & outMaxPayloadArgumentIndex ,
2021-05-11 20:50:29 +08:00
int32_t & outMaxSamplerIndex ,
2020-07-30 19:18:54 +08:00
ConstStringRef context ,
std : : string & outErrReason , std : : string & outWarning ) {
bool validPayload = true ;
for ( const auto & payloadArgumentNd : parser . createChildrenRange ( node ) ) {
ouPayloadArguments . resize ( ouPayloadArguments . size ( ) + 1 ) ;
auto & payloadArgMetadata = * ouPayloadArguments . rbegin ( ) ;
for ( const auto & payloadArgumentMemberNd : parser . createChildrenRange ( payloadArgumentNd ) ) {
auto key = parser . readKey ( payloadArgumentMemberNd ) ;
if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PayloadArgument : : argType = = key ) {
auto argTypeToken = parser . getValueToken ( payloadArgumentMemberNd ) ;
validPayload & = readEnumChecked ( argTypeToken , payloadArgMetadata . argType , context , outErrReason ) ;
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PayloadArgument : : argIndex = = key ) {
validPayload & = parser . readValueChecked ( payloadArgumentMemberNd , payloadArgMetadata . argIndex ) ;
outMaxPayloadArgumentIndex = std : : max < uint32_t > ( outMaxPayloadArgumentIndex , payloadArgMetadata . argIndex ) ;
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PayloadArgument : : offset = = key ) {
validPayload & = readZeInfoValueChecked ( parser , payloadArgumentMemberNd , payloadArgMetadata . offset , context , outErrReason ) ;
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PayloadArgument : : size = = key ) {
validPayload & = readZeInfoValueChecked ( parser , payloadArgumentMemberNd , payloadArgMetadata . size , context , outErrReason ) ;
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PayloadArgument : : addrmode = = key ) {
auto memTypeToken = parser . getValueToken ( payloadArgumentMemberNd ) ;
validPayload & = readEnumChecked ( memTypeToken , payloadArgMetadata . addrmode , context , outErrReason ) ;
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PayloadArgument : : addrspace = = key ) {
auto addrSpaceToken = parser . getValueToken ( payloadArgumentMemberNd ) ;
validPayload & = readEnumChecked ( addrSpaceToken , payloadArgMetadata . addrspace , context , outErrReason ) ;
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PayloadArgument : : accessType = = key ) {
auto accessTypeToken = parser . getValueToken ( payloadArgumentMemberNd ) ;
validPayload & = readEnumChecked ( accessTypeToken , payloadArgMetadata . accessType , context , outErrReason ) ;
2021-05-11 20:50:29 +08:00
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PayloadArgument : : samplerIndex = = key ) {
validPayload & = parser . readValueChecked ( payloadArgumentMemberNd , payloadArgMetadata . samplerIndex ) ;
outMaxSamplerIndex = std : : max < int32_t > ( outMaxSamplerIndex , payloadArgMetadata . samplerIndex ) ;
2020-07-30 19:18:54 +08:00
} else {
outWarning . append ( " DeviceBinaryFormat::Zebin:: " + NEO : : Elf : : SectionsNamesZebin : : zeInfo . str ( ) + " : Unknown entry \" " + key . str ( ) + " \" for payload argument in context of " + context . str ( ) + " \n " ) ;
}
}
}
return validPayload ? DecodeError : : Success : DecodeError : : InvalidBinary ;
}
DecodeError readZeInfoBindingTableIndices ( const NEO : : Yaml : : YamlParser & parser , const NEO : : Yaml : : Node & node ,
ZeInfoBindingTableIndices & outBindingTableIndices , ZeInfoBindingTableIndices : : value_type & outMaxBindingTableIndex ,
ConstStringRef context ,
std : : string & outErrReason , std : : string & outWarning ) {
bool validBindingTableEntries = true ;
for ( const auto & bindingTableIndexNd : parser . createChildrenRange ( node ) ) {
outBindingTableIndices . resize ( outBindingTableIndices . size ( ) + 1 ) ;
auto & bindingTableIndexMetadata = * outBindingTableIndices . rbegin ( ) ;
for ( const auto & bindingTableIndexMemberNd : parser . createChildrenRange ( bindingTableIndexNd ) ) {
auto key = parser . readKey ( bindingTableIndexMemberNd ) ;
if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : BindingTableIndex : : argIndex = = key ) {
validBindingTableEntries & = readZeInfoValueChecked ( parser , bindingTableIndexMemberNd , bindingTableIndexMetadata . argIndex , context , outErrReason ) ;
outMaxBindingTableIndex . argIndex = std : : max < uint32_t > ( outMaxBindingTableIndex . argIndex , bindingTableIndexMetadata . argIndex ) ;
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : BindingTableIndex : : btiValue = = key ) {
validBindingTableEntries & = readZeInfoValueChecked ( parser , bindingTableIndexMemberNd , bindingTableIndexMetadata . btiValue , context , outErrReason ) ;
outMaxBindingTableIndex . btiValue = std : : max < uint32_t > ( outMaxBindingTableIndex . btiValue , bindingTableIndexMetadata . btiValue ) ;
} else {
outWarning . append ( " DeviceBinaryFormat::Zebin:: " + NEO : : Elf : : SectionsNamesZebin : : zeInfo . str ( ) + " : Unknown entry \" " + key . str ( ) + " \" for binding table index in context of " + context . str ( ) + " \n " ) ;
}
}
}
return validBindingTableEntries ? DecodeError : : Success : DecodeError : : InvalidBinary ;
}
2020-08-30 14:50:00 +08:00
DecodeError readZeInfoPerThreadMemoryBuffers ( const NEO : : Yaml : : YamlParser & parser , const NEO : : Yaml : : Node & node ,
ZeInfoPerThreadMemoryBuffers & outPerThreadMemoryBuffers ,
ConstStringRef context ,
std : : string & outErrReason , std : : string & outWarning ) {
bool validBuffer = true ;
for ( const auto & perThreadMemoryBufferNd : parser . createChildrenRange ( node ) ) {
outPerThreadMemoryBuffers . resize ( outPerThreadMemoryBuffers . size ( ) + 1 ) ;
auto & perThreadMemoryBufferMetadata = * outPerThreadMemoryBuffers . rbegin ( ) ;
for ( const auto & perThreadMemoryBufferMemberNd : parser . createChildrenRange ( perThreadMemoryBufferNd ) ) {
auto key = parser . readKey ( perThreadMemoryBufferMemberNd ) ;
if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PerThreadMemoryBuffer : : allocationType = = key ) {
auto allocationTypeToken = parser . getValueToken ( perThreadMemoryBufferMemberNd ) ;
validBuffer & = readEnumChecked ( allocationTypeToken , perThreadMemoryBufferMetadata . allocationType , context , outErrReason ) ;
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PerThreadMemoryBuffer : : memoryUsage = = key ) {
auto memoryUsageToken = parser . getValueToken ( perThreadMemoryBufferMemberNd ) ;
validBuffer & = readEnumChecked ( memoryUsageToken , perThreadMemoryBufferMetadata . memoryUsage , context , outErrReason ) ;
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PerThreadMemoryBuffer : : size = = key ) {
validBuffer & = readZeInfoValueChecked ( parser , perThreadMemoryBufferMemberNd , perThreadMemoryBufferMetadata . size , context , outErrReason ) ;
2020-10-13 19:14:51 +08:00
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PerThreadMemoryBuffer : : isSimtThread = = key ) {
validBuffer & = readZeInfoValueChecked ( parser , perThreadMemoryBufferMemberNd , perThreadMemoryBufferMetadata . isSimtThread , context , outErrReason ) ;
2020-10-05 01:18:49 +08:00
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PerThreadMemoryBuffer : : slot = = key ) {
validBuffer & = readZeInfoValueChecked ( parser , perThreadMemoryBufferMemberNd , perThreadMemoryBufferMetadata . slot , context , outErrReason ) ;
2020-08-30 14:50:00 +08:00
} else {
outWarning . append ( " DeviceBinaryFormat::Zebin:: " + NEO : : Elf : : SectionsNamesZebin : : zeInfo . str ( ) + " : Unknown entry \" " + key . str ( ) + " \" for per-thread memory buffer in context of " + context . str ( ) + " \n " ) ;
}
}
}
return validBuffer ? DecodeError : : Success : DecodeError : : InvalidBinary ;
}
2020-07-30 19:18:54 +08:00
template < typename ElSize , size_t Len >
bool setVecArgIndicesBasedOnSize ( CrossThreadDataOffset ( & vec ) [ Len ] , size_t vecSize , CrossThreadDataOffset baseOffset ) {
switch ( vecSize ) {
default :
return false ;
case sizeof ( ElSize ) * 3 :
vec [ 2 ] = static_cast < CrossThreadDataOffset > ( baseOffset + 2 * sizeof ( ElSize ) ) ;
CPP_ATTRIBUTE_FALLTHROUGH ;
case sizeof ( ElSize ) * 2 :
vec [ 1 ] = static_cast < CrossThreadDataOffset > ( baseOffset + 1 * sizeof ( ElSize ) ) ;
CPP_ATTRIBUTE_FALLTHROUGH ;
case sizeof ( ElSize ) * 1 :
vec [ 0 ] = static_cast < CrossThreadDataOffset > ( baseOffset + 0 * sizeof ( ElSize ) ) ;
break ;
}
return true ;
}
2021-07-13 23:29:58 +08:00
NEO : : DecodeError populateArgDescriptor ( const NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PerThreadPayloadArgument : : PerThreadPayloadArgumentBaseT & src , NEO : : KernelDescriptor & dst , uint32_t grfSize ,
2020-07-30 19:18:54 +08:00
std : : string & outErrReason , std : : string & outWarning ) {
switch ( src . argType ) {
default :
2020-08-30 14:50:00 +08:00
outErrReason . append ( " DeviceBinaryFormat::Zebin : Invalid arg type in per-thread data section in context of : " + dst . kernelMetadata . kernelName + " . \n " ) ;
2020-07-30 19:18:54 +08:00
return DecodeError : : InvalidBinary ;
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ArgTypeLocalId : {
if ( src . offset ! = 0 ) {
outErrReason . append ( " DeviceBinaryFormat::Zebin : Invalid offset for argument of type " + NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PerThreadPayloadArgument : : ArgType : : localId . str ( ) + " in context of : " + dst . kernelMetadata . kernelName + " . Expected 0. \n " ) ;
return DecodeError : : InvalidBinary ;
}
using LocalIdT = uint16_t ;
uint32_t singleChannelIndicesCount = ( dst . kernelAttributes . simdSize = = 32 ? 32 : 16 ) ;
uint32_t singleChannelBytes = singleChannelIndicesCount * sizeof ( LocalIdT ) ;
2021-07-13 23:29:58 +08:00
UNRECOVERABLE_IF ( 0 = = grfSize ) ;
singleChannelBytes = alignUp ( singleChannelBytes , grfSize ) ;
2020-07-30 19:18:54 +08:00
auto tupleSize = ( src . size / singleChannelBytes ) ;
switch ( tupleSize ) {
default :
outErrReason . append ( " DeviceBinaryFormat::Zebin : Invalid size for argument of type " + NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PerThreadPayloadArgument : : ArgType : : localId . str ( ) + " in context of : " + dst . kernelMetadata . kernelName + " . For simd= " + std : : to_string ( dst . kernelAttributes . simdSize ) + " expected : " + std : : to_string ( singleChannelBytes ) + " or " + std : : to_string ( singleChannelBytes * 2 ) + " or " + std : : to_string ( singleChannelBytes * 3 ) + " . Got : " + std : : to_string ( src . size ) + " \n " ) ;
return DecodeError : : InvalidBinary ;
case 1 :
CPP_ATTRIBUTE_FALLTHROUGH ;
case 2 :
CPP_ATTRIBUTE_FALLTHROUGH ;
case 3 :
dst . kernelAttributes . numLocalIdChannels = static_cast < uint8_t > ( tupleSize ) ;
break ;
}
dst . kernelAttributes . perThreadDataSize = dst . kernelAttributes . simdSize ;
dst . kernelAttributes . perThreadDataSize * = sizeof ( LocalIdT ) ;
2021-07-13 23:29:58 +08:00
dst . kernelAttributes . perThreadDataSize = alignUp ( dst . kernelAttributes . perThreadDataSize , grfSize ) ;
dst . kernelAttributes . perThreadDataSize * = dst . kernelAttributes . numLocalIdChannels ;
2020-07-30 19:18:54 +08:00
break ;
}
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ArgTypePackedLocalIds : {
if ( src . offset ! = 0 ) {
outErrReason . append ( " DeviceBinaryFormat::Zebin : Unhandled offset for argument of type " + NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PerThreadPayloadArgument : : ArgType : : packedLocalIds . str ( ) + " in context of : " + dst . kernelMetadata . kernelName + " . Expected 0. \n " ) ;
return DecodeError : : InvalidBinary ;
}
using LocalIdT = uint16_t ;
auto tupleSize = src . size / sizeof ( LocalIdT ) ;
switch ( tupleSize ) {
default :
outErrReason . append ( " DeviceBinaryFormat::Zebin : Invalid size for argument of type " + NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PerThreadPayloadArgument : : ArgType : : packedLocalIds . str ( ) + " in context of : " + dst . kernelMetadata . kernelName + " . Expected : " + std : : to_string ( sizeof ( LocalIdT ) ) + " or " + std : : to_string ( sizeof ( LocalIdT ) * 2 ) + " or " + std : : to_string ( sizeof ( LocalIdT ) * 3 ) + " . Got : " + std : : to_string ( src . size ) + " \n " ) ;
return DecodeError : : InvalidBinary ;
case 1 :
CPP_ATTRIBUTE_FALLTHROUGH ;
case 2 :
CPP_ATTRIBUTE_FALLTHROUGH ;
case 3 :
dst . kernelAttributes . numLocalIdChannels = static_cast < uint8_t > ( tupleSize ) ;
break ;
}
dst . kernelAttributes . simdSize = 1 ;
dst . kernelAttributes . perThreadDataSize = dst . kernelAttributes . simdSize ;
dst . kernelAttributes . perThreadDataSize * = dst . kernelAttributes . numLocalIdChannels ;
dst . kernelAttributes . perThreadDataSize * = sizeof ( LocalIdT ) ;
break ;
}
}
return DecodeError : : Success ;
}
NEO : : DecodeError populateArgDescriptor ( const NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PayloadArgument : : PayloadArgumentBaseT & src , NEO : : KernelDescriptor & dst , uint32_t & crossThreadDataSize ,
std : : string & outErrReason , std : : string & outWarning ) {
crossThreadDataSize = std : : max < uint32_t > ( crossThreadDataSize , src . offset + src . size ) ;
switch ( src . argType ) {
default :
outErrReason . append ( " DeviceBinaryFormat::Zebin : Invalid arg type in cross thread data section in context of : " + dst . kernelMetadata . kernelName + " . \n " ) ;
return DecodeError : : InvalidBinary ; // unsupported
2020-09-24 21:13:30 +08:00
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ArgTypePrivateBaseStateless : {
dst . payloadMappings . implicitArgs . privateMemoryAddress . stateless = src . offset ;
dst . payloadMappings . implicitArgs . privateMemoryAddress . pointerSize = src . size ;
break ;
}
2020-07-30 19:18:54 +08:00
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ArgTypeArgBypointer : {
auto & argTraits = dst . payloadMappings . explicitArgs [ src . argIndex ] . getTraits ( ) ;
switch ( src . addrspace ) {
default :
UNRECOVERABLE_IF ( NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PayloadArgument : : AddressSpaceUnknown ! = src . addrspace ) ;
argTraits . addressQualifier = KernelArgMetadata : : AddrUnknown ;
2020-10-30 01:00:06 +08:00
dst . payloadMappings . explicitArgs [ src . argIndex ] . as < ArgDescPointer > ( true ) ;
2020-07-30 19:18:54 +08:00
break ;
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PayloadArgument : : AddressSpaceGlobal :
argTraits . addressQualifier = KernelArgMetadata : : AddrGlobal ;
2020-10-30 01:00:06 +08:00
dst . payloadMappings . explicitArgs [ src . argIndex ] . as < ArgDescPointer > ( true ) ;
2020-07-30 19:18:54 +08:00
break ;
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PayloadArgument : : AddressSpaceLocal :
argTraits . addressQualifier = KernelArgMetadata : : AddrLocal ;
2020-10-30 01:00:06 +08:00
dst . payloadMappings . explicitArgs [ src . argIndex ] . as < ArgDescPointer > ( true ) ;
2020-07-30 19:18:54 +08:00
break ;
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PayloadArgument : : AddressSpaceConstant :
argTraits . addressQualifier = KernelArgMetadata : : AddrConstant ;
2020-10-30 01:00:06 +08:00
dst . payloadMappings . explicitArgs [ src . argIndex ] . as < ArgDescPointer > ( true ) ;
break ;
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PayloadArgument : : AddressSpaceImage :
dst . payloadMappings . explicitArgs [ src . argIndex ] . as < ArgDescImage > ( true ) ;
break ;
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PayloadArgument : : AddressSpaceSampler :
2021-05-11 20:50:29 +08:00
static constexpr auto maxSamplerStateSize = 16U ;
static constexpr auto maxIndirectSamplerStateSize = 64U ;
dst . payloadMappings . explicitArgs [ src . argIndex ] . as < ArgDescSampler > ( true ) . bindful = maxIndirectSamplerStateSize + maxSamplerStateSize * src . samplerIndex ;
2020-07-30 19:18:54 +08:00
break ;
}
switch ( src . accessType ) {
default :
UNRECOVERABLE_IF ( argTraits . accessQualifier ! = NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PayloadArgument : : AccessTypeUnknown ) ;
argTraits . accessQualifier = KernelArgMetadata : : AccessUnknown ;
break ;
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PayloadArgument : : AccessTypeReadonly :
argTraits . accessQualifier = KernelArgMetadata : : AccessReadOnly ;
break ;
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PayloadArgument : : AccessTypeReadwrite :
argTraits . accessQualifier = KernelArgMetadata : : AccessReadWrite ;
break ;
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PayloadArgument : : AccessTypeWriteonly :
argTraits . accessQualifier = KernelArgMetadata : : AccessWriteOnly ;
break ;
}
argTraits . argByValSize = sizeof ( void * ) ;
switch ( src . addrmode ) {
default :
outErrReason . append ( " Invalid or missing memory addressing mode for arg idx : " + std : : to_string ( src . argIndex ) + " in context of : " + dst . kernelMetadata . kernelName + " . \n " ) ;
return DecodeError : : InvalidBinary ;
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PayloadArgument : : MemoryAddressingModeStateful :
break ;
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PayloadArgument : : MemoryAddressingModeStateless :
2020-10-30 01:00:06 +08:00
if ( false = = dst . payloadMappings . explicitArgs [ src . argIndex ] . is < NEO : : ArgDescriptor : : ArgTPointer > ( ) ) {
outErrReason . append ( " Invalid or missing memory addressing " + NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PayloadArgument : : MemoryAddressingMode : : stateless . str ( ) + " for arg idx : " + std : : to_string ( src . argIndex ) + " in context of : " + dst . kernelMetadata . kernelName + " . \n " ) ;
return DecodeError : : InvalidBinary ;
}
dst . payloadMappings . explicitArgs [ src . argIndex ] . as < ArgDescPointer > ( false ) . stateless = src . offset ;
dst . payloadMappings . explicitArgs [ src . argIndex ] . as < ArgDescPointer > ( false ) . pointerSize = src . size ;
2020-07-30 19:18:54 +08:00
break ;
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PayloadArgument : : MemoryAddressingModeBindless :
2020-10-30 01:00:06 +08:00
if ( dst . payloadMappings . explicitArgs [ src . argIndex ] . is < NEO : : ArgDescriptor : : ArgTPointer > ( ) ) {
dst . payloadMappings . explicitArgs [ src . argIndex ] . as < ArgDescPointer > ( false ) . bindless = src . offset ;
} else if ( dst . payloadMappings . explicitArgs [ src . argIndex ] . is < NEO : : ArgDescriptor : : ArgTImage > ( ) ) {
dst . payloadMappings . explicitArgs [ src . argIndex ] . as < ArgDescImage > ( false ) . bindless = src . offset ;
} else {
dst . payloadMappings . explicitArgs [ src . argIndex ] . as < ArgDescSampler > ( false ) . bindless = src . offset ;
}
2020-07-30 19:18:54 +08:00
break ;
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PayloadArgument : : MemoryAddressingModeSharedLocalMemory :
2020-10-30 01:00:06 +08:00
dst . payloadMappings . explicitArgs [ src . argIndex ] . as < ArgDescPointer > ( false ) . slmOffset = src . offset ;
dst . payloadMappings . explicitArgs [ src . argIndex ] . as < ArgDescPointer > ( false ) . requiredSlmAlignment = NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PayloadArgument : : Defaults : : slmArgAlignment ;
2020-07-30 19:18:54 +08:00
break ;
}
break ;
}
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ArgTypeArgByvalue : {
auto & argAsValue = dst . payloadMappings . explicitArgs [ src . argIndex ] . as < ArgDescValue > ( true ) ;
ArgDescValue : : Element valueElement ;
valueElement . offset = src . offset ;
valueElement . sourceOffset = 0U ;
valueElement . size = src . size ;
argAsValue . elements . push_back ( valueElement ) ;
break ;
}
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ArgTypeLocalSize : {
using LocalSizeT = uint32_t ;
if ( false = = setVecArgIndicesBasedOnSize < LocalSizeT > ( dst . payloadMappings . dispatchTraits . localWorkSize , src . size , src . offset ) ) {
outErrReason . append ( " DeviceBinaryFormat::Zebin : Invalid size for argument of type " + NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PayloadArgument : : ArgType : : localSize . str ( ) + " in context of : " + dst . kernelMetadata . kernelName + " . Expected 4 or 8 or 12. Got : " + std : : to_string ( src . size ) + " \n " ) ;
return DecodeError : : InvalidBinary ;
}
break ;
}
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ArgTypeGlobalIdOffset : {
using GlovaIdOffsetT = uint32_t ;
if ( false = = setVecArgIndicesBasedOnSize < GlovaIdOffsetT > ( dst . payloadMappings . dispatchTraits . globalWorkOffset , src . size , src . offset ) ) {
outErrReason . append ( " DeviceBinaryFormat::Zebin : Invalid size for argument of type " + NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PayloadArgument : : ArgType : : globalIdOffset . str ( ) + " in context of : " + dst . kernelMetadata . kernelName + " . Expected 4 or 8 or 12. Got : " + std : : to_string ( src . size ) + " \n " ) ;
return DecodeError : : InvalidBinary ;
}
break ;
}
2020-08-19 19:07:34 +08:00
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ArgTypeGroupCount : {
2020-07-30 19:18:54 +08:00
using GroupSizeT = uint32_t ;
if ( false = = setVecArgIndicesBasedOnSize < GroupSizeT > ( dst . payloadMappings . dispatchTraits . numWorkGroups , src . size , src . offset ) ) {
2020-08-19 19:07:34 +08:00
outErrReason . append ( " DeviceBinaryFormat::Zebin : Invalid size for argument of type " + NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PayloadArgument : : ArgType : : groupCount . str ( ) + " in context of : " + dst . kernelMetadata . kernelName + " . Expected 4 or 8 or 12. Got : " + std : : to_string ( src . size ) + " \n " ) ;
return DecodeError : : InvalidBinary ;
}
break ;
}
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ArgTypeGlobalSize : {
using GroupSizeT = uint32_t ;
if ( false = = setVecArgIndicesBasedOnSize < GroupSizeT > ( dst . payloadMappings . dispatchTraits . globalWorkSize , src . size , src . offset ) ) {
outErrReason . append ( " DeviceBinaryFormat::Zebin : Invalid size for argument of type " + NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PayloadArgument : : ArgType : : globalSize . str ( ) + " in context of : " + dst . kernelMetadata . kernelName + " . Expected 4 or 8 or 12. Got : " + std : : to_string ( src . size ) + " \n " ) ;
return DecodeError : : InvalidBinary ;
}
break ;
}
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ArgTypeEnqueuedLocalSize : {
using GroupSizeT = uint32_t ;
if ( false = = setVecArgIndicesBasedOnSize < GroupSizeT > ( dst . payloadMappings . dispatchTraits . enqueuedLocalWorkSize , src . size , src . offset ) ) {
outErrReason . append ( " DeviceBinaryFormat::Zebin : Invalid size for argument of type " + NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PayloadArgument : : ArgType : : enqueuedLocalSize . str ( ) + " in context of : " + dst . kernelMetadata . kernelName + " . Expected 4 or 8 or 12. Got : " + std : : to_string ( src . size ) + " \n " ) ;
return DecodeError : : InvalidBinary ;
2020-07-30 19:18:54 +08:00
}
break ;
}
2021-03-15 23:51:56 +08:00
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ArgTypeBufferOffset : {
if ( 4 ! = src . size ) {
outErrReason . append ( " DeviceBinaryFormat::Zebin : Invalid size for argument of type " + NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PayloadArgument : : ArgType : : bufferOffset . str ( ) + " in context of : " + dst . kernelMetadata . kernelName + " . Expected 4. Got : " + std : : to_string ( src . size ) + " \n " ) ;
return DecodeError : : InvalidBinary ;
}
auto & argAsPointer = dst . payloadMappings . explicitArgs [ src . argIndex ] . as < ArgDescPointer > ( true ) ;
argAsPointer . bufferOffset = src . offset ;
break ;
}
2021-03-17 22:31:36 +08:00
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ArgTypePrintfBuffer : {
dst . kernelAttributes . flags . usesPrintf = true ;
dst . payloadMappings . implicitArgs . printfSurfaceAddress . stateless = src . offset ;
dst . payloadMappings . implicitArgs . printfSurfaceAddress . pointerSize = src . size ;
break ;
}
2020-07-30 19:18:54 +08:00
}
return DecodeError : : Success ;
}
2020-08-30 14:50:00 +08:00
NEO : : DecodeError populateKernelDescriptor ( const NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PerThreadMemoryBuffer : : PerThreadMemoryBufferBaseT & src , NEO : : KernelDescriptor & dst ,
std : : string & outErrReason , std : : string & outWarning ) {
using namespace NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PerThreadMemoryBuffer ;
using namespace NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PerThreadMemoryBuffer : : AllocationType ;
using namespace NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PerThreadMemoryBuffer : : MemoryUsage ;
2020-10-05 01:18:49 +08:00
auto size = src . size ;
if ( src . isSimtThread ) {
size * = dst . kernelAttributes . simdSize ;
}
2020-08-30 14:50:00 +08:00
switch ( src . allocationType ) {
default :
outErrReason . append ( " DeviceBinaryFormat::Zebin : Invalid per-thread memory buffer allocation type in context of : " + dst . kernelMetadata . kernelName + " . \n " ) ;
return DecodeError : : InvalidBinary ;
case AllocationTypeGlobal :
if ( MemoryUsagePrivateSpace ! = src . memoryUsage ) {
outErrReason . append ( " DeviceBinaryFormat::Zebin : Invalid per-thread memory buffer memory usage type for " + global . str ( ) + " allocation type in context of : " + dst . kernelMetadata . kernelName + " . Expected : " + privateSpace . str ( ) + " . \n " ) ;
return DecodeError : : InvalidBinary ;
}
2020-10-05 01:18:49 +08:00
dst . kernelAttributes . perHwThreadPrivateMemorySize = size ;
2020-08-30 14:50:00 +08:00
break ;
case AllocationTypeScratch :
2020-10-05 01:18:49 +08:00
if ( src . slot > 1 ) {
outErrReason . append ( " DeviceBinaryFormat::Zebin : Invalid scratch buffer slot " + std : : to_string ( src . slot ) + " in context of : " + dst . kernelMetadata . kernelName + " . Expected 0 or 1. \n " ) ;
return DecodeError : : InvalidBinary ;
}
if ( 0 ! = dst . kernelAttributes . perThreadScratchSize [ src . slot ] ) {
outErrReason . append ( " DeviceBinaryFormat::Zebin : Invalid duplicated scratch buffer entry " + std : : to_string ( src . slot ) + " in context of : " + dst . kernelMetadata . kernelName + " . \n " ) ;
2020-08-30 14:50:00 +08:00
return DecodeError : : InvalidBinary ;
}
2020-10-05 01:18:49 +08:00
dst . kernelAttributes . perThreadScratchSize [ src . slot ] = size ;
2020-08-30 14:50:00 +08:00
break ;
}
return DecodeError : : Success ;
}
2020-07-30 19:18:54 +08:00
NEO : : DecodeError populateKernelDescriptor ( NEO : : ProgramInfo & dst , NEO : : Elf : : Elf < NEO : : Elf : : EI_CLASS_64 > & elf , NEO : : ZebinSections & zebinSections ,
NEO : : Yaml : : YamlParser & yamlParser , const NEO : : Yaml : : Node & kernelNd , std : : string & outErrReason , std : : string & outWarning ) {
auto kernelInfo = std : : make_unique < NEO : : KernelInfo > ( ) ;
auto & kernelDescriptor = kernelInfo - > kernelDescriptor ;
ZeInfoKernelSections zeInfokernelSections ;
extractZeInfoKernelSections ( yamlParser , kernelNd , zeInfokernelSections , NEO : : Elf : : SectionsNamesZebin : : zeInfo , outWarning ) ;
auto extractError = validateZeInfoKernelSectionsCount ( zeInfokernelSections , outErrReason , outWarning ) ;
if ( DecodeError : : Success ! = extractError ) {
return extractError ;
}
2020-09-08 00:23:47 +08:00
kernelDescriptor . kernelMetadata . kernelName = yamlParser . readValueNoQuotes ( * zeInfokernelSections . nameNd [ 0 ] ) . str ( ) ;
2020-07-30 19:18:54 +08:00
NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ExecutionEnv : : ExecutionEnvBaseT execEnv ;
auto execEnvErr = readZeInfoExecutionEnvironment ( yamlParser , * zeInfokernelSections . executionEnvNd [ 0 ] , execEnv , kernelInfo - > kernelDescriptor . kernelMetadata . kernelName , outErrReason , outWarning ) ;
if ( DecodeError : : Success ! = execEnvErr ) {
return execEnvErr ;
}
ZeInfoPerThreadPayloadArguments perThreadPayloadArguments ;
if ( false = = zeInfokernelSections . perThreadPayloadArgumentsNd . empty ( ) ) {
auto perThreadPayloadArgsErr = readZeInfoPerThreadPayloadArguments ( yamlParser , * zeInfokernelSections . perThreadPayloadArgumentsNd [ 0 ] , perThreadPayloadArguments ,
kernelDescriptor . kernelMetadata . kernelName , outErrReason , outWarning ) ;
if ( DecodeError : : Success ! = perThreadPayloadArgsErr ) {
return perThreadPayloadArgsErr ;
}
}
uint32_t maxArgumentIndex = 0U ;
2021-05-11 20:50:29 +08:00
int32_t maxSamplerIndex = - 1 ;
2020-07-30 19:18:54 +08:00
ZeInfoPayloadArguments payloadArguments ;
if ( false = = zeInfokernelSections . payloadArgumentsNd . empty ( ) ) {
2021-05-11 20:50:29 +08:00
auto payloadArgsErr = readZeInfoPayloadArguments ( yamlParser , * zeInfokernelSections . payloadArgumentsNd [ 0 ] , payloadArguments , maxArgumentIndex , maxSamplerIndex ,
2020-07-30 19:18:54 +08:00
kernelDescriptor . kernelMetadata . kernelName , outErrReason , outWarning ) ;
if ( DecodeError : : Success ! = payloadArgsErr ) {
return payloadArgsErr ;
}
}
2020-08-30 14:50:00 +08:00
ZeInfoPerThreadMemoryBuffers perThreadMemoryBuffers ;
if ( false = = zeInfokernelSections . perThreadMemoryBuffersNd . empty ( ) ) {
auto perThreadMemoryBuffersErr = readZeInfoPerThreadMemoryBuffers ( yamlParser , * zeInfokernelSections . perThreadMemoryBuffersNd [ 0 ] , perThreadMemoryBuffers ,
kernelDescriptor . kernelMetadata . kernelName , outErrReason , outWarning ) ;
if ( DecodeError : : Success ! = perThreadMemoryBuffersErr ) {
return perThreadMemoryBuffersErr ;
}
}
2021-01-14 09:19:44 +08:00
NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ExecutionEnv : : ExperimentalPropertiesBaseT outExperimentalProperties ;
if ( false = = zeInfokernelSections . experimentalPropertiesNd . empty ( ) ) {
auto experimentalPropertiesErr = readZeInfoExperimentalProperties ( yamlParser , * zeInfokernelSections . experimentalPropertiesNd [ 0 ] , outExperimentalProperties ,
kernelInfo - > kernelDescriptor . kernelMetadata . kernelName , outErrReason , outWarning ) ;
if ( DecodeError : : Success ! = experimentalPropertiesErr ) {
return experimentalPropertiesErr ;
}
kernelDescriptor . kernelAttributes . hasNonKernelArgLoad = outExperimentalProperties . hasNonKernelArgLoad ;
kernelDescriptor . kernelAttributes . hasNonKernelArgStore = outExperimentalProperties . hasNonKernelArgStore ;
kernelDescriptor . kernelAttributes . hasNonKernelArgAtomic = outExperimentalProperties . hasNonKernelArgAtomic ;
}
2020-11-19 19:30:44 +08:00
kernelDescriptor . kernelAttributes . barrierCount = execEnv . barrierCount ;
2020-07-30 19:18:54 +08:00
kernelDescriptor . kernelAttributes . flags . requiresDisabledMidThreadPreemption = execEnv . disableMidThreadPreemption ;
kernelDescriptor . kernelAttributes . numGrfRequired = execEnv . grfCount ;
if ( execEnv . has4GBBuffers ) {
kernelDescriptor . kernelAttributes . bufferAddressingMode = KernelDescriptor : : Stateless ;
}
kernelDescriptor . kernelAttributes . flags . usesDeviceSideEnqueue = execEnv . hasDeviceEnqueue ;
kernelDescriptor . kernelAttributes . flags . usesFencesForReadWriteImages = execEnv . hasFenceForImageAccess ;
kernelDescriptor . kernelAttributes . flags . useGlobalAtomics = execEnv . hasGlobalAtomics ;
kernelDescriptor . kernelAttributes . flags . usesStatelessWrites = ( false = = execEnv . hasNoStatelessWrite ) ;
kernelDescriptor . entryPoints . skipPerThreadDataLoad = execEnv . offsetToSkipPerThreadDataLoad ;
kernelDescriptor . entryPoints . skipSetFFIDGP = execEnv . offsetToSkipSetFfidGp ;
kernelDescriptor . kernelMetadata . requiredSubGroupSize = execEnv . requiredSubGroupSize ;
kernelDescriptor . kernelAttributes . simdSize = execEnv . simdSize ;
kernelDescriptor . kernelAttributes . slmInlineSize = execEnv . slmSize ;
kernelDescriptor . kernelAttributes . flags . requiresSubgroupIndependentForwardProgress = execEnv . subgroupIndependentForwardProgress ;
if ( ( kernelDescriptor . kernelAttributes . simdSize ! = 1 ) & & ( kernelDescriptor . kernelAttributes . simdSize ! = 8 ) & & ( kernelDescriptor . kernelAttributes . simdSize ! = 16 ) & & ( kernelDescriptor . kernelAttributes . simdSize ! = 32 ) ) {
outErrReason . append ( " DeviceBinaryFormat::Zebin : Invalid simd size : " + std : : to_string ( kernelDescriptor . kernelAttributes . simdSize ) + " in context of : " + kernelDescriptor . kernelMetadata . kernelName + " . Expected 1, 8, 16 or 32. Got : " + std : : to_string ( kernelDescriptor . kernelAttributes . simdSize ) + " \n " ) ;
return DecodeError : : InvalidBinary ;
}
for ( const auto & arg : perThreadPayloadArguments ) {
2021-07-13 23:29:58 +08:00
auto decodeErr = populateArgDescriptor ( arg , kernelDescriptor , dst . grfSize , outErrReason , outWarning ) ;
2020-07-30 19:18:54 +08:00
if ( DecodeError : : Success ! = decodeErr ) {
return decodeErr ;
}
}
2021-03-19 22:58:46 +08:00
if ( ! payloadArguments . empty ( ) ) {
kernelDescriptor . payloadMappings . explicitArgs . resize ( maxArgumentIndex + 1 ) ;
kernelDescriptor . explicitArgsExtendedMetadata . resize ( maxArgumentIndex + 1 ) ;
kernelDescriptor . kernelAttributes . numArgsToPatch = maxArgumentIndex + 1 ;
}
2020-07-30 19:18:54 +08:00
uint32_t crossThreadDataSize = 0 ;
for ( const auto & arg : payloadArguments ) {
auto decodeErr = populateArgDescriptor ( arg , kernelDescriptor , crossThreadDataSize , outErrReason , outWarning ) ;
if ( DecodeError : : Success ! = decodeErr ) {
return decodeErr ;
}
}
2020-08-30 14:50:00 +08:00
for ( const auto & memBuff : perThreadMemoryBuffers ) {
auto decodeErr = populateKernelDescriptor ( memBuff , kernelDescriptor , outErrReason , outWarning ) ;
if ( DecodeError : : Success ! = decodeErr ) {
return decodeErr ;
}
}
2020-07-30 19:18:54 +08:00
if ( NEO : : DebugManager . flags . ZebinAppendElws . get ( ) ) {
kernelDescriptor . payloadMappings . dispatchTraits . enqueuedLocalWorkSize [ 0 ] = alignDown ( crossThreadDataSize + 12 , 32 ) ;
kernelDescriptor . payloadMappings . dispatchTraits . enqueuedLocalWorkSize [ 1 ] = kernelDescriptor . payloadMappings . dispatchTraits . enqueuedLocalWorkSize [ 0 ] + 4 ;
kernelDescriptor . payloadMappings . dispatchTraits . enqueuedLocalWorkSize [ 2 ] = kernelDescriptor . payloadMappings . dispatchTraits . enqueuedLocalWorkSize [ 1 ] + 4 ;
crossThreadDataSize = kernelDescriptor . payloadMappings . dispatchTraits . enqueuedLocalWorkSize [ 2 ] + 4 ;
}
kernelDescriptor . kernelAttributes . crossThreadDataSize = static_cast < uint16_t > ( alignUp ( crossThreadDataSize , 32 ) ) ;
ZeInfoBindingTableIndices bindingTableIndices ;
ZeInfoBindingTableIndices : : value_type maximumBindingTableEntry ;
if ( false = = zeInfokernelSections . bindingTableIndicesNd . empty ( ) ) {
auto btisErr = readZeInfoBindingTableIndices ( yamlParser , * zeInfokernelSections . bindingTableIndicesNd [ 0 ] , bindingTableIndices , maximumBindingTableEntry ,
kernelDescriptor . kernelMetadata . kernelName , outErrReason , outWarning ) ;
if ( DecodeError : : Success ! = btisErr ) {
return btisErr ;
}
}
auto generatedSshPos = kernelDescriptor . generatedHeaps . size ( ) ;
uint32_t generatedSshSize = 0U ;
if ( bindingTableIndices . empty ( ) = = false ) {
static constexpr auto maxSurfaceStateSize = 64U ;
static constexpr auto btiSize = sizeof ( int ) ;
auto numEntries = maximumBindingTableEntry . btiValue + 1 ;
kernelDescriptor . generatedHeaps . resize ( alignUp ( generatedSshPos , maxSurfaceStateSize ) , 0U ) ;
generatedSshPos = kernelInfo - > kernelDescriptor . generatedHeaps . size ( ) ;
// make room for surface states
kernelDescriptor . generatedHeaps . resize ( generatedSshPos + numEntries * maxSurfaceStateSize , 0U ) ;
auto generatedBindingTablePos = kernelDescriptor . generatedHeaps . size ( ) ;
kernelDescriptor . generatedHeaps . resize ( generatedBindingTablePos + numEntries * btiSize , 0U ) ;
2021-01-07 18:30:05 +08:00
2020-07-30 19:18:54 +08:00
auto bindingTableIt = reinterpret_cast < int * > ( kernelDescriptor . generatedHeaps . data ( ) + generatedBindingTablePos ) ;
2021-01-07 18:30:05 +08:00
for ( int i = 0 ; i < numEntries ; + + i ) {
* bindingTableIt = i * maxSurfaceStateSize ;
2020-07-30 19:18:54 +08:00
+ + bindingTableIt ;
2021-01-07 18:30:05 +08:00
}
for ( auto & bti : bindingTableIndices ) {
2020-07-30 19:18:54 +08:00
auto & explicitArg = kernelDescriptor . payloadMappings . explicitArgs [ bti . argIndex ] ;
switch ( explicitArg . type ) {
default :
outErrReason . append ( " DeviceBinaryFormat::Zebin::.ze_info : Invalid binding table entry for non-pointer and non-image argument idx : " + std : : to_string ( bti . argIndex ) + " . \n " ) ;
return DecodeError : : InvalidBinary ;
2020-10-30 01:00:06 +08:00
case ArgDescriptor : : ArgTImage : {
explicitArg . as < ArgDescImage > ( ) . bindful = bti . btiValue * maxSurfaceStateSize ;
break ;
}
2020-07-30 19:18:54 +08:00
case ArgDescriptor : : ArgTPointer : {
explicitArg . as < ArgDescPointer > ( ) . bindful = bti . btiValue * maxSurfaceStateSize ;
break ;
}
}
}
kernelDescriptor . generatedHeaps . resize ( alignUp ( kernelDescriptor . generatedHeaps . size ( ) , maxSurfaceStateSize ) , 0U ) ;
generatedSshSize = static_cast < uint32_t > ( kernelDescriptor . generatedHeaps . size ( ) - generatedSshPos ) ;
kernelDescriptor . payloadMappings . bindingTable . numEntries = numEntries ;
kernelDescriptor . payloadMappings . bindingTable . tableOffset = static_cast < SurfaceStateHeapOffset > ( generatedBindingTablePos - generatedSshPos ) ;
}
2021-05-11 20:50:29 +08:00
auto generatedDshPos = kernelDescriptor . generatedHeaps . size ( ) ;
uint32_t generatedDshSize = 0U ;
if ( maxSamplerIndex > = 0 ) {
static constexpr auto maxSamplerStateSize = 16U ;
static constexpr auto maxIndirectSamplerStateSize = 64U ;
kernelDescriptor . kernelAttributes . flags . usesSamplers = true ;
auto & samplerTable = kernelDescriptor . payloadMappings . samplerTable ;
samplerTable . borderColor = 0U ;
samplerTable . tableOffset = maxIndirectSamplerStateSize ;
samplerTable . numSamplers = maxSamplerIndex + 1 ;
generatedDshSize = maxIndirectSamplerStateSize + kernelDescriptor . payloadMappings . samplerTable . numSamplers * maxSamplerStateSize ;
generatedDshSize = alignUp ( generatedDshSize , MemoryConstants : : cacheLineSize ) ;
kernelDescriptor . generatedHeaps . resize ( kernelDescriptor . generatedHeaps . size ( ) + generatedDshSize ) ;
}
2020-07-30 19:18:54 +08:00
ZebinSections : : SectionHeaderData * correspondingTextSegment = nullptr ;
auto sectionHeaderNamesData = elf . sectionHeaders [ elf . elfFileHeader - > shStrNdx ] . data ;
ConstStringRef sectionHeaderNamesString ( reinterpret_cast < const char * > ( sectionHeaderNamesData . begin ( ) ) , sectionHeaderNamesData . size ( ) ) ;
for ( auto * textSection : zebinSections . textKernelSections ) {
ConstStringRef sectionName = ConstStringRef ( sectionHeaderNamesString . begin ( ) + textSection - > header - > name ) ;
auto sufix = sectionName . substr ( static_cast < int > ( NEO : : Elf : : SectionsNamesZebin : : textPrefix . length ( ) ) ) ;
if ( sufix = = kernelDescriptor . kernelMetadata . kernelName ) {
correspondingTextSegment = textSection ;
}
}
if ( nullptr = = correspondingTextSegment ) {
2020-10-05 01:18:49 +08:00
outErrReason . append ( " DeviceBinaryFormat::Zebin : Could not find text section for kernel " + kernelDescriptor . kernelMetadata . kernelName + " \n " ) ;
2020-07-30 19:18:54 +08:00
return DecodeError : : InvalidBinary ;
}
kernelInfo - > heapInfo . pKernelHeap = correspondingTextSegment - > data . begin ( ) ;
kernelInfo - > heapInfo . KernelHeapSize = static_cast < uint32_t > ( correspondingTextSegment - > data . size ( ) ) ;
kernelInfo - > heapInfo . KernelUnpaddedSize = static_cast < uint32_t > ( correspondingTextSegment - > data . size ( ) ) ;
kernelInfo - > heapInfo . pSsh = kernelDescriptor . generatedHeaps . data ( ) + generatedSshPos ;
kernelInfo - > heapInfo . SurfaceStateHeapSize = generatedSshSize ;
2021-05-11 20:50:29 +08:00
kernelInfo - > heapInfo . pDsh = kernelDescriptor . generatedHeaps . data ( ) + generatedDshPos ;
kernelInfo - > heapInfo . DynamicStateHeapSize = generatedDshSize ;
2020-07-30 19:18:54 +08:00
dst . kernelInfos . push_back ( kernelInfo . release ( ) ) ;
return DecodeError : : Success ;
}
2020-10-05 01:18:49 +08:00
NEO : : DecodeError populateZeInfoVersion ( NEO : : Elf : : ZebinKernelMetadata : : Types : : Version & dst ,
NEO : : Yaml : : YamlParser & yamlParser , const NEO : : Yaml : : Node & versionNd , std : : string & outErrReason , std : : string & outWarning ) {
if ( nullptr = = yamlParser . getValueToken ( versionNd ) ) {
outErrReason . append ( " DeviceBinaryFormat::Zebin:: " + NEO : : Elf : : SectionsNamesZebin : : zeInfo . str ( ) + " : Invalid version format - expected \' MAJOR.MINOR \' string \n " ) ;
return NEO : : DecodeError : : InvalidBinary ;
}
auto versionStr = yamlParser . readValueNoQuotes ( versionNd ) ;
StackVec < char , 32 > nullTerminated { versionStr . begin ( ) , versionStr . end ( ) } ;
nullTerminated . push_back ( ' \0 ' ) ;
auto separator = std : : find ( nullTerminated . begin ( ) , nullTerminated . end ( ) , ' . ' ) ;
if ( ( nullTerminated . end ( ) = = separator ) | | ( nullTerminated . begin ( ) = = separator ) | | ( & * nullTerminated . rbegin ( ) = = separator + 1 ) ) {
outErrReason . append ( " DeviceBinaryFormat::Zebin:: " + NEO : : Elf : : SectionsNamesZebin : : zeInfo . str ( ) + " : Invalid version format - expected 'MAJOR.MINOR' string, got : " + yamlParser . readValue ( versionNd ) . str ( ) + " \n " ) ;
return NEO : : DecodeError : : InvalidBinary ;
}
* separator = 0 ;
dst . major = atoi ( nullTerminated . begin ( ) ) ;
dst . minor = atoi ( separator + 1 ) ;
return NEO : : DecodeError : : Success ;
}
2020-07-30 19:18:54 +08:00
template < >
DecodeError decodeSingleDeviceBinary < NEO : : DeviceBinaryFormat : : Zebin > ( ProgramInfo & dst , const SingleDeviceBinary & src , std : : string & outErrReason , std : : string & outWarning ) {
auto elf = Elf : : decodeElf < Elf : : EI_CLASS_64 > ( src . deviceBinary , outErrReason , outWarning ) ;
if ( nullptr = = elf . elfFileHeader ) {
return DecodeError : : InvalidBinary ;
}
ZebinSections zebinSections ;
auto extractError = extractZebinSections ( elf , zebinSections , outErrReason , outWarning ) ;
if ( DecodeError : : Success ! = extractError ) {
return extractError ;
}
extractError = validateZebinSectionsCount ( zebinSections , outErrReason , outWarning ) ;
if ( DecodeError : : Success ! = extractError ) {
return extractError ;
}
2021-01-20 00:29:20 +08:00
dst . decodedElf = elf ;
2021-07-13 23:29:58 +08:00
dst . grfSize = src . targetDevice . grfSize ;
2021-01-20 00:29:20 +08:00
2020-07-30 19:18:54 +08:00
if ( false = = zebinSections . globalDataSections . empty ( ) ) {
dst . globalVariables . initData = zebinSections . globalDataSections [ 0 ] - > data . begin ( ) ;
dst . globalVariables . size = zebinSections . globalDataSections [ 0 ] - > data . size ( ) ;
}
if ( false = = zebinSections . constDataSections . empty ( ) ) {
dst . globalConstants . initData = zebinSections . constDataSections [ 0 ] - > data . begin ( ) ;
dst . globalConstants . size = zebinSections . constDataSections [ 0 ] - > data . size ( ) ;
}
if ( false = = zebinSections . symtabSections . empty ( ) ) {
outWarning . append ( " DeviceBinaryFormat::Zebin : Ignoring symbol table \n " ) ;
}
if ( zebinSections . zeInfoSections . empty ( ) ) {
outWarning . append ( " DeviceBinaryFormat::Zebin : Expected at least one " + NEO : : Elf : : SectionsNamesZebin : : zeInfo . str ( ) + " section, got 0 \n " ) ;
return DecodeError : : Success ;
}
auto metadataSectionData = zebinSections . zeInfoSections [ 0 ] - > data ;
ConstStringRef metadataString ( reinterpret_cast < const char * > ( metadataSectionData . begin ( ) ) , metadataSectionData . size ( ) ) ;
NEO : : Yaml : : YamlParser yamlParser ;
bool parseSuccess = yamlParser . parse ( metadataString , outErrReason , outWarning ) ;
if ( false = = parseSuccess ) {
return DecodeError : : InvalidBinary ;
}
if ( yamlParser . empty ( ) ) {
outWarning . append ( " DeviceBinaryFormat::Zebin : Empty kernels metadata section ( " + NEO : : Elf : : SectionsNamesZebin : : zeInfo . str ( ) + " ) \n " ) ;
return DecodeError : : Success ;
}
UniqueNode kernelsSectionNodes ;
2020-10-05 01:18:49 +08:00
UniqueNode versionSectionNodes ;
2020-07-30 19:18:54 +08:00
for ( const auto & globalScopeNd : yamlParser . createChildrenRange ( * yamlParser . getRoot ( ) ) ) {
auto key = yamlParser . readKey ( globalScopeNd ) ;
if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : kernels = = key ) {
kernelsSectionNodes . push_back ( & globalScopeNd ) ;
continue ;
2020-10-05 01:18:49 +08:00
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : version = = key ) {
versionSectionNodes . push_back ( & globalScopeNd ) ;
continue ;
2020-07-30 19:18:54 +08:00
}
outWarning . append ( " DeviceBinaryFormat::Zebin:: " + NEO : : Elf : : SectionsNamesZebin : : zeInfo . str ( ) + " : Unknown entry \" " + yamlParser . readKey ( globalScopeNd ) . str ( ) + " \" in global scope of " + NEO : : Elf : : SectionsNamesZebin : : zeInfo . str ( ) + " \n " ) ;
}
2020-10-05 01:18:49 +08:00
if ( versionSectionNodes . size ( ) > 1U ) {
outErrReason . append ( " DeviceBinaryFormat::Zebin:: " + NEO : : Elf : : SectionsNamesZebin : : zeInfo . str ( ) + " : Expected at most one " + NEO : : Elf : : ZebinKernelMetadata : : Tags : : version . str ( ) + " entry in global scope of " + NEO : : Elf : : SectionsNamesZebin : : zeInfo . str ( ) + " , got : " + std : : to_string ( versionSectionNodes . size ( ) ) + " \n " ) ;
return DecodeError : : InvalidBinary ;
}
NEO : : Elf : : ZebinKernelMetadata : : Types : : Version zeInfoVersion = zeInfoDecoderVersion ;
if ( versionSectionNodes . empty ( ) ) {
outWarning . append ( " DeviceBinaryFormat::Zebin:: " + NEO : : Elf : : SectionsNamesZebin : : zeInfo . str ( ) + " : No version info provided (i.e. no " + NEO : : Elf : : ZebinKernelMetadata : : Tags : : version . str ( ) + " entry in global scope of DeviceBinaryFormat::Zebin:: " + NEO : : Elf : : SectionsNamesZebin : : zeInfo . str ( ) + " ) - will use decoder's default : \' " + std : : to_string ( zeInfoDecoderVersion . major ) + " . " + std : : to_string ( zeInfoDecoderVersion . minor ) + " \' \n " ) ;
zeInfoVersion = NEO : : zeInfoDecoderVersion ;
} else {
auto zeInfoErr = populateZeInfoVersion ( zeInfoVersion , yamlParser , * versionSectionNodes [ 0 ] , outErrReason , outWarning ) ;
if ( DecodeError : : Success ! = zeInfoErr ) {
return zeInfoErr ;
}
}
if ( zeInfoVersion . major ! = zeInfoDecoderVersion . major ) {
outErrReason . append ( " DeviceBinaryFormat::Zebin:: " + NEO : : Elf : : SectionsNamesZebin : : zeInfo . str ( ) + " : Unhandled major version : " + std : : to_string ( zeInfoVersion . major ) + " , decoder is at : " + std : : to_string ( zeInfoDecoderVersion . major ) + " \n " ) ;
return DecodeError : : UnhandledBinary ;
}
if ( zeInfoVersion . minor > zeInfoDecoderVersion . minor ) {
outWarning . append ( " DeviceBinaryFormat::Zebin:: " + NEO : : Elf : : SectionsNamesZebin : : zeInfo . str ( ) + " : Minor version : " + std : : to_string ( zeInfoVersion . minor ) + " is newer than available in decoder : " + std : : to_string ( zeInfoDecoderVersion . minor ) + " - some features may be skipped \n " ) ;
}
2020-07-30 19:18:54 +08:00
if ( kernelsSectionNodes . size ( ) > 1U ) {
outErrReason . append ( " DeviceBinaryFormat::Zebin:: " + NEO : : Elf : : SectionsNamesZebin : : zeInfo . str ( ) + " : Expected at most one " + NEO : : Elf : : ZebinKernelMetadata : : Tags : : kernels . str ( ) + " entry in global scope of " + NEO : : Elf : : SectionsNamesZebin : : zeInfo . str ( ) + " , got : " + std : : to_string ( kernelsSectionNodes . size ( ) ) + " \n " ) ;
return DecodeError : : InvalidBinary ;
}
if ( kernelsSectionNodes . empty ( ) ) {
outWarning . append ( " DeviceBinaryFormat::Zebin:: " + NEO : : Elf : : SectionsNamesZebin : : zeInfo . str ( ) + " : Expected one " + NEO : : Elf : : ZebinKernelMetadata : : Tags : : kernels . str ( ) + " entry in global scope of " + NEO : : Elf : : SectionsNamesZebin : : zeInfo . str ( ) + " , got : " + std : : to_string ( kernelsSectionNodes . size ( ) ) + " \n " ) ;
return DecodeError : : Success ;
}
for ( const auto & kernelNd : yamlParser . createChildrenRange ( * kernelsSectionNodes [ 0 ] ) ) {
auto zeInfoErr = populateKernelDescriptor ( dst , elf , zebinSections , yamlParser , kernelNd , outErrReason , outWarning ) ;
if ( DecodeError : : Success ! = zeInfoErr ) {
return zeInfoErr ;
}
}
return DecodeError : : Success ;
}
} // namespace NEO