2020-07-30 13:18:54 +02:00
/*
2022-01-12 14:47:27 +00:00
* Copyright ( C ) 2020 - 2022 Intel Corporation
2020-07-30 13:18:54 +02: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"
2022-08-09 18:46:36 +00:00
# include "shared/source/device_binary_format/elf/zeinfo_enum_lookup.h"
2020-07-30 13:18:54 +02:00
# include "shared/source/device_binary_format/yaml/yaml_parser.h"
2022-09-08 11:12:08 +00:00
# include "shared/source/helpers/basic_math.h"
2022-07-26 14:37:45 +00:00
# include "shared/source/helpers/ptr_math.h"
2022-08-10 16:11:49 +00:00
# include "shared/source/kernel/kernel_arg_descriptor_extended_vme.h"
2021-09-29 19:10:53 +00:00
# include "shared/source/program/kernel_info.h"
2020-07-30 13:18:54 +02:00
# include "shared/source/program/program_info.h"
# include "shared/source/utilities/stackvec.h"
# include <tuple>
namespace NEO {
2022-09-21 17:34:18 +00:00
template < >
bool isDeviceBinaryFormat < NEO : : DeviceBinaryFormat : : Zebin > ( const ArrayRef < const uint8_t > binary ) {
2022-09-22 11:03:51 +00:00
auto isValidZebinHeader = [ ] ( auto header ) {
return header ! = nullptr & &
( header - > type = = NEO : : Elf : : ET_REL | |
header - > type = = NEO : : Elf : : ET_ZEBIN_EXE ) ;
} ;
return Elf : : isElf < Elf : : EI_CLASS_32 > ( binary )
? isValidZebinHeader ( Elf : : decodeElfFileHeader < Elf : : EI_CLASS_32 > ( binary ) )
: isValidZebinHeader ( Elf : : decodeElfFileHeader < Elf : : EI_CLASS_64 > ( binary ) ) ;
2022-09-21 17:34:18 +00:00
}
2022-09-22 11:03:51 +00:00
template bool validateTargetDevice < Elf : : EI_CLASS_32 > ( const Elf : : Elf < Elf : : EI_CLASS_32 > & elf , const TargetDevice & targetDevice , std : : string & outErrReason , std : : string & outWarning ) ;
template bool validateTargetDevice < Elf : : EI_CLASS_64 > ( const Elf : : Elf < Elf : : EI_CLASS_64 > & elf , const TargetDevice & targetDevice , std : : string & outErrReason , std : : string & outWarning ) ;
template < Elf : : ELF_IDENTIFIER_CLASS numBits >
bool validateTargetDevice ( const Elf : : Elf < numBits > & elf , const TargetDevice & targetDevice , std : : string & outErrReason , std : : string & outWarning ) {
2021-07-02 14:28:08 +00:00
GFXCORE_FAMILY gfxCore = IGFX_UNKNOWN_CORE ;
PRODUCT_FAMILY productFamily = IGFX_UNKNOWN ;
2022-03-08 10:30:15 +00:00
Elf : : ZebinTargetFlags targetMetadata = { } ;
2022-07-26 14:37:45 +00:00
std : : vector < Elf : : IntelGTNote > intelGTNotes = { } ;
auto decodeError = getIntelGTNotes ( elf , intelGTNotes , outErrReason , outWarning ) ;
if ( DecodeError : : Success ! = decodeError ) {
return false ;
}
2021-07-02 14:28:08 +00:00
for ( const auto & intelGTNote : intelGTNotes ) {
2022-07-26 14:37:45 +00:00
switch ( intelGTNote . type ) {
case Elf : : IntelGTSectionType : : ProductFamily : {
DEBUG_BREAK_IF ( sizeof ( uint32_t ) ! = intelGTNote . data . size ( ) ) ;
auto productFamilyData = reinterpret_cast < const uint32_t * > ( intelGTNote . data . begin ( ) ) ;
productFamily = static_cast < PRODUCT_FAMILY > ( * productFamilyData ) ;
break ;
}
case Elf : : IntelGTSectionType : : GfxCore : {
DEBUG_BREAK_IF ( sizeof ( uint32_t ) ! = intelGTNote . data . size ( ) ) ;
auto gfxCoreData = reinterpret_cast < const uint32_t * > ( intelGTNote . data . begin ( ) ) ;
gfxCore = static_cast < GFXCORE_FAMILY > ( * gfxCoreData ) ;
2021-07-02 14:28:08 +00:00
break ;
2022-07-26 14:37:45 +00:00
}
case Elf : : IntelGTSectionType : : TargetMetadata : {
DEBUG_BREAK_IF ( sizeof ( uint32_t ) ! = intelGTNote . data . size ( ) ) ;
auto targetMetadataPacked = reinterpret_cast < const uint32_t * > ( intelGTNote . data . begin ( ) ) ;
targetMetadata . packed = static_cast < uint32_t > ( * targetMetadataPacked ) ;
2021-07-02 14:28:08 +00:00
break ;
2022-07-26 14:37:45 +00:00
}
case Elf : : IntelGTSectionType : : ZebinVersion : {
auto zebinVersionData = reinterpret_cast < const char * > ( intelGTNote . data . begin ( ) ) ;
ConstStringRef versionString ( zebinVersionData ) ;
Elf : : ZebinKernelMetadata : : Types : : Version receivedZeInfoVersion { 0 , 0 } ;
decodeError = populateZeInfoVersion ( receivedZeInfoVersion , versionString , outErrReason ) ;
if ( DecodeError : : Success ! = decodeError ) {
return false ;
}
decodeError = validateZeInfoVersion ( receivedZeInfoVersion , outErrReason , outWarning ) ;
if ( DecodeError : : Success ! = decodeError ) {
return false ;
}
2021-07-02 14:28:08 +00:00
break ;
2022-07-26 14:37:45 +00:00
}
2021-07-02 14:28:08 +00:00
default :
2022-08-10 11:54:18 +00:00
outWarning . append ( " DeviceBinaryFormat::Zebin : Unrecognized IntelGTNote type: " + std : : to_string ( intelGTNote . type ) + " \n " ) ;
break ;
2021-07-02 14:28:08 +00:00
}
}
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 ;
}
2022-07-26 14:37:45 +00:00
DecodeError validateZeInfoVersion ( const Elf : : ZebinKernelMetadata : : Types : : Version & receivedZeInfoVersion , std : : string & outErrReason , std : : string & outWarning ) {
if ( receivedZeInfoVersion . major ! = zeInfoDecoderVersion . major ) {
outErrReason . append ( " DeviceBinaryFormat::Zebin:: " + NEO : : Elf : : SectionsNamesZebin : : zeInfo . str ( ) + " : Unhandled major version : " + std : : to_string ( receivedZeInfoVersion . major ) + " , decoder is at : " + std : : to_string ( zeInfoDecoderVersion . major ) + " \n " ) ;
return DecodeError : : UnhandledBinary ;
}
if ( receivedZeInfoVersion . minor > zeInfoDecoderVersion . minor ) {
outWarning . append ( " DeviceBinaryFormat::Zebin:: " + NEO : : Elf : : SectionsNamesZebin : : zeInfo . str ( ) + " : Minor version : " + std : : to_string ( receivedZeInfoVersion . minor ) + " is newer than available in decoder : " + std : : to_string ( zeInfoDecoderVersion . minor ) + " - some features may be skipped \n " ) ;
}
return DecodeError : : Success ;
}
2022-09-22 11:03:51 +00:00
template < Elf : : ELF_IDENTIFIER_CLASS numBits >
DecodeError getIntelGTNotes ( const Elf : : Elf < numBits > & elf , std : : vector < Elf : : IntelGTNote > & intelGTNotes , std : : string & outErrReason , std : : string & outWarning ) {
2021-07-02 14:28:08 +00:00
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 ) ) ) {
2022-07-26 14:37:45 +00:00
uint64_t currentPos = 0 ;
auto sectionSize = section . header - > size ;
while ( currentPos < sectionSize ) {
auto intelGTNote = reinterpret_cast < const Elf : : ElfNoteSection * > ( section . data . begin ( ) + currentPos ) ;
auto nameSz = intelGTNote - > nameSize ;
auto descSz = intelGTNote - > descSize ;
auto currOffset = sizeof ( Elf : : ElfNoteSection ) + alignUp ( nameSz , 4 ) + alignUp ( descSz , 4 ) ;
if ( currentPos + currOffset > sectionSize ) {
intelGTNotes . clear ( ) ;
outErrReason . append ( " DeviceBinaryFormat::Zebin : Offseting will cause out-of-bound memory read! Section size: " + std : : to_string ( sectionSize ) +
" , current section data offset: " + std : : to_string ( currentPos ) + " , next offset : " + std : : to_string ( currOffset ) + " \n " ) ;
return DecodeError : : InvalidBinary ;
}
currentPos + = currOffset ;
auto ownerName = reinterpret_cast < const char * > ( ptrOffset ( intelGTNote , sizeof ( Elf : : ElfNoteSection ) ) ) ;
bool isValidGTNote = Elf : : IntelGtNoteOwnerName . size ( ) + 1 = = nameSz ;
isValidGTNote & = Elf : : IntelGtNoteOwnerName = = ConstStringRef ( ownerName , nameSz - 1 ) ;
if ( false = = isValidGTNote ) {
outWarning . append ( " DeviceBinaryFormat::Zebin : Invalid owner name : " ) ;
ownerName [ nameSz - 1 ] = = ' \0 ' ? outWarning . append ( std : : string { ownerName , nameSz - 1 } ) : outWarning . append ( ownerName , nameSz ) ;
outWarning . append ( " for IntelGTNote - note will not be used. \n " ) ;
2021-07-02 14:28:08 +00:00
continue ;
}
2022-07-26 14:37:45 +00:00
auto notesData = ArrayRef < const uint8_t > ( reinterpret_cast < const uint8_t * > ( ptrOffset ( ownerName , nameSz ) ) , descSz ) ;
if ( intelGTNote - > type = = Elf : : IntelGTSectionType : : ZebinVersion ) {
isValidGTNote & = notesData [ descSz - 1 ] = = ' \0 ' ;
if ( false = = isValidGTNote ) {
outWarning . append ( " DeviceBinaryFormat::Zebin : Versioning string is not null-terminated: " + ConstStringRef ( reinterpret_cast < const char * > ( notesData . begin ( ) ) , descSz ) . str ( ) + " - note will not be used. \n " ) ;
continue ;
}
}
intelGTNotes . push_back ( Elf : : IntelGTNote { static_cast < Elf : : IntelGTSectionType > ( intelGTNote - > type ) , notesData } ) ;
2021-07-02 14:28:08 +00:00
}
}
}
2022-07-26 14:37:45 +00:00
return DecodeError : : Success ;
2021-07-02 14:28:08 +00:00
}
2022-09-22 11:03:51 +00:00
template < Elf : : ELF_IDENTIFIER_CLASS numBits >
DecodeError extractZebinSections ( NEO : : Elf : : Elf < numBits > & elf , ZebinSections < numBits > & out , std : : string & outErrReason , std : : string & outWarning ) {
2020-07-30 13:18:54 +02:00
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-19 17:29:20 +01:00
2020-07-30 13:18:54 +02: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-19 17:29:20 +01:00
} else if ( sectionName = = NEO : : Elf : : SectionsNamesZebin : : dataGlobalConst ) {
2020-07-30 13:18:54 +02: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-11-02 15:29:09 +00:00
} else if ( sectionName = = NEO : : Elf : : SectionsNamesZebin : : dataConstString ) {
out . constDataStringSections . push_back ( & elfSectionHeader ) ;
2021-07-15 16:32:33 +02:00
} else if ( sectionName . startsWith ( NEO : : Elf : : SectionsNamesZebin : : debugPrefix . data ( ) ) ) {
// ignoring intentionally
2020-07-30 13:18:54 +02:00
} else {
2021-07-15 16:32:33 +02: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 13:18:54 +02: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 14:28:08 +00: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 ;
2022-04-25 12:12:15 +00:00
case NEO : : Elf : : SHT_ZEBIN_MISC :
if ( sectionName = = NEO : : Elf : : SectionsNamesZebin : : buildOptions ) {
out . buildOptionsSection . push_back ( & elfSectionHeader ) ;
} else {
outWarning . append ( " DeviceBinaryFormat::Zebin : unhandled SHT_ZEBIN_MISC section : " + sectionName . str ( ) + " currently supports only : " + NEO : : Elf : : SectionsNamesZebin : : buildOptions . str ( ) + " . \n " ) ;
}
break ;
2020-07-30 13:18:54 +02:00
case NEO : : Elf : : SHT_STRTAB :
// ignoring intentionally - section header names
continue ;
2021-01-19 17:29:20 +01:00
case NEO : : Elf : : SHT_REL :
case NEO : : Elf : : SHT_RELA :
// ignoring intentionally - rel/rela sections handled by Elf decoder
continue ;
2020-09-07 03:05:13 +02:00
case NEO : : Elf : : SHT_ZEBIN_GTPIN_INFO :
// ignoring intentionally - gtpin internal data
continue ;
2021-12-03 10:52:01 +00:00
case NEO : : Elf : : SHT_ZEBIN_VISA_ASM :
// ignoring intentionally - visa asm
continue ;
2020-07-30 13:18:54 +02: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 ;
}
2022-09-22 11:03:51 +00:00
template DecodeError validateZebinSectionsCount < Elf : : EI_CLASS_32 > ( const ZebinSections < Elf : : EI_CLASS_32 > & sections , std : : string & outErrReason , std : : string & outWarning ) ;
template DecodeError validateZebinSectionsCount < Elf : : EI_CLASS_64 > ( const ZebinSections < Elf : : EI_CLASS_64 > & sections , std : : string & outErrReason , std : : string & outWarning ) ;
template < Elf : : ELF_IDENTIFIER_CLASS numBits >
DecodeError validateZebinSectionsCount ( const ZebinSections < numBits > & sections , std : : string & outErrReason , std : : string & outWarning ) {
2020-07-30 13:18:54 +02:00
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 ) ;
2021-11-02 15:29:09 +00:00
valid & = validateZebinSectionsCountAtMost ( sections . constDataStringSections , NEO : : Elf : : SectionsNamesZebin : : dataConstString , 1U , outErrReason , outWarning ) ;
2020-07-30 13:18:54 +02:00
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 14:28:08 +00:00
valid & = validateZebinSectionsCountAtMost ( sections . noteIntelGTSections , NEO : : Elf : : SectionsNamesZebin : : noteIntelGT , 1U , outErrReason , outWarning ) ;
2020-07-30 13:18:54 +02: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 ) ;
2022-09-07 13:21:53 +00:00
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : attributes = = key ) {
outZeInfoKernelSections . attributesNd . push_back ( & kernelMetadataNd ) ;
2020-07-30 13:18:54 +02:00
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : executionEnv = = key ) {
outZeInfoKernelSections . executionEnvNd . push_back ( & kernelMetadataNd ) ;
2021-08-30 13:59:08 +00:00
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : debugEnv = = key ) {
outZeInfoKernelSections . debugEnvNd . push_back ( & kernelMetadataNd ) ;
2020-07-30 13:18:54 +02:00
} 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 08:50:00 +02:00
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : perThreadMemoryBuffers = = key ) {
outZeInfoKernelSections . perThreadMemoryBuffersNd . push_back ( & kernelMetadataNd ) ;
2021-01-13 17:19:44 -08:00
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : experimentalProperties = = key ) {
outZeInfoKernelSections . experimentalPropertiesNd . push_back ( & kernelMetadataNd ) ;
2020-07-30 13:18:54 +02: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 ) ;
2022-09-07 13:21:53 +00:00
valid & = validateZebinSectionsCountAtMost ( outZeInfoKernelSections . attributesNd , NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : attributes , 1U , outErrReason , outWarning ) ;
2021-08-30 13:59:08 +00:00
valid & = validateZebinSectionsCountAtMost ( outZeInfoKernelSections . debugEnvNd , NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : debugEnv , 1U , outErrReason , outWarning ) ;
2020-07-30 13:18:54 +02:00
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 08:50:00 +02:00
valid & = validateZebinSectionsCountAtMost ( outZeInfoKernelSections . perThreadMemoryBuffersNd , NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : perThreadMemoryBuffers , 1U , outErrReason , outWarning ) ;
2021-01-13 17:19:44 -08:00
valid & = validateZebinSectionsCountAtMost ( outZeInfoKernelSections . experimentalPropertiesNd , NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : experimentalProperties , 1U , outErrReason , outWarning ) ;
2020-07-30 13:18:54 +02: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 ;
}
2021-07-26 12:09:15 +00:00
template < typename DestinationT , size_t Len >
2022-09-07 13:21:53 +00:00
bool readZeInfoValueCollectionCheckedArr ( std : : array < DestinationT , Len > & vec , const NEO : : Yaml : : YamlParser & parser , const NEO : : Yaml : : Node & node , ConstStringRef context , std : : string & outErrReason ) {
2021-07-26 12:09:15 +00:00
auto collectionNodes = parser . createChildrenRange ( node ) ;
size_t index = 0U ;
bool isValid = true ;
for ( const auto & elementNd : collectionNodes ) {
isValid & = readZeInfoValueChecked ( parser , elementNd , vec [ index + + ] , context , outErrReason ) ;
}
if ( index ! = Len ) {
outErrReason . append ( " DeviceBinaryFormat::Zebin:: " + NEO : : Elf : : SectionsNamesZebin : : zeInfo . str ( ) + " : wrong size of collection " + parser . readKey ( node ) . str ( ) + " in context of : " + context . str ( ) + " . Got : " + std : : to_string ( index ) + " expected : " + std : : to_string ( Len ) + " \n " ) ;
isValid = false ;
}
return isValid ;
}
2022-09-07 13:21:53 +00:00
template < typename DestinationT , size_t Len >
bool readZeInfoValueCollectionChecked ( DestinationT ( & vec ) [ Len ] , const NEO : : Yaml : : YamlParser & parser , const NEO : : Yaml : : Node & node , ConstStringRef context , std : : string & outErrReason ) {
auto & array = reinterpret_cast < std : : array < DestinationT , Len > & > ( vec ) ;
return readZeInfoValueCollectionCheckedArr ( array , parser , node , context , outErrReason ) ;
}
2020-07-30 13:18:54 +02:00
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 ) ;
2022-07-20 09:29:50 +00:00
if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : ExecutionEnv : : barrierCount = = key ) {
2020-07-30 13:18:54 +02:00
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 ) ;
2021-10-25 08:52:17 +00:00
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : ExecutionEnv : : hasDpas = = key ) {
validExecEnv = validExecEnv & readZeInfoValueChecked ( parser , execEnvMetadataNd , outExecEnv . hasDpas , context , outErrReason ) ;
2020-07-30 13:18:54 +02:00
} 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 ) ;
2021-11-09 12:45:57 +00:00
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : ExecutionEnv : : hasStackCalls = = key ) {
validExecEnv = validExecEnv & readZeInfoValueChecked ( parser , execEnvMetadataNd , outExecEnv . hasStackCalls , context , outErrReason ) ;
2020-07-30 13:18:54 +02:00
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : ExecutionEnv : : hwPreemptionMode = = key ) {
validExecEnv = validExecEnv & readZeInfoValueChecked ( parser , execEnvMetadataNd , outExecEnv . hwPreemptionMode , context , outErrReason ) ;
2021-11-22 11:06:16 +00:00
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : ExecutionEnv : : inlineDataPayloadSize = = key ) {
validExecEnv = validExecEnv & readZeInfoValueChecked ( parser , execEnvMetadataNd , outExecEnv . inlineDataPayloadSize , context , outErrReason ) ;
2020-07-30 13:18:54 +02:00
} 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 ) ;
2021-07-26 12:09:15 +00:00
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : ExecutionEnv : : requiredWorkGroupSize = = key ) {
validExecEnv = validExecEnv & readZeInfoValueCollectionChecked ( outExecEnv . requiredWorkGroupSize , parser , execEnvMetadataNd , context , outErrReason ) ;
2022-02-10 23:33:40 +00:00
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : ExecutionEnv : : requireDisableEUFusion = = key ) {
validExecEnv = validExecEnv & readZeInfoValueChecked ( parser , execEnvMetadataNd , outExecEnv . requireDisableEUFusion , context , outErrReason ) ;
2020-07-30 13:18:54 +02:00
} 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 ) ;
2021-07-26 12:09:15 +00:00
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : ExecutionEnv : : workGroupWalkOrderDimensions = = key ) {
validExecEnv = validExecEnv & readZeInfoValueCollectionChecked ( outExecEnv . workgroupWalkOrderDimensions , parser , execEnvMetadataNd , context , outErrReason ) ;
2022-08-12 14:58:41 +00:00
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : ExecutionEnv : : threadSchedulingMode = = key ) {
validExecEnv & = readZeInfoEnumChecked ( parser , execEnvMetadataNd , outExecEnv . threadSchedulingMode , context , outErrReason ) ;
2020-07-30 13:18:54 +02:00
} 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 ;
}
2022-09-07 13:21:53 +00:00
DecodeError readZeInfoAttributes ( const NEO : : Yaml : : YamlParser & parser , const NEO : : Yaml : : Node & node , NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : Attributes : : AttributesBaseT & outAttributes , ConstStringRef context , std : : string & outErrReason , std : : string & outWarning ) {
namespace AttributeTypes = NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : Attributes ;
bool validAttributes = true ;
for ( const auto & attributesMetadataNd : parser . createChildrenRange ( node ) ) {
auto key = parser . readKey ( attributesMetadataNd ) ;
if ( key = = NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : Attributes : : intelReqdSubgroupSize ) {
outAttributes . intelReqdSubgroupSize = AttributeTypes : : Defaults : : intelReqdSubgroupSize ;
validAttributes & = readZeInfoValueChecked ( parser , attributesMetadataNd , * outAttributes . intelReqdSubgroupSize , context , outErrReason ) ;
} else if ( key = = NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : Attributes : : intelReqdWorkgroupWalkOrder ) {
outAttributes . intelReqdWorkgroupWalkOrder = AttributeTypes : : Defaults : : intelReqdWorkgroupWalkOrder ;
validAttributes & = readZeInfoValueCollectionCheckedArr ( * outAttributes . intelReqdWorkgroupWalkOrder , parser , attributesMetadataNd , context , outErrReason ) ;
} else if ( key = = NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : Attributes : : reqdWorkgroupSize ) {
outAttributes . reqdWorkgroupSize = AttributeTypes : : Defaults : : reqdWorkgroupSize ;
validAttributes & = readZeInfoValueCollectionCheckedArr ( * outAttributes . reqdWorkgroupSize , parser , attributesMetadataNd , context , outErrReason ) ;
} else if ( key = = NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : Attributes : : workgroupSizeHint ) {
outAttributes . workgroupSizeHint = AttributeTypes : : Defaults : : workgroupSizeHint ;
validAttributes & = readZeInfoValueCollectionCheckedArr ( * outAttributes . workgroupSizeHint , parser , attributesMetadataNd , context , outErrReason ) ;
} else if ( key = = NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : Attributes : : invalidKernel ) {
outAttributes . invalidKernel = parser . readValue ( attributesMetadataNd ) ;
} else if ( key = = NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : Attributes : : vecTypeHint ) {
outAttributes . vecTypeHint = parser . readValue ( attributesMetadataNd ) ;
} else if ( key . contains ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : Attributes : : hintSuffix . data ( ) ) ) {
outAttributes . otherHints . push_back ( { key , parser . readValue ( attributesMetadataNd ) } ) ;
} else {
outErrReason . append ( " DeviceBinaryFormat::Zebin:: " + NEO : : Elf : : SectionsNamesZebin : : zeInfo . str ( ) + " : Unknown attribute entry \" " + key . str ( ) + " \" in context of " + context . str ( ) + " \n " ) ;
validAttributes = false ;
}
}
return validAttributes ? DecodeError : : Success : DecodeError : : InvalidBinary ;
}
2021-08-30 13:59:08 +00:00
DecodeError readZeInfoDebugEnvironment ( const NEO : : Yaml : : YamlParser & parser , const NEO : : Yaml : : Node & node ,
NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : DebugEnv : : DebugEnvBaseT & outDebugEnv ,
ConstStringRef context ,
std : : string & outErrReason , std : : string & outWarning ) {
bool validDebugEnv = true ;
for ( const auto & debugEnvNd : parser . createChildrenRange ( node ) ) {
auto key = parser . readKey ( debugEnvNd ) ;
if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : DebugEnv : : debugSurfaceBTI = = key ) {
validDebugEnv = validDebugEnv & readZeInfoValueChecked ( parser , debugEnvNd , outDebugEnv . debugSurfaceBTI , context , outErrReason ) ;
} else {
outWarning . append ( " DeviceBinaryFormat::Zebin:: " + NEO : : Elf : : SectionsNamesZebin : : zeInfo . str ( ) + " : Unknown entry \" " + key . str ( ) + " \" in context of " + context . str ( ) + " \n " ) ;
}
}
return validDebugEnv ? DecodeError : : Success : DecodeError : : InvalidBinary ;
}
2021-01-13 17: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 ;
}
2022-08-09 18:46:36 +00:00
template < typename T >
bool readEnumChecked ( ConstStringRef enumString , T & outValue , ConstStringRef kernelName , std : : string & outErrReason ) {
using EnumLooker = NEO : : Zebin : : ZeInfo : : EnumLookup : : EnumLooker < T > ;
auto enumVal = EnumLooker : : members . find ( enumString ) ;
outValue = enumVal . value_or ( static_cast < T > ( 0 ) ) ;
2020-08-30 08:50:00 +02:00
2022-08-09 18:46:36 +00:00
if ( false = = enumVal . has_value ( ) ) {
outErrReason . append ( " DeviceBinaryFormat::Zebin:: " + NEO : : Elf : : SectionsNamesZebin : : zeInfo . str ( ) + " : Unhandled \" " + enumString . str ( ) + " \" " + EnumLooker : : name . str ( ) + " in context of " + kernelName . str ( ) + " \n " ) ;
2020-08-30 08:50:00 +02:00
}
2022-08-09 18:46:36 +00:00
return enumVal . has_value ( ) ;
2020-08-30 08:50:00 +02:00
}
2022-08-09 18:46:36 +00:00
template < typename T >
bool readZeInfoEnumChecked ( const NEO : : Yaml : : YamlParser & parser , const NEO : : Yaml : : Node & node , T & outValue , ConstStringRef kernelName , std : : string & outErrReason ) {
auto token = parser . getValueToken ( node ) ;
2020-08-30 08:50:00 +02:00
if ( nullptr = = token ) {
return false ;
}
auto tokenValue = token - > cstrref ( ) ;
2022-08-09 18:46:36 +00:00
return readEnumChecked ( tokenValue , outValue , kernelName , outErrReason ) ;
2020-08-30 08:50:00 +02:00
}
2022-08-09 18:46:36 +00:00
template bool readZeInfoEnumChecked < NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PayloadArgument : : ArgTypeT > ( const NEO : : Yaml : : YamlParser & parser , const NEO : : Yaml : : Node & node , NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PayloadArgument : : ArgTypeT & outValue , ConstStringRef kernelName , std : : string & outErrReason ) ;
2020-08-30 08:50:00 +02:00
2020-07-30 13:18:54 +02: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 ) {
argTypeStr = parser . readValue ( perThreadPayloadArgumentMemberNd ) ;
2022-08-09 18:46:36 +00:00
validPerThreadPayload & = readZeInfoEnumChecked ( parser , perThreadPayloadArgumentMemberNd , perThreadPayloadArgMetadata . argType , context , outErrReason ) ;
2020-07-30 13:18:54 +02:00
} 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 ,
2021-11-25 11:53:03 +00:00
int32_t & outMaxPayloadArgumentIndex ,
2021-05-11 14:50:29 +02:00
int32_t & outMaxSamplerIndex ,
2020-07-30 13:18:54 +02: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 ) {
2022-08-09 18:46:36 +00:00
validPayload & = readZeInfoEnumChecked ( parser , payloadArgumentMemberNd , payloadArgMetadata . argType , context , outErrReason ) ;
2020-07-30 13:18:54 +02:00
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PayloadArgument : : argIndex = = key ) {
validPayload & = parser . readValueChecked ( payloadArgumentMemberNd , payloadArgMetadata . argIndex ) ;
2021-11-25 11:53:03 +00:00
outMaxPayloadArgumentIndex = std : : max < int32_t > ( outMaxPayloadArgumentIndex , payloadArgMetadata . argIndex ) ;
2020-07-30 13:18:54 +02:00
} 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 ) {
2022-08-09 18:46:36 +00:00
validPayload & = readZeInfoEnumChecked ( parser , payloadArgumentMemberNd , payloadArgMetadata . addrmode , context , outErrReason ) ;
2020-07-30 13:18:54 +02:00
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PayloadArgument : : addrspace = = key ) {
2022-08-09 18:46:36 +00:00
validPayload & = readZeInfoEnumChecked ( parser , payloadArgumentMemberNd , payloadArgMetadata . addrspace , context , outErrReason ) ;
2020-07-30 13:18:54 +02:00
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PayloadArgument : : accessType = = key ) {
2022-08-09 18:46:36 +00:00
validPayload & = readZeInfoEnumChecked ( parser , payloadArgumentMemberNd , payloadArgMetadata . accessType , context , outErrReason ) ;
2021-05-11 14:50:29 +02: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 ) ;
2021-12-15 14:32:25 +00:00
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PayloadArgument : : sourceOffset = = key ) {
validPayload & = readZeInfoValueChecked ( parser , payloadArgumentMemberNd , payloadArgMetadata . sourceOffset , context , outErrReason ) ;
2022-03-24 12:28:45 +00:00
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PayloadArgument : : slmArgAlignment = = key ) {
validPayload & = readZeInfoValueChecked ( parser , payloadArgumentMemberNd , payloadArgMetadata . slmArgAlignment , context , outErrReason ) ;
2022-08-09 17:17:54 +00:00
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PayloadArgument : : imageType = = key ) {
2022-08-09 18:46:36 +00:00
validPayload & = readZeInfoEnumChecked ( parser , payloadArgumentMemberNd , payloadArgMetadata . imageType , context , outErrReason ) ;
2022-08-09 17:17:54 +00:00
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PayloadArgument : : imageTransformable = = key ) {
validPayload & = readZeInfoValueChecked ( parser , payloadArgumentMemberNd , payloadArgMetadata . imageTransformable , context , outErrReason ) ;
2022-08-10 16:11:49 +00:00
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PayloadArgument : : samplerType = = key ) {
validPayload & = readZeInfoEnumChecked ( parser , payloadArgumentMemberNd , payloadArgMetadata . samplerType , context , outErrReason ) ;
2020-07-30 13:18:54 +02: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 08:50:00 +02: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 ) {
2022-08-09 18:46:36 +00:00
validBuffer & = readZeInfoEnumChecked ( parser , perThreadMemoryBufferMemberNd , perThreadMemoryBufferMetadata . allocationType , context , outErrReason ) ;
2020-08-30 08:50:00 +02:00
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PerThreadMemoryBuffer : : memoryUsage = = key ) {
2022-08-09 18:46:36 +00:00
validBuffer & = readZeInfoEnumChecked ( parser , perThreadMemoryBufferMemberNd , perThreadMemoryBufferMetadata . memoryUsage , context , outErrReason ) ;
2020-08-30 08:50:00 +02:00
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PerThreadMemoryBuffer : : size = = key ) {
validBuffer & = readZeInfoValueChecked ( parser , perThreadMemoryBufferMemberNd , perThreadMemoryBufferMetadata . size , context , outErrReason ) ;
2020-10-13 13:14:51 +02:00
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PerThreadMemoryBuffer : : isSimtThread = = key ) {
validBuffer & = readZeInfoValueChecked ( parser , perThreadMemoryBufferMemberNd , perThreadMemoryBufferMetadata . isSimtThread , context , outErrReason ) ;
2020-10-04 19:18:49 +02:00
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PerThreadMemoryBuffer : : slot = = key ) {
validBuffer & = readZeInfoValueChecked ( parser , perThreadMemoryBufferMemberNd , perThreadMemoryBufferMetadata . slot , context , outErrReason ) ;
2020-08-30 08:50:00 +02: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 ;
}
2022-02-23 11:48:31 +00:00
DecodeError readZeInfoGlobalHostAceessTable ( const NEO : : Yaml : : YamlParser & parser , const NEO : : Yaml : : Node & node ,
ZeInfoGlobalHostAccessTables & outDeviceNameToHostTable ,
ConstStringRef context ,
std : : string & outErrReason , std : : string & outWarning ) {
bool validTable = true ;
for ( const auto & globalHostAccessNameNd : parser . createChildrenRange ( node ) ) {
outDeviceNameToHostTable . resize ( outDeviceNameToHostTable . size ( ) + 1 ) ;
for ( const auto & globalHostAccessNameMemberNd : parser . createChildrenRange ( globalHostAccessNameNd ) ) {
auto & globalHostAccessMetadata = * outDeviceNameToHostTable . rbegin ( ) ;
auto key = parser . readKey ( globalHostAccessNameMemberNd ) ;
if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : GlobalHostAccessTable : : deviceName = = key ) {
validTable & = readZeInfoValueChecked ( parser , globalHostAccessNameMemberNd , globalHostAccessMetadata . deviceName , context , outErrReason ) ;
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : GlobalHostAccessTable : : hostName = = key ) {
validTable & = readZeInfoValueChecked ( parser , globalHostAccessNameMemberNd , globalHostAccessMetadata . hostName , context , outErrReason ) ;
} else {
outWarning . append ( " DeviceBinaryFormat::Zebin:: " + NEO : : Elf : : SectionsNamesZebin : : zeInfo . str ( ) + " : Unknown entry \" " + key . str ( ) + " \" for payload argument in context of " + context . str ( ) + " \n " ) ;
}
}
}
return validTable ? DecodeError : : Success : DecodeError : : InvalidBinary ;
}
2020-07-30 13:18:54 +02: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 ) ) ;
2021-10-22 16:12:30 +00:00
[[fallthrough]] ;
2020-07-30 13:18:54 +02:00
case sizeof ( ElSize ) * 2 :
vec [ 1 ] = static_cast < CrossThreadDataOffset > ( baseOffset + 1 * sizeof ( ElSize ) ) ;
2021-10-22 16:12:30 +00:00
[[fallthrough]] ;
2020-07-30 13:18:54 +02:00
case sizeof ( ElSize ) * 1 :
vec [ 0 ] = static_cast < CrossThreadDataOffset > ( baseOffset + 0 * sizeof ( ElSize ) ) ;
break ;
}
return true ;
}
2021-07-13 15:29:58 +00:00
NEO : : DecodeError populateArgDescriptor ( const NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PerThreadPayloadArgument : : PerThreadPayloadArgumentBaseT & src , NEO : : KernelDescriptor & dst , uint32_t grfSize ,
2020-07-30 13:18:54 +02:00
std : : string & outErrReason , std : : string & outWarning ) {
switch ( src . argType ) {
default :
2020-08-30 08:50:00 +02:00
outErrReason . append ( " DeviceBinaryFormat::Zebin : Invalid arg type in per-thread data section in context of : " + dst . kernelMetadata . kernelName + " . \n " ) ;
2020-07-30 13:18:54 +02: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 15:29:58 +00:00
UNRECOVERABLE_IF ( 0 = = grfSize ) ;
singleChannelBytes = alignUp ( singleChannelBytes , grfSize ) ;
2020-07-30 13:18:54 +02: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 :
case 2 :
case 3 :
dst . kernelAttributes . numLocalIdChannels = static_cast < uint8_t > ( tupleSize ) ;
break ;
}
2022-02-21 15:27:41 +00:00
dst . kernelAttributes . localId [ 0 ] = tupleSize > 0 ;
dst . kernelAttributes . localId [ 1 ] = tupleSize > 1 ;
dst . kernelAttributes . localId [ 2 ] = tupleSize > 2 ;
2020-07-30 13:18:54 +02:00
dst . kernelAttributes . perThreadDataSize = dst . kernelAttributes . simdSize ;
dst . kernelAttributes . perThreadDataSize * = sizeof ( LocalIdT ) ;
2021-07-13 15:29:58 +00:00
dst . kernelAttributes . perThreadDataSize = alignUp ( dst . kernelAttributes . perThreadDataSize , grfSize ) ;
dst . kernelAttributes . perThreadDataSize * = dst . kernelAttributes . numLocalIdChannels ;
2020-07-30 13:18:54 +02: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 :
case 2 :
case 3 :
dst . kernelAttributes . numLocalIdChannels = static_cast < uint8_t > ( tupleSize ) ;
break ;
}
2022-02-21 15:27:41 +00:00
dst . kernelAttributes . localId [ 0 ] = tupleSize > 0 ;
dst . kernelAttributes . localId [ 1 ] = tupleSize > 1 ;
dst . kernelAttributes . localId [ 2 ] = tupleSize > 2 ;
2020-07-30 13:18:54 +02:00
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 ) ;
2022-08-10 16:11:49 +00:00
auto & explicitArgs = dst . payloadMappings . explicitArgs ;
auto getVmeDescriptor = [ & src , & dst ] ( ) {
auto & argsExt = dst . payloadMappings . explicitArgsExtendedDescriptors ;
argsExt . resize ( dst . payloadMappings . explicitArgs . size ( ) ) ;
if ( argsExt [ src . argIndex ] = = nullptr ) {
argsExt [ src . argIndex ] = std : : make_unique < ArgDescVme > ( ) ;
}
return static_cast < ArgDescVme * > ( argsExt [ src . argIndex ] . get ( ) ) ;
} ;
2020-07-30 13:18:54 +02:00
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 15:13:30 +02: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 13:18:54 +02:00
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ArgTypeArgBypointer : {
2022-08-10 16:11:49 +00:00
auto & arg = dst . payloadMappings . explicitArgs [ src . argIndex ] ;
auto & argTraits = arg . getTraits ( ) ;
2020-07-30 13:18:54 +02:00
switch ( src . addrspace ) {
default :
UNRECOVERABLE_IF ( NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PayloadArgument : : AddressSpaceUnknown ! = src . addrspace ) ;
argTraits . addressQualifier = KernelArgMetadata : : AddrUnknown ;
2020-10-29 18:00:06 +01:00
dst . payloadMappings . explicitArgs [ src . argIndex ] . as < ArgDescPointer > ( true ) ;
2020-07-30 13:18:54 +02:00
break ;
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PayloadArgument : : AddressSpaceGlobal :
argTraits . addressQualifier = KernelArgMetadata : : AddrGlobal ;
2020-10-29 18:00:06 +01:00
dst . payloadMappings . explicitArgs [ src . argIndex ] . as < ArgDescPointer > ( true ) ;
2020-07-30 13:18:54 +02:00
break ;
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PayloadArgument : : AddressSpaceLocal :
argTraits . addressQualifier = KernelArgMetadata : : AddrLocal ;
2020-10-29 18:00:06 +01:00
dst . payloadMappings . explicitArgs [ src . argIndex ] . as < ArgDescPointer > ( true ) ;
2020-07-30 13:18:54 +02:00
break ;
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PayloadArgument : : AddressSpaceConstant :
argTraits . addressQualifier = KernelArgMetadata : : AddrConstant ;
2020-10-29 18:00:06 +01:00
dst . payloadMappings . explicitArgs [ src . argIndex ] . as < ArgDescPointer > ( true ) ;
break ;
2022-08-09 17:17:54 +00:00
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PayloadArgument : : AddressSpaceImage : {
2020-10-29 18:00:06 +01:00
dst . payloadMappings . explicitArgs [ src . argIndex ] . as < ArgDescImage > ( true ) ;
2022-08-09 17:17:54 +00:00
auto & extendedInfo = dst . payloadMappings . explicitArgs [ src . argIndex ] . getExtendedTypeInfo ( ) ;
2022-08-10 16:11:49 +00:00
extendedInfo . isMediaImage = ( src . imageType = = NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PayloadArgument : : ImageType : : ImageType2DMedia ) ;
extendedInfo . isMediaBlockImage = ( src . imageType = = NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PayloadArgument : : ImageType : : ImageType2DMediaBlock ) ;
2022-08-09 17:17:54 +00:00
extendedInfo . isTransformable = src . imageTransformable ;
2022-08-10 16:11:49 +00:00
dst . kernelAttributes . flags . usesImages = true ;
} break ;
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PayloadArgument : : AddressSpaceSampler : {
using SamplerType = NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PayloadArgument : : SamplerType ;
dst . payloadMappings . explicitArgs [ src . argIndex ] . as < ArgDescSampler > ( true ) ;
auto & extendedInfo = arg . getExtendedTypeInfo ( ) ;
extendedInfo . isAccelerator = ( src . samplerType = = SamplerType : : SamplerTypeVME ) | |
( src . samplerType = = SamplerType : : SamplerTypeVE ) | |
( src . samplerType = = SamplerType : : SamplerTypeVD ) ;
const bool usesVme = src . samplerType = = SamplerType : : SamplerTypeVME ;
extendedInfo . hasVmeExtendedDescriptor = usesVme ;
dst . kernelAttributes . flags . usesVme = usesVme ;
dst . kernelAttributes . flags . usesSamplers = true ;
2022-08-09 17:17:54 +00:00
} break ;
2020-07-30 13:18:54 +02:00
}
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 * ) ;
2022-06-03 16:01:33 +00:00
if ( dst . payloadMappings . explicitArgs [ src . argIndex ] . is < NEO : : ArgDescriptor : : ArgTPointer > ( ) ) {
dst . payloadMappings . explicitArgs [ src . argIndex ] . as < ArgDescPointer > ( ) . accessedUsingStatelessAddressingMode = false ;
}
2020-07-30 13:18:54 +02:00
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 :
2022-08-10 16:11:49 +00:00
if ( dst . payloadMappings . explicitArgs [ src . argIndex ] . is < NEO : : ArgDescriptor : : ArgTSampler > ( ) ) {
static constexpr auto maxSamplerStateSize = 16U ;
static constexpr auto maxIndirectSamplerStateSize = 64U ;
auto & sampler = dst . payloadMappings . explicitArgs [ src . argIndex ] . as < ArgDescSampler > ( ) ;
sampler . bindful = maxIndirectSamplerStateSize + maxSamplerStateSize * src . samplerIndex ;
}
2020-07-30 13:18:54 +02:00
break ;
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PayloadArgument : : MemoryAddressingModeStateless :
2020-10-29 18:00:06 +01: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 ;
2022-06-03 16:01:33 +00:00
dst . payloadMappings . explicitArgs [ src . argIndex ] . as < ArgDescPointer > ( false ) . accessedUsingStatelessAddressingMode = true ;
2020-07-30 13:18:54 +02:00
break ;
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PayloadArgument : : MemoryAddressingModeBindless :
2020-10-29 18:00:06 +01: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 13:18:54 +02:00
break ;
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PayloadArgument : : MemoryAddressingModeSharedLocalMemory :
2020-10-29 18:00:06 +01:00
dst . payloadMappings . explicitArgs [ src . argIndex ] . as < ArgDescPointer > ( false ) . slmOffset = src . offset ;
2022-03-24 12:28:45 +00:00
dst . payloadMappings . explicitArgs [ src . argIndex ] . as < ArgDescPointer > ( false ) . requiredSlmAlignment = src . slmArgAlignment ;
2020-07-30 13:18:54 +02:00
break ;
}
break ;
}
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ArgTypeArgByvalue : {
auto & argAsValue = dst . payloadMappings . explicitArgs [ src . argIndex ] . as < ArgDescValue > ( true ) ;
ArgDescValue : : Element valueElement ;
2021-12-15 14:32:25 +00:00
valueElement . sourceOffset = 0 ;
if ( src . sourceOffset ! = - 1 ) {
valueElement . sourceOffset = src . sourceOffset ;
} else if ( argAsValue . elements . empty ( ) = = false ) {
outErrReason . append ( " Missing source offset value for element in argByValue \n " ) ;
return DecodeError : : InvalidBinary ;
}
2020-07-30 13:18:54 +02:00
valueElement . offset = src . offset ;
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 13:07:34 +02:00
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ArgTypeGroupCount : {
2020-07-30 13:18:54 +02:00
using GroupSizeT = uint32_t ;
if ( false = = setVecArgIndicesBasedOnSize < GroupSizeT > ( dst . payloadMappings . dispatchTraits . numWorkGroups , src . size , src . offset ) ) {
2020-08-19 13:07:34 +02: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 13:18:54 +02:00
}
break ;
}
2021-03-15 16:51:56 +01:00
2022-06-03 16:01:33 +00:00
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ArgTypeBufferAddress : {
2022-06-14 16:28:55 +00:00
auto & argAsPtr = dst . payloadMappings . explicitArgs [ src . argIndex ] . as < ArgDescPointer > ( true ) ;
argAsPtr . stateless = src . offset ;
argAsPtr . pointerSize = src . size ;
2022-06-03 16:01:33 +00:00
break ;
}
2021-03-15 16:51:56 +01: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 15:31:36 +01: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 ;
}
2021-07-16 10:31:05 +00:00
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ArgTypeWorkDimensions : {
if ( 4 ! = src . size ) {
outErrReason . append ( " DeviceBinaryFormat::Zebin : Invalid size for argument of type " + NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : PayloadArgument : : ArgType : : workDimensions . str ( ) + " in context of : " + dst . kernelMetadata . kernelName + " . Expected 4. Got : " + std : : to_string ( src . size ) + " \n " ) ;
return DecodeError : : InvalidBinary ;
}
dst . payloadMappings . dispatchTraits . workDim = src . offset ;
break ;
}
2022-02-23 18:48:58 +00:00
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ArgTypeImplicitArgBuffer : {
2022-02-25 14:43:46 +00:00
dst . payloadMappings . implicitArgs . implicitArgsBuffer = src . offset ;
2022-02-23 18:48:58 +00:00
dst . kernelAttributes . flags . requiresImplicitArgs = true ;
break ;
}
2020-07-30 13:18:54 +02:00
2022-08-10 16:11:49 +00:00
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ArgTypeImageHeight :
explicitArgs [ src . argIndex ] . as < ArgDescImage > ( true ) . metadataPayload . imgHeight = src . offset ;
break ;
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ArgTypeImageWidth :
explicitArgs [ src . argIndex ] . as < ArgDescImage > ( true ) . metadataPayload . imgWidth = src . offset ;
break ;
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ArgTypeImageDepth :
explicitArgs [ src . argIndex ] . as < ArgDescImage > ( true ) . metadataPayload . imgDepth = src . offset ;
break ;
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ArgTypeImageChannelDataType :
explicitArgs [ src . argIndex ] . as < ArgDescImage > ( true ) . metadataPayload . channelDataType = src . offset ;
break ;
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ArgTypeImageChannelOrder :
explicitArgs [ src . argIndex ] . as < ArgDescImage > ( true ) . metadataPayload . channelOrder = src . offset ;
break ;
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ArgTypeImageArraySize :
explicitArgs [ src . argIndex ] . as < ArgDescImage > ( true ) . metadataPayload . arraySize = src . offset ;
break ;
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ArgTypeImageNumSamples :
explicitArgs [ src . argIndex ] . as < ArgDescImage > ( true ) . metadataPayload . numSamples = src . offset ;
break ;
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ArgTypeImageMipLevels :
explicitArgs [ src . argIndex ] . as < ArgDescImage > ( true ) . metadataPayload . numMipLevels = src . offset ;
break ;
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ArgTypeImageFlatBaseOffset :
explicitArgs [ src . argIndex ] . as < ArgDescImage > ( true ) . metadataPayload . flatBaseOffset = src . offset ;
break ;
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ArgTypeImageFlatWidth :
explicitArgs [ src . argIndex ] . as < ArgDescImage > ( true ) . metadataPayload . flatWidth = src . offset ;
break ;
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ArgTypeImageFlatHeight :
explicitArgs [ src . argIndex ] . as < ArgDescImage > ( true ) . metadataPayload . flatHeight = src . offset ;
break ;
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ArgTypeImageFlatPitch :
explicitArgs [ src . argIndex ] . as < ArgDescImage > ( true ) . metadataPayload . flatPitch = src . offset ;
break ;
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ArgTypeSamplerAddrMode :
explicitArgs [ src . argIndex ] . as < ArgDescSampler > ( true ) . metadataPayload . samplerAddressingMode = src . offset ;
break ;
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ArgTypeSamplerNormCoords :
explicitArgs [ src . argIndex ] . as < ArgDescSampler > ( true ) . metadataPayload . samplerNormalizedCoords = src . offset ;
break ;
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ArgTypeSamplerSnapWa :
explicitArgs [ src . argIndex ] . as < ArgDescSampler > ( true ) . metadataPayload . samplerSnapWa = src . offset ;
break ;
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ArgTypeVmeMbBlockType :
getVmeDescriptor ( ) - > mbBlockType = src . offset ;
break ;
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ArgTypeVmeSubpixelMode :
getVmeDescriptor ( ) - > subpixelMode = src . offset ;
break ;
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ArgTypeVmeSadAdjustMode :
getVmeDescriptor ( ) - > sadAdjustMode = src . offset ;
break ;
case NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ArgTypeVmeSearchPathType :
getVmeDescriptor ( ) - > searchPathType = src . offset ;
break ;
2022-08-09 17:17:54 +00:00
}
2020-07-30 13:18:54 +02:00
return DecodeError : : Success ;
}
2022-09-08 11:12:08 +00:00
NEO : : DecodeError populateKernelDescriptor ( const NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : PerThreadMemoryBuffer : : PerThreadMemoryBufferBaseT & src , NEO : : KernelDescriptor & dst , uint32_t minScratchSpaceSize ,
2020-08-30 08:50:00 +02:00
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 ;
2022-09-08 11:12:08 +00:00
if ( src . size < = 0 ) {
outErrReason . append ( " DeviceBinaryFormat::Zebin : Invalid per-thread memory buffer allocation size (size must be greater than 0) in context of : " + dst . kernelMetadata . kernelName + " . \n " ) ;
return DecodeError : : InvalidBinary ;
}
2020-10-04 19:18:49 +02:00
auto size = src . size ;
if ( src . isSimtThread ) {
size * = dst . kernelAttributes . simdSize ;
}
2020-08-30 08:50:00 +02: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-04 19:18:49 +02:00
dst . kernelAttributes . perHwThreadPrivateMemorySize = size ;
2020-08-30 08:50:00 +02:00
break ;
case AllocationTypeScratch :
2020-10-04 19:18:49 +02: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 08:50:00 +02:00
return DecodeError : : InvalidBinary ;
}
2022-09-08 11:12:08 +00:00
uint32_t scratchSpaceSize = std : : max ( static_cast < uint32_t > ( size ) , minScratchSpaceSize ) ;
scratchSpaceSize = Math : : isPow2 ( scratchSpaceSize ) ? scratchSpaceSize : Math : : nextPowerOfTwo ( scratchSpaceSize ) ;
dst . kernelAttributes . perThreadScratchSize [ src . slot ] = scratchSpaceSize ;
2020-08-30 08:50:00 +02:00
break ;
}
return DecodeError : : Success ;
}
2022-09-22 11:03:51 +00:00
template < Elf : : ELF_IDENTIFIER_CLASS numBits >
NEO : : DecodeError populateKernelDescriptor ( NEO : : ProgramInfo & dst , NEO : : Elf : : Elf < numBits > & elf , NEO : : ZebinSections < numBits > & zebinSections ,
2020-07-30 13:18:54 +02:00
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-07 18:23:47 +02:00
kernelDescriptor . kernelMetadata . kernelName = yamlParser . readValueNoQuotes ( * zeInfokernelSections . nameNd [ 0 ] ) . str ( ) ;
2020-07-30 13:18:54 +02: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 ;
}
2022-09-07 13:21:53 +00:00
NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : Attributes : : AttributesBaseT attributes ;
if ( false = = zeInfokernelSections . attributesNd . empty ( ) ) {
auto attributeErr = readZeInfoAttributes ( yamlParser , * zeInfokernelSections . attributesNd [ 0 ] , attributes , kernelInfo - > kernelDescriptor . kernelMetadata . kernelName , outErrReason , outWarning ) ;
if ( DecodeError : : Success ! = attributeErr ) {
return attributeErr ;
}
populateKernelSourceAttributes ( kernelDescriptor , attributes ) ;
}
2021-08-30 13:59:08 +00:00
NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : DebugEnv : : DebugEnvBaseT debugEnv ;
if ( false = = zeInfokernelSections . debugEnvNd . empty ( ) ) {
auto debugEnvErr = readZeInfoDebugEnvironment ( yamlParser , * zeInfokernelSections . debugEnvNd [ 0 ] , debugEnv , kernelInfo - > kernelDescriptor . kernelMetadata . kernelName , outErrReason , outWarning ) ;
if ( DecodeError : : Success ! = debugEnvErr ) {
return debugEnvErr ;
}
if ( debugEnv . debugSurfaceBTI = = 0 ) {
kernelDescriptor . payloadMappings . implicitArgs . systemThreadSurfaceAddress . bindful = 0U ;
}
}
2020-07-30 13:18:54 +02:00
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 ;
}
}
2021-11-25 11:53:03 +00:00
int32_t maxArgumentIndex = - 1 ;
2021-05-11 14:50:29 +02:00
int32_t maxSamplerIndex = - 1 ;
2020-07-30 13:18:54 +02:00
ZeInfoPayloadArguments payloadArguments ;
if ( false = = zeInfokernelSections . payloadArgumentsNd . empty ( ) ) {
2021-05-11 14:50:29 +02:00
auto payloadArgsErr = readZeInfoPayloadArguments ( yamlParser , * zeInfokernelSections . payloadArgumentsNd [ 0 ] , payloadArguments , maxArgumentIndex , maxSamplerIndex ,
2020-07-30 13:18:54 +02:00
kernelDescriptor . kernelMetadata . kernelName , outErrReason , outWarning ) ;
if ( DecodeError : : Success ! = payloadArgsErr ) {
return payloadArgsErr ;
}
}
2020-08-30 08:50:00 +02: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-13 17: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 ;
}
2022-02-14 16:05:39 +00:00
kernelDescriptor . kernelAttributes . binaryFormat = DeviceBinaryFormat : : Zebin ;
2021-01-13 17:19:44 -08:00
2021-11-10 11:56:49 +00:00
kernelDescriptor . entryPoints . skipPerThreadDataLoad = execEnv . offsetToSkipPerThreadDataLoad ;
kernelDescriptor . entryPoints . skipSetFFIDGP = execEnv . offsetToSkipSetFfidGp ;
2021-11-22 11:06:16 +00:00
kernelDescriptor . kernelAttributes . flags . passInlineData = ( execEnv . inlineDataPayloadSize ! = 0 ) ;
2020-07-30 13:18:54 +02:00
kernelDescriptor . kernelAttributes . flags . requiresDisabledMidThreadPreemption = execEnv . disableMidThreadPreemption ;
2021-11-10 11:56:49 +00:00
kernelDescriptor . kernelAttributes . flags . requiresSubgroupIndependentForwardProgress = execEnv . subgroupIndependentForwardProgress ;
2022-02-10 23:33:40 +00:00
kernelDescriptor . kernelAttributes . flags . requiresDisabledEUFusion = execEnv . requireDisableEUFusion ;
2021-11-10 11:56:49 +00:00
kernelDescriptor . kernelAttributes . flags . useGlobalAtomics = execEnv . hasGlobalAtomics ;
2021-11-09 12:45:57 +00:00
kernelDescriptor . kernelAttributes . flags . useStackCalls = execEnv . hasStackCalls ;
2020-07-30 13:18:54 +02:00
kernelDescriptor . kernelAttributes . flags . usesFencesForReadWriteImages = execEnv . hasFenceForImageAccess ;
2022-08-31 13:26:29 +00:00
kernelDescriptor . kernelAttributes . flags . usesSystolicPipelineSelectMode = execEnv . hasDpas ;
2021-11-10 11:56:49 +00:00
kernelDescriptor . kernelAttributes . flags . usesStatelessWrites = ( false = = execEnv . hasNoStatelessWrite ) ;
kernelDescriptor . kernelAttributes . barrierCount = execEnv . barrierCount ;
kernelDescriptor . kernelAttributes . bufferAddressingMode = ( execEnv . has4GBBuffers ) ? KernelDescriptor : : Stateless : KernelDescriptor : : BindfulAndStateless ;
2021-11-22 11:06:16 +00:00
kernelDescriptor . kernelAttributes . inlineDataPayloadSize = static_cast < uint16_t > ( execEnv . inlineDataPayloadSize ) ;
2021-11-10 11:56:49 +00:00
kernelDescriptor . kernelAttributes . numGrfRequired = execEnv . grfCount ;
2021-07-26 12:09:15 +00:00
kernelDescriptor . kernelAttributes . requiredWorkgroupSize [ 0 ] = static_cast < uint16_t > ( execEnv . requiredWorkGroupSize [ 0 ] ) ;
kernelDescriptor . kernelAttributes . requiredWorkgroupSize [ 1 ] = static_cast < uint16_t > ( execEnv . requiredWorkGroupSize [ 1 ] ) ;
kernelDescriptor . kernelAttributes . requiredWorkgroupSize [ 2 ] = static_cast < uint16_t > ( execEnv . requiredWorkGroupSize [ 2 ] ) ;
2021-11-10 11:56:49 +00:00
kernelDescriptor . kernelAttributes . simdSize = execEnv . simdSize ;
kernelDescriptor . kernelAttributes . slmInlineSize = execEnv . slmSize ;
2021-07-26 12:09:15 +00:00
kernelDescriptor . kernelAttributes . workgroupWalkOrder [ 0 ] = static_cast < uint8_t > ( execEnv . workgroupWalkOrderDimensions [ 0 ] ) ;
kernelDescriptor . kernelAttributes . workgroupWalkOrder [ 1 ] = static_cast < uint8_t > ( execEnv . workgroupWalkOrderDimensions [ 1 ] ) ;
kernelDescriptor . kernelAttributes . workgroupWalkOrder [ 2 ] = static_cast < uint8_t > ( execEnv . workgroupWalkOrderDimensions [ 2 ] ) ;
2021-11-10 11:56:49 +00:00
kernelDescriptor . kernelMetadata . requiredSubGroupSize = execEnv . requiredSubGroupSize ;
2020-07-30 13:18:54 +02:00
2022-08-12 14:58:41 +00:00
using ThreadSchedulingMode = NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : ExecutionEnv : : ThreadSchedulingMode ;
switch ( execEnv . threadSchedulingMode ) {
default :
kernelDescriptor . kernelAttributes . threadArbitrationPolicy = ThreadArbitrationPolicy : : NotPresent ;
break ;
case ThreadSchedulingMode : : ThreadSchedulingModeAgeBased :
kernelDescriptor . kernelAttributes . threadArbitrationPolicy = ThreadArbitrationPolicy : : AgeBased ;
break ;
case ThreadSchedulingMode : : ThreadSchedulingModeRoundRobin :
kernelDescriptor . kernelAttributes . threadArbitrationPolicy = ThreadArbitrationPolicy : : RoundRobin ;
break ;
case ThreadSchedulingMode : : ThreadSchedulingModeRoundRobinStall :
kernelDescriptor . kernelAttributes . threadArbitrationPolicy = ThreadArbitrationPolicy : : RoundRobinAfterDependency ;
break ;
}
2020-07-30 13:18:54 +02:00
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 15:29:58 +00:00
auto decodeErr = populateArgDescriptor ( arg , kernelDescriptor , dst . grfSize , outErrReason , outWarning ) ;
2020-07-30 13:18:54 +02:00
if ( DecodeError : : Success ! = decodeErr ) {
return decodeErr ;
}
}
2021-03-19 14:58:46 +00:00
if ( ! payloadArguments . empty ( ) ) {
kernelDescriptor . payloadMappings . explicitArgs . resize ( maxArgumentIndex + 1 ) ;
kernelDescriptor . explicitArgsExtendedMetadata . resize ( maxArgumentIndex + 1 ) ;
kernelDescriptor . kernelAttributes . numArgsToPatch = maxArgumentIndex + 1 ;
}
2020-07-30 13:18:54 +02: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 08:50:00 +02:00
for ( const auto & memBuff : perThreadMemoryBuffers ) {
2022-09-08 11:12:08 +00:00
auto decodeErr = populateKernelDescriptor ( memBuff , kernelDescriptor , dst . minScratchSpaceSize , outErrReason , outWarning ) ;
2020-08-30 08:50:00 +02:00
if ( DecodeError : : Success ! = decodeErr ) {
return decodeErr ;
}
}
2020-07-30 13:18:54 +02: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 ;
2021-08-30 13:59:08 +00:00
if ( false = = bindingTableIndices . empty ( ) | |
NEO : : isValidOffset ( kernelDescriptor . payloadMappings . implicitArgs . systemThreadSurfaceAddress . bindful ) ) {
2020-07-30 13:18:54 +02:00
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 11:30:05 +01:00
2020-07-30 13:18:54 +02:00
auto bindingTableIt = reinterpret_cast < int * > ( kernelDescriptor . generatedHeaps . data ( ) + generatedBindingTablePos ) ;
2021-01-07 11:30:05 +01:00
for ( int i = 0 ; i < numEntries ; + + i ) {
* bindingTableIt = i * maxSurfaceStateSize ;
2020-07-30 13:18:54 +02:00
+ + bindingTableIt ;
2021-01-07 11:30:05 +01:00
}
for ( auto & bti : bindingTableIndices ) {
2020-07-30 13:18:54 +02: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-29 18:00:06 +01:00
case ArgDescriptor : : ArgTImage : {
explicitArg . as < ArgDescImage > ( ) . bindful = bti . btiValue * maxSurfaceStateSize ;
break ;
}
2020-07-30 13:18:54 +02: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 14:50:29 +02:00
auto generatedDshPos = kernelDescriptor . generatedHeaps . size ( ) ;
uint32_t generatedDshSize = 0U ;
if ( maxSamplerIndex > = 0 ) {
2022-01-12 14:47:27 +00:00
constexpr auto maxSamplerStateSize = 16U ;
constexpr auto maxIndirectSamplerStateSize = 64U ;
2021-05-11 14:50:29 +02:00
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 ) ;
}
2022-09-22 11:03:51 +00:00
typename ZebinSections < numBits > : : SectionHeaderData * correspondingTextSegment = nullptr ;
2020-07-30 13:18:54 +02:00
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-04 19:18:49 +02:00
outErrReason . append ( " DeviceBinaryFormat::Zebin : Could not find text section for kernel " + kernelDescriptor . kernelMetadata . kernelName + " \n " ) ;
2020-07-30 13:18:54 +02: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 14:50:29 +02:00
kernelInfo - > heapInfo . pDsh = kernelDescriptor . generatedHeaps . data ( ) + generatedDshPos ;
kernelInfo - > heapInfo . DynamicStateHeapSize = generatedDshSize ;
2020-07-30 13:18:54 +02:00
dst . kernelInfos . push_back ( kernelInfo . release ( ) ) ;
return DecodeError : : Success ;
}
2022-07-26 14:37:45 +00:00
NEO : : DecodeError readZeInfoVersionFromZeInfo ( NEO : : Elf : : ZebinKernelMetadata : : Types : : Version & dst ,
NEO : : Yaml : : YamlParser & yamlParser , const NEO : : Yaml : : Node & versionNd , std : : string & outErrReason , std : : string & outWarning ) {
2020-10-04 19:18:49 +02:00
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 ) ;
2022-07-26 14:37:45 +00:00
return populateZeInfoVersion ( dst , versionStr , outErrReason ) ;
}
NEO : : DecodeError populateZeInfoVersion ( NEO : : Elf : : ZebinKernelMetadata : : Types : : Version & dst , ConstStringRef & versionStr , std : : string & outErrReason ) {
2020-10-04 19:18:49 +02:00
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 ) ) {
2022-07-26 14:37:45 +00:00
outErrReason . append ( " DeviceBinaryFormat::Zebin:: " + NEO : : Elf : : SectionsNamesZebin : : zeInfo . str ( ) + " : Invalid version format - expected 'MAJOR.MINOR' string, got : " + std : : string { versionStr } + " \n " ) ;
2020-10-04 19:18:49 +02:00
return NEO : : DecodeError : : InvalidBinary ;
}
* separator = 0 ;
dst . major = atoi ( nullTerminated . begin ( ) ) ;
dst . minor = atoi ( separator + 1 ) ;
return NEO : : DecodeError : : Success ;
}
2022-02-28 17:44:06 +00:00
NEO : : DecodeError populateExternalFunctionsMetadata ( NEO : : ProgramInfo & dst , NEO : : Yaml : : YamlParser & yamlParser , const NEO : : Yaml : : Node & functionNd , std : : string & outErrReason , std : : string & outWarning ) {
ConstStringRef functionName ;
NEO : : Elf : : ZebinKernelMetadata : : Types : : Function : : ExecutionEnv : : ExecutionEnvBaseT execEnv = { } ;
bool isValid = true ;
for ( const auto & functionMetadataNd : yamlParser . createChildrenRange ( functionNd ) ) {
auto key = yamlParser . readKey ( functionMetadataNd ) ;
if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Function : : name = = key ) {
functionName = yamlParser . readValueNoQuotes ( functionMetadataNd ) ;
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : Function : : executionEnv = = key ) {
auto execEnvErr = readZeInfoExecutionEnvironment ( yamlParser , functionMetadataNd , execEnv , " external functions " , outErrReason , outWarning ) ;
if ( execEnvErr ! = DecodeError : : Success ) {
isValid = false ;
}
} else {
outWarning . append ( " DeviceBinaryFormat::Zebin:: " + NEO : : Elf : : SectionsNamesZebin : : zeInfo . str ( ) + " : Unknown entry \" " + yamlParser . readKey ( functionMetadataNd ) . str ( ) + " \" in context of : external functions \n " ) ;
}
}
if ( isValid ) {
NEO : : ExternalFunctionInfo extFunInfo ;
extFunInfo . functionName = functionName . str ( ) ;
extFunInfo . barrierCount = static_cast < uint8_t > ( execEnv . barrierCount ) ;
extFunInfo . numGrfRequired = static_cast < uint16_t > ( execEnv . grfCount ) ;
extFunInfo . simdSize = static_cast < uint8_t > ( execEnv . simdSize ) ;
dst . externalFunctions . push_back ( extFunInfo ) ;
return DecodeError : : Success ;
} else {
return DecodeError : : InvalidBinary ;
}
}
2022-09-07 13:21:53 +00:00
std : : string attributeToString ( const int32_t & attribute ) {
return std : : to_string ( attribute ) ;
}
std : : string attributeToString ( const std : : array < int32_t , 3 > & attribute ) {
return std : : to_string ( attribute [ 0 ] ) + " , " + std : : to_string ( attribute [ 1 ] ) + " , " + std : : to_string ( attribute [ 2 ] ) ;
}
std : : string attributeToString ( ConstStringRef attribute ) {
return attribute . str ( ) ;
}
void appendAttribute ( std : : string & dst , const std : : string & attributeName , const std : : string & attributeValue ) {
if ( dst . empty ( ) = = false ) {
dst . append ( " " ) ;
}
dst . append ( attributeName + " ( " + attributeValue + " ) " ) ;
}
template < typename T >
void appendAttributeIfSet ( std : : string & dst , ConstStringRef attributeName , std : : optional < T > & attributeValue ) {
if ( attributeValue ) {
appendAttribute ( dst , attributeName . str ( ) , attributeToString ( * attributeValue ) ) ;
}
}
NEO : : DecodeError populateKernelSourceAttributes ( NEO : : KernelDescriptor & dst , NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : Attributes : : AttributesBaseT & attributes ) {
namespace AttributeTags = NEO : : Elf : : ZebinKernelMetadata : : Tags : : Kernel : : Attributes ;
namespace AttributeTypes = NEO : : Elf : : ZebinKernelMetadata : : Types : : Kernel : : Attributes ;
auto & languageAttributes = dst . kernelMetadata . kernelLanguageAttributes ;
for ( auto & hint : attributes . otherHints ) {
appendAttribute ( languageAttributes , hint . first . str ( ) , hint . second . str ( ) ) ;
}
appendAttributeIfSet ( languageAttributes , AttributeTags : : intelReqdSubgroupSize , attributes . intelReqdSubgroupSize ) ;
appendAttributeIfSet ( languageAttributes , AttributeTags : : intelReqdWorkgroupWalkOrder , attributes . intelReqdWorkgroupWalkOrder ) ;
appendAttributeIfSet ( languageAttributes , AttributeTags : : reqdWorkgroupSize , attributes . reqdWorkgroupSize ) ;
appendAttributeIfSet ( languageAttributes , AttributeTags : : workgroupSizeHint , attributes . workgroupSizeHint ) ;
appendAttributeIfSet ( languageAttributes , AttributeTags : : vecTypeHint , attributes . vecTypeHint ) ;
appendAttributeIfSet ( languageAttributes , AttributeTags : : invalidKernel , attributes . invalidKernel ) ;
dst . kernelAttributes . flags . isInvalid = attributes . invalidKernel . has_value ( ) ;
return DecodeError : : Success ;
}
2022-09-22 11:03:51 +00:00
template NEO : : DecodeError decodeZebin < Elf : : EI_CLASS_32 > ( ProgramInfo & dst , NEO : : Elf : : Elf < Elf : : EI_CLASS_32 > & elf , std : : string & outErrReason , std : : string & outWarning ) ;
template NEO : : DecodeError decodeZebin < Elf : : EI_CLASS_64 > ( ProgramInfo & dst , NEO : : Elf : : Elf < Elf : : EI_CLASS_64 > & elf , std : : string & outErrReason , std : : string & outWarning ) ;
template < Elf : : ELF_IDENTIFIER_CLASS numBits >
NEO : : DecodeError decodeZebin ( ProgramInfo & dst , NEO : : Elf : : Elf < numBits > & elf , std : : string & outErrReason , std : : string & outWarning ) {
ZebinSections < numBits > zebinSections ;
2020-07-30 13:18:54 +02:00
auto extractError = extractZebinSections ( elf , zebinSections , outErrReason , outWarning ) ;
if ( DecodeError : : Success ! = extractError ) {
return extractError ;
}
extractError = validateZebinSectionsCount ( zebinSections , outErrReason , outWarning ) ;
if ( DecodeError : : Success ! = extractError ) {
return extractError ;
}
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 ( ) ;
}
2021-11-02 15:29:09 +00:00
if ( false = = zebinSections . constDataStringSections . empty ( ) ) {
dst . globalStrings . initData = zebinSections . constDataStringSections [ 0 ] - > data . begin ( ) ;
dst . globalStrings . size = zebinSections . constDataStringSections [ 0 ] - > data . size ( ) ;
}
2020-07-30 13:18:54 +02:00
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-04 19:18:49 +02:00
UniqueNode versionSectionNodes ;
2022-02-23 11:48:31 +00:00
UniqueNode globalHostAccessTableNodes ;
2022-02-28 17:44:06 +00:00
UniqueNode functionsSectionNodes ;
2020-07-30 13:18:54 +02: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 ) ;
2020-10-04 19:18:49 +02:00
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : version = = key ) {
versionSectionNodes . push_back ( & globalScopeNd ) ;
2022-02-23 11:48:31 +00:00
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : globalHostAccessTable = = key ) {
globalHostAccessTableNodes . push_back ( & globalScopeNd ) ;
2022-02-28 17:44:06 +00:00
} else if ( NEO : : Elf : : ZebinKernelMetadata : : Tags : : functions = = key ) {
functionsSectionNodes . push_back ( & globalScopeNd ) ;
2022-02-23 11:48:31 +00:00
} else {
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-07-30 13:18:54 +02:00
}
}
2020-10-04 19:18:49 +02: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 " ) ;
2022-07-26 14:37:45 +00:00
zeInfoVersion = zeInfoDecoderVersion ;
2020-10-04 19:18:49 +02:00
} else {
2022-07-26 14:37:45 +00:00
auto zeInfoErr = readZeInfoVersionFromZeInfo ( zeInfoVersion , yamlParser , * versionSectionNodes [ 0 ] , outErrReason , outWarning ) ;
2020-10-04 19:18:49 +02:00
if ( DecodeError : : Success ! = zeInfoErr ) {
return zeInfoErr ;
}
}
2022-07-26 14:37:45 +00:00
auto zeInfoVersionError = validateZeInfoVersion ( zeInfoVersion , outErrReason , outWarning ) ;
if ( DecodeError : : Success ! = zeInfoVersionError ) {
return zeInfoVersionError ;
2020-10-04 19:18:49 +02:00
}
2020-07-30 13:18:54 +02: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 ;
}
}
2022-02-23 11:48:31 +00:00
if ( false = = globalHostAccessTableNodes . empty ( ) ) {
ZeInfoGlobalHostAccessTables globalHostAccessMapping ;
auto zeInfoErr = readZeInfoGlobalHostAceessTable ( yamlParser , * globalHostAccessTableNodes [ 0 ] , globalHostAccessMapping , " globalHostAccessTable " , outErrReason , outWarning ) ;
if ( DecodeError : : Success ! = zeInfoErr ) {
return zeInfoErr ;
}
2022-03-22 14:54:28 +00:00
dst . globalsDeviceToHostNameMap . reserve ( globalHostAccessMapping . size ( ) ) ;
2022-02-23 11:48:31 +00:00
for ( auto it = globalHostAccessMapping . begin ( ) ; it ! = globalHostAccessMapping . end ( ) ; it + + ) {
dst . globalsDeviceToHostNameMap [ it - > deviceName ] = it - > hostName ;
}
}
2022-02-28 17:44:06 +00:00
if ( functionsSectionNodes . size ( ) > 1U ) {
outErrReason . append ( " DeviceBinaryFormat::Zebin:: " + NEO : : Elf : : SectionsNamesZebin : : zeInfo . str ( ) + " : Expected at most one " + NEO : : Elf : : ZebinKernelMetadata : : Tags : : functions . str ( ) + " entry in global scope of " + NEO : : Elf : : SectionsNamesZebin : : zeInfo . str ( ) + " , got : " + std : : to_string ( functionsSectionNodes . size ( ) ) + " \n " ) ;
return DecodeError : : InvalidBinary ;
}
if ( false = = functionsSectionNodes . empty ( ) ) {
for ( const auto & functionNd : yamlParser . createChildrenRange ( * functionsSectionNodes [ 0 ] ) ) {
auto zeInfoErr = populateExternalFunctionsMetadata ( dst , yamlParser , functionNd , outErrReason , outWarning ) ;
if ( DecodeError : : Success ! = zeInfoErr ) {
return zeInfoErr ;
}
}
}
2020-07-30 13:18:54 +02:00
return DecodeError : : Success ;
}
} // namespace NEO