For AI Agents
Use this page if you are an AI coding assistant (or building one) that needs to generate flopscope code correctly.
You will learn:
- How to orient yourself with llms.txt, ops.json, per-op JSON, and the cheat sheet
- The five rules for generating correct flopscope code
- How to avoid common mistakes AI agents make with flopscope
This page is for AI coding assistants (Claude, Cursor, Copilot, etc.) helping users write flopscope code. It explains what resources are available, how to access them, and the key things you must know before generating code.
Quick orientation
flopscope is NOT NumPy. It wraps a subset of NumPy with analytical FLOP counting. Every arithmetic operation is charged against a budget. Code that works with NumPy may fail or behave differently with flopscope:
- All counted operations require an active
BudgetContext - 35 operations are blocked entirely (I/O, config, state)
sort,argsort,trace,random.*sampling ops are now counted (not free)- Costs are analytical (from tensor shapes), not measured at runtime
Machine-readable resources
| Resource | Format | Use case |
|---|---|---|
| llms.txt | Markdown | Start here. Curated index of all doc pages with one-line descriptions. Under 4K tokens. |
| llms-full.txt | Markdown | Complete docs in one file. Use if your context window is large enough (~115KB). |
| ops.json | JSON | Slim machine-readable index of all 508 operations. Query programmatically for names, filters, and detail URLs. |
/api-data/ops/<slug>.json | JSON | Full standalone payload for one operation, including summary, signature, notes, and structured doc sections. |
| API Reference | Markdown | Dense reference of every operation's cost and full operation inventory. |
How to use llms.txt
If you're an agent encountering flopscope for the first time:
- Fetch
llms.txt— this gives you the doc map in ~300 words - Identify which page answers your question from the section descriptions
- Fetch that specific page
URL patterns: llms.txt links to .md variants of each page (raw
markdown for agents). Every page is also available as rendered HTML — just
drop the trailing /index.md from the URL:
| Agent URL (raw markdown) | Human URL (rendered HTML) |
|---|---|
.../getting-started/installation/index.md | .../getting-started/installation/ |
.../guides/einsum/index.md | .../guides/einsum/ |
.../api/index.md | .../api/ |
If you have a large context window, fetch llms-full.txt instead to get
everything in one request.
How to use ops.json
ops.json contains a JSON object with an operations array. Each entry is a
slim index row with the information needed to search, filter, and find the full
payload for one operation:
{
"name": "einsum",
"slug": "einsum",
"detail_href": "/docs/api/einsum/",
"detail_json_href": "/api-data/ops/einsum.json",
"module": "numpy",
"flopscope_ref": "fnp.einsum",
"numpy_ref": "np.einsum",
"category": "counted_custom",
"cost_formula": "product of all index dims (FMA=1)",
"cost_formula_latex": "$\\prod_i d_i$",
"free": false,
"blocked": false,
"status": "supported",
"summary": "Evaluate Einstein summation with FLOP counting and optional path optimization.",
"notes": "Supports SymmetricTensor inputs and repeated-operand detection for automatic cost reduction"
}Use this to:
- Check if an operation is supported: filter by
"blocked": false - Get the cost formula for a specific operation: look up by
name - List all free operations: filter by
"free": true - Map between NumPy and flopscope calls: use
numpy_refandflopscope_ref - Jump to the standalone page or full payload: use
detail_hrefanddetail_json_href
How to use per-op JSON
Each operation also has a full standalone JSON payload at:
/api-data/ops/<slug>.jsonFor example:
/api-data/ops/einsum.jsonThese payloads include:
- top-level metadata (
slug,detail_href,detail_json_href) - source links (
source.flopscope,source.numpy) - operation metadata (
op.*) - normalized doc sections under
docs.sections[]
Fetch the per-op JSON when you need the full signature, summary, notes, parameter list, returns, or examples for a single function without loading the entire reference surface.
Five rules for generating flopscope code
1. A global default budget is active automatically — use BudgetContext for control.
A global default budget auto-activates when flopscope is imported, so quick
scripts work without any setup. For precise budget control and namespacing,
use an explicit BudgetContext. Both forms are valid:
import flopscope as flops
import flopscope.numpy as fnp
# Quick work — global default handles budget tracking automatically
result = fnp.einsum('ij,jk->ik', A, B)
# Recommended for budget control and namespacing
with flops.BudgetContext(flop_budget=10**8) as budget:
result = fnp.einsum('ij,jk->ik', A, B)
# Decorator form for functions
@flops.BudgetContext(flop_budget=10**8)
def my_forward_pass(x):
return fnp.einsum('ij,j->i', W, x)2. Know what's free and what's counted.
Free (0 FLOPs): zeros, ones, reshape, transpose, copy,
random.seed, random.get_state, random.set_state, random.default_rng.
Custom cost (numel FLOPs): array, linspace, arange, concatenate, where.
These are NOT free — each charges numel(output) FLOPs against the budget.
Counted: einsum, dot, matmul, exp, log, add, multiply, sum,
mean, all linalg.*, all fft.*, sort, argsort, trace,
unique, set ops (in1d, isin, etc.), histogram, random.* sampling.
Blocked: save, load, geterr, seterr, and 28 others. These raise
AttributeError.
When in doubt, check ops.json, the relevant /api-data/ops/<slug>.json, or the API Reference.
3. Use flops.accounting.* to estimate costs before running.
cost = flops.accounting.einsum_cost('ij,jk->ik', shapes=[(256, 256), (256, 256)])
cost = flops.accounting.svd_cost(m=256, n=256, k=10)These are pure functions — no BudgetContext needed.
4. Use fnp.einsum as the primary computation primitive.
Most linear algebra can be expressed as einsum. The cost is simply the
product of all index dimensions — each FMA (fused multiply-add) counts
as 1 operation.
'ij,jk->ik' with shapes (m, k) and (k, n) costs m * k * n FLOPs.
5. Use wall_time_limit_s for time-limited execution.
In competition evaluation, submissions run under both a FLOP budget and a wall-clock time limit. Test locally with:
with flops.BudgetContext(flop_budget=10**9, wall_time_limit_s=5.0) as budget:
# your code — must complete within 5 seconds
...If the time limit is exceeded, TimeExhaustedError is raised at the next
operation boundary. The error includes the operation name, elapsed time, and
configured limit for diagnostics.
6. Exploit symmetry for cost savings.
- Use
symmetric_axesfor symmetric outputs:fnp.einsum('ki,kj->ij', X, X, symmetric_axes=[(0, 1)]) - Wrap known-symmetric matrices with
flops.as_symmetric(data, symmetric_axes=(0, 1))for automatic savings in downstream ops
Common mistakes agents make
| Mistake | What happens | Fix |
|---|---|---|
Using np.einsum instead of fnp.einsum | FLOPs not counted, budget not checked | Always use fnp.* for counted NumPy-like operations |
Skipping BudgetContext entirely | No error (global default handles it), but budget is harder to track and namespace | Use an explicit BudgetContext for any work you want to measure or label |
Assuming array, linspace, concatenate, where are free | Underestimates budget usage — each charges numel(output) FLOPs | These are custom-cost ops, not free; check the cheat sheet |
Assuming sort is free | Underestimates budget usage | sort costs n*ceil(log2(n)) per slice — check the cheat sheet |
Using fnp.save() or fnp.load() | AttributeError — blocked | Use numpy directly for I/O |
Nesting two explicit BudgetContext blocks | RuntimeError | Use a single explicit context; nesting with the global default is fine |
Ignoring wall_time_limit_s in testing | TimeExhaustedError in competition | Test with a time limit locally to catch slow code early |
Related pages
- API Reference — full operation inventory and cost reference
- Exploit Symmetry — detailed symmetry guide