mirror of
https://github.com/microsoft/mscclpp.git
synced 2026-04-19 22:39:11 +00:00
Address corner case when generating version file (#641)
Address corner case for version file generation --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: github-actions <github-actions@github.com>
This commit is contained in:
@@ -1,135 +0,0 @@
|
||||
# Copyright (c) Microsoft Corporation.
|
||||
# Licensed under the MIT license.
|
||||
|
||||
"""Custom build backend wrapper to ensure version generation."""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
import logging
|
||||
from pathlib import Path
|
||||
|
||||
# Import the original backend
|
||||
from scikit_build_core.build import * # noqa: F401, F403
|
||||
from scikit_build_core.build import build_wheel as _orig_build_wheel
|
||||
from scikit_build_core.build import build_sdist as _orig_build_sdist
|
||||
from scikit_build_core.build import build_editable as _orig_build_editable
|
||||
from scikit_build_core.build import get_requires_for_build_wheel as _orig_get_requires_for_build_wheel
|
||||
from scikit_build_core.build import prepare_metadata_for_build_wheel as _orig_prepare_metadata_for_build_wheel
|
||||
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
|
||||
def _get_version():
|
||||
"""Get version using setuptools-scm, VERSION and clean it up"""
|
||||
try:
|
||||
with open("VERSION", "r") as vf:
|
||||
base_version = vf.read().strip()
|
||||
except FileNotFoundError:
|
||||
base_version = "0.0.0"
|
||||
|
||||
try:
|
||||
import setuptools_scm
|
||||
|
||||
version = setuptools_scm.get_version(root=".")
|
||||
|
||||
# Remove the .dYYYYMMDD timestamp if present
|
||||
# Convert "0.7.1.dev36+g6e2360d69.d20250926" to "0.7.1.dev36+g6e2360d69"
|
||||
version = re.sub(r"\.d\d{8}", "", version)
|
||||
|
||||
# Use the value in VERSION as the base version
|
||||
# Change to "0.7.0.dev36+g6e2360d69"
|
||||
version = re.sub(r"^[0-9]+\.[0-9]+\.[0-9]+", base_version, version)
|
||||
|
||||
logging.info(f"Generated version with setuptools-scm: {version}")
|
||||
return version
|
||||
except Exception as e:
|
||||
logging.warning(f"setuptools-scm failed: {e}, using fallback")
|
||||
return base_version + "+unknown"
|
||||
|
||||
|
||||
def _generate_version_file():
|
||||
"""Generate _version.py file using setuptools-scm"""
|
||||
version = _get_version()
|
||||
|
||||
# Write version file
|
||||
version_file = Path("python/mscclpp/_version.py")
|
||||
version_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
with open(version_file, "w") as f:
|
||||
f.write(f"# Generated by build backend\n")
|
||||
f.write(f'__version__ = "{version}"\n')
|
||||
f.write(f'version = "{version}"\n')
|
||||
|
||||
logging.info(f"Wrote version {version} to {version_file}")
|
||||
|
||||
# Also write a metadata file that scikit-build-core can read
|
||||
metadata_file = Path("python/mscclpp/PKG-INFO")
|
||||
metadata_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
with open(metadata_file, "w") as f:
|
||||
f.write(f"Metadata-Version: 2.1\n")
|
||||
f.write(f"Name: mscclpp\n")
|
||||
f.write(f"Version: {version}\n")
|
||||
|
||||
# Set environment variable for scikit-build-core
|
||||
os.environ["SETUPTOOLS_SCM_PRETEND_VERSION"] = version
|
||||
|
||||
return version
|
||||
|
||||
|
||||
def get_requires_for_build_wheel(config_settings=None):
|
||||
"""Get requirements with version generation"""
|
||||
_generate_version_file()
|
||||
return _orig_get_requires_for_build_wheel(config_settings)
|
||||
|
||||
|
||||
def prepare_metadata_for_build_wheel(metadata_directory, config_settings=None):
|
||||
"""Prepare metadata with version generation"""
|
||||
version = _generate_version_file()
|
||||
|
||||
# Call original function
|
||||
result = _orig_prepare_metadata_for_build_wheel(metadata_directory, config_settings)
|
||||
|
||||
# Patch the metadata with correct version
|
||||
import configparser
|
||||
|
||||
metadata_file = Path(metadata_directory) / f"{result}/METADATA"
|
||||
if metadata_file.exists():
|
||||
with open(metadata_file, "r") as f:
|
||||
content = f.read()
|
||||
|
||||
# Replace version line
|
||||
lines = content.split("\n")
|
||||
for i, line in enumerate(lines):
|
||||
if line.startswith("Version:"):
|
||||
lines[i] = f"Version: {version}"
|
||||
break
|
||||
|
||||
with open(metadata_file, "w") as f:
|
||||
f.write("\n".join(lines))
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def build_wheel(wheel_directory, config_settings=None, metadata_directory=None):
|
||||
"""Build wheel with version generation"""
|
||||
version = _generate_version_file()
|
||||
|
||||
# Set version in environment for scikit-build-core to pick up
|
||||
os.environ["SETUPTOOLS_SCM_PRETEND_VERSION"] = version
|
||||
|
||||
return _orig_build_wheel(wheel_directory, config_settings, metadata_directory)
|
||||
|
||||
|
||||
def build_sdist(sdist_directory, config_settings=None):
|
||||
"""Build sdist with version generation"""
|
||||
version = _generate_version_file()
|
||||
os.environ["SETUPTOOLS_SCM_PRETEND_VERSION"] = version
|
||||
return _orig_build_sdist(sdist_directory, config_settings)
|
||||
|
||||
|
||||
def build_editable(wheel_directory, config_settings=None, metadata_directory=None):
|
||||
"""Build editable with version generation"""
|
||||
version = _generate_version_file()
|
||||
os.environ["SETUPTOOLS_SCM_PRETEND_VERSION"] = version
|
||||
return _orig_build_editable(wheel_directory, config_settings, metadata_directory)
|
||||
@@ -9,7 +9,7 @@
|
||||
project = "mscclpp"
|
||||
copyright = "2025, MSCCL++ Team"
|
||||
author = "MSCCL++ Team"
|
||||
release = "v0.7.0"
|
||||
release = "v0.8.0"
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
|
||||
|
||||
@@ -206,18 +206,17 @@ export LD_LIBRARY_PATH=$MSCCLPP_INSTALL_DIR:$LD_LIBRARY_PATH
|
||||
torchrun --nnodes=1 --nproc_per_node=8 your_script.py
|
||||
```
|
||||
|
||||
### Version Tracking
|
||||
## Version Tracking
|
||||
|
||||
The MSCCL++ Python package includes comprehensive version tracking that captures git repository information at build time. This feature allows users to identify the exact source code version of their installed package.
|
||||
|
||||
#### Version Format
|
||||
### Version Format
|
||||
|
||||
The package version includes the git commit hash directly in the version string for development builds:
|
||||
- **Release version**: `0.7.0`
|
||||
- **Development version**: `0.7.0.dev36+g6e2360d69` (includes short commit hash)
|
||||
- **Development with uncommitted changes**: `0.7.0.dev36+g6e2360d69.dirty`
|
||||
- **Development version**: `mscclpp-0.8.0.post1.dev0+gc632fee37.d20251007`
|
||||
|
||||
#### Checking Version Information
|
||||
### Checking Version Information
|
||||
|
||||
After installation, you can check the version information in several ways:
|
||||
|
||||
@@ -227,16 +226,10 @@ import mscclpp
|
||||
|
||||
# Access individual attributes
|
||||
print(f"Version: {mscclpp.__version__}") # Full version with commit
|
||||
Version: 0.7.0.dev36+g6e2360d69
|
||||
Version: 0.8.0.post1.dev0+gc632fee37.d20251007
|
||||
|
||||
# Get as dictionary
|
||||
mscclpp.version
|
||||
{'version': '0.7.0.dev36+g6e2360d69', 'base_version': '0.7.0', 'git_commit': '6e2360d69'}
|
||||
{'version': '0.8.0.post1.dev0+gc632fee37.d20251007', 'git_commit': 'g50382c567'}
|
||||
```
|
||||
|
||||
#### Version Information Details
|
||||
|
||||
The version tracking captures:
|
||||
- **Package Version** (`mscclpp.__version__`): Full version string including git commit (e.g., `0.7.1.dev36+g6e2360d69`)
|
||||
|
||||
This information is embedded during the package build process and remains accessible even after distribution, making it easier to debug issues and ensure reproducibility.
|
||||
|
||||
@@ -3,11 +3,10 @@
|
||||
|
||||
[build-system]
|
||||
requires = [
|
||||
"scikit-build-core>=0.4.3",
|
||||
"setuptools-scm[toml]>=6.2"
|
||||
"scikit-build-core>=0.10.0",
|
||||
"setuptools-scm[toml]>=8"
|
||||
]
|
||||
build-backend = "_build_version_metadata"
|
||||
backend-path = ["."]
|
||||
build-backend = "scikit_build_core.build"
|
||||
|
||||
[project]
|
||||
name = "mscclpp"
|
||||
@@ -17,6 +16,7 @@ requires-python = ">=3.8"
|
||||
|
||||
[tool.setuptools_scm]
|
||||
write_to = "python/mscclpp/_version.py"
|
||||
version_scheme = "no-guess-dev"
|
||||
|
||||
[tool.scikit-build]
|
||||
cmake.version = ">=3.25.0"
|
||||
@@ -31,6 +31,9 @@ install-dir = "mscclpp"
|
||||
license-files = ["VERSION", "LICENSE", "CITATION.cff", "CODE_OF_CONDUCT.md", "README.md", "SECURITY.md", "SUPPORT.md"]
|
||||
exclude = ["mscclpp/*.cpp"]
|
||||
|
||||
[tool.scikit-build.sdist]
|
||||
include= ["python/mscclpp/_version.py"]
|
||||
|
||||
[tool.scikit-build.cmake.define]
|
||||
MSCCLPP_BUILD_PYTHON_BINDINGS = "ON"
|
||||
MSCCLPP_BUILD_TESTS = "OFF"
|
||||
|
||||
@@ -5,59 +5,22 @@
|
||||
|
||||
import os
|
||||
import warnings
|
||||
import re
|
||||
from functools import wraps
|
||||
|
||||
|
||||
# Get version
|
||||
def _get_version():
|
||||
"""Get version from the best available source"""
|
||||
if os.environ.get("MSCCLPP_HOME", None) is None:
|
||||
os.environ["MSCCLPP_HOME"] = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
# Try setuptools-scm generated _version.py (most reliable)
|
||||
try:
|
||||
from ._version import __version__
|
||||
from ._version import __version__, __commit_id__
|
||||
|
||||
return __version__
|
||||
except ImportError:
|
||||
raise RuntimeError("Could not determine MSCCL++ version from setuptools-scm generated _version.py.")
|
||||
|
||||
|
||||
# Parse version components
|
||||
def _parse_version(version_string):
|
||||
"""Parse version components from setuptools-scm generated version"""
|
||||
# Pattern for versions like "0.7.0.dev36+g6e2360d69" (without .dYYYYMMDD)
|
||||
pattern = r"^v?(?P<base>[\d\.]+)(?:\.dev(?P<distance>\d+))?(?:\+g(?P<commit>[a-f0-9]+))?(?P<dirty>\.dirty)?$"
|
||||
match = re.match(pattern, version_string)
|
||||
|
||||
if match:
|
||||
return {"base_version": match.group("base"), "git_commit": match.group("commit") or "unknown"}
|
||||
else:
|
||||
# Fallback parsing - try to extract what we can
|
||||
base = version_string.split("+")[0].lstrip("v").split(".dev")[0]
|
||||
commit = "unknown"
|
||||
|
||||
return {"base_version": base, "git_commit": commit}
|
||||
|
||||
|
||||
__version__ = _get_version()
|
||||
|
||||
# Parse the version
|
||||
_version_info = _parse_version(__version__)
|
||||
__base_version__ = _version_info["base_version"]
|
||||
__git_commit__ = _version_info["git_commit"]
|
||||
version = {
|
||||
"version": __version__,
|
||||
"git_commit": __commit_id__,
|
||||
}
|
||||
|
||||
|
||||
def _version():
|
||||
"""Get complete version information as a dictionary"""
|
||||
return {
|
||||
"version": __version__,
|
||||
"base_version": __base_version__,
|
||||
"git_commit": __git_commit__,
|
||||
}
|
||||
|
||||
|
||||
version: dict = _version()
|
||||
|
||||
from ._mscclpp import (
|
||||
Env,
|
||||
ErrorCode,
|
||||
@@ -132,9 +95,6 @@ __all__ = [
|
||||
"SmDevice2DeviceSemaphore",
|
||||
]
|
||||
|
||||
if os.environ.get("MSCCLPP_HOME", None) is None:
|
||||
os.environ["MSCCLPP_HOME"] = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
|
||||
def get_include() -> str:
|
||||
"""Return the directory that contains the MSCCL++ headers."""
|
||||
|
||||
Reference in New Issue
Block a user