---
title: "Rust API"
description: "Look up interfaces for automatic path optimization, path generation, tree search, network simplification, slicing, and file I/O."
eyebrow: "API reference"
---

## Automatic path optimization {#facade}

Before calling Light / Heavy from Rust, set `ARCTN_ENGINE_LIBRARY` to a compatible compiled library; see [Installation configuration](/docs/installation#engine). The standalone algorithms and numerical execution functions below do not depend on this library.

| Type / function | Purpose |
| --- | --- |
| AutoPreset::{Light, Heavy} | Search preset; defaults to Heavy |
| SlicingMode::{Fixed, Dynamic} | The two public slicing modes |
| auto\_path\_preset | Default objective, without slicing |
| auto\_path\_preset\_with\_objective | Explicit PlannerObjective |
| auto\_path\_preset\_to\_size | Fixed-path slicing |
| auto\_path\_preset\_to\_size\_with\_mode | Specify Fixed or Dynamic |
| auto\_path\_preset\_to\_size\_with\_objective | Fixed-path slicing with an explicit objective |
| auto\_path\_preset\_to\_size\_with\_mode\_and\_objective | Specify slicing mode, objective, and rate\_enabled |

```rust
use arctn::{
    auto_path_preset_with_objective, AutoPreset,
    PlannerObjective, TensorNetwork,
};

let objective = PlannerObjective::new(1.0, 64.0)?;
let plan = auto_path_preset_with_objective(
    &net, AutoPreset::Heavy, 0, None, objective,
)?;
```

## Core types and modules {#core-types}

| Type | Meaning |
| --- | --- |
| TensorNetwork | Integer index IDs, input tensors, output indices, and dimensions |
| SsaPath | A binary contraction sequence whose steps reference current SSA node IDs |
| PathStats | Path-model metrics, not hardware counters |
| PlannerObjective | FLOPs and read/write weights specified per call |
| AutoResult | `path`, `stats`, optional `sliced: Option<SliceResult>`, and search time `wall_s` |
| ExecutionPlanNetwork | Integer-labeled network stored in a version 2 path file |
| LoadedExecutionPlan | Validated SSA path, slices, and size limit |
| EmbeddedExecutionPlan | Network and execution information in a version 2 path file |
| DenseTensor\<T\> | Row-major dense tensor used by the native executor |
| Scalar | Element-type requirements for the native executor |
| CompiledContraction | Reusable execution object prepared for a fixed network and SSA path; does not store input arrays |
| SliceResult | Sliced indices, slice count, and per-slice path metrics; see [Slicing results](/docs/slicing#result) |

### Low-level modules {#modules}

| Module | Responsibility | Usage |
| --- | --- | --- |
| paths | Greedy, dynamic programming, hypergraph bisection, and budget-controlled search | Call the required algorithm directly |
| tree | Contraction trees, local rotations, subtree reconfiguration, simulated annealing, and replica exchange | Supply an initial path and configure parameters |
| simplify | Deterministic network simplification and path stitching | Can be used independently |
| slice | Slice-index selection, alternating slicing and reconfiguration, and sliced execution | When using Light / Heavy, access through the corresponding path-optimization interface |
| contract / compiled | One-shot and reusable compiled execution | Requires a valid SSA path |

Low-level functions can be called independently. Their parameters are separate from the Python Light / Heavy interfaces.

## Path generation {#path-search}

The signatures below omit `pub` and use short type names. Except for single-pass deterministic greedy search, functions without an objective parameter use `PlannerObjective::FIXED`, namely $F+64R$.

### greedy {#greedy}

~~~rust
fn greedy(
    net: &TensorNetwork,
) -> Result<(SsaPath, PathStats), String>;
~~~

Import `arctn::greedy`. Runs one deterministic greedy pass with no additional objective parameter.

### random_greedy {#random-greedy}

~~~rust
fn random_greedy(
    net: &TensorNetwork,
    ntrials: usize,
    seed: u64,
) -> Result<(SsaPath, PathStats), String>;
~~~

Import `arctn::random_greedy`. `ntrials` must be greater than zero. For a custom objective, use `arctn::paths::greedy::random_greedy_with_objective`, adding `objective: PlannerObjective` after the parameters above.

### random_greedy_simplified {#random-greedy-simplified}

~~~rust
fn random_greedy_simplified(
    net: &TensorNetwork,
    ntrials: usize,
    seed: u64,
) -> Result<(SsaPath, PathStats), String>;
~~~

Import `arctn::random_greedy_simplified`. Searches the reduced network and returns a complete path for the original network.

### optimal_dp {#optimal-dp}

~~~rust
fn optimal_dp(
    net: &TensorNetwork,
    max_n: usize,
) -> Result<(SsaPath, PathStats), String>;
~~~

Import `arctn::optimal_dp`. `max_n` limits the tensor count of the complete input network. `arctn::paths::optimal::optimal_dp_with_objective` adds an objective parameter at the end; see [Dynamic programming](/docs/structured-search#optimal-dp) for its exactness scope.

### bisect {#bisect}

~~~rust
fn bisect(
    net: &TensorNetwork,
    ntrials: usize,
    seed: u64,
    cutoff: usize,
) -> Result<(SsaPath, PathStats), String>;
~~~

Import `arctn::paths::bisect::bisect`. `cutoff` is restricted to 2–20. In the same module, `bisect_with_objective` adds an objective parameter at the end to compare complete candidates; DP within small subproblems still uses the default objective.

### order_dp {#order-dp}

~~~rust
fn order_dp(
    net: &TensorNetwork,
    order: &[usize],
) -> Result<(SsaPath, PathStats), String>;
~~~

Import `arctn::paths::ordertree::order_dp`. `order` must contain every input ID exactly once; only parenthesizations preserving that leaf order are optimized. The same module provides `order_dp_with_objective` with an objective parameter at the end.

## Tree search and reconfiguration {#tree-search}

The following functions are in `arctn::tree`. All except `treesa_path` are also exported from the `arctn` root module. Each has a `*_with_objective` variant in the same module with a final `objective: PlannerObjective` parameter; versions without it use the default objective $F+64R$.

### reconfigure_path {#reconfigure-path}

~~~rust
fn reconfigure_path(
    net: &TensorNetwork,
    path: &SsaPath,
    subtree_size: usize,
    max_sweeps: usize,
) -> Result<(SsaPath, PathStats), String>;
~~~

`subtree_size` limits the number of input nodes in the local subnetwork, which need not equal the number of original tensors.

### anneal_path {#anneal-path}

~~~rust
fn anneal_path(
    net: &TensorNetwork,
    path: &SsaPath,
    niters: usize,
    seed: u64,
    t0_rel: f64,
    t1_rel: f64,
) -> Result<(SsaPath, PathStats), String>;
~~~

Runs one simulated annealing chain, with relative temperature changing from `t0_rel` to `t1_rel`.

### anneal_paths {#anneal-paths}

~~~rust
fn anneal_paths(
    net: &TensorNetwork,
    path: &SsaPath,
    chains: usize,
    niters: usize,
    seed: u64,
) -> (SsaPath, PathStats);
~~~

Runs multiple independent annealing chains and returns one best path. `chains=0` is treated as at least one chain. This function does not return `Result`; an invalid initial path may panic. Validate the network and path before calling.

### treesa_path {#treesa-path}

~~~rust
fn treesa_path(
    net: &TensorNetwork,
    path: &SsaPath,
    chains: usize,
    beta0: f64,
    beta1: f64,
    beta_steps: usize,
    sweeps_per_beta: usize,
    reconf_interval: usize,
    reconf_size: usize,
    seed: u64,
) -> Result<(SsaPath, PathStats), String>;
~~~

Advances through inverse temperatures, repeatedly sweeping the tree. `reconf_interval=0` disables periodic subtree reconfiguration.

### temper_path {#temper-path}

~~~rust
fn temper_path(
    net: &TensorNetwork,
    path: &SsaPath,
    n_replicas: usize,
    rounds: usize,
    moves_per_round: usize,
    t_min: f64,
    t_max: f64,
    reconf_interval: usize,
    reconf_size: usize,
    seed: u64,
) -> Result<(SsaPath, PathStats), String>;
~~~

All replicas start from the same path; local updates alternate with exchanges between adjacent temperatures.

### temper_paths {#temper-paths}

~~~rust
fn temper_paths(
    net: &TensorNetwork,
    init_paths: &[SsaPath],
    n_replicas: usize,
    rounds: usize,
    moves_per_round: usize,
    t_min: f64,
    t_max: f64,
    reconf_interval: usize,
    reconf_size: usize,
    seed: u64,
    patience: usize,
) -> Result<(SsaPath, PathStats), String>;
~~~

Initializes from a nonempty set of starting paths. `patience=0` disables stopping after consecutive rounds without improvement; the best path retained during the run is still returned.

## Network simplification and path validation {#simplification}

The following functions are all exported from the `arctn` root module. Structural simplification does not execute numerical arrays.

### simplify {#simplify}

~~~rust
fn simplify(
    net: &TensorNetwork,
) -> Simplified;
~~~

Returns `prefix`, `reduced`, and `map`. This function does not report input errors through `Result`; validate the network before calling.

### stitch {#stitch}

~~~rust
fn stitch(
    n_orig: usize,
    prefix: &SsaPath,
    map: &[usize],
    reduced_path: &SsaPath,
) -> SsaPath;
~~~

The prefix and mapping must come from the same simplification, and the reduced path must match that reduced network. Check the stitched path with `simulate_path`.

### simulate_path {#simulate-path}

~~~rust
fn simulate_path(
    net: &TensorNetwork,
    path: &SsaPath,
) -> Result<PathStats, String>;
~~~

Checks SSA references and the final result and recomputes path metrics without executing tensor arrays.

## Slice selection {#slice-selection}

Fixed-path slice selection leaves the supplied path unchanged. For execution, see [Fixed-path slicing and execution](#sliced).

### find_slices_to_size {#find-slices-to-size}

~~~rust
fn find_slices_to_size(
    net: &TensorNetwork,
    path: &SsaPath,
    target_size: usize,
) -> Option<SliceResult>;
~~~

Import `arctn::find_slices_to_size`. The target is an element count. Returns `None` if the target is zero or no valid scheme satisfying the limit is found.

## Numerical execution {#contraction}

### contract_network {#contract-network}

~~~rust
fn contract_network<T: Scalar>(
    net: &TensorNetwork,
    tensors: Vec<DenseTensor<T>>,
    path: &SsaPath,
) -> Result<DenseTensor<T>, String>;
~~~

Import `arctn::contract_network`. Executes the supplied SSA path without searching again or selecting slices. Input array order and dimensions must match the network; output axes follow `net.output`. `tensors` is passed by value, transferring ownership into the function. Invalid inputs or paths return `Err(String)`.

For repeated execution with a fixed network and path, use `CompiledContraction`; see [Compilation and reuse](/docs/compiled-contraction).

## Sliced execution {#sliced}

```rust
use arctn::{
    auto_path_preset_to_size, contract_network_sliced,
    AutoPreset,
};

let plan = auto_path_preset_to_size(
    &net, AutoPreset::Heavy, 0, None, 1 << 24,
)?;
let slice = plan.slice.as_ref().ok_or("missing slice plan")?;
let out = contract_network_sliced(
    &net, &tensors, &plan.path, &slice.legs,
)?;
```

## Reading and writing path files {#execution-plan}

| Function | Purpose |
| --- | --- |
| complete\_execution\_plan\_v2 | Add the network, format identifier, and normalized metadata to a tnpath record, and validate the saved content |
| parse\_embedded\_execution\_plan | Read a version 2 path file containing the network structure |
| parse\_execution\_plan\_for\_network | Read a version 1, version 2, or explicitly permitted legacy path file and check it against the supplied network |

Version 1 files store only an identifier for checking the network, not its structure, so the network must be supplied when loading. Version 2 files also contain the normalized network structure. Legacy files without a format identifier still require explicit permission to load.
