Skip to content

CPU contractions do not scale across threads (t1 ≈ t8) #51

Description

@isPANN

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 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_gemmtropical_matmultropical_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).

Secondary (lower priority)

Suggested order

  1. Fix feat: integrate faer for Standard GEMM and migrate to column-major layout #1 (two-line change) — smallest, immediately measurable for Standard.
  2. Land upstream tropical single-GEMM parallelism + bump pin (Support unary transpose/permutation in einsum #2).
  3. Decide the fate of the parallel feature (Support higher-dimensional partial trace #3).
  4. 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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions