CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
272 lines
14 KiB
Python
272 lines
14 KiB
Python
################################################################################
|
|
#
|
|
# Copyright (C) 2022 Advanced Micro Devices, Inc. All rights reserved.
|
|
#
|
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
# of this software and associated documentation files (the "Software"), to deal
|
|
# in the Software without restriction, including without limitation the rights
|
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
# copies of the Software, and to permit persons to whom the Software is
|
|
# furnished to do so, subject to the following conditions:
|
|
#
|
|
# The above copyright notice and this permission notice shall be included in
|
|
# all copies or substantial portions of the Software.
|
|
#
|
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
# SOFTWARE.
|
|
#
|
|
################################################################################
|
|
from . import __version__
|
|
from . import LibraryIO
|
|
from .Common import tPrint,HR,defaultBenchmarkCommonParameters,defaultProblemType
|
|
from .DataType import DataType
|
|
|
|
import argparse
|
|
import os
|
|
import sys
|
|
|
|
def TensileLibLogicToYaml(userArgs):
|
|
tPrint(1, "")
|
|
tPrint(1, HR)
|
|
tPrint(1, "#")
|
|
tPrint(1, "# TensileLibLogicToYaml Library v{}".format(__version__))
|
|
|
|
# argument parsing and related setup
|
|
argParser = argparse.ArgumentParser()
|
|
|
|
argParser.add_argument("LibLogicFile", type=os.path.realpath,
|
|
help="Library logic file to be converted to tensile input yaml file")
|
|
argParser.add_argument("SolutionIndex", type=int,help="Solution index from library logic File"
|
|
,
|
|
default=None)
|
|
argParser.add_argument("OutputYaml", type=os.path.realpath,
|
|
help="OutputYaml path where output tensile yaml files are placed")
|
|
|
|
argParser.add_argument('--skipMI','-s', action="store_true", help="Skips the MatrixInstruction field in the tensile yaml file"
|
|
"i.e Thread Tile and Work Group parameters without MI",required=False)
|
|
|
|
args = argParser.parse_args(userArgs)
|
|
logicFilePath = args.LibLogicFile
|
|
solutionIndex = args.SolutionIndex
|
|
tensileYamlFile = args.OutputYaml
|
|
|
|
tPrint(1, "# Library Logic: {}".format(logicFilePath))
|
|
tPrint(1, "# Solution Index: {}".format(solutionIndex))
|
|
tPrint(1, "#")
|
|
tPrint(1, HR)
|
|
tPrint(1, "")
|
|
libYaml = LibraryIO.readYAML(logicFilePath)
|
|
if libYaml == "":
|
|
raise RuntimeError("Yaml file data is empty, read yaml file :{} failed".format(logicFilePath))
|
|
|
|
#reads library logic file. AllsolutionStates=>has solution data for all solution index
|
|
fields = LibraryIO.rawLibraryLogic(libYaml)
|
|
(versionString, scheduleName,architectureName,deviceNames,problemTypeState,allsolutionStates,indexOrder,exactLogic,rangeLogic, otherFields) = fields
|
|
|
|
#Extract the solution data for the user specified solution Index
|
|
currentIndexSolution = allsolutionStates[solutionIndex]
|
|
|
|
if currentIndexSolution == "":
|
|
raise RuntimeError("Could not find the matching data for the solution index:{} from the library logic file, Try different solution index".format(solutionIndex))
|
|
|
|
#Skip the MI calculation if 9 bit MI is not needed or MatrixInstruction field is disabled
|
|
isMatrixInsEnabled = False
|
|
if "EnableMatrixInstruction" in currentIndexSolution:
|
|
isMatrixInsEnabled = currentIndexSolution["EnableMatrixInstruction"]
|
|
|
|
if currentIndexSolution["EnableMatrixInstruction"] and currentIndexSolution["MatrixInstruction"]:
|
|
isMatrixInsEnabled = True
|
|
else:
|
|
tPrint(1, "Matrix instruction is disabled skipping the matrix instruction parameter ..")
|
|
|
|
tensileYamlFileData = []
|
|
if args.skipMI != True and isMatrixInsEnabled:
|
|
checkMacroTileThreadTileWorkGroupMatches(currentIndexSolution)
|
|
MIInstruction9Bits = form9BitMIInstruction(currentIndexSolution)
|
|
else:
|
|
MIInstruction9Bits = "None"
|
|
|
|
#Extract the problem type parameters
|
|
currentIndexProblemType = currentIndexSolution["ProblemType"]
|
|
|
|
#Iterate over problem type parameters and form problem type yaml data
|
|
problemTypeYamlData = formProblemTypeYamlData(currentIndexProblemType,versionString)
|
|
tensileYamlFileData.append(problemTypeYamlData)
|
|
|
|
#Iterate over Fork parameters and form the Yaml data
|
|
forkParameterYamlData = formForkParametersYamlData(currentIndexSolution, MIInstruction9Bits)
|
|
tensileYamlFileData.append(forkParameterYamlData)
|
|
|
|
#Forms the Library logic string
|
|
problemSizeYamlData = formProblemSizeYamlData(exactLogic,solutionIndex,scheduleName,deviceNames,architectureName)
|
|
tensileYamlFileData.append(problemSizeYamlData)
|
|
|
|
#Write the Formed Yaml data into the Yaml File
|
|
writeToTensileYamlFile(tensileYamlFile,tensileYamlFileData)
|
|
|
|
def formProblemTypeYamlData(currentIndexProblemType, versionString):
|
|
problemTypeYamlData = []
|
|
if len(currentIndexProblemType) == 0:
|
|
raise RuntimeError("Length of problem Type Parameters is empty!!, Please re-check the library logic file !")
|
|
|
|
# Form Global parameters section as well
|
|
problemTypeYamlData.append("GlobalParameters:\n")
|
|
problemTypeYamlData.append(" MinimumRequiredVersion: {}\n\n".format(versionString['MinimumRequiredVersion']))
|
|
problemTypeYamlData.append("BenchmarkProblems:\n -\n - # ProblemType\n")
|
|
|
|
for problemTypeKey, problemTypeValue in currentIndexProblemType.items():
|
|
# always print DataType, DestDataType, ComputeDataType, HighPrecisionAccumulate, OperationType fields
|
|
if problemTypeKey == "DataType" or problemTypeKey == "DestDataType" or problemTypeKey == "ComputeDataType":
|
|
problemTypeYamlData.append(" {}: {}\n".format(problemTypeKey, DataType(problemTypeValue).toChar().lower()))
|
|
continue
|
|
if (problemTypeKey == "HighPrecisionAccumulate" or problemTypeKey == "OperationType" or
|
|
problemTypeKey == "TransposeA" or problemTypeKey == "TransposeB" or problemTypeKey == "UseBeta" or problemTypeKey == "Batched"):
|
|
problemTypeYamlData.append(" {}: {}\n".format(problemTypeKey, problemTypeValue))
|
|
continue
|
|
if problemTypeKey in defaultProblemType:
|
|
if problemTypeValue != defaultProblemType[problemTypeKey]:
|
|
problemTypeYamlData.append(" {}: {}\n".format(problemTypeKey, problemTypeValue))
|
|
|
|
return ''.join(str(x) for x in problemTypeYamlData)
|
|
|
|
def formForkParametersYamlData(currentIndexSolution, MIInstruction9Bits):
|
|
forkParametersYamlData = []
|
|
forkParametersYamlData.append(" - # BenchmarkProblemSizeGroup\n")
|
|
forkParametersYamlData.append(" InitialSolutionParameters:\n")
|
|
forkParametersYamlData.append(" BenchmarkCommonParameters:\n")
|
|
forkParametersYamlData.append(" ForkParameters:\n")
|
|
|
|
for forkKey, forkValue in currentIndexSolution.items():
|
|
if MIInstruction9Bits == "None":
|
|
if forkKey == "ProblemType" or forkKey == "MatrixInstruction":
|
|
tPrint(1, "Continuing Matrix Instructions for Non MI\n")
|
|
continue
|
|
|
|
if forkKey == "MACInstruction":
|
|
if forkValue == "MAC": #This is a bug in the library logic file
|
|
forkValue ="MAD"
|
|
forkParametersYamlData.append(" - {}: {}\n".format(forkKey,[forkValue]))
|
|
continue
|
|
|
|
else:
|
|
if forkKey == "ProblemType" or forkKey == "ThreadTile" or forkKey == "WorkGroup" or forkKey == "MACInstruction":
|
|
continue
|
|
if forkKey == "MatrixInstruction":
|
|
forkParametersYamlData.append(MIInstruction9Bits)
|
|
continue
|
|
|
|
# Find the matching index for fork key name from list of dictionaries => defaultBenchmarkCommonParameters
|
|
index = next((i for i,d in enumerate(defaultBenchmarkCommonParameters) if forkKey in d), None)
|
|
if index != None:
|
|
forkValue = [forkValue] # convert to list
|
|
if forkValue != defaultBenchmarkCommonParameters[index][forkKey]:
|
|
forkParametersYamlData.append(" - {}: {}\n".format(forkKey, forkValue))
|
|
|
|
return ''.join(str(x) for x in forkParametersYamlData)
|
|
|
|
def form9BitMIInstruction(currentSolutionState):
|
|
MIBlock = currentSolutionState["MIBlock"]
|
|
MIWaveTile = currentSolutionState["MIWaveTile"]
|
|
MIWaveGroup = currentSolutionState["MIWaveGroup"]
|
|
|
|
if len(MIBlock) == 0 or len(MIWaveTile) == 0 or len(MIWaveGroup) == 0:
|
|
raise RuntimeError("Length of MIBlock:{0}, MIWave Tile:{1},MIWaveGroup:{2} cannot be empty".format(len(MIBlock),len(MIWaveTile),len(MIWaveGroup)))
|
|
|
|
MIBlock1 = [MIBlock[i] for i in (0,1,2,3,4)]
|
|
MIBlock5bits = ','.join([str(item) for item in MIBlock1])
|
|
MIWaveTile2Bits = ','.join([str(item) for item in MIWaveTile])
|
|
MIWaveGroup2Bits = ','.join([str(item) for item in MIWaveGroup])
|
|
|
|
if len(MIBlock5bits) == 0 or len(MIWaveTile2Bits) == 0 or len(MIWaveGroup2Bits) == 0:
|
|
raise RuntimeError("Length of MIBlock5bits:{0}, MIWaveGroup2Bits:{1},MIWaveGroup2Bits:{2} cannot be empty".format(len(MIBlock5bits),len(MIWaveTile2Bits),len(MIWaveGroup2Bits)))
|
|
|
|
MIInstruction9Bits = " - MatrixInstruction:\n - ["+ MIBlock5bits + "," + MIWaveTile2Bits + "," + MIWaveGroup2Bits + "]\n"
|
|
|
|
return MIInstruction9Bits
|
|
|
|
def formProblemSizeYamlData(exactLogic,solutionIndex,scheduleName,deviceNames,architectureName):
|
|
problemSizeYamlData =[]
|
|
|
|
problemSizeYamlData.append(" BenchmarkJoinParameters:\n")
|
|
problemSizeYamlData.append(" BenchmarkFinalParameters:\n")
|
|
problemSizeYamlData.append(" - ProblemSizes:\n")
|
|
#Form the problem Size
|
|
for (size, mapping) in exactLogic:
|
|
if mapping[0] == solutionIndex:
|
|
problemSizeYamlData.append(" - Exact: %s # Eff: %s Solution Index: %s\n" % (size,mapping[1],mapping[0]))
|
|
|
|
#Form final library logic string
|
|
problemSizeYamlData.append("#########################################################################################\n")
|
|
problemSizeYamlData.append("LibraryLogic:\n")
|
|
problemSizeYamlData.append(" ScheduleName: %s\n"%scheduleName)
|
|
problemSizeYamlData.append(" DeviceNames: %s\n"%deviceNames)
|
|
problemSizeYamlData.append(" ArchitectureName: \"%s\"\n"%architectureName)
|
|
|
|
return ''.join(str(x) for x in problemSizeYamlData)
|
|
|
|
def checkMacroTileThreadTileWorkGroupMatches(currentSolution):
|
|
MIBlock = currentSolution["MIBlock"]
|
|
MIWaveTile = currentSolution["MIWaveTile"]
|
|
MIWaveGroup = currentSolution["MIWaveGroup"]
|
|
|
|
if MIBlock == "" or MIWaveTile == "" or MIWaveGroup == "":
|
|
raise RuntimeError("Length of MIBlock:{0}, MIWaveTile:{1},MIWaveGroup:{2} cannot be empty,Check the library logic file !\n".format(len(MIBlock),len(MIWaveTile),len(MIWaveGroup)))
|
|
|
|
if not currentSolution.keys() & {'WavefrontSize'}:
|
|
waveFrontSize = 64
|
|
else:
|
|
waveFrontSize = int(currentSolution["WavefrontSize"])
|
|
|
|
TT0,TT1,MT0,MT1,WG0,WG1 = calculateThreadTileMacroTileWorkGroupParameters(MIBlock,MIWaveTile,MIWaveGroup,waveFrontSize)
|
|
|
|
if not currentSolution.keys() & {'MacroTile0','MacroTile1','ThreadTile','WorkGroup','MatrixInstM','MatrixInstN'}:
|
|
raise RuntimeError("one or more of these fields MacroTile0,MacroTile1,ThreadTile, WorkGroup,MatrixInstM,MatrixInstN is missing in the library logic file!! ..\n")
|
|
|
|
if MT0 != currentSolution["MacroTile0"]:
|
|
raise RuntimeError("Macro Tile0 {0} does not match LibLogic value {1}".format(MT0, currentSolution["MacroTile0"]))
|
|
|
|
if MT1 != currentSolution["MacroTile1"]:
|
|
raise RuntimeError("Macro Tile1 {0} does not match LibLogic value {1}".format(MT1, currentSolution["MacroTile1"]))
|
|
|
|
if TT0 != int(currentSolution["ThreadTile"][0]):
|
|
raise RuntimeError("ThreadTile0 {0} does not match LibLogic value {1}".format(TT0, currentSolution["ThreadTile"][0]))
|
|
|
|
if TT1 != int(currentSolution["ThreadTile"][1]):
|
|
raise RuntimeError("ThreadTile1 {0} does not match LibLogic value {1}".format(TT1, currentSolution["ThreadTile"][1]))
|
|
|
|
if WG0 != int(currentSolution["WorkGroup"][0]):
|
|
raise RuntimeError("WorkGroup0 {0} does not match LibLogic value {1}\n".format(WG0, currentSolution["WorkGroup"][0]))
|
|
|
|
if WG1 != int(currentSolution["WorkGroup"][1]):
|
|
raise RuntimeError("WorkGroup1 {0} does not match LibLogic value {1}".format(WG1, currentSolution["WorkGroup"][1]))
|
|
|
|
def calculateThreadTileMacroTileWorkGroupParameters(MIBlock,MIWaveTile,MIWaveGroup,waveFrontSize):
|
|
#Matrix M -->MIBlock[0]
|
|
#Matrix N -->MIBlock[1]
|
|
TT0 = int(MIWaveTile[0])
|
|
TT1 = int(MIWaveTile[1])*int(MIBlock[1])
|
|
MT0 = int(MIBlock[0])*int(MIBlock[4])*int(MIWaveTile[0])*int(MIWaveGroup[0])
|
|
MT1 = int(MIBlock[1])*int(MIWaveTile[1])*int(MIWaveGroup[1])
|
|
WG0 = int(MIBlock[0]) * int(MIBlock[4])*int(MIWaveGroup[0])
|
|
WG1 = int(MIWaveGroup[0]) * int(MIWaveGroup[1])*waveFrontSize // int(WG0)
|
|
|
|
return TT0,TT1,MT0,MT1,WG0,WG1
|
|
|
|
def writeToTensileYamlFile(tensileYamlFile, tensileYamlData):
|
|
try:
|
|
os.makedirs(os.path.dirname(tensileYamlFile), exist_ok=True)
|
|
with open(tensileYamlFile, "w") as fileHandle:
|
|
fileHandle.writelines("%s" % place for place in tensileYamlData)
|
|
fileHandle.close()
|
|
tPrint(1, "Successfully created the Tensile Input Yaml File {} from library logic file !!.\n".format(tensileYamlFile))
|
|
except (OSError, IOError):
|
|
tPrint(1, "Error: Creating file {} Please provide file name in this format <filename>.yaml.".format(tensileYamlFile))
|
|
|
|
def main():
|
|
TensileLibLogicToYaml(sys.argv[1:])
|