Skip to main content

Schema-versioned Roofline analysis, comparison, and plotting for humans and AI agents.

Project description

English · 中文

roofp logo

roofp

Schema-versioned Roofline analysis, comparison, and plotting for humans and AI agents.

roofp accepts JSON configuration, CLI arguments, or structured MCP calls. It generates SVG, PNG, and PDF plots and reports every measured operator against each configured roof. Version 0.2 separates theoretical hardware capability from per-hardware measured utilization and makes dimensional units explicit in the output schema.

Roofline model

For a roof with peak compute P in FLOP/s, bandwidth B in Byte/s, and arithmetic intensity I in FLOP/Byte:

ridge point = P / B
roof ceiling(I) = min(P, B * I)
utilization = measured performance / roof ceiling(I)

An operator left of the ridge is memory-bound, one right of it is compute-bound, and a value equal within the documented numerical tolerance is reported as ridge. A measurement above its configured roof is diagnostic evidence of mismatched units, precision, FLOP counting, sparsity conventions, or measurement scope—not a valid utilization winner.

Install and run

The current release is lyroofp 0.2.3 on PyPI and GitHub Releases. Install the distribution as lyroofp, then import and invoke it as roofp:

python -m pip install lyroofp==0.2.3
roofp --version
import roofp

print(roofp.__version__)

There is no public lyroofp command or import lyroofp package. lyroofp is only the package-index distribution name; the stable Python and command interfaces are roofp and roofp-mcp.

roofp-mcp is a long-running stdio MCP server command, not a one-shot health check. Configure or start it only when an MCP client will connect.

Development checkout:

uv sync --locked --all-groups
uv run --no-sync roofp --config examples/sample_config.json

CLI-only example:

uv run --no-sync roofp \
  --ideal-compute "1.2 TFLOP/s" \
  --ideal-bandwidth "800 GB/s" \
  --actual-compute "800 GFLOP/s" \
  --actual-bandwidth "500 GB/s" \
  --operator GEMM "650 GFLOP/s" "3.25 FLOP/Byte" \
  --output roofline.svg

The CLI writes exactly one JSON document to stdout. Human-readable artifact status goes to stderr, so shell tools can safely consume stdout:

uv run --no-sync roofp --config examples/sample_config.json > result.json

Analysis-only mode

--analysis-only skips plotting and atomically writes a JSON artifact. --silent remains an alias for compatibility:

uv run --no-sync roofp --analysis-only \
  --ideal-compute "1.2 TFLOP/s" \
  --ideal-bandwidth "800 GB/s" \
  --operator GEMM "650 GFLOP/s" "3.25 FLOP/Byte" \
  --output analysis.json

When a plot-oriented config selects roofline.svg, adding --analysis-only uses analysis.json unless the CLI explicitly provides another .json path. This prevents JSON from being written into an image-named file.

Supported units

Inputs may be normalized numbers, strings, or { "value": ..., "unit": ... } objects in JSON configuration.

Quantity Normalized unit Examples
Compute throughput FLOP/s 1e12, 1200 GFLOP/s, 1.2 TFLOP/s
Bandwidth Byte/s 8e11, 800 GB/s, 745 GiB/s
Arithmetic intensity FLOP/Byte 3.25, 3.25 FLOP/Byte, 650 GFLOP/s/200 GB/s

Prefixes are case-sensitive: M means mega. Ambiguous lowercase m is rejected. Uppercase B means bytes; bit-rate forms such as Gb/s and Gbps are rejected rather than silently interpreted as Byte/s. Bare FLOP is an operation count, not throughput, and is rejected; common throughput spellings such as GFLOPS remain supported.

JSON configuration

See the complete sample configuration.

{
  "title": "Example Roofline",
  "output": "roofline.svg",
  "plot": {
    "width": 1280,
    "height": 720,
    "show_bound_regions": true
  },
  "ideal": {
    "label": "FP32 theoretical roof",
    "compute": "1.2 TFLOP/s",
    "bandwidth": "800 GB/s",
    "precision": "FP32",
    "compute_kind": "theoretical",
    "bandwidth_level": "dram",
    "bandwidth_kind": "theoretical",
    "fma_flop_count": 2,
    "sparsity": "dense"
  },
  "actual": {
    "label": "FP32 measured roof",
    "compute": "800 GFLOP/s",
    "bandwidth": "500 GB/s",
    "precision": "FP32",
    "compute_kind": "measured",
    "bandwidth_level": "dram",
    "bandwidth_kind": "measured",
    "fma_flop_count": 2,
    "sparsity": "dense"
  },
  "operators": [
    {
      "name": "GEMM",
      "compute": "650 GFLOP/s",
      "arithmetic_intensity": "3.25 FLOP/Byte"
    }
  ]
}

The config schema is strict: misspelled or unknown fields fail early. ideal is required, actual is optional, and every roof must provide compute and bandwidth together. All numeric quantities must be finite and positive. When one or more --operator options are supplied, they replace the configured operator list rather than appending to it.

Analysis schema 2.0

All analysis results include "schema_version": "2.0". Dimensional names are explicit, including:

  • peak_compute_flop_per_second
  • bandwidth_byte_per_second
  • measured_performance_flop_per_second
  • achieved_bandwidth_byte_per_second
  • arithmetic_intensity_flop_per_byte
  • roof_ceiling_flop_per_second

Each operator contains an evaluations object with separate ideal, actual, and additional_N results. An evaluation includes bound, ridge_ratio, utilization_ratio, remaining_headroom_ratio, and above_roof. Version 0.2 intentionally removes ambiguous 0.1 aliases such as headroom_ratio and compute_flops.

MCP server

After installing from PyPI, start the MCP server directly:

roofp-mcp

The command intentionally remains running while it waits for or serves an MCP client; it does not print a version and exit.

For development, prepare the locked environment and disable implicit syncing when starting the long-running server:

uv sync --locked
uv run --no-sync roofp-mcp

For a PyPI installation, use roofp-mcp directly as the client's stdio command. For a repository checkout, use this configuration after the one-time sync:

{
  "mcpServers": {
    "roofp": {
      "command": "uv",
      "args": [
        "run",
        "--no-sync",
        "--directory",
        "/absolute/path/to/roofp",
        "roofp-mcp"
      ]
    }
  }
}

The server exposes structured inputs and structured outputs—do not JSON-encode lists inside strings.

analyze_performance

Use one roof and measured operators for diagnosis:

{
  "roof": {
    "label": "FP32 theoretical",
    "compute": "1.2 TFLOP/s",
    "bandwidth": "800 GB/s",
    "precision": "FP32"
  },
  "operators": [
    {
      "name": "GEMM",
      "compute": "650 GFLOP/s",
      "arithmetic_intensity": "650 GFLOP/s/200 GB/s"
    }
  ]
}

generate_roofline

Accepts a required ideal roof, optional actual roof, and optional operators. Set include_svg: true to include the SVG. It defaults to false so ordinary agent calls remain compact; SVG calls support at most 64 plotted points.

compare_rooflines

This tool accepts peer roofs and workloads. Theoretical comparison needs only arithmetic intensity. Put measured performance under the matching roof label when a per-hardware utilization comparison is actually available:

{
  "roofs": [
    {
      "label": "System A FP32",
      "compute": "1.2 TFLOP/s",
      "bandwidth": "800 GB/s",
      "precision": "FP32",
      "fma_flop_count": 2,
      "bandwidth_level": "dram"
    },
    {
      "label": "System B FP32",
      "compute": "1.6 TFLOP/s",
      "bandwidth": "600 GB/s",
      "precision": "FP32",
      "fma_flop_count": 2,
      "bandwidth_level": "dram"
    }
  ],
  "workloads": [
    {
      "name": "Kernel 1",
      "arithmetic_intensity": "2 FLOP/Byte",
      "measurements": [
        {"roof_label": "System A FP32", "compute": "700 GFLOP/s"},
        {"roof_label": "System B FP32", "compute": "850 GFLOP/s"}
      ]
    }
  ]
}

best_theoretical_hardware ranks capability. best_valid_utilization_hardware is emitted only from valid per-hardware measurements. Above-roof measurements are preserved in excluded_above_roof_measurements but cannot win. Metadata warnings flag mismatched or partially omitted precision, bandwidth level, FMA count, and sparsity conventions.

Release and integrity

Release v0.2.3 contains the same wheel and sdist published to PyPI, the standalone SKILL.md, and SHA256SUMS covering all three files:

Verify downloaded release files from the directory that contains them:

sha256sum -c SHA256SUMS

AI agent Skill

The repository SKILL.md describes the 0.2 MCP workflow. Install a version-pinned copy for Codex:

mkdir -p ~/.codex/skills/roofp
curl --fail --silent --show-error --location --proto '=https' \
  --output ~/.codex/skills/roofp/SKILL.md \
  https://raw.githubusercontent.com/luoyueyuguang/roofp/v0.2.3/SKILL.md

For another agent, place the same pinned file at that product's documented skill location. Review the downloaded instructions before enabling them. To verify only the Skill against the checksum attached to the same release:

curl --fail --silent --show-error --location --proto '=https' \
  --output SHA256SUMS \
  https://github.com/luoyueyuguang/roofp/releases/download/v0.2.3/SHA256SUMS
grep ' SKILL.md$' SHA256SUMS | sha256sum -c -

Tests and release checks

uv sync --locked --all-groups
uv run --no-sync python -W error -m unittest discover -s tests -v
uv run --no-sync ruff check .
uv run --no-sync ruff format --check .
uv run --no-sync mypy roofp
uv run --no-sync python tests/validate_skill.py .
uv run --no-sync coverage run -m unittest discover -s tests
uv run --no-sync coverage report
uv run --no-sync python -m compileall -q roofp tests
uv lock --check --offline
uv pip check
uv build
python tests/verify_distribution.py dist

CI covers Python 3.10–3.14, lowest direct dependencies, protocol behavior, wheel-only installation, linting, type checks, coverage, source distribution, and Skill validation.

License

MIT. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

lyroofp-0.2.3.tar.gz (944.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

lyroofp-0.2.3-py3-none-any.whl (23.8 kB view details)

Uploaded Python 3

File details

Details for the file lyroofp-0.2.3.tar.gz.

File metadata

  • Download URL: lyroofp-0.2.3.tar.gz
  • Upload date:
  • Size: 944.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.25 {"installer":{"name":"uv","version":"0.9.25","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for lyroofp-0.2.3.tar.gz
Algorithm Hash digest
SHA256 798e93f5cd8a6ad177343f467d4ab979b681bd8834c5813149cf848f4e1b1d6e
MD5 c20d44a49946972ff889d07ff9e2964b
BLAKE2b-256 3594f1a531f039cb9bbc74c1e70e7a1f5102a1092529a6b8f1c3f73dc6277856

See more details on using hashes here.

File details

Details for the file lyroofp-0.2.3-py3-none-any.whl.

File metadata

  • Download URL: lyroofp-0.2.3-py3-none-any.whl
  • Upload date:
  • Size: 23.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.25 {"installer":{"name":"uv","version":"0.9.25","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for lyroofp-0.2.3-py3-none-any.whl
Algorithm Hash digest
SHA256 5baf27206ff6918257781f0886fc275d39e803aa7833018d23cccd451a05b363
MD5 3ba63ae775877d8ee9d0a2b18450344a
BLAKE2b-256 4bacbe0ac890a961f6f3ff13e2d977fc0cc111f98691c084fc5cb64020d83bb8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page