ParetoStackpareto-stackdocshpc-labs

Glossary

The words this documentation uses, in plain language. Each entry says what the thing is and, where it helps, how ParetoStack treats it. Terms are grouped; use the search box to jump to one.

Correctness: the contract

Contract. The rule a changed program's output must meet before its speed-up counts. The default contract is identical output, byte for byte. Where small differences are expected (rounding, fixed-point arithmetic, an FFT), the contract is a tolerance you declare: a numeric error, PSNR or SSIM for images, or a task metric. A change that does not meet its contract is rejected, whatever its speed. The contract is the reason a speed-up can be trusted.

Bit-exact (byte-identical). The changed program writes exactly the same bytes as the original on the same input. This is the default. A change that is only a reordering of work, or a faster way to get the same integers or the same floating-point results, can be bit-exact.

Tolerance. A difference you accept and write down: for example "the numbers may differ by up to 1e-9" or "the image must have a PSNR of at least 50 dB". A tolerance is only used when you declare it; nothing is loosened silently. Changes that alter numerics (L3, below) need one.

ULP (unit in the last place). The gap between two neighbouring floating-point numbers. "Within 2 ULP" means the result differs from the reference by at most two of those smallest steps: a way to say "almost exactly the same" that does not depend on the size of the numbers.

PSNR (peak signal-to-noise ratio). A score in decibels for how close an image is to a reference. Higher is closer; identical images have no finite PSNR. Used as a contract for image programs.

SSIM (structural similarity). A score from 0 to 1 for how similar two images look in structure (edges, contrast), where 1 means identical. Used as a contract for image programs, often together with PSNR.

Task metric. A measure of what the program is for, such as classification accuracy or a detection score, used as the contract when exact output is not the point.

Differential testing. Running the original and the changed program on the same inputs and comparing what they produce. ParetoStack does this for every candidate before it believes a timing.

Verifier. The part that applies the contract. Nothing is believed before it passes.

Guarded change / fallback. A change that checks at run time that the conditions it relies on hold, and otherwise runs the original code path.

Measuring speed

Speed-up. The original's time divided by the changed program's time, both measured on the same machine, with alternating runs. 2x means the work takes half the time; 1.0x means no change; below 1.0x is slower.

Alternating runs. The original and the candidate are timed one after the other, repeatedly, so that a slow moment on the machine hits both and does not favour one.

Median. The middle timing. ParetoStack reports medians of repeated runs, which a single slow outlier cannot move.

Noise, "noisy machine". Timings vary because other programs use the processor. When the machine is noisy, ParetoStack runs more pairs and reports a conservative estimate, and says so.

Statistically significant; p-value; Mann-Whitney test. A speed-up counts only when it is unlikely to be chance. The Mann-Whitney U test compares two sets of timings by rank, without assuming a bell-shaped spread; the p-value is the probability of seeing such a difference by chance if the two programs were really equally fast. A small p-value (the gate is stated in the reports) means the difference is real.

Hotspot; profile. The few places where a program spends most of its time. A profile is the measurement that finds them. Optimizing anything else cannot make the whole program much faster.

Pareto front. When there are several goals (speed, memory, accuracy), the set of results where no other result is better on every goal. Not a single winner, but the best trade-offs to choose from.

Candidate; change set. A candidate is one proposed change, built and measured against the original. A change set is the group of candidates that passed, saved as a patch with a backup so your original files are never changed unless you apply it.

Build and compiler settings (L0)

L0: build and runtime settings. The levels of change are ordered from lowest risk. L0 changes how the program is compiled, linked and run (flags, link-time optimization, profile-guided optimization, interpreter or runtime settings) and changes no source code.

Optimization level (-O0, -O1, -O2, -O3, -Os). How hard the compiler works to make code fast or small. -O2 is the usual default; -O3 enables more aggressive transformations (more inlining, vectorization); -Os favours size. Higher is not always faster.

PGO (profile-guided optimization). A two-step build. First the program is built with counters and run on a representative workload, which records which branches and functions are really hot. Then it is rebuilt using that record, so the compiler can lay out code, inline and predict branches according to real behaviour rather than guesses. Gains are usually modest (a few percent to tens of percent), depend on the workload being typical, and ParetoStack measures it like any other candidate. It normally keeps results bit-exact.

LTO (link-time optimization). Normally the compiler optimizes each source file separately. With LTO it keeps an intermediate form and optimizes the whole program when linking, so it can inline functions across files and remove code that is never used. It costs longer builds and more memory, and usually keeps results bit-exact.

CPU target (-march=native, x86_64-v3, aarch64). Which processor features the compiler may use. "native" means this machine's CPU; a named level such as x86_64-v3 means a family of CPUs that all share certain vector instructions. A program built for a newer target can run faster but fails on older CPUs, so ParetoStack names the target and refuses one the machine cannot run.

Fast-math (-ffast-math). A compiler setting that lets it reorder floating-point arithmetic and drop some safety rules. It can be faster, but the results may differ in the last digits, so it is never bit-exact: it is only allowed under a tolerance you declare.

Inlining. Replacing a function call with the function's body, which removes call overhead and lets the compiler optimize across the boundary.

Loop unrolling. Repeating a loop body several times per pass to cut loop overhead and expose more work to run in parallel.

SIMD, vectorization (AVX, AVX-512, NEON, SVE). SIMD ("single instruction, multiple data") processors apply one instruction to several values at once. AVX and AVX-512 are the x86 versions; NEON and SVE are Arm's. Vectorization is rewriting or compiling a loop to use them. The compiler can do it automatically for simple loops; in Python, NumPy does it for you.

Cache; tiling (blocking). A processor keeps recently used data in small, fast caches. Tiling processes data in cache-sized blocks so it is reused before it is evicted, which can speed up large loops and matrix work a great deal.

Code-level changes (L1, LIB, L2, L3)

L1: loops and vectors. Changes inside functions and loops: loop restructuring, vectorized code, replacing a Python loop with an array operation, cheaper repeated calls. Usually bit-exact.

LIB: library replacement (Library Scout). Replacing a hand-written routine with a tuned, well-tested library: for example a matrix product with BLAS, an image operation with OpenCV, a transform with FFTW. The replacement is verified against your outputs like any change.

BLAS (Basic Linear Algebra Subprograms). The standard interface for vector and matrix operations; OpenBLAS, MKL and Apple's Accelerate are fast implementations. NumPy uses one for matrix products.

L2: data layout and memory. Changes to how data is arranged: for example an array of structures (each record holds all its fields together) versus a structure of arrays (each field in its own array), or transposing data so the loop reads memory in order (unit stride). The same numbers are computed, but the processor reads memory far more efficiently.

L3: algorithmic changes. A different way to compute the same thing, which may change the numbers slightly: an FFT instead of a direct convolution, a separable filter instead of a full 2-D filter, an integral image instead of repeated window sums, fixed-point instead of floating-point arithmetic. Because it can change the numerics, L3 is only used under a tolerance you declare.

FFT (fast Fourier transform). An efficient way to move between a signal and its frequencies. Convolution becomes a cheap multiplication in that domain.

Separable filter. A 2-D filter that can be applied as two 1-D passes (rows, then columns) with the same result in far fewer operations.

Integral image (summed-area table). A table that lets the sum over any rectangle of an image be read with four lookups, so box filters and window statistics cost the same for any window size.

Fixed-point arithmetic. Integers scaled by a fixed factor in place of floating-point numbers. Often faster on small processors, with rounding that differs from floating-point, so it needs a tolerance.

Threads, OpenMP, the GIL. Threads run work in parallel on several cores; OpenMP is a common way to ask for that in C and C++. Python's GIL (global interpreter lock) lets only one thread run Python code at a time, so parallel Python usually needs processes or libraries that release the lock.

Cloud functions

AWS Lambda; Google Cloud Functions. Serverless functions: you upload code, the provider runs it on demand and bills by use. ParetoStack's cloud commands measure and tune them.

Memory size. In Lambda, the memory setting also sets the share of CPU, and the price per millisecond rises with it. A larger setting can make a function faster and sometimes cheaper, because it runs for less time. Measuring is the only way to know.

Right-sizing. Choosing the memory (and architecture) setting with the best cost and speed for a function, from measurements rather than guesses.

Cold start; warm. The first call after a pause includes starting the runtime (a cold start); later calls reuse it (warm). They are measured separately.

p50, p95. The median latency (half of calls are faster) and the 95th percentile (95% of calls are faster): the second shows the slow tail.

arm64 (Graviton) and x86_64. The two processor architectures Lambda offers. arm64 on AWS Graviton is often cheaper per call; a function must run correctly on it, which ParetoStack checks.

Throwaway copy; cost ceiling; the sandbox flag. Live cloud tests run on temporary copies of your function, never on the real one, and they are deleted afterwards. A cost ceiling stops a test before it spends more than you set. The --sandbox flag is your statement that the account or project is meant for testing.

ParetoStack itself

Sandbox. A restricted environment for running a program you have approved: in ParetoStack's sandbox (rootless Podman, where a recipe asks for it) the program has no network, a read-only view of the code, and one writable output folder. A run that asks for the sandbox is never run without it.

Local model (Ollama). An AI model that runs on your own machine, through a program called Ollama, instead of a cloud service. Nothing is sent over the network when the assistant uses it, so no code leaves the machine. ParetoStack picks a model sized for your computer's memory. It is optional: the optimizers, the verifier and the timing never need an AI model.

Offline mode. A switch in the assistant (/offline on, or paretostack models offline on to keep it for later sessions) that restricts it to the local model. Switching it on first checks that Ollama and a suitable model are installed, looks for a newer model or Ollama release when the network is reachable (and says so when it is not), offers to download or re-download, and always asks first. Only then does it turn the cloud models off for the session, so no code excerpt is sent anywhere. /offline off restores the previous choice. If no usable local model is installed and you decline the download, offline mode stays off and tells you why.

Strategy Memory. A local record of which kinds of change worked on which kinds of code on which machine, used to rank what to try first. It stores strategy names and numbers, never your code.

Versions and levels (V1 to V11, L0 to L3). Engine versions add capabilities (for example V10 adds GPU offload and V11 adds cloud optimization); levels classify a change by how deep it goes and how much risk it carries, from L0 (settings only) to L3 (algorithmic).