You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Standard<Complex32> and Standard<Complex64> CPU contractions currently miss the faer GEMM fast paths used by Standard<f32> and Standard<f64>. They therefore fall through to generic_gemm, the scalar triple loop, even when contraction planning has already lowered the operation to an ordinary GEMM.
This issue tracks the benchmark, implementation, correctness proof, and downstream validation needed to merge optimized complex dispatch without adding a TDVP-specific workaround to OMEinsum.
The motivating downstream workload is QudeLeap/rydbergsim-rs#272, where complex local-Hamiltonian contractions dominate saturated two-site TDVP runtime.
Current diagnosis
At main commit 239e962, optimized CPU dispatch is limited to real standard algebra in four entry points in src/backend/cpu/mod.rs:
Cpu::gemm_internal
Cpu::gemm_standard_layout_internal
Cpu::gemm_batched_internal
Cpu::gemm_batched_standard_layout_internal
The contraction planner already classifies modes, handles directly usable layouts, materializes required permutations, and lowers binary contractions to GEMM. The missing piece is complex scalar dispatch at that GEMM boundary.
The benchmark calls the public Tensor::contract_binary::<Standard<Complex64>> path with deterministic inputs, MPO bond dimension D=9, and chi in {32, 64, 128}. It covers four contractions taken directly from the downstream TDVP local-Hamiltonian applications:
Case
Equivalent GEMM
one-site left environment
(D chi × chi) @ (chi × 2 chi)
one-site right environment
(2 chi × chi D) @ (chi D × chi)
two-site left environment
(D chi × chi) @ (chi × 4 chi)
two-site right environment
(4 chi × chi D) @ (chi D × chi)
make check passes on the current comparison working tree: formatting, all-target clippy, 158 unit tests, 333 integration tests, and 16 doctests passed. The OMEinsum-versus-Tenferro results are summarized below and reported in full in this comment.
Implementation plan
Verify that complex standard contractions reach generic_gemm.
Document target paths, workload, risks, and acceptance criteria.
Record scalar baselines for chi=32, then chi=64, then chi=128 under the repository's runscribe protocol.
Add faer dispatch for contiguous Complex32 and Complex64 GEMM.
Add complex dispatch for borrowed strided/transposed layouts.
Add complex dispatch for materialized and direct-layout batched GEMM.
Add concrete-value tests against generic_gemm for both complex widths.
Cover rectangular, transposed, positive-stride, supported negative-stride, and multi-batch layouts.
Verify that ordinary GEMM semantics do not accidentally conjugate either operand.
Run candidate benchmarks and existing real-valued binary benchmarks.
Pin the candidate downstream, remove the local prototype contraction workaround, and rerun saturated TDVP kernel/step measurements.
Open a focused upstream PR with before/after results and downstream evidence.
Implementation constraints
Keep this inside the existing CPU GEMM boundary; no public API or contraction-order change.
Reuse faer_mat_ref, layout bounds checking, and the existing checked-TypeId dispatch pattern.
Borrow inputs where possible and allocate the output once.
Keep Par::Seq initially, matching existing real-valued behavior; parallel policy is a separate benchmark question.
Do not create a permanent downstream mini-einsum implementation.
Prefer four short, obvious dispatch arms over a trait hierarchy unless genericization materially reduces unsafe casts or duplicated layout code.
Correctness acceptance
Complex fast paths agree with generic_gemm within dtype-appropriate absolute and relative tolerances.
Tests use nontrivial real and imaginary values and concrete expected values.
Contiguous, strided/transposed, and batched paths are covered for Complex32 and Complex64.
Existing standard-real, tropical, repeated-label, scalar-output, and backward tests remain green.
make check passes.
Performance acceptance
On one pinned host/toolchain:
At least 5× lower median latency than the scalar baseline for all four chi=64, D=9 target contractions.
No target contraction regresses.
chi=128 improves in the same direction without pathological allocation or memory growth.
Existing real-valued binary benchmarks do not regress by more than 5% beyond measurement noise.
Downstream saturated TDVP timing confirms that the kernel improvement survives contraction planning, environment updates, and Krylov repetition.
The 5× kernel threshold is a minimum useful result, not a claim that it alone makes the full paper-reproduction grid feasible.
OMEinsum versus Tenferro result (2026-07-15)
Both implementations resolve complex GEMM to single-threaded faer 0.24.4. With identical column-major Complex64 inputs, Tenferro's prepared contraction path ties OMEinsum on the two left-environment layouts and wins on the two right-environment layouts.
The reverse-order chi=64 check measured:
Case
OMEinsum median
Tenferro median
Tenferro speedup
h1-left-environment
0.8066 ms
0.8031 ms
1.00x
h1-right-environment
1.0950 ms
0.8784 ms
1.25x
h2-left-environment
1.6763 ms
1.6670 ms
1.01x
h2-right-environment
2.2396 ms
1.7475 ms
1.28x
At chi=128, the right-environment advantages narrow to 1.16x and 1.09x. This is not evidence for a faster Tenferro arithmetic kernel; the leading explanation is different contraction lowering, including plan reuse, strided-layout handling, materialization, buffer reuse, or per-call framework overhead. Profiling is still required to isolate the mechanism.
Full protocol, all chi values, the order-bias check, and caveats are in the comparison comment. runscribe was unavailable, so the repository owner explicitly approved a documented fallback that captured raw Criterion output, samples, confidence intervals, environment metadata, and the exact benchmark patch.
Summary
Standard<Complex32>andStandard<Complex64>CPU contractions currently miss the faer GEMM fast paths used byStandard<f32>andStandard<f64>. They therefore fall through togeneric_gemm, the scalar triple loop, even when contraction planning has already lowered the operation to an ordinary GEMM.This issue tracks the benchmark, implementation, correctness proof, and downstream validation needed to merge optimized complex dispatch without adding a TDVP-specific workaround to OMEinsum.
The motivating downstream workload is QudeLeap/rydbergsim-rs#272, where complex local-Hamiltonian contractions dominate saturated two-site TDVP runtime.
Current diagnosis
At
maincommit239e962, optimized CPU dispatch is limited to real standard algebra in four entry points insrc/backend/cpu/mod.rs:Cpu::gemm_internalCpu::gemm_standard_layout_internalCpu::gemm_batched_internalCpu::gemm_batched_standard_layout_internalThe contraction planner already classifies modes, handles directly usable layouts, materializes required permutations, and lowers binary contractions to GEMM. The missing piece is complex scalar dispatch at that GEMM boundary.
Work prepared
A benchmark-and-plan branch exists at:
exAClior/omeinsum-rs:perf/complex-gemmd6695fcbenchmarks/complex_tdvp.mdbenches/complex_tdvp.rsThe benchmark calls the public
Tensor::contract_binary::<Standard<Complex64>>path with deterministic inputs, MPO bond dimensionD=9, andchi in {32, 64, 128}. It covers four contractions taken directly from the downstream TDVP local-Hamiltonian applications:(D chi × chi) @ (chi × 2 chi)(2 chi × chi D) @ (chi D × chi)(D chi × chi) @ (chi × 4 chi)(4 chi × chi D) @ (chi D × chi)make checkpasses on the current comparison working tree: formatting, all-target clippy, 158 unit tests, 333 integration tests, and 16 doctests passed. The OMEinsum-versus-Tenferro results are summarized below and reported in full in this comment.Implementation plan
generic_gemm.chi=32, thenchi=64, thenchi=128under the repository's runscribe protocol.Complex32andComplex64GEMM.generic_gemmfor both complex widths.Implementation constraints
faer_mat_ref, layout bounds checking, and the existing checked-TypeIddispatch pattern.Par::Seqinitially, matching existing real-valued behavior; parallel policy is a separate benchmark question.Correctness acceptance
generic_gemmwithin dtype-appropriate absolute and relative tolerances.Complex32andComplex64.make checkpasses.Performance acceptance
On one pinned host/toolchain:
chi=64, D=9target contractions.chi=128improves in the same direction without pathological allocation or memory growth.The 5× kernel threshold is a minimum useful result, not a claim that it alone makes the full paper-reproduction grid feasible.
OMEinsum versus Tenferro result (2026-07-15)
Both implementations resolve complex GEMM to single-threaded faer 0.24.4. With identical column-major
Complex64inputs, Tenferro's prepared contraction path ties OMEinsum on the two left-environment layouts and wins on the two right-environment layouts.The reverse-order
chi=64check measured:h1-left-environmenth1-right-environmenth2-left-environmenth2-right-environmentAt
chi=128, the right-environment advantages narrow to 1.16x and 1.09x. This is not evidence for a faster Tenferro arithmetic kernel; the leading explanation is different contraction lowering, including plan reuse, strided-layout handling, materialization, buffer reuse, or per-call framework overhead. Profiling is still required to isolate the mechanism.Full protocol, all
chivalues, the order-bias check, and caveats are in the comparison comment.runscribewas unavailable, so the repository owner explicitly approved a documented fallback that captured raw Criterion output, samples, confidence intervals, environment metadata, and the exact benchmark patch.