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
CPU contractions show no thread scaling: running with 8 threads is no faster than
with 1 (t1 ≈ t8), across both Standard and Tropical algebras. The available
parallelism in our GEMM backends is never reached.
Root causes (verified)
1. Standard nocopy path is hardcoded sequential
The preferred Standard fast path (gemm_standard_layout_internal, hit first in contract.rs:440) flows through faer_gemm_f32_layout_into / faer_gemm_f64_layout_into, which pass Par::Seq to faer's matmul:
src/backend/cpu/mod.rs:677 (f32)
src/backend/cpu/mod.rs:719 (f64)
faer's global parallelism already defaults to Rayon (its rayon feature is in
faer's default set, which we don't disable), and the operator path
(gemm_internal → &a_mat * &b_mat) already runs parallel via get_global_parallelism(). Only these two _layout_into helpers opt out — so
the most commonly hit Standard path is the one stuck on a single core.
Fix: replace Par::Seq with faer::get_global_parallelism() in both
helpers, making the nocopy path consistent with the operator path and
controllable via RAYON_NUM_THREADS / faer::set_global_parallelism.
2. Tropical single GEMM is single-threaded upstream
try_tropical_gemm → tropical_matmul → tropical_gemm_dispatch. In the
pinned tropical-gemm (feat/cuda-andor-gpu), rayon is used only in the batched API entries; the single blocked kernel (core::gemm::tropical_gemm_inner)
has no threading. So a batch_size = 1 tropical contraction — the common case
for an einsum pairwise step — never uses more than one core.
Fix: parallelize the single GEMM upstream in tropical-gemm, then bump the
pin here. No call-site change needed in this repo (tropical_matmul picks it up
automatically). Upstream plan drafted separately.
3. The parallel feature is an empty shell
Cargo.toml declares parallel = ["rayon"], but there is no rayon usage and
no cfg(feature = "parallel") anywhere in src/. Enabling it pulls in the
dependency and does nothing else. Decide whether to drop it (both faer and
tropical-gemm carry their own default-on rayon, controlled by the global Rayon
pool) or wire it to something meaningful (e.g. tree-level parallelism over
independent pairwise contractions).
Re-run the t1-vs-t8 benchmark to confirm scaling for both algebras.
Acceptance
A representative Standard and Tropical contraction shows meaningful speedup from RAYON_NUM_THREADS=1 to =8 (bandwidth-bound, so sub-linear is expected, but
clearly t8 < t1), proven with recorded timings.
Summary
CPU contractions show no thread scaling: running with 8 threads is no faster than
with 1 (
t1 ≈ t8), across both Standard and Tropical algebras. The availableparallelism in our GEMM backends is never reached.
Root causes (verified)
1. Standard nocopy path is hardcoded sequential
The preferred Standard fast path (
gemm_standard_layout_internal, hit first incontract.rs:440) flows throughfaer_gemm_f32_layout_into/faer_gemm_f64_layout_into, which passPar::Seqto faer'smatmul:src/backend/cpu/mod.rs:677(f32)src/backend/cpu/mod.rs:719(f64)faer's global parallelism already defaults to Rayon (its
rayonfeature is infaer's default set, which we don't disable), and the operator path
(
gemm_internal→&a_mat * &b_mat) already runs parallel viaget_global_parallelism(). Only these two_layout_intohelpers opt out — sothe most commonly hit Standard path is the one stuck on a single core.
Fix: replace
Par::Seqwithfaer::get_global_parallelism()in bothhelpers, making the nocopy path consistent with the operator path and
controllable via
RAYON_NUM_THREADS/faer::set_global_parallelism.2. Tropical single GEMM is single-threaded upstream
try_tropical_gemm→tropical_matmul→tropical_gemm_dispatch. In thepinned
tropical-gemm(feat/cuda-andor-gpu), rayon is used only in thebatched API entries; the single blocked kernel (
core::gemm::tropical_gemm_inner)has no threading. So a
batch_size = 1tropical contraction — the common casefor an einsum pairwise step — never uses more than one core.
Fix: parallelize the single GEMM upstream in
tropical-gemm, then bump thepin here. No call-site change needed in this repo (
tropical_matmulpicks it upautomatically). Upstream plan drafted separately.
3. The
parallelfeature is an empty shellCargo.tomldeclaresparallel = ["rayon"], but there is norayonusage andno
cfg(feature = "parallel")anywhere insrc/. Enabling it pulls in thedependency and does nothing else. Decide whether to drop it (both faer and
tropical-gemm carry their own default-on rayon, controlled by the global Rayon
pool) or wire it to something meaningful (e.g. tree-level parallelism over
independent pairwise contractions).
Secondary (lower priority)
gemm_batched_internal/gemm_batched_with_argmax_internal(
src/backend/cpu/mod.rs) andgemm_batched_standard_layout_internalloopover batches serially. Once feat: integrate faer for Standard GEMM and migrate to column-major layout #1 and the upstream tropical fix land, each
per-batch GEMM parallelizes internally; routing the tropical batched paths to
tropical_matmul_strided_batched(_with_argmax)only adds value for themany-small-batches case. (Related:
gemm_batched_internalandgemm_batched_with_argmax_internalbypasstropical-kernelsdispatch #45.)Suggested order
parallelfeature (Support higher-dimensional partial trace #3).Acceptance
A representative Standard and Tropical contraction shows meaningful speedup from
RAYON_NUM_THREADS=1to=8(bandwidth-bound, so sub-linear is expected, butclearly
t8 < t1), proven with recorded timings.