whestbench.
Reference

Code Patterns

Quick reference for flopscope operations, including operators, FLOP costs, and common patterns for mean and variance propagation.

Quick reference for flopscope operations. All examples assume import flopscope as flops and import flopscope.numpy as fnp.

Operators are tracked

Python arithmetic operators (+, -, *, /, @) on fnp.ndarray values are FLOP-tracked — you do not need to use the verbose fnp.add, fnp.multiply, etc. forms.

import flopscope as flops
import flopscope.numpy as fnp

a = fnp.ones(4)
b = fnp.ones(4)

# These are all equivalent and all tracked:
c = a + b           # tracked: same as fnp.add(a, b)
d = a * b           # tracked: same as fnp.multiply(a, b)
e = a / b           # tracked: same as fnp.divide(a, b)

W = fnp.eye(4)
v = fnp.ones(4)
f = W @ v           # tracked: same as fnp.matmul(W, v)
g = W.T @ v         # tracked: transpose is free, matmul is tracked
h = W.T @ W @ v     # tracked: two matmuls, chained with @

Use operators whenever they improve readability. The verbose fnp.* forms are still available but are no longer required for tracking purposes.

Operation costs

What you wantCodeFLOP costNotes
Create zerosfnp.zeros((n, n))0Free
Create onesfnp.ones(n)0Free
Identity matrixfnp.eye(n)0Free
Wrap existing datafnp.array(data)0Free
Matrix multiplyfnp.matmul(A, B)O(m x n x k)Dominates budgets
Element-wise addfnp.add(a, b)1 per element
Element-wise multiplyfnp.multiply(a, b)1 per element
Element-wise dividefnp.divide(a, b)1 per element
ReLUfnp.maximum(x, 0.0)1 per element
Square rootfnp.sqrt(x)1 per element
Exponentialfnp.exp(x)1 per element
Logarithmfnp.log(x)1 per element
Transposefnp.transpose(W)0Free
Reshapefnp.reshape(x, shape)0Free
Extract diagonalfnp.diag(M)0Free
Set diagonalfnp.fill_diagonal(M, v)0Free, in-place
Outer productfnp.outer(a, b)n x m
Sumfnp.sum(x, axis=0)input size
Meanfnp.mean(x, axis=0)input size
Maxfnp.max(x)input size
Stack arraysfnp.stack(rows, axis=0)0Free
Concatenatefnp.concatenate([a, b])0Free
Index/slicex[0], x[:, 3]0Free

Common patterns

Standard normal PDF and CDF (built-in)

flopscope provides built-in PDF and CDF functions that are FLOP-tracked:

import flopscope as flops
import flopscope.numpy as fnp

phi = flops.stats.norm.pdf(x)   # standard normal PDF
Phi = flops.stats.norm.cdf(x)   # standard normal CDF

These are the recommended approach — all example estimators use them. The manual implementations below are shown for reference.

Standard normal PDF (for ReLU expectation)

import flopscope as flops
import flopscope.numpy as fnp

def norm_pdf(x):
    """phi(x) = exp(-x^2/2) / sqrt(2*pi)"""
    return fnp.exp(-0.5 * x * x) / fnp.sqrt(2.0 * fnp.pi)

Standard normal CDF

Pure flopscope implementation using the Abramowitz & Stegun approximation (accurate to <7.5e-8):

import flopscope as flops
import flopscope.numpy as fnp

_P = 0.2316419
_A1, _A2, _A3 = 0.319381530, -0.356563782, 1.781477937
_A4, _A5 = -1.821255978, 1.330274429

def norm_cdf(x):
    t = 1.0 / (1.0 + _P * fnp.abs(x))
    poly = ((((_A5 * t + _A4) * t + _A3) * t + _A2) * t + _A1) * t
    pdf = fnp.exp(-0.5 * x * x) / fnp.sqrt(2.0 * fnp.pi)
    cdf = 1.0 - pdf * poly
    return fnp.where(x >= 0, cdf, 1.0 - cdf)

Alternatively, if you add scipy to your requirements.txt:

# Optional: requires scipy as a user-provided dependency
from scipy.special import ndtr

def norm_cdf(x):
    return fnp.array(ndtr(fnp.asarray(x, dtype=fnp.float64)).astype(fnp.float32))

ReLU expectation (E[max(0, z)] where z ~ N(mu, sigma^2))

import flopscope as flops
import flopscope.numpy as fnp

alpha = mu_pre / sigma_pre
E_relu = mu_pre * norm_cdf(alpha) + sigma_pre * norm_pdf(alpha)

See 02_mean_propagation.py (in the starter kit) for a complete worked example using these patterns.

Per-neuron variance propagation (diagonal)

import flopscope as flops
import flopscope.numpy as fnp

# var_pre[i] = sum_j W[j,i]^2 * var[j]
var_pre = (w * w).T @ var

Next step

On this page