---
title: "Fixed and dynamic slicing"
description: "Fixed preserves the contraction path; Dynamic attempts local path changes while selecting sliced indices."
eyebrow: "Slicing"
---

## Fixed-path slicing (Fixed) {#public-values}

Fixed keeps the contraction order already found and selects only which internal indices to slice. Its purpose is to reduce intermediate tensor sizes at each contraction, without searching for a new path.

For example, slicing an internal index $x$ of dimension 2 creates subtasks for $x=0$ and $x=1$, whose results are added. Both subtasks use the same contraction order.

```pseudocode
path = path obtained by contraction-order optimization
sliced_indices = select slicing indices on path to meet the intermediate-size limit
return path, sliced_indices
```

## Dynamic slicing (Dynamic) {#mode-semantics}

Dynamic starts from the path found by unsliced search. After choosing sliced indices, it attempts local reconfiguration of the contraction order, then selects sliced indices again. It considers the path and slices together instead of keeping one path fixed.

```pseudocode
path = path obtained by contraction-order optimization
Select slicing indices and check intermediate result sizes
Within the specified search range:
    Try a local path reconfiguration and reselect slicing indices
    Keep the better plan by size limit and total objective after slicing
return the final path and slicing indices
```

Dynamic adds search work. The final path may change or remain the same, and it is not guaranteed to require less computation than Fixed.

“Dynamic” refers to the planning stage, where the path and sliced indices can change together. Once planning finishes, every slice uses the returned final path for numerical computation. Compare Fixed and Dynamic using the sliced indices, slice count, and total objective across all slices.

```diagram
slicing-modes
Fixed preserves the contraction tree; Dynamic can change it. Both illustrations use the same sliced indices to show only the structural difference; the indices selected in practice may also differ.
```

## Setting an intermediate-size limit {#shared-start}

`target_size` specifies **the maximum number of elements in any single binary contraction result within each slice**. For example, with `target_size=65_536`, a $256\times256$ result tensor satisfies the limit, while a $512\times512$ result exceeds it.

It limits the size of one result tensor, not the total memory occupied by all tensors, process memory, or GPU memory. See [Intermediate-size limit](/docs/slicing#target-size) for the full definition.

In the high-level Python interface, `slicing_mode="fixed"` is the default. Without `target_size`, contraction uses an ordinary path and no additional slices are selected. `slicing_mode="dynamic"` requires `target_size`. If the original path already satisfies the size limit, Fixed may return an empty slice list.

## Slicing plans and numerical computation {#execution}

Selecting a slicing scheme determines only the contraction path and sliced indices; it does not compute tensor values. `arctn_schedule` returns the scheme and report. Given arrays, `arctn_contract` selects the scheme, contracts each slice, and performs the final summation.

See the [Slicing example](/docs/tutorial-slicing) for both call styles, and [Computing and summing slices](/docs/slicing-execution) for how individual slices are computed and added.

## Size checks and failures {#hard-constraint}

ArcTN checks the size limit using integer arithmetic on the final path and sliced indices. If no scheme satisfying `target_size` is found, Rust returns `Err` and the high-level Python interface raises `ValueError`. An oversized scheme is never returned as a successful result.

`max_time` controls time checks during ordinary path search. It does not guarantee that the whole task, including slicing and numerical computation, finishes within that time. Regardless of when search stops, the final scheme must pass the size check.
