Files
derek.holloway 7502bf64a4
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
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

285 lines
11 KiB
Python

################################################################################
#
# Copyright (C) 2016-2023 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 copy import deepcopy
import itertools
from .Common import tPrint, printExit, \
defaultBenchmarkCommonParameters, validParameters, globalParameters, \
defaultBatchedBenchmarkFinalProblemSizes, defaultBenchmarkFinalProblemSizes
from .CustomKernels import getAllCustomKernelNames
from .SolutionStructs import ProblemType, ProblemSizes
def checkParametersAreValid(param, validParams):
"""Ensures paramaters in params exist and have valid values as specified by validParames"""
(name, values) = param
if name == "ProblemSizes":
return
if name not in validParams:
printExit("Invalid parameter name: {}\nValid parameters are {}." \
.format(name, sorted(validParameters.keys())))
for value in values:
if validParams[name] != -1 and value not in validParams[name]:
msgBase = "Invalid parameter value: {} = {}\nValid values for {} are {}{}."
msgExt = " (only first 32 combos printed)\nRefer to Common.py for more info" \
if len(validParams[name])>32 else ""
printExit(msgBase.format(name, value, name, validParams[name][:32], msgExt))
def separateParameters(paramSetList):
"""Separates paramSetList into parameters with single and multiple values"""
singleVaules = {}
multiValues = {}
for name, values in paramSetList.items():
if values == None:
printExit("You must specify value(s) for parameter \"{}\"".format(name))
if len(values) == 1 and name != "ProblemSizes":
singleVaules[name] = values[0]
elif len(values) > 1 and name != "ProblemSizes":
multiValues[name] = values
return singleVaules, multiValues
def checkCDBufferAndStrides(problemType, problemSizes, isCEqualD):
"""Ensures ldd == ldc when CEqualD"""
if isCEqualD and problemType["OperationType"] == "GEMM":
for problem in problemSizes.problems:
ldd = problem.sizes[problemType["IndexAssignmentsLD"][0]]
ldc = problem.sizes[problemType["IndexAssignmentsLD"][1]]
if ldd != ldc:
printExit("LDD({}) != LDC({}) causes unpredictable result when CEqualD(True)" \
.format(ldd, ldc))
class BenchmarkProcess:
"""Representation of benchmarking parameters and resulting steps"""
def __init__(self, problemTypeConfig, problemSizeGroupConfig):
"""Create from the two sections of a config for a BenchmarkProblem"""
self.problemType = ProblemType(problemTypeConfig)
self.isBatched = "Batched" in problemTypeConfig and problemTypeConfig["Batched"]
tPrint(3, "# BenchmarkProcess beginning {}".format(self.problemType))
# fill parameter values from config
self.singleValueParams = {}
self.multiValueParams = {}
self.customKernels = []
self.sizes = None
self.getConfigParameters(self.isBatched, problemSizeGroupConfig)
# convert parameter lists to steps
# previously, multiple benchmark steps were possible
# currently only 1 benchmark step is possible; more may be added back later
self.benchmarkSteps = []
self.benchmarkStepIdx = 0
self.convertParametersToSteps()
def getConfigParameters(self, isbatched, config):
"""Parse and validate benchmarking parameters in config"""
tPrint(3, "")
tPrint(3, "####################################################################")
tPrint(1, "# Filling in Parameters With Defaults")
tPrint(3, "####################################################################")
tPrint(3, "")
# check for no longer supported legacy benchmark steps
badParams = ["InitialSolutionParameters", "BenchmarkForkParameters", \
"JoinParameters", "BenchmarkJoinParameters"]
badsInConfig = []
for p in badParams:
if config.get(p) is not None:
badsInConfig.append(p)
if len(badsInConfig) == 1:
printExit("Benchmark step {} is no longer supported".format("'" + badsInConfig[0] +
"'"))
elif len(badsInConfig) > 1:
printExit("Benchmark steps {} are no longer supported".format(badsInConfig))
# get supported configurations
# value in config file may be "None", which we should ignore
def getNonNoneFromConfig(key, default):
if config.get(key) is not None:
return config[key]
else:
return default
# converts list of dicts into a flat dict
benchmarkCommonParams = dict(itertools.chain(*[x.items() \
for x in getNonNoneFromConfig("BenchmarkCommonParameters", [])]))
forkParams = dict(itertools.chain(*[x.items() \
for x in getNonNoneFromConfig("ForkParameters", [])]))
self.paramGroups = forkParams.pop("Groups") if "Groups" in forkParams else []
self.customKernels = getNonNoneFromConfig("CustomKernels", [])
if "BenchmarkFinalParameters" in config:
sizes = config["BenchmarkFinalParameters"][0]["ProblemSizes"]
else:
sizes = defaultBatchedBenchmarkFinalProblemSizes if isbatched \
else defaultBenchmarkFinalProblemSizes
self.problemSizes = ProblemSizes(self.problemType, sizes)
checkCDBufferAndStrides(self.problemType, self.problemSizes, globalParameters["CEqualD"])
# validate parameter values
configParams = {**benchmarkCommonParams, **forkParams}
for param in configParams.items():
checkParametersAreValid(param, validParameters)
# TODO other checks on groups (same params for each entry? no dups between groups?)
for list in self.paramGroups:
for group in list:
for k, v in group.items():
checkParametersAreValid((k, [v]), validParameters)
params = dict(itertools.chain(*[x.items() for x in defaultBenchmarkCommonParameters]))
params.update(configParams)
self.singleValueParams, self.multiValueParams = separateParameters(params)
# print summary of parameter values
tPrint(3, "Single Value Parameters:")
for k, v in sorted(self.singleValueParams.items()):
tPrint(3, " {}: {}".format(k, v))
tPrint(3, "Multi-Value Parameters:")
for k, v in sorted(self.multiValueParams.items()):
tPrint(3, " {}: {}".format(k, v))
if len(self.paramGroups) > 0:
tPrint(3, "{} Parameter Group(s):".format(len(self.paramGroups)))
for i, group in enumerate(self.paramGroups):
tPrint(3, " {} entries is group {}".format(len(group), i + 1))
def convertParametersToSteps(self):
"""Create benchmark steps based on parsed parameters"""
tPrint(3, "")
tPrint(3, "####################################################################")
tPrint(1, "# Convert Parameters to Benchmark Step(s)")
tPrint(3, "####################################################################")
tPrint(3, "")
# currently only a single step is supported
tPrint(3, "")
tPrint(3, "####################################################################")
tPrint(1, "# Benchmark Final")
benchmarkStep = BenchmarkStep( \
self.multiValueParams, \
self.singleValueParams, \
self.paramGroups, \
self.customKernels, \
self.problemSizes, \
self.benchmarkStepIdx)
self.benchmarkSteps.append(benchmarkStep)
self.benchmarkStepIdx += 1
def __len__(self):
return len(self.benchmarkSteps)
def __getitem__(self, key):
return self.benchmarkSteps[key]
def __str__(self):
string = "BenchmarkProcess:\n"
for step in self.benchmarkSteps:
string += str(step)
return string
def __repr__(self):
return self.__str__()
def constructForkPermutations(forkParams, paramGroups):
"""Constructs cartesian product of parameter values in forkParams and paramGroups"""
myParams = {}
myParams.update(forkParams)
totalPermutations = 1
for _, values in forkParams.items():
totalPermutations *= len(values)
# add groups to parameters to fork on
for i, group in enumerate(paramGroups):
myParams["_group" + str(i)] = group
totalPermutations *= len(group)
forkPermutations = []
for i in range(0, totalPermutations):
permutation = {}
pIdx = i
for name, v in myParams.items():
values = deepcopy(v)
valueIdx = pIdx % len(v)
# groups have multiple parameters to update
if "_group" in name:
entry = values[valueIdx]
for n2, v2 in entry.items():
permutation[n2] = v2
else:
permutation[name] = values[valueIdx]
pIdx //= len(values)
forkPermutations.append(permutation)
return forkPermutations
class BenchmarkStep:
"""A single benchmark step which consists of constant and fork parameters and a set of sizes"""
def __init__(self, forkParams, constantParams, paramGroups, customKernels, problemSizes, idx):
"""Basic constructor storing each argument"""
self.forkParams = forkParams
self.constantParams = constantParams
self.paramGroups = paramGroups
self.customKernels = customKernels
self.problemSizes = problemSizes
self.stepIdx = idx
self.customKernelWildcard = False
if self.customKernels == ["*"]:
self.customKernels = getAllCustomKernelNames()
self.customKernelWildcard = True
tPrint(3, "# Creating BenchmarkStep: {} fork params and {} sizes" \
.format( len(forkParams), problemSizes.totalProblemSizes))
def isFinal(self):
"""Legacy. Currently always returns true since only one benchmark step is possible"""
return True
def __str__(self):
string = "{:02d}".format(self.stepIdx)
if self.isFinal():
string += "_Final"
return string
def __repr__(self):
return self.__str__()