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
134 lines
5.3 KiB
Python
134 lines
5.3 KiB
Python
# Copyright (C) Advanced Micro Devices. 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.
|
|
|
|
import logging
|
|
import re
|
|
|
|
|
|
class BDF:
|
|
"""BDF Class to cast and compare BDF objects using built-in python comparators
|
|
|
|
Useful for validating a BDF string and converting it to a BDF object
|
|
This allows us to handle BDF objects in a pythonic way
|
|
|
|
Attributes:
|
|
__eq__: The equals comparator
|
|
__: An integer count of the eggs we have laid.
|
|
"""
|
|
|
|
def __init__(self, bdf):
|
|
"""Init a BDF object"""
|
|
if isinstance(bdf, BDF):
|
|
self.segment, self.bus, self.device, self.function = tuple(bdf)
|
|
else:
|
|
if bdf.startswith("BDF("):
|
|
bdf = bdf.replace("BDF(", "").replace(")", "")
|
|
|
|
# Validate BDF format before parsing
|
|
# PCI BDF format: [SSSS:]BB:DD.F where:
|
|
# - SSSS: 4 hex digits (segment/domain) - optional
|
|
# - BB: 2 hex digits (bus)
|
|
# - DD: 2 hex digits (device)
|
|
# - F: 1 hex digit 0-7 (function) - MUST be single digit
|
|
bdf_format_regex = r"^(?:[0-9a-fA-F]{4}:)?[0-9a-fA-F]{2}:[0-9a-fA-F]{2}\.[0-7]$"
|
|
if not re.match(bdf_format_regex, bdf):
|
|
raise self.BDFError(
|
|
f"Invalid BDF format: '{bdf}'. Expected format: [SSSS:]BB:DD.F (where F is 0-7)"
|
|
)
|
|
|
|
try:
|
|
bdf_components = [int(x, 16) for x in re.split("[:.]", bdf)]
|
|
except self.BDFError as e:
|
|
logging.error(f"Invalid string passed: {bdf}")
|
|
raise e
|
|
|
|
self.segment = bdf_components[0] if len(bdf_components) == 4 else 0
|
|
self.bus, self.device, self.function = bdf_components[-3:]
|
|
if self.segment > 65535:
|
|
raise self.BDFError("Segment can't be greater than 65535")
|
|
if self.bus > 255:
|
|
raise self.BDFError("Bus can't be greater than 255")
|
|
if self.device > 31:
|
|
raise self.BDFError("Device can't be greater than 31")
|
|
if self.function > 7:
|
|
raise self.BDFError("Function can't be greater than 7")
|
|
|
|
class BDFError(Exception):
|
|
"""BDF Class Error"""
|
|
|
|
def __eq__(self, passed_bdf):
|
|
"""Overrides the == operator and allows for BDF objects to be compared to BDF strings"""
|
|
|
|
# Only accept strings and BDF objects
|
|
if isinstance(passed_bdf, str):
|
|
if passed_bdf == "":
|
|
return False
|
|
passed_bdf = BDF(passed_bdf)
|
|
elif not isinstance(passed_bdf, BDF):
|
|
return False
|
|
|
|
if (
|
|
self.segment == passed_bdf.segment
|
|
and self.bus == passed_bdf.bus
|
|
and self.device == passed_bdf.device
|
|
and self.function == passed_bdf.function
|
|
):
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
def __ne__(self, passed_bdf):
|
|
"""Overrides the != operator and allows for BDF objects to be compared to BDF strings"""
|
|
# Since we overrode the == operator we can use that to make this simple
|
|
return not self == passed_bdf
|
|
|
|
def __add__(self, passed_bdf):
|
|
"""Overrides the + operator and allows for string concatenation"""
|
|
return str(self) + passed_bdf
|
|
|
|
def __radd__(self, passed_bdf):
|
|
"""Overrides the + operator and allows for string concatenation"""
|
|
return passed_bdf + str(self)
|
|
|
|
def __str__(self):
|
|
"""Cast BDF object to a string"""
|
|
return "{:04X}:{:02X}:{:02X}:{}".format(self.segment, self.bus, self.device, self.function)
|
|
|
|
def __repr__(self):
|
|
"""How the BDF object is represented"""
|
|
return f"BDF({self})"
|
|
|
|
def __hash__(self):
|
|
"""Allow the BDF object to be hashable"""
|
|
return hash(str(self))
|
|
|
|
def __iter__(self):
|
|
"""Make the BDF object iterable over its 4 values"""
|
|
yield from (self.segment, self.bus, self.device, self.function)
|
|
|
|
def __contains__(self, passed_bdf):
|
|
"""Overrode the 'in' comparator in python"""
|
|
passed_bdf = str(BDF(passed_bdf))
|
|
|
|
bdf_regex = "(?:[0-6]?[0-9a-fA-F]{1,4}:)?[0-2]?[0-9a-fA-F]{1,2}:[0-9a-fA-F]{1,2}\\.[0-7]"
|
|
for match in re.findall(bdf_regex, passed_bdf):
|
|
if self == match:
|
|
return True
|
|
return False
|