Operations reference
Input rules, output convention, and graph-capture notes for torchmatch.assignment ops.
Signatures, parameter types, and per-op descriptions are auto-generated from the source and browseable in the API reference →.
This page covers cross-cutting rules that apply to every op.
Namespace
Every op binds under two equivalent names:
torchmatch.assignment.ops.<op>: the Python attribute binding (autocomplete-friendly, importable viafrom torchmatch.assignment.ops import <op>).torch.ops.assignment.<op>: the PyTorch op-namespace form (use insidetorch.compileregions or for dynamic dispatch by name).
Both names point to the same callable: torchmatch.assignment.ops.jonker_dense is torch.ops.assignment.jonker_dense returns True.
Outputs are int64 row→col tensors with -1 for unmatched rows.
Input semantics
These rules hold for every op under torch.ops.assignment.*, both
through torchmatch.assignment.solve and through direct op calls:
+infis a forbidden edge (a row-column pair that must not be assigned). The op rewrites it internally to a large finite sentinel(max_finite + 1) * (K + 1)whereK = max(rows, cols). The caller does not need to sanitise the tensor first.NaNis rejected with aRuntimeError. NaN signals an upstream bug (zero-norm cosine, singular Kalman covariance, log of zero); it is never a valid forbidden-edge marker.-infis rejected with aRuntimeError. An unboundedly cheap edge would force the solver into an infinite loop, and-infhas no meaningful "must-not-assign" interpretation either.
torchmatch.assignment.solve raises ValueError for the same NaN / -inf
conditions before reaching a backend; direct op calls raise the same
class of error from the C++ entry point.
Output convention
For every op:
- Output dtype is
int64("long"). - Single-problem ops return shape
(N,).out[i] = jmeans rowimatches columnj.out[i] = -1means rowiis unmatched. - Batched ops return shape
(B, N)with the same per-row semantics. - Matches into padded columns (from rectangular inputs in the JV ops)
map to
-1.
Tracing & graph capture
Every op registers a FakeTensor kernel (a shape-only stub used by torch.compile to trace the op without running real computation):
- The CUDA primed-zeros Hungarian ops —
munkres,hybrid, andlawler— arecudagraph_unsafe. They perform host-sidecudaStreamSynchronizecalls to read managed-memory iteration flags; undertorch.compile(mode="reduce-overhead")they trigger a graph break. jonker_dense_batch(CUDA backend) is fully capturable.- The CPU ops carry no graph constraints; they do not participate in CUDA-graph capture.
Pure-Python functions
Two functions live outside torch.ops.assignment.* and are called directly
from torchmatch.assignment:
auction_assignment
Bertsekas' synchronous auction algorithm — an iterative, pure-Python solver
that works on CPU and CUDA without the compiled extension. Unlike the ops
above, it returns a triple (matches, unmatched_rows, unmatched_cols)
rather than a row→col tensor, and is not wired into solve.
torchmatch.assignment.auction_assignment(
cost_matrix: Tensor, # (N, M) float; +inf = forbidden; NaN/-inf rejected
bid_size: float, # bid step; epsilon = min(bid_size / min(N,M), 1e-3)
max_iters: int = 100_000,
) -> tuple[Tensor, Tensor, Tensor]
# (K,2) matches, (N-K,) unmatched_rows, (M-K,) unmatched_cols
Integer and low-precision (float16, bfloat16) inputs are cast to float32
automatically. Raises RuntimeError if convergence is not reached within
max_iters iterations.
assignment_cost
Computes the total cost of a LAP solution. Accepts the output of solve or
the row→col column from auction_assignment's matches tensor.
torchmatch.assignment.assignment_cost(
cost: Tensor, # (N, M) or (B, N, M), float32/float64
matches: Tensor, # (N,) or (B, N), int64; -1 = unmatched
*,
reduction: str = "sum", # "sum" | "mean" | "none"
) -> Tensor # scalar / (B,) / (N,) / (B,N) depending on ndim and reduction
Unmatched rows (-1) contribute 0 to the result regardless of reduction.
See also
- Algorithms: why the two families exist.
- Benchmarks: per-op latency across cost distributions, with use-case recommendations.
Algorithms
The linear assignment problem, the Hungarian primal-dual method, and the three implementations torchmatch ships (Munkres, Lawler, Jonker-Volgenant).
Choosing
A decision tree drawn from the 540-case benchmark sweep, with rules of thumb by problem size, cost distribution, and tracing requirement.