Load script tooling dependencies lazily

Add a shared nvbench_tooling_deps helper for importing packages required
by NVBench console tools. Missing tooling packages now raise a dedicated
error with an install recipe instead of failing with a raw ImportError.

Update script imports to work both as installed package modules and as
direct source-tree scripts by using the __package__ import pattern for
nvbench_json and the new tooling helper.

Defer nvbench-compare dependencies to the points where they are needed:
NumPy/colorama during normal comparison setup, tabulate during table
rendering, jsondiff only for device mismatch reporting, and plotting
packages only for plot modes.

Update tests to initialize compare tooling when calling internals
directly and add coverage for the tooling dependency loader.

Closes #384
This commit is contained in:
Oleksandr Pavlyk
2026-06-29 11:38:42 -05:00
parent 6dae814da5
commit 5fd21dd7fa
7 changed files with 348 additions and 41 deletions

View File

@@ -4,13 +4,44 @@ import argparse
import os
import sys
import matplotlib.pyplot as plt
from matplotlib.ticker import PercentFormatter
try:
if __package__:
from .nvbench_json import reader
from .nvbench_tooling_deps import (
MissingToolingDependencyError,
ToolingDependency,
require_tooling_dependency,
)
else:
from nvbench_json import reader
except ImportError:
from scripts.nvbench_json import reader
from nvbench_tooling_deps import (
MissingToolingDependencyError,
ToolingDependency,
require_tooling_dependency,
)
plt = None
PercentFormatter = None
def load_nvbench_plot_bwutil_tooling():
global PercentFormatter, plt
if plt is None:
plt = require_tooling_dependency(
ToolingDependency(
"matplotlib.pyplot", "matplotlib", "bandwidth plot rendering"
),
tool_name="nvbench-plot-bwutil",
)
if PercentFormatter is None:
ticker = require_tooling_dependency(
ToolingDependency(
"matplotlib.ticker", "matplotlib", "plot axis formatting"
),
tool_name="nvbench-plot-bwutil",
)
PercentFormatter = ticker.PercentFormatter
UTILIZATION_TAG = "nv/cold/bw/global/utilization"
@@ -263,6 +294,12 @@ def plot_entries(entries, title=None, output=None, dark=False):
def main():
args, filenames = parse_files()
try:
load_nvbench_plot_bwutil_tooling()
except MissingToolingDependencyError as exc:
print(str(exc), file=sys.stderr)
return 1
try:
axis_filters = parse_axis_filters(args.axis)
except ValueError as exc: