Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
61aab7a
fix: align partial contract site nodes
shinaoka May 16, 2026
8a994f5
feat: add partial contract target layout
shinaoka May 16, 2026
f0f91d0
fix: preserve target topology in restructure planning
shinaoka May 17, 2026
9419ad1
feat: insert fixed sites into treetn chains
shinaoka May 17, 2026
160d459
feat: remove fixed sites from treetn chains
shinaoka May 17, 2026
80850ec
feat: restructure linear operators and unfuse mappings
shinaoka May 17, 2026
633bf21
feat: support complex linsolve coefficients
shinaoka May 17, 2026
752790a
feat: allow spectator nodes in mapped linsolve
shinaoka May 17, 2026
6fbeb21
test: cover identity term mapped linsolve
shinaoka May 17, 2026
f11191e
feat: report square linsolve residuals
shinaoka May 17, 2026
dca21f9
fix: solve identity-only square linsolve directly
shinaoka May 17, 2026
054709c
feat: support appending hdf5 tensor objects
shinaoka May 17, 2026
bba5a95
refactor: hide zipup implementation detail
shinaoka May 17, 2026
8eb342d
fix: preserve fit topology for contracted sites
shinaoka May 17, 2026
f4638f9
fix: align compatible partial contraction topologies
shinaoka May 17, 2026
f34eaf1
Make TreeTN reindexing addition explicit
shinaoka May 17, 2026
4d8e043
Save projected apply benchmarks
shinaoka May 18, 2026
c244ade
Add prepared local linsolve benchmarks
shinaoka May 18, 2026
eebbc1b
Add HDF5 linsolve input dump benchmark
shinaoka May 18, 2026
de51179
Note TensorTrain index order relaxation
shinaoka May 18, 2026
c890aa3
Preserve TensorTrain site tensor order
shinaoka May 18, 2026
81924ff
Align linsolve GMRES maxiter with KrylovKit
shinaoka May 18, 2026
444fdc7
Rename linsolve GMRES options
shinaoka May 18, 2026
1ad4f8c
Clean up tensor contraction APIs
shinaoka May 20, 2026
62d6f01
Fix clippy warnings
shinaoka May 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ build/
Manifest.toml
LocalPreferences.toml
.julia-tests/
benchmarks/results/*.h5

# Avoid accidentally committing ad-hoc analysis notes at repo root
/*.md
Expand Down
9 changes: 5 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ bnum = "0.12"
uint = "0.10"
libc = "0.2"
paste = "1.0"
smallvec = "1.15"
thiserror = "2.0"
rand = "0.9"
rand_chacha = "0.9"
Expand All @@ -53,7 +54,7 @@ hdf5-metno = { version = "0.12", default-features = false }
ndarray = "0.17"
quanticsgrids = { git = "https://github.com/tensor4all/quanticsgrids-rs", rev = "a76b8fb" }
hdf5-rt = { git = "https://github.com/tensor4all/hdf5-rt", default-features = false }
tenferro = { git = "https://github.com/tensor4all/tenferro-rs.git", rev = "925e2511bc6bd019432f66596de39389dfced754", default-features = false }
tenferro-device = { git = "https://github.com/tensor4all/tenferro-rs.git", rev = "925e2511bc6bd019432f66596de39389dfced754" }
tenferro-einsum = { git = "https://github.com/tensor4all/tenferro-rs.git", rev = "925e2511bc6bd019432f66596de39389dfced754", default-features = false }
tenferro-tensor = { git = "https://github.com/tensor4all/tenferro-rs.git", rev = "925e2511bc6bd019432f66596de39389dfced754", default-features = false }
tenferro = { git = "https://github.com/tensor4all/tenferro-rs.git", rev = "6283c6f1a8a56f920a2600f6c27e9e6ade28beed", default-features = false }
tenferro-device = { git = "https://github.com/tensor4all/tenferro-rs.git", rev = "6283c6f1a8a56f920a2600f6c27e9e6ade28beed" }
tenferro-einsum = { git = "https://github.com/tensor4all/tenferro-rs.git", rev = "6283c6f1a8a56f920a2600f6c27e9e6ade28beed", default-features = false }
tenferro-tensor = { git = "https://github.com/tensor4all/tenferro-rs.git", rev = "6283c6f1a8a56f920a2600f6c27e9e6ade28beed", default-features = false }
94 changes: 94 additions & 0 deletions benchmarks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ This directory contains benchmark code for comparing Rust and Julia implementati

- `rust/`: Rust benchmark code using `tensor4all-rs`
- `julia/`: Julia benchmark code using `ITensors.jl` and `ITensorMPS.jl`
- `results/`: saved benchmark commands and representative local outputs

## Running Benchmarks

Expand All @@ -16,13 +17,73 @@ cd crates/tensor4all-itensorlike
cargo run --release --example benchmark_contract
```

Projected local-operator apply:

```bash
RAYON_NUM_THREADS=1 cargo run -p tensor4all-treetn --example benchmark_projected_apply --release -- 38 32 32 3 0
```

Prepared local linsolve:

```bash
RAYON_NUM_THREADS=1 cargo run -p tensor4all-treetn --example benchmark_local_linsolve --release -- 38 32 32 1 10 30 0
```

Non-AD local tensor operations:

```bash
RAYON_NUM_THREADS=1 cargo run -p tensor4all-core --example benchmark_tensor_ops --release -- 20000 6 2 2 6
```

TensorTrain-level operations against ITensorMPS:

```bash
RAYON_NUM_THREADS=1 cargo run -p tensor4all-itensorlike --example benchmark_tt_ops --release -- --L 32 --zipup-L 10 --chis 4,8,16,32,64
```

Inspect Julia-dumped local linsolve inputs:

```bash
cargo run -p tensor4all-hdf5 --example inspect_mps_inputs --release -- benchmarks/results/local_linsolve_inputs_N38_b32_o32.h5
```

### Julia

```bash
cd external/ITensorMPS.jl
julia benchmark/benchmark_contract.jl
```

Projected local-operator apply:

```bash
BLAS_NUM_THREADS=1 julia --project=benchmarks/julia benchmarks/julia/benchmark_projected_apply.jl 38 32 32 3 0
```

Prepared local linsolve:

```bash
BLAS_NUM_THREADS=1 julia --project=benchmarks/julia benchmarks/julia/benchmark_local_linsolve.jl 38 32 32 1 1 10
```

Non-AD local tensor operations:

```bash
BLAS_NUM_THREADS=1 julia --project=benchmarks/julia benchmarks/julia/benchmark_tensor_ops.jl 20000 6 2 2 6
```

TensorTrain-level operations against tensor4all:

```bash
BLAS_NUM_THREADS=1 julia --project=benchmarks/julia benchmarks/julia/benchmark_tt_ops.jl --L 32 --zipup-L 10 --chis 4,8,16,32,64
```

Dump local linsolve inputs as ITensorMPS-compatible HDF5:

```bash
BLAS_NUM_THREADS=1 julia --project=benchmarks/julia benchmarks/julia/dump_local_linsolve_inputs.jl benchmarks/results/local_linsolve_inputs_N38_b32_o32.h5 38 32 32
```

## Benchmark Details

Both benchmarks perform MPO-MPO contraction using zip-up algorithm:
Expand All @@ -31,3 +92,36 @@ Both benchmarks perform MPO-MPO contraction using zip-up algorithm:
- Bond dimension: 50
- Max rank: 50
- Includes orthogonalization time in measurements

The projected local-operator apply benchmarks isolate the local matvec hot path
used by two-site TreeTN/ITensor-style local solves. The Rust source of truth is
`benchmarks/rust/benchmark_projected_apply.rs`, included by the cargo example
target under `tensor4all-treetn`; the Julia counterpart is
`benchmarks/julia/benchmark_projected_apply.jl`.

The prepared local linsolve benchmarks construct the operator, right-hand side,
and initial state once, then time the local solve body. They also report local
GMRES/apply/RHS/factorization buckets. Use Julia `maxiter=1, krylovdim=10` as a
rough match to Rust's `krylov_maxiter=10` total-iteration cap; KrylovKit's
`maxiter=10, krylovdim=30` performs far more local operator applications.

The non-AD local tensor operation benchmarks isolate `inner`, `norm`, affine
addition, and explicit `conj`-then-contract on a small dense tensor. The default
shape `[6, 2, 2, 6]` mirrors the small two-site local tensors observed in the
QuanticsNEGF long-time local Krylov test, where dispatch/allocation overhead can
dominate floating-point work.

The TensorTrain-level operation benchmarks compare tensor4all's
`TensorTrain::inner`, strict direct-sum MPS addition, and prepared MPO×MPO zipup
contraction against ITensorMPS.jl. They use deterministic Complex64 fixtures and
print CSV-style rows with sample counts, min/median/mean/max milliseconds,
result max bond dimension, and a checksum. The Rust source of truth is
`benchmarks/rust/benchmark_tt_ops.rs`, included by
`tensor4all-itensorlike/examples/benchmark_tt_ops.rs`; the Julia counterpart is
`benchmarks/julia/benchmark_tt_ops.jl`.

`dump_local_linsolve_inputs.jl` writes the prepared local operator as
`operator_as_mps`, plus `rhs` and `init`, in one HDF5 file. The operator is a
Julia `MPO` stored through the `MPS` schema by saving its site tensors as
`MPS([H[i] for i in 1:length(H)])`; Rust reads all three groups with
`tensor4all_hdf5::load_mps`.
7 changes: 7 additions & 0 deletions benchmarks/julia/Project.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
[deps]
FastMPOContractions = "f6e391d2-8ffa-4d7a-98cd-7e70024481ca"
HDF5 = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f"
ITensorMPS = "0d1a4710-d33b-49a5-8f18-73bdf49b47e2"
ITensorTDVP = "25707e16-a4db-4a07-99d9-4d67b7af0342"
ITensors = "9136182c-28ba-11e9-034c-db9fb085ebd5"
KrylovKit = "0b1a1467-8014-51b9-945f-bf0ae24f4b77"
VectorInterface = "409d34a3-91d5-4945-b6ec-7529ddf182d8"

[compat]
ITensorTDVP = "^0.4"
ITensors = "^0.6"
Loading
Loading