---
title: "Slicing principles"
description: "Split a contraction by enumerating internal-index values to limit intermediate result sizes within each slice."
eyebrow: "Slicing"
---

## Splitting contraction into subtasks {#exact-decomposition}

After selecting internal indices, ArcTN enumerates every combination of their values. Each combination fixes the corresponding input axes, performs a contraction along the same SSA path, and contributes to an elementwise sum of all results. Slicing is an exact mathematical decomposition: it performs no low-rank truncation and omits no value combinations. With floating-point arithmetic, sliced summation and unsliced contraction may add values in different orders, so ordinary rounding differences are possible; bitwise equality is not promised.

### How slicing reduces intermediate tensors {#slicing-example}

Consider a three-tensor contraction:

$$
Y_{ace}=\sum_{b,d}A_{abc}B_{bcd}C_{de}.
$$

Let the dimensions of $a,b,c,d,e$ be 2, 3, 4, 5, and 6. Contracting $B,C$ first produces $Z_{bce}$ without slicing. Fixing $b=j$, each slice first computes $Z^{(j)}_{ce}=\sum_d B_{jcd}C_{de}$ and then contracts it with $A_{ajc}$.

```diagram
slicing-overview
```

$$
Y_{ace}=Y^{(0)}_{ace}+Y^{(1)}_{ace}+Y^{(2)}_{ace}.
$$

In the diagram, each slice has a 24-element intermediate and a 48-element partial output, so its largest tensor contains 48 elements. The complete 72-element $Z$ is shown only for comparison; sliced execution does not allocate it first. Fixed preserves the original contraction order, potentially at the cost of repeated computation and result accumulation. See the [Slicing example](/docs/tutorial-slicing).

### Slice count {#slice-count}

If the sliced indices have dimensions $d_1,\ldots,d_k$, the number of slices is

$$
N_{\mathrm{slice}}=\prod_{j=1}^{k}d_j.
$$

`SliceResult.log2_n_slices` stores the base-2 logarithm of the slice count. Index dimensions need not be 2.

## Intermediate-size limit {#target-size}

`target_size` controls intermediate tensor sizes after slicing. It is a positive integer measured in elements. Every binary contraction result within each slice must satisfy this limit; for a single-tensor network, the final output after unary processing is checked. It does not limit every temporary tensor created by unary preprocessing, nor is it a process-memory or GPU-memory cap.

| What target\_size constrains | What target\_size does not constrain |
| --- | --- |
| Largest binary contraction result per slice; final output for a single-tensor network | Process RSS or GPU memory |
| Binary contraction results computed for the specified path and sliced indices | Sum of elements in all simultaneously retained tensors |
| Logical element count | Bytes after accounting for dtype |
| An individual slice | Total resident memory of multiple concurrent slices |
| Result tensor $\lvert C\rvert$ | Per-step $\lvert A\rvert+\lvert B\rvert+\lvert C\rvert$ or backend temporary workspace |

`log2_max_contraction_size` reports the base-2 logarithm of the largest logical input-plus-output element count in a single step, counting original leaf tensors by their logical size after unary summation, trace, or diagonal operations. `log2_peak_size` reports the base-2 logarithm of peak live elements in the path model. Neither is another name for `target_size`.

A single-tensor network has an empty SSA path, but may still need traces, summation, or output-axis reordering. ArcTN checks the final output size after these unary operations. An excessively small `target_size` fails even when the path contains no binary contraction steps.

## Choosing sliced indices for a fixed path {#leg-selection}

`find_slices_to_size` keeps the path fixed, temporarily sets selected index dimensions to 1, and replays the path. If intermediate results still exceed the target, it first selects the index appearing in the most oversized results. Ties are broken by larger dimension, then by smaller ID.

```diagram
slicing-leg-selection
```

1. Sliced indices must exist in both the network and size\_dict, with positive dimensions.
2. Slicing output indices is currently unsupported; the final output shape remains unchanged.
3. The slice list must not contain duplicate indices.
4. An index repeated within one input tensor cannot be sliced; such indices involve trace or diagonal operations.
5. If no valid index can further reduce result sizes, the search reports that no feasible scheme was found.

If the final output already has more elements than `target_size`, slicing only internal indices cannot satisfy the limit.

```rust
use arctn::{find_slices_to_size, slice_result_fits_target_size};

let target_size = 1usize << 24;
let slices = find_slices_to_size(&net, &path, target_size)
    .ok_or("target_size is unreachable for this fixed path")?;
assert!(slice_result_fits_target_size(
    &net, &path, &slices, target_size
)?);
```

This is greedy selection on a fixed path, with no guarantee of the fewest sliced indices or lowest total FLOPs. Successful schemes pass the target check; search failure does not prove that every possible scheme is infeasible.

## Reading SliceResult {#result}

| Field | Meaning |
| --- | --- |
| legs | IDs of the internal indices actually selected |
| log2\_n\_slices | Base-2 logarithm of the total number of value combinations |
| per\_slice | PathStats computed with sliced-index dimensions set to 1 |
| log10\_flops\_total | Base-10 logarithm of total FLOPs, computed as per-slice FLOPs times slice count |

The largest intermediate is measured per slice and is not multiplied by the slice count. Total FLOPs and read/write volume must be multiplied by it. Evaluate a scheme using its path, sliced indices, slice count, largest per-slice result, total FLOPs, and actual execution time.

Save the path and SliceResult together. Slicing methods that allow path changes also return the corresponding final path. After changing a path, recheck that the slicing scheme satisfies the size limit.
