2020-02-10 06:59:57 +08:00
/*
2021-01-12 01:45:43 +08:00
* Copyright ( C ) 2020 - 2021 Intel Corporation
2020-02-10 06:59:57 +08:00
*
* SPDX - License - Identifier : MIT
*
*/
2020-02-27 23:17:08 +08:00
# include "shared/offline_compiler/source/ocloc_fatbinary.h"
2020-02-10 06:59:57 +08:00
2020-03-10 21:02:09 +08:00
# include "shared/offline_compiler/source/ocloc_arg_helper.h"
2020-02-27 23:17:08 +08:00
# include "shared/offline_compiler/source/offline_compiler.h"
# include "shared/offline_compiler/source/utilities/safety_caller.h"
2020-02-24 05:44:01 +08:00
# include "shared/source/device_binary_format/ar/ar_encoder.h"
# include "shared/source/helpers/file_io.h"
# include "shared/source/helpers/hw_info.h"
2020-02-24 17:22:30 +08:00
2020-02-10 06:59:57 +08:00
# include "compiler_options.h"
# include "igfxfmid.h"
# include <cstddef>
# include <cstdint>
# include <cstdio>
namespace NEO {
2021-04-16 21:25:00 +08:00
bool requestedFatBinary ( const std : : vector < std : : string > & args , OclocArgHelper * helper ) {
2020-05-18 17:47:20 +08:00
for ( size_t argIndex = 1 ; argIndex < args . size ( ) ; argIndex + + ) {
const auto & currArg = args [ argIndex ] ;
const bool hasMoreArgs = ( argIndex + 1 < args . size ( ) ) ;
2020-02-10 06:59:57 +08:00
if ( ( ConstStringRef ( " -device " ) = = currArg ) & & hasMoreArgs ) {
2020-05-18 17:47:20 +08:00
ConstStringRef deviceArg ( args [ argIndex + 1 ] ) ;
2021-04-16 21:25:00 +08:00
return deviceArg . contains ( " * " ) | | deviceArg . contains ( " - " ) | | deviceArg . contains ( " , " ) | | helper - > isGen ( deviceArg . str ( ) ) ;
2020-02-10 06:59:57 +08:00
}
}
return false ;
}
std : : vector < PRODUCT_FAMILY > getAllSupportedTargetPlatforms ( ) {
2020-02-11 15:33:07 +08:00
return std : : vector < PRODUCT_FAMILY > { ALL_SUPPORTED_PRODUCT_FAMILIES } ;
2020-02-10 06:59:57 +08:00
}
std : : vector < ConstStringRef > toProductNames ( const std : : vector < PRODUCT_FAMILY > & productIds ) {
std : : vector < ConstStringRef > ret ;
for ( auto prodId : productIds ) {
ret . push_back ( ConstStringRef ( hardwarePrefix [ prodId ] , strlen ( hardwarePrefix [ prodId ] ) ) ) ;
}
return ret ;
}
PRODUCT_FAMILY asProductId ( ConstStringRef product , const std : : vector < PRODUCT_FAMILY > & allSupportedPlatforms ) {
for ( auto family : allSupportedPlatforms ) {
if ( product = = hardwarePrefix [ family ] ) {
return family ;
}
}
return IGFX_UNKNOWN ;
}
void appendPlatformsForGfxCore ( GFXCORE_FAMILY core , const std : : vector < PRODUCT_FAMILY > & allSupportedPlatforms , std : : vector < PRODUCT_FAMILY > & out ) {
for ( auto family : allSupportedPlatforms ) {
if ( core = = hardwareInfoTable [ family ] - > platform . eRenderCoreFamily ) {
out . push_back ( family ) ;
}
}
}
2020-03-05 18:49:46 +08:00
std : : vector < ConstStringRef > getTargetPlatformsForFatbinary ( ConstStringRef deviceArg , OclocArgHelper * argHelper ) {
2020-02-10 06:59:57 +08:00
std : : vector < PRODUCT_FAMILY > allSupportedPlatforms = getAllSupportedTargetPlatforms ( ) ;
if ( deviceArg = = " * " ) {
return toProductNames ( allSupportedPlatforms ) ;
}
auto genArg = ConstStringRef ( " gen " ) ;
std : : vector < PRODUCT_FAMILY > requestedPlatforms ;
auto sets = CompilerOptions : : tokenize ( deviceArg , ' , ' ) ;
for ( auto set : sets ) {
if ( set . contains ( " - " ) ) {
auto range = CompilerOptions : : tokenize ( deviceArg , ' - ' ) ;
if ( range . size ( ) > 2 ) {
2020-03-05 18:49:46 +08:00
argHelper - > printf ( " Invalid range : %s - should be from-to or -to or from- \n " , set . str ( ) . c_str ( ) ) ;
2020-02-10 06:59:57 +08:00
return { } ;
}
if ( range . size ( ) = = 1 ) {
// open range , from-max or min-to
2021-04-16 21:25:00 +08:00
if ( argHelper - > isGen ( range [ 0 ] . str ( ) ) ) {
std : : vector < GFXCORE_FAMILY > coreIdList ;
auto coreId = argHelper - > returnIGFXforGen ( range [ 0 ] . str ( ) ) ;
if ( coreId = = 0 ) {
2020-03-05 18:49:46 +08:00
argHelper - > printf ( " Unknown device : %s \n " , set . str ( ) . c_str ( ) ) ;
2020-02-10 06:59:57 +08:00
return { } ;
}
2021-04-16 21:25:00 +08:00
coreIdList . push_back ( static_cast < GFXCORE_FAMILY > ( coreId ) ) ;
2020-02-10 06:59:57 +08:00
if ( ' - ' = = set [ 0 ] ) {
// to
2020-06-25 16:56:53 +08:00
auto coreId = coreIdList . back ( ) ;
2020-02-10 06:59:57 +08:00
unsigned int coreIt = IGFX_UNKNOWN_CORE ;
+ + coreIt ;
while ( coreIt < = static_cast < unsigned int > ( coreId ) ) {
appendPlatformsForGfxCore ( static_cast < GFXCORE_FAMILY > ( coreIt ) , allSupportedPlatforms , requestedPlatforms ) ;
+ + coreIt ;
}
} else {
// from
2020-06-25 16:56:53 +08:00
unsigned int coreIt = coreIdList . front ( ) ;
2020-02-10 06:59:57 +08:00
while ( coreIt < static_cast < unsigned int > ( IGFX_MAX_CORE ) ) {
appendPlatformsForGfxCore ( static_cast < GFXCORE_FAMILY > ( coreIt ) , allSupportedPlatforms , requestedPlatforms ) ;
+ + coreIt ;
}
}
} else {
auto prodId = asProductId ( range [ 0 ] , allSupportedPlatforms ) ;
if ( IGFX_UNKNOWN = = prodId ) {
2020-03-05 18:49:46 +08:00
argHelper - > printf ( " Unknown device : %s \n " , range [ 0 ] . str ( ) . c_str ( ) ) ;
2020-02-10 06:59:57 +08:00
return { } ;
}
auto prodIt = std : : find ( allSupportedPlatforms . begin ( ) , allSupportedPlatforms . end ( ) , prodId ) ;
assert ( prodIt ! = allSupportedPlatforms . end ( ) ) ;
if ( ' - ' = = set [ 0 ] ) {
// to
requestedPlatforms . insert ( requestedPlatforms . end ( ) , allSupportedPlatforms . begin ( ) , prodIt + 1 ) ;
} else {
// from
requestedPlatforms . insert ( requestedPlatforms . end ( ) , prodIt , allSupportedPlatforms . end ( ) ) ;
}
}
} else {
2021-04-16 21:25:00 +08:00
if ( argHelper - > isGen ( range [ 0 ] . str ( ) ) ) {
if ( false = = argHelper - > isGen ( range [ 1 ] . str ( ) ) ) {
2020-03-05 18:49:46 +08:00
argHelper - > printf ( " Ranges mixing platforms and gfxCores is not supported : %s - should be genFrom-genTo or platformFrom-platformTo \n " , set . str ( ) . c_str ( ) ) ;
2020-02-10 06:59:57 +08:00
return { } ;
}
2021-04-16 21:25:00 +08:00
auto coreFrom = argHelper - > returnIGFXforGen ( range [ 0 ] . str ( ) ) ;
auto coreTo = argHelper - > returnIGFXforGen ( range [ 1 ] . str ( ) ) ;
if ( coreFrom = = 0 ) {
2020-03-05 18:49:46 +08:00
argHelper - > printf ( " Unknown device : %s \n " , set . str ( ) . c_str ( ) ) ;
2020-02-10 06:59:57 +08:00
return { } ;
}
2021-04-16 21:25:00 +08:00
if ( coreTo = = 0 ) {
2020-03-05 18:49:46 +08:00
argHelper - > printf ( " Unknown device : %s \n " , set . str ( ) . c_str ( ) ) ;
2020-02-10 06:59:57 +08:00
return { } ;
}
2021-04-16 21:25:00 +08:00
if ( static_cast < GFXCORE_FAMILY > ( coreFrom ) > static_cast < GFXCORE_FAMILY > ( coreTo ) ) {
2020-02-10 06:59:57 +08:00
std : : swap ( coreFrom , coreTo ) ;
}
while ( coreFrom < = coreTo ) {
appendPlatformsForGfxCore ( static_cast < GFXCORE_FAMILY > ( coreFrom ) , allSupportedPlatforms , requestedPlatforms ) ;
coreFrom = static_cast < GFXCORE_FAMILY > ( static_cast < unsigned int > ( coreFrom ) + 1 ) ;
}
} else {
auto platformFrom = asProductId ( range [ 0 ] , allSupportedPlatforms ) ;
auto platformTo = asProductId ( range [ 1 ] , allSupportedPlatforms ) ;
if ( IGFX_UNKNOWN = = platformFrom ) {
2020-03-05 18:49:46 +08:00
argHelper - > printf ( " Unknown device : %s \n " , set . str ( ) . c_str ( ) ) ;
2020-02-10 06:59:57 +08:00
return { } ;
}
if ( IGFX_UNKNOWN = = platformTo ) {
2020-03-05 18:49:46 +08:00
argHelper - > printf ( " Unknown device : %s \n " , set . str ( ) . c_str ( ) ) ;
2020-02-10 06:59:57 +08:00
return { } ;
}
if ( platformFrom > platformTo ) {
std : : swap ( platformFrom , platformTo ) ;
}
auto from = std : : find ( allSupportedPlatforms . begin ( ) , allSupportedPlatforms . end ( ) , platformFrom ) ;
auto to = std : : find ( allSupportedPlatforms . begin ( ) , allSupportedPlatforms . end ( ) , platformTo ) + 1 ;
requestedPlatforms . insert ( requestedPlatforms . end ( ) , from , to ) ;
}
}
2021-04-16 21:25:00 +08:00
} else if ( argHelper - > isGen ( set . str ( ) ) ) {
2020-02-10 06:59:57 +08:00
if ( set . size ( ) = = genArg . size ( ) ) {
2020-03-05 18:49:46 +08:00
argHelper - > printf ( " Invalid gen-based device : %s - gen should be followed by a number \n " , set . str ( ) . c_str ( ) ) ;
2020-02-10 06:59:57 +08:00
} else {
2021-04-16 21:25:00 +08:00
auto coreId = argHelper - > returnIGFXforGen ( set . str ( ) ) ;
if ( coreId = = 0 ) {
2020-03-05 18:49:46 +08:00
argHelper - > printf ( " Unknown device : %s \n " , set . str ( ) . c_str ( ) ) ;
2020-02-10 06:59:57 +08:00
return { } ;
}
2021-04-16 21:25:00 +08:00
appendPlatformsForGfxCore ( static_cast < GFXCORE_FAMILY > ( coreId ) , allSupportedPlatforms , requestedPlatforms ) ;
2020-02-10 06:59:57 +08:00
}
} else {
auto prodId = asProductId ( set , allSupportedPlatforms ) ;
if ( IGFX_UNKNOWN = = prodId ) {
2020-03-05 18:49:46 +08:00
argHelper - > printf ( " Unknown device : %s \n " , set . str ( ) . c_str ( ) ) ;
2020-02-10 06:59:57 +08:00
return { } ;
}
requestedPlatforms . push_back ( prodId ) ;
}
}
return toProductNames ( requestedPlatforms ) ;
}
2020-05-18 17:47:20 +08:00
int buildFatBinary ( const std : : vector < std : : string > & args , OclocArgHelper * argHelper ) {
2020-02-10 06:59:57 +08:00
std : : string pointerSizeInBits = ( sizeof ( void * ) = = 4 ) ? " 32 " : " 64 " ;
2020-05-18 17:47:20 +08:00
size_t deviceArgIndex = - 1 ;
2020-02-10 06:59:57 +08:00
std : : string inputFileName = " " ;
std : : string outputFileName = " " ;
std : : string outputDirectory = " " ;
2020-05-18 17:47:20 +08:00
std : : vector < std : : string > argsCopy ( args ) ;
for ( size_t argIndex = 1 ; argIndex < args . size ( ) ; argIndex + + ) {
const auto & currArg = args [ argIndex ] ;
const bool hasMoreArgs = ( argIndex + 1 < args . size ( ) ) ;
2020-02-10 06:59:57 +08:00
if ( ( ConstStringRef ( " -device " ) = = currArg ) & & hasMoreArgs ) {
deviceArgIndex = argIndex + 1 ;
+ + argIndex ;
} else if ( ( CompilerOptions : : arch32bit = = currArg ) | | ( ConstStringRef ( " -32 " ) = = currArg ) ) {
pointerSizeInBits = " 32 " ;
} else if ( ( CompilerOptions : : arch64bit = = currArg ) | | ( ConstStringRef ( " -64 " ) = = currArg ) ) {
pointerSizeInBits = " 64 " ;
} else if ( ( ConstStringRef ( " -file " ) = = currArg ) & & hasMoreArgs ) {
2020-05-18 17:47:20 +08:00
inputFileName = args [ argIndex + 1 ] ;
2020-02-10 06:59:57 +08:00
+ + argIndex ;
} else if ( ( ConstStringRef ( " -output " ) = = currArg ) & & hasMoreArgs ) {
2020-05-18 17:47:20 +08:00
outputFileName = args [ argIndex + 1 ] ;
2020-02-10 06:59:57 +08:00
+ + argIndex ;
} else if ( ( ConstStringRef ( " -out_dir " ) = = currArg ) & & hasMoreArgs ) {
2020-05-18 17:47:20 +08:00
outputDirectory = args [ argIndex + 1 ] ;
2020-02-10 06:59:57 +08:00
+ + argIndex ;
}
}
std : : vector < ConstStringRef > targetPlatforms ;
2020-05-18 17:47:20 +08:00
targetPlatforms = getTargetPlatformsForFatbinary ( ConstStringRef ( args [ deviceArgIndex ] ) , argHelper ) ;
2020-02-10 06:59:57 +08:00
if ( targetPlatforms . empty ( ) ) {
2020-05-18 17:47:20 +08:00
argHelper - > printf ( " Failed to parse target devices from : %s \n " , args [ deviceArgIndex ] . c_str ( ) ) ;
2020-02-10 06:59:57 +08:00
return 1 ;
}
NEO : : Ar : : ArEncoder fatbinary ( true ) ;
for ( auto targetPlatform : targetPlatforms ) {
int retVal = 0 ;
argsCopy [ deviceArgIndex ] = targetPlatform . str ( ) ;
2020-03-05 18:49:46 +08:00
2020-05-18 17:47:20 +08:00
std : : unique_ptr < OfflineCompiler > pCompiler { OfflineCompiler : : create ( argsCopy . size ( ) , argsCopy , false , retVal , argHelper ) } ;
2021-01-13 16:30:01 +08:00
if ( OfflineCompiler : : ErrorCode : : SUCCESS ! = retVal ) {
2020-03-05 18:49:46 +08:00
argHelper - > printf ( " Error! Couldn't create OfflineCompiler. Exiting. \n " ) ;
2020-03-23 19:57:24 +08:00
return retVal ;
}
2020-03-05 18:49:46 +08:00
2020-02-10 06:59:57 +08:00
auto stepping = pCompiler - > getHardwareInfo ( ) . platform . usRevId ;
if ( retVal = = 0 ) {
retVal = buildWithSafetyGuard ( pCompiler . get ( ) ) ;
std : : string buildLog = pCompiler - > getBuildLog ( ) ;
if ( buildLog . empty ( ) = = false ) {
2020-03-05 18:49:46 +08:00
argHelper - > printf ( " %s \n " , buildLog . c_str ( ) ) ;
2020-02-10 06:59:57 +08:00
}
if ( retVal = = 0 ) {
if ( ! pCompiler - > isQuiet ( ) )
2020-03-05 18:49:46 +08:00
argHelper - > printf ( " Build succeeded for : %s. \n " , ( targetPlatform . str ( ) + " . " + std : : to_string ( stepping ) ) . c_str ( ) ) ;
2020-02-10 06:59:57 +08:00
} else {
2020-03-05 18:49:46 +08:00
argHelper - > printf ( " Build failed for : %s with error code: %d \n " , ( targetPlatform . str ( ) + " . " + std : : to_string ( stepping ) ) . c_str ( ) , retVal ) ;
argHelper - > printf ( " Command was: " ) ;
2020-05-18 17:47:20 +08:00
for ( const auto & arg : argsCopy )
argHelper - > printf ( " %s " , arg . c_str ( ) ) ;
2020-03-05 18:49:46 +08:00
argHelper - > printf ( " \n " ) ;
2020-02-10 06:59:57 +08:00
}
}
if ( 0 ! = retVal ) {
return retVal ;
}
fatbinary . appendFileEntry ( pointerSizeInBits + " . " + targetPlatform . str ( ) + " . " + std : : to_string ( stepping ) , pCompiler - > getPackedDeviceBinaryOutput ( ) ) ;
}
auto fatbinaryData = fatbinary . encode ( ) ;
std : : string fatbinaryFileName = outputFileName ;
if ( outputFileName . empty ( ) & & ( false = = inputFileName . empty ( ) ) ) {
fatbinaryFileName = OfflineCompiler : : getFileNameTrunk ( inputFileName ) + " .ar " ;
}
if ( false = = outputDirectory . empty ( ) ) {
fatbinaryFileName = outputDirectory + " / " + outputFileName ;
}
2020-03-05 18:49:46 +08:00
argHelper - > saveOutput ( fatbinaryFileName , fatbinaryData . data ( ) , fatbinaryData . size ( ) ) ;
2020-02-10 06:59:57 +08:00
return 0 ;
}
} // namespace NEO