Computing and summing slices
Enumerating slice values, executing in parallel, and combining results, including the effect of slicing on total work and memory.
On this page
Compute each slice, then add the results
Array computation starts only after the path and sliced indices are determined. Each combination of index values defines a subtask: extract the corresponding input data and follow the planned contraction path to produce a slice result. After all slices finish, add their results elementwise to obtain the contraction of the original network.
For example, slicing an internal index of dimension 2 produces two results, and , with final result . This executes the slicing scheme; it does not search for another path.
0→(0,0)1→(0,1)2→(0,2)3→(1,0)4→(1,1)5→(1,2)Group 0 · [0,2)T₀ + T₁Group 1 · [2,4)T₂ + T₃Group 2 · [4,6)T₄ + T₅partial₀ + partial₁ + partial₂Combine partial sums in group-ID orderuse arctn::contract_network_sliced;
let output = contract_network_sliced(
&net, &tensors, &ssa_path, &sliced_legs
)?;
Parallel computation and result summation
The native executor divides consecutively numbered slices into chunks. Each chunk accumulates in slice-ID order, and Rayon processes different chunks in parallel. Partial sums are then merged in chunk-ID order. Chunking depends only on the slice count and output element count, not the thread count.
| Item | Behavior |
|---|---|
| Maximum chunk count | At most 256, further limited by the partial-output element budget |
| Changing thread count | Changes when chunks finish, but not their grouping or final merge order |
| No sliced indices | Calls contract_network directly |
| Concurrent memory | Each simultaneously executing slice has its own input copies and intermediates |
The thread-count-independent merge order stabilizes single-machine floating-point results. It does not imply that MPI Allreduce is bitwise identical across different rank counts.
Total work and memory
For slices, the binary contraction work across all slices is
Slicing may reduce the largest per-slice result while increasing total FLOPs through repeated computation. The model excludes extra additions in the final cross-slice summation.
| Usually decreases with more slicing | Usually increases with more slicing |
|---|---|
| Largest per-slice intermediate | Number of slices in a complete execution |
| Path-model memory per subtask | Total FLOPs and input reads |
target_size limits only per-slice binary contraction results; for single-tensor networks it checks the final output. Original inputs, unary preprocessing, transpose temporaries, backend workspace, partial sums, and other concurrently executing slices all increase actual RSS. Execution parallelism must also be considered when controlling total memory.
Three execution routes
| Route | Slice scheduling | Per-slice contraction | Result accumulation |
|---|---|---|---|
| Rust / Python native | Fixed chunks in Rust, parallelized with Rayon | ArcTN Rust CPU executor | Accumulation in ID order both within and between chunks |
| Python external backend | Serial enumeration in a fixed order in Python | Reuses one opt_einsum.contract_expression |
Addition on the selected array backend |
| tnmpi | Each process executes a different contiguous slice range | ArcTN Rust CPU executor; --dtype supports four real / complex types; see MPI execution |
MPI Allreduce |
All three routes use the same mathematical decomposition, but scheduling, synchronization, and floating-point reduction order differ. State the execution route when reporting performance.