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
25 changes: 0 additions & 25 deletions .flake8

This file was deleted.

24 changes: 7 additions & 17 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,13 @@ repos:
# project can specify its own first/third-party packages.
args: ["--config-root=python/", "--resolve-all-configs"]
files: python/.*
types_or: [python, cython, pyi]
- repo: https://github.com/psf/black
rev: 22.3.0
types: [cython]
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.14.3
hooks:
- id: black
files: python/.*
# Explicitly specify the pyproject.toml at the repo root, not per-project.
args: ["--config", "pyproject.toml"]
- repo: https://github.com/PyCQA/flake8
rev: 7.1.1
hooks:
- id: flake8
args: ["--config=.flake8"]
files: python/.*$
types: [file]
types_or: [python, cython]
additional_dependencies: ["flake8-force"]
- id: ruff-check
args: [--fix]
- id: ruff-format
- repo: https://github.com/pre-commit/mirrors-mypy
rev: 'v0.971'
hooks:
Expand Down Expand Up @@ -110,7 +100,7 @@ repos:
^CHANGELOG[.]md$|
^cpp/cmake/patches/cutlass/build-export[.]patch$
- repo: https://github.com/rapidsai/pre-commit-hooks
rev: v1.2.0
rev: v1.2.1
hooks:
- id: verify-copyright
name: verify-copyright-cuvs
Expand Down
92 changes: 61 additions & 31 deletions cpp/scripts/analyze_nvcc_log.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
#!/usr/bin/env python3
# SPDX-FileCopyrightText: Copyright (c) 2023, NVIDIA CORPORATION.
# SPDX-FileCopyrightText: Copyright (c) 2023-2025, NVIDIA CORPORATION.
# SPDX-License-Identifier: Apache-2.0

import sys
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from pathlib import Path
from matplotlib import colors


def main(input_path):
input_path = Path(input_path)
print("-- loading data")
Expand All @@ -22,40 +22,56 @@ def main(input_path):
df["file"] = df["source file name"]
df["phase"] = df["phase name"].str.strip()

dfp = (df
# Remove nvcc driver entries. They don't contain a source file name
.query("phase!='nvcc (driver)'")
# Make a pivot table containing files as row, phase (preprocessing,
# cicc, etc.) as column and the total times as table entries. NOTE:
# if compiled for multiple archs, the archs will be summed.
.pivot_table(index="file", values="seconds", columns="phase", aggfunc='sum'))
dfp = (
df
# Remove nvcc driver entries. They don't contain a source file name
.query("phase!='nvcc (driver)'")
# Make a pivot table containing files as row, phase (preprocessing,
# cicc, etc.) as column and the total times as table entries. NOTE:
# if compiled for multiple archs, the archs will be summed.
.pivot_table(
index="file", values="seconds", columns="phase", aggfunc="sum"
)
)

dfp_sum = dfp.sum(axis="columns")

df_fraction = dfp.divide(dfp_sum, axis="index")
df_fraction["total time"] = dfp_sum
df_fraction = df_fraction.melt(ignore_index=False, id_vars="total time", var_name="phase", value_name="fraction")
df_fraction = df_fraction.melt(
ignore_index=False,
id_vars="total time",
var_name="phase",
value_name="fraction",
)

dfp["total time"] = dfp_sum
df_absolute = dfp.melt(ignore_index=False, id_vars="total time", var_name="phase", value_name="seconds")
df_absolute = dfp.melt(
ignore_index=False,
id_vars="total time",
var_name="phase",
value_name="seconds",
)

# host: light red to dark red (preprocessing, cudafe, gcc (compiling))
# device: ligt green to dark green (preprocessing, cicc, ptxas)
palette = {
"gcc (preprocessing 4)": colors.hsv_to_rgb((0, 1, 1)),
'cudafe++': colors.hsv_to_rgb((0, 1, .75)),
'gcc (compiling)': colors.hsv_to_rgb((0, 1, .4)),
"gcc (preprocessing 1)": colors.hsv_to_rgb((.33, 1, 1)),
'cicc': colors.hsv_to_rgb((.33, 1, 0.75)),
'ptxas': colors.hsv_to_rgb((.33, 1, 0.4)),
'fatbinary': "grey",
"cudafe++": colors.hsv_to_rgb((0, 1, 0.75)),
"gcc (compiling)": colors.hsv_to_rgb((0, 1, 0.4)),
"gcc (preprocessing 1)": colors.hsv_to_rgb((0.33, 1, 1)),
"cicc": colors.hsv_to_rgb((0.33, 1, 0.75)),
"ptxas": colors.hsv_to_rgb((0.33, 1, 0.4)),
"fatbinary": "grey",
}

print("-- Ten longest translation units:")
colwidth = pd.get_option('display.max_colwidth') - 1
colwidth = pd.get_option("display.max_colwidth") - 1
dfp = dfp.reset_index()
dfp["file"] = dfp["file"].apply(lambda s: s[-colwidth:])
print(dfp.sort_values("total time", ascending=False).reset_index().loc[:10])
print(
dfp.sort_values("total time", ascending=False).reset_index().loc[:10]
)

print("-- Plotting absolute compile times")
abs_out_path = f"{input_path}.absolute.compile_times.png"
Expand All @@ -64,43 +80,57 @@ def main(input_path):
y="file",
hue="phase",
hue_order=reversed(
["gcc (preprocessing 4)", 'cudafe++', 'gcc (compiling)',
"gcc (preprocessing 1)", 'cicc', 'ptxas',
'fatbinary',
]),
[
"gcc (preprocessing 4)",
"cudafe++",
"gcc (compiling)",
"gcc (preprocessing 1)",
"cicc",
"ptxas",
"fatbinary",
]
),
palette=palette,
weights="seconds",
multiple="stack",
kind="hist",
height=20,
)
plt.xlabel("seconds");
plt.xlabel("seconds")
plt.savefig(abs_out_path)
print(f"-- Wrote absolute compile time plot to {abs_out_path}")

print("-- Plotting relative compile times")
rel_out_path = f"{input_path}.relative.compile_times.png"
sns.displot(
df_fraction.sort_values('total time').reset_index(),
df_fraction.sort_values("total time").reset_index(),
y="file",
hue="phase",
hue_order=reversed(["gcc (preprocessing 4)", 'cudafe++', 'gcc (compiling)',
"gcc (preprocessing 1)", 'cicc', 'ptxas',
'fatbinary',
]),
hue_order=reversed(
[
"gcc (preprocessing 4)",
"cudafe++",
"gcc (compiling)",
"gcc (preprocessing 1)",
"cicc",
"ptxas",
"fatbinary",
]
),
palette=palette,
weights="fraction",
multiple="stack",
kind="hist",
height=15,
)
plt.xlabel("fraction");
plt.xlabel("fraction")
plt.savefig(rel_out_path)
print(f"-- Wrote relative compile time plot to {rel_out_path}")


if __name__ == "__main__":
if len(sys.argv) != 2:
printf("""NVCC log analyzer
print("""NVCC log analyzer

Analyzes nvcc logs and outputs a figure with highest ranking translation
units.
Expand Down
103 changes: 59 additions & 44 deletions cpp/scripts/gitutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,17 +55,20 @@ def repo_version_major_minor():

full_repo_version = repo_version()

match = re.match(r"^v?(?P<major>[0-9]+)(?:\.(?P<minor>[0-9]+))?",
full_repo_version)

if (match is None):
print(" [DEBUG] Could not determine repo major minor version. "
f"Full repo version: {full_repo_version}.")
match = re.match(
r"^v?(?P<major>[0-9]+)(?:\.(?P<minor>[0-9]+))?", full_repo_version
)

if match is None:
print(
" [DEBUG] Could not determine repo major minor version. "
f"Full repo version: {full_repo_version}."
)
return None

out_version = match.group("major")

if (match.group("minor")):
if match.group("minor"):
out_version += "." + match.group("minor")

return out_version
Expand All @@ -91,44 +94,50 @@ def determine_merge_commit(current_branch="HEAD"):

try:
# Try to determine the target branch from the most recent tag
head_branch = __git("describe",
"--all",
"--tags",
"--match='branch-*'",
"--abbrev=0")
head_branch = __git(
"describe", "--all", "--tags", "--match='branch-*'", "--abbrev=0"
)
except subprocess.CalledProcessError:
print(" [DEBUG] Could not determine target branch from most recent "
"tag. Falling back to 'branch-{major}.{minor}.")
print(
" [DEBUG] Could not determine target branch from most recent "
"tag. Falling back to 'branch-{major}.{minor}."
)
head_branch = None

if (head_branch is not None):
if head_branch is not None:
# Convert from head to branch name
head_branch = __git("name-rev", "--name-only", head_branch)
else:
# Try and guess the target branch as "branch-<major>.<minor>"
version = repo_version_major_minor()

if (version is None):
if version is None:
return None

head_branch = "branch-{}".format(version)

try:
# Now get the remote tracking branch
remote_branch = __git("rev-parse",
"--abbrev-ref",
"--symbolic-full-name",
head_branch + "@{upstream}")
remote_branch = __git(
"rev-parse",
"--abbrev-ref",
"--symbolic-full-name",
head_branch + "@{upstream}",
)
except subprocess.CalledProcessError:
print(" [DEBUG] Could not remote tracking reference for "
f"branch {head_branch}.")
print(
" [DEBUG] Could not remote tracking reference for "
f"branch {head_branch}."
)
remote_branch = None

if (remote_branch is None):
if remote_branch is None:
return None

print(f" [DEBUG] Determined TARGET_BRANCH as: '{remote_branch}'. "
"Finding common ancestor.")
print(
f" [DEBUG] Determined TARGET_BRANCH as: '{remote_branch}'. "
"Finding common ancestor."
)

common_commit = __git("merge-base", remote_branch, current_branch)

Expand Down Expand Up @@ -166,9 +175,9 @@ def changedFilesBetween(baseName, branchName, commitHash):
# checkout latest commit from branch
__git("checkout", "-fq", commitHash)

files = __gitdiff("--name-only",
"--ignore-submodules",
f"{baseName}..{branchName}")
files = __gitdiff(
"--name-only", "--ignore-submodules", f"{baseName}..{branchName}"
)

# restore the original branch
__git("checkout", "--force", current)
Expand All @@ -180,13 +189,15 @@ def changesInFileBetween(file, b1, b2, filter=None):
current = branch()
__git("checkout", "--quiet", b1)
__git("checkout", "--quiet", b2)
diffs = __gitdiff("--ignore-submodules",
"-w",
"--minimal",
"-U0",
"%s...%s" % (b1, b2),
"--",
file)
diffs = __gitdiff(
"--ignore-submodules",
"-w",
"--minimal",
"-U0",
"%s...%s" % (b1, b2),
"--",
file,
)
__git("checkout", "--quiet", current)
lines = []
for line in diffs.splitlines():
Expand Down Expand Up @@ -215,25 +226,29 @@ def modifiedFiles(pathFilter=None):
currentBranch = branch()
print(
f" [DEBUG] TARGET_BRANCH={targetBranch}, COMMIT_HASH={commitHash}, "
f"currentBranch={currentBranch}")
f"currentBranch={currentBranch}"
)

if targetBranch and commitHash and (currentBranch == "current-pr-branch"):
print(" [DEBUG] Assuming a CI environment.")
allFiles = changedFilesBetween(targetBranch, currentBranch, commitHash)
else:
print(" [DEBUG] Did not detect CI environment. "
"Determining TARGET_BRANCH locally.")
print(
" [DEBUG] Did not detect CI environment. "
"Determining TARGET_BRANCH locally."
)

common_commit = determine_merge_commit(currentBranch)

if (common_commit is not None):

if common_commit is not None:
# Now get the diff. Use --staged to get both diff between
# common_commit..HEAD and any locally staged files
allFiles = __gitdiff("--name-only",
"--ignore-submodules",
"--staged",
f"{common_commit}").splitlines()
allFiles = __gitdiff(
"--name-only",
"--ignore-submodules",
"--staged",
f"{common_commit}",
).splitlines()
else:
# Fallback to just uncommitted files
allFiles = uncommittedFiles()
Expand Down
Loading