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 package is published under the distribution name lyroofp. The stable Python import and command names remain roofp:

python -m pip install lyroofp
roofp --version

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

For development, start the locked environment explicitly:

uv run --locked roofp-mcp

For a long-running client integration, sync once and disable startup syncing:

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

Example client 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.

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.0/SKILL.md

For another agent, place the same pinned file at that product's documented skill location. Review the downloaded instructions before enabling them. When release checksums are published, verify the file against the checksum in the same tagged release; this README deliberately does not invent a checksum before release publication.

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 mypy roofp
uv run --no-sync coverage run -m unittest discover -s tests
uv run --no-sync coverage report
uv build

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.1.tar.gz (939.2 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.1-py3-none-any.whl (23.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: lyroofp-0.2.1.tar.gz
  • Upload date:
  • Size: 939.2 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.1.tar.gz
Algorithm Hash digest
SHA256 ecd5488221712310d0d1b6322b055518fcba21b037da85df5d2d6c688595b607
MD5 874cc44cd1e1c21a3847f20f2311fb21
BLAKE2b-256 c8679eff39abab341f7c57d0ea3fa768ef536ee1874e24353f520cc97d3e5f40

See more details on using hashes here.

File details

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

File metadata

  • Download URL: lyroofp-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 23.2 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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 a487b2ae8549de228d089bb0b38529a1ef8d1e753615bc79e80e6f19d049bc70
MD5 7912c4a50ea237791810c905acd9e22f
BLAKE2b-256 f1693fdf52e8c9a4582362308d17c9f1a31cb80699cafd1b63fef66fa9e573a0

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