Files
TheRock/rocm-libraries/projects/hipblaslt/tensilelite/Tensile/Tests/common/config_helpers.py
T
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

254 lines
9.3 KiB
Python

################################################################################
#
# Copyright (C) 2022-2025 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.
#
################################################################################
"""Pytest-specific test configuration helpers.
For artifact compression/extraction utilities (no pytest dependency),
see artifact_helpers.py.
"""
import os
import re
import pytest
import yaml
from Tensile.Common.DataType import DataType
_TESTS_ROOT_DIR = os.path.dirname(os.path.dirname(__file__))
try:
DEFAULT_YAML_LOADER = yaml.CSafeLoader
except AttributeError:
DEFAULT_YAML_LOADER = yaml.SafeLoader
def get_rocm_version_or_none():
"""Gets the ROCm version from the version file."""
try:
rocmpath = os.environ.get("ROCM_PATH", "/opt/rocm")
version_file_path = os.path.join(rocmpath, ".info/version")
with open(version_file_path, 'r') as f:
version_string = f.readline().strip()
return version_string
except (FileNotFoundError, IOError):
return None
def walkDict(root, path=""):
"""
Recursively walks a structure which may consist of dictionaries, lists,
and other objects. Yields (object, path) for each object in the
structure.
"""
yield root, path
if isinstance(root, dict):
for key, value in root.items():
keypath = key
if path != "":
keypath = path + "." + str(keypath)
yield from walkDict(value, keypath)
elif isinstance(root, list):
for i, obj in enumerate(root):
keypath = str(i)
if path != "":
keypath = path + "." + keypath
yield from walkDict(obj, keypath)
def markNamed(name):
"""
Gets a mark by a name contained in a variable.
"""
return getattr(pytest.mark, name)
def configMarks(filepath, rootDir, availableArchs):
"""
Returns a list of marks to add to a particular YAML config path. Currently gets a mark for:
- Root directory name. This separates tests into pre_checkin, nightly, etc.
- Expected failures. Include 'xfail' in the name of the YAML file.
- Anything in yaml["TestParameters"]["marks"]
- Architecture from GlobalParameters.Architecture (e.g. gfx1250)
- Architecture from filename (e.g. bf16_gfx1250.yaml -> gfx1250)
- validate / validateAll - whether the test validates (all?) results.
- Data type(s) used in the YAML
- Problem type(s) used in the YAML
- Kernel language(s) used in the YAML
"""
relpath = os.path.relpath(filepath, rootDir)
components = relpath.split(os.path.sep)
# First part of directory - nightly, pre-checkin, etc.
# Skip underscore-prefixed path components (e.g. characterization's _codegen
# fixture dir): pytest rejects marks starting with "_", and such dirs hold
# library logic YAMLs that are filtered out below by the not-dict guard anyway.
marks = list([markNamed(c) for c in components[:-1] if not c.startswith("_")])
if 'xfail' in relpath or 'wip' in relpath:
marks.append(pytest.mark.xfail)
if 'disabled' in relpath:
marks.append(pytest.mark.skip)
try:
with open(filepath) as f:
doc = yaml.load(f, DEFAULT_YAML_LOADER)
except yaml.parser.ParserError:
marks.append(pytest.mark.syntax_error)
return marks
# A Tensile config is a mapping (GlobalParameters/BenchmarkProblems/...).
# Top-level sequences are library logic YAMLs (e.g. characterization data
# files), which are not standalone Tensile.py configs. Signal the caller to
# skip them rather than crashing on doc["BenchmarkProblems"].
if not isinstance(doc, dict):
return None
if "TestParameters" in doc:
if "marks" in doc["TestParameters"]:
marks += [markNamed(m) for m in doc["TestParameters"]["marks"]]
arch_val = doc.get("GlobalParameters", {}).get("Architecture")
if arch_val and markNamed(arch_val) not in marks:
marks.append(markNamed(arch_val))
arch_in_name = re.search(r'(gfx\d+)', components[-1])
if arch_in_name and markNamed(arch_in_name.group(1)) not in marks:
marks.append(markNamed(arch_in_name.group(1)))
# Architecture specific xfail marks
for arch in availableArchs:
ArchFail = "xfail-%s" % arch
if markNamed(ArchFail) in marks:
marks.append(pytest.mark.xfail)
ArchSkip = "skip-%s" % arch
if markNamed(ArchSkip) in marks:
marks.append(pytest.mark.skip)
validate = True
validateAll = False
try:
if doc["GlobalParameters"]['NumElementsToValidate'] == 0:
validate = False
if doc["GlobalParameters"]['NumElementsToValidate'] == -1:
validateAll = True
except KeyError:
pass
if validate:
marks.append(pytest.mark.validate)
if validateAll:
marks.append(pytest.mark.validateAll)
dataTypes = set([problem[0]["DataType"] for problem in doc["BenchmarkProblems"]])
operationTypes = set([problem[0]["OperationType"] for problem in doc["BenchmarkProblems"]])
languages = set()
for obj, path in walkDict(doc):
if "KernelLanguage" in path and isinstance(obj, str):
languages.add(obj)
for l in languages:
marks.append(markNamed(l))
for dt in dataTypes:
dataType = DataType(dt)
marks.append(markNamed(dataType.toName()))
for operationType in operationTypes:
marks.append(markNamed(operationType))
return marks
def findAvailableArchs(gpu_targets=None):
"""Detect available GPU architectures, or use an explicit override.
Args:
gpu_targets: Semicolon-separated GPU targets (e.g. "gfx942").
When provided, skips hardware detection entirely.
Returns:
List of architecture strings (e.g. ["gfx942"]).
"""
if gpu_targets:
return [t.strip() for t in gpu_targets.split(";") if t.strip()]
from Tensile.Tests.gpu_detection import get_available_archs
return get_available_archs()
def findConfigs(rootDir=None, availableArchs=None):
"""
Walks rootDir (defaults to trying to find Tensile/Tests) and returns a
list of test parameters, one for each YAML file.
Args:
rootDir: Directory to walk for YAML configs. Defaults to Tensile/Tests.
availableArchs: Pre-resolved list of GPU architectures.
When None, calls findAvailableArchs() to auto-detect.
"""
if rootDir is None:
rootDir = _TESTS_ROOT_DIR
printRoot = os.path.dirname(os.path.dirname(rootDir))
else:
printRoot = rootDir
if availableArchs is None:
availableArchs = findAvailableArchs()
globalParamArchsStr = ';'.join(availableArchs)
os.environ["PyTestBuildArchNames"] = globalParamArchsStr
rocm_version = get_rocm_version_or_none()
params = []
for (dirpath, dirnames, filenames) in os.walk(rootDir):
for filename in filenames:
# Conditionally skip icache_flush.yaml on rocm 7.1 due to ROCm bug.
if filename == "icache_flush.yaml" and rocm_version and rocm_version.startswith("7.1"):
print(f"INFO: Skipping '{filename}' on ROCm {rocm_version}.")
continue
# Skip build client script
if filename == "build_client.yaml":
continue
# filter out yamls in logic_yaml since they are not meant for Tensile.py
elif filename.endswith('.yaml') and "logic_yaml" not in dirpath:
filepath = os.path.join(rootDir, dirpath, filename)
if not "test_data" in filepath:
marks = configMarks(filepath, rootDir, availableArchs)
if marks is None:
# Not a Tensile config (e.g. a library logic YAML); skip.
continue
# Conditionally xfail icache_flush.yaml on rocm 7.1 due to ROCm bug.
if filename == "icache_flush.yaml" and rocm_version and rocm_version.startswith("7.1"):
reason = "Test is expected to fail on ROCm 7.1 due to a known bug."
marks.append(pytest.mark.xfail(reason=reason, strict=True))
relpath = os.path.relpath(filepath, printRoot)
params.append(pytest.param(filepath, marks=marks, id=relpath))
return params