diff --git a/rocclr/compiler/lib/amdoclcl.def.in b/rocclr/compiler/lib/amdoclcl.def.in index 10cd7442c2..981004bdb7 100644 --- a/rocclr/compiler/lib/amdoclcl.def.in +++ b/rocclr/compiler/lib/amdoclcl.def.in @@ -37,6 +37,7 @@ aclSetType aclConvertType aclDisassemble aclGetDeviceBinary +aclInsertKernelStatistics oclCompilerInit oclCompilerFini oclCompilerVersion diff --git a/rocclr/compiler/lib/amdoclcl.map.in b/rocclr/compiler/lib/amdoclcl.map.in index 9d54251784..1ca2459ab9 100644 --- a/rocclr/compiler/lib/amdoclcl.map.in +++ b/rocclr/compiler/lib/amdoclcl.map.in @@ -82,6 +82,7 @@ global: aclSetType; aclConvertType; aclDisassemble; + aclInsertKernelStatistics; aclGetDeviceBinary; aclLoader_OnLoad; aclLoader_OnUnload; diff --git a/rocclr/compiler/lib/include/v0_8/acl.h b/rocclr/compiler/lib/include/v0_8/acl.h index 340bfee11d..44e0817315 100644 --- a/rocclr/compiler/lib/include/v0_8/acl.h +++ b/rocclr/compiler/lib/include/v0_8/acl.h @@ -7,7 +7,6 @@ extern "C" { #endif #include "aclTypes.h" - //!--------------------------------------------------------------------------!// // Functions that deal with aclCompiler objects. //!--------------------------------------------------------------------------!// @@ -235,7 +234,18 @@ const void* ACL_API_ENTRY // Debug functionality //!--------------------------------------------------------------------------!// void aclDumpBinary(const aclBinary *bin); - +// Functions to retrieve kernel information +void aclGetKstatsR800(const void* shader, + aclKernelStats &kstats, const char* chip_id); +void aclGetKstatsSI(const void* shader, + aclKernelStats &kstats); +acl_error + aclInsertKernelStatistics(aclCompiler *cl, + aclBinary *bin); +//! Define hardware info constants for SI and above devices +const static unsigned SI_sgprs_avail = 102; +const static unsigned SI_vgprs_avail = 256; +const static unsigned SI_ldssize_avail = 32*1024; //!--------------------------------------------------------------------------!// // Functions that deal with memory. diff --git a/rocclr/compiler/lib/include/v0_8/aclEnums.h b/rocclr/compiler/lib/include/v0_8/aclEnums.h index 993a038f8b..0dc34d24af 100644 --- a/rocclr/compiler/lib/include/v0_8/aclEnums.h +++ b/rocclr/compiler/lib/include/v0_8/aclEnums.h @@ -182,7 +182,8 @@ typedef enum _bif_sections_enum_0_8 { aclBRIGoprs = 32, aclBRIGstrs = 33, aclHSADEBUG = 34, - aclLAST = 35 + aclKSTATS = 35, // For storing kernel statistics + aclLAST = 36 } aclSections_0_8; //! An enumeration that defines what are valid queries for aclQueryInfo. diff --git a/rocclr/compiler/lib/include/v0_8/aclStructs.h b/rocclr/compiler/lib/include/v0_8/aclStructs.h index 8603fb6731..eea1797f30 100644 --- a/rocclr/compiler/lib/include/v0_8/aclStructs.h +++ b/rocclr/compiler/lib/include/v0_8/aclStructs.h @@ -311,4 +311,24 @@ typedef struct _acl_compiler_rec_0_8_1 { aclLoaderData *apiData; // pointer to data store for the compiler API loader. } aclCompilerHandle_0_8_1; +//! Structure to hold kernel statistics obtained from kernel +typedef struct _acl_kernel_stats_0_8_1 { + unsigned int scratchRegs; + unsigned int scratchSize; + unsigned int availablevgprs; + unsigned int availablesgprs; + unsigned int usedvgprs; + unsigned int usedsgprs; + unsigned int availableldssize; + unsigned int usedldssize; + unsigned int availablestacksize; + unsigned int usedstacksize; + unsigned int wavefrontsize; + unsigned int wavefrontpersimd; + unsigned int threadsperworkgroup; + unsigned int reqdworkgroup_x; + unsigned int reqdworkgroup_y; + unsigned int reqdworkgroup_z; +} aclKernelStats; + #endif // _ACL_STRUCTS_0_8_H_ diff --git a/rocclr/compiler/lib/utils/bif_section_labels.hpp b/rocclr/compiler/lib/utils/bif_section_labels.hpp index f5fb1f7cef..b684661d8b 100644 --- a/rocclr/compiler/lib/utils/bif_section_labels.hpp +++ b/rocclr/compiler/lib/utils/bif_section_labels.hpp @@ -36,7 +36,8 @@ typedef enum { symDebugilBinary, symAsmText, symDLL, - symLast + symLast, + symKernelStats } oclBIFSymbolID; struct oclBIFSymbolStruct { @@ -48,7 +49,7 @@ struct oclBIFSymbolStruct { }; // These are the symbols that are defined by the BIF 3.0 spec -static const oclBIFSymbolStruct BIF30[26] = +static const oclBIFSymbolStruct BIF30[27] = { // 0: BIF 3.0 compiler options, .comment section via library support. {symOpenclCompilerOptions, @@ -106,6 +107,8 @@ static const oclBIFSymbolStruct BIF30[26] = {symDebugilBinary, { "__debugil_binary", "" }, {aclINTERNAL, aclLAST}}, {symAsmText, {"", ""}, {aclLAST, aclCODEGEN}}, {symDLL, {"", ""}, {aclLAST, aclTEXT}}, + // 26: BIF 3.0 HSAIL kernel statistics + {symKernelStats, { "__HSAIL_", "_kernel_statistics" }, {aclKSTATS, aclLAST}}, }; // BIF30 diff --git a/rocclr/compiler/lib/utils/v0_8/libUtils.cpp b/rocclr/compiler/lib/utils/v0_8/libUtils.cpp index 136ab1b329..1f709672d9 100644 --- a/rocclr/compiler/lib/utils/v0_8/libUtils.cpp +++ b/rocclr/compiler/lib/utils/v0_8/libUtils.cpp @@ -3,6 +3,7 @@ // #include "acl.h" #include "aclTypes.h" +#include "api/v0_8/aclValidation.h" #include "v0_7/clTypes.h" #include "v0_7/clCompiler.h" #include "libUtils.h" @@ -10,6 +11,7 @@ #include "utils/target_mappings.h" #include "utils/versions.hpp" #include "utils/options.hpp" +#include "backends/gpu/scwrapper/devState.h" #include #include #include "bif/bif.hpp" @@ -373,6 +375,43 @@ aclutCopyBinOpts(aclBinaryOptions *dst, const aclBinaryOptions *src, bool is64) } } +acl_error +aclutInsertKernelStatistics(aclCompiler *cl, aclBinary *bin) +{ + if (!aclValidateCompiler(cl, true)) { + return ACL_INVALID_COMPILER; + } + if (!aclValidateBinary(bin)) { + return ACL_INVALID_BINARY; + } + size_t len = 0; + acl_error err = ACL_SUCCESS; + const void *isa = aclExtractSection(cl, bin, &len, aclTEXT, &err); + if (err != ACL_SUCCESS) + return err; + aclTargetInfo *tgtInfo = aclutGetTargetInfo(bin); + const char* chipName = aclGetChip(*tgtInfo); + unsigned family = getFamilyEnum(tgtInfo); + unsigned chip = getChipEnum(tgtInfo); + // Non-GPU devices have family_enum set to 1 and do not qualify. Need to update. + if (family >= FAMILY_R600 && + family <= FAMILY_CZ) { + aclKernelStats kstats = {0}; + if (family < FAMILY_SI) { + aclGetKstatsR800(isa, kstats, chipName); + } + else { + aclGetKstatsSI(isa, kstats); + } + kstats.wavefrontsize = amdcl::GetWavefrontSize(family, chip); + const oclBIFSymbolStruct* symbol = findBIF30SymStruct(symKernelStats); + assert(symbol && "symbol not found"); + std::string symName = std::string(symbol->str[PRE]) + std::string(symbol->str[POST]); + err = aclInsertSymbol(cl, bin, reinterpret_cast(&kstats), sizeof(kstats), aclKSTATS, symName.c_str()); + } + return err; +} + void initElfDeviceCaps(aclBinary *elf) { if (aclutGetCaps(elf)->encryptCode) { diff --git a/rocclr/compiler/lib/utils/v0_8/libUtils.h b/rocclr/compiler/lib/utils/v0_8/libUtils.h index 83c59f2485..9ab0243e83 100644 --- a/rocclr/compiler/lib/utils/v0_8/libUtils.h +++ b/rocclr/compiler/lib/utils/v0_8/libUtils.h @@ -108,6 +108,10 @@ aclutCopyBinOpts(aclBinaryOptions *dst, const aclBinaryOptions *src, bool is64bit); +// Retrieve kernel statistics from binary +// and insert to elf as symbol +acl_error aclutInsertKernelStatistics(aclCompiler*, aclBinary*); + // Helper function that returns the // allocation function from the binary. AllocFunc diff --git a/rocclr/runtime/device/gpu/gpuscsi.cpp b/rocclr/runtime/device/gpu/gpuscsi.cpp index d7d2df3cf6..7cbc8f3bfc 100644 --- a/rocclr/runtime/device/gpu/gpuscsi.cpp +++ b/rocclr/runtime/device/gpu/gpuscsi.cpp @@ -56,10 +56,10 @@ NullKernel::siCreateHwInfo(const void* shader, AMUabiAddEncoding& encoding) newInfos[i].value = cShader->common.numSgprs; i++; newInfos[i].address = AMU_ABI_SI_NUM_SGPRS_AVAIL; - newInfos[i].value = 104-2; //512;//options.NumSGPRsAvailable; + newInfos[i].value = SI_sgprs_avail; //512;//options.NumSGPRsAvailable; i++; newInfos[i].address = AMU_ABI_SI_NUM_VGPRS_AVAIL; - newInfos[i].value = 256;//options.NumVGPRsAvailable; + newInfos[i].value = SI_vgprs_avail;//options.NumVGPRsAvailable; i++; newInfos[i].address = AMU_ABI_SI_FLOAT_MODE; @@ -110,7 +110,7 @@ NullKernel::siCreateHwInfo(const void* shader, AMUabiAddEncoding& encoding) i++; newInfos[i].address = AMU_ABI_LDS_SIZE_AVAIL; - newInfos[i].value = 32*1024; //options.LDSSize; + newInfos[i].value = SI_ldssize_avail; //options.LDSSize; i++; COMPUTE_PGM_RSRC2 computePgmRsrc2;