Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
[build-system]
requires = ["setuptools>=77"]
build-backend = "setuptools.build_meta"

[project]
name = "mldebug_xdp"
version = "0.1.0"
Expand Down
93 changes: 93 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright (C) 2024-2025 Advanced Micro Devices, Inc. All rights reserved.

"""
Stamps the git commit into the built package. All metadata lives in pyproject.toml.
"""

from datetime import datetime, timezone
from pathlib import Path

import os
import subprocess

from setuptools import setup
from setuptools.command.build_py import build_py
from setuptools.command.sdist import sdist

ROOT = Path(__file__).parent.resolve()


def _git(*args):
"""
Run a git command in the source tree, returning "" on any failure.
"""
try:
out = subprocess.run(
["git", "-C", str(ROOT), *args], capture_output=True, text=True, check=True, timeout=5
)
except (OSError, subprocess.SubprocessError):
return ""
return out.stdout.strip()


def _commit():
"""
Full HEAD commit. Falls back to GITHUB_SHA when building without a .git dir.
"""
commit = _git("rev-parse", "HEAD") or os.environ.get("GITHUB_SHA", "")
if not commit:
return ""
# Scoped to tracked *.py: the LFS binaries under bin/ and backend/ show as modified
# after a smudge, and sdist leaves an untracked copy of the tree behind while it runs.
if _git("status", "--porcelain", "-uno", "--", "*.py"):
commit += "-dirty"
return commit


def _write_stamp(stamp, version):
"""
Write _build_info.py, or keep the existing one when the commit is unknown.
An unknown commit means we are building from an sdist, which already carries
the stamp written when the sdist itself was built.
"""
commit = _commit()
if not commit:
print(f"[WARNING] no git commit found, leaving {stamp} as is")
return
build_date = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%SZ")
# sdist hard links files out of the source tree, so replace instead of writing in place.
stamp.unlink(missing_ok=True)
stamp.write_text(
'"""Generated at build time by setup.py."""\n\n'
f'VERSION = "{version}"\n'
f'COMMIT = "{commit}"\n'
f'BUILD_DATE = "{build_date}"\n',
encoding="utf-8",
)
print(f"[INFO] stamped {stamp} with commit '{commit}'")


class BuildPyStamped(build_py):
"""
Stamp the build tree after the sources are copied, leaving the source tree untouched.
"""

def run(self):
super().run()
stamp = Path(self.build_lib) / "mldebug" / "_build_info.py"
_write_stamp(stamp, self.distribution.get_version())


class SdistStamped(sdist):
"""
Stamp the sdist so a wheel built from it keeps the commit.
"""

def make_release_tree(self, base_dir, files):
super().make_release_tree(base_dir, files)
stamp = Path(base_dir) / "src" / "mldebug" / "_build_info.py"
_write_stamp(stamp, self.distribution.get_version())


setup(cmdclass={"build_py": BuildPyStamped, "sdist": SdistStamped})
11 changes: 11 additions & 0 deletions src/mldebug/_build_info.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright (C) 2024-2025 Advanced Micro Devices, Inc. All rights reserved.

"""
Build stamp. setup.py overwrites this inside the built package.
Values stay empty when running from a source tree.
"""

VERSION = ""
COMMIT = ""
BUILD_DATE = ""
9 changes: 8 additions & 1 deletion src/mldebug/mldebug_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
create_run_flags,
)
from mldebug.interactive_prompt import InteractivePrompt
from mldebug.utils import setup_logger, close_logger, is_windows
from mldebug.utils import LOGGER, setup_logger, close_logger, is_windows, version_string


def _apply_unsupported_kernels_from_args(args):
Expand Down Expand Up @@ -220,6 +220,12 @@ def app():
top_msg = "AIE Debug for VAIML.\nDefault data dump mode is binary. Files have 8byte header specifying total bytes."
p = argparse.ArgumentParser(description=top_msg, formatter_class=RawTextHelpFormatter)

p.add_argument(
"--version",
action="version",
version=version_string(),
help="Show version, commit ID and exit.\n",
)
p.add_argument(
"-b",
"--buffer_info",
Expand Down Expand Up @@ -410,6 +416,7 @@ def app():
)
args = p.parse_args()
setup_logger(args)
LOGGER.log(f"[INFO] {version_string()}")

if not check_args(args):
print("Argument check failed")
Expand Down
17 changes: 15 additions & 2 deletions src/mldebug/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
Helpful utilities like logging
"""

from pathlib import Path

import os
import platform
import sys
import threading
import time
from pathlib import Path

from mldebug import _build_info


class Logger:
Expand Down Expand Up @@ -106,6 +107,18 @@ def close_logger():
LOGGER.close()


def version_string():
"""
One line banner: version, commit and build date of the installed package.
"""
if not _build_info.COMMIT:
return "mldebug (running from source, no build stamp)"
return (
f"mldebug {_build_info.VERSION} (commit {_build_info.COMMIT})"
f" built {_build_info.BUILD_DATE}"
)


class Version:
"""
Simple versioning class for (major, minor) version management.
Expand Down
Loading