From 3567b710332d71dacb6d3660fdef5ab407e77767 Mon Sep 17 00:00:00 2001 From: Hiroshi Shinaoka Date: Tue, 12 May 2026 13:03:19 +0900 Subject: [PATCH] prepare workspace publishing facade --- .github/workflows/ci.yml | 3 + .github/workflows/docs.yml | 3 + Cargo.toml | 48 +++++++++++++- README.md | 42 +++++++------ .../2026-05-12-strided-rs-publish-prep.md | 62 ++++++++++++++++++ mdarray-opteinsum/Cargo.toml | 27 ++++---- ndarray-opteinsum/Cargo.toml | 29 +++++---- strided-einsum2/Cargo.toml | 43 +++++++------ strided-einsum2/src/backend.rs | 10 +-- strided-kernel/Cargo.toml | 37 ++++++----- strided-opteinsum/Cargo.toml | 31 +++++---- strided-perm/Cargo.toml | 25 ++++---- strided-rs/Cargo.toml | 53 ++++++++++++++++ strided-rs/README.md | 63 +++++++++++++++++++ strided-rs/src/lib.rs | 63 +++++++++++++++++++ strided-traits/Cargo.toml | 15 +++-- strided-traits/README.md | 10 +++ strided-view/Cargo.toml | 19 +++--- 18 files changed, 444 insertions(+), 139 deletions(-) create mode 100644 docs/plans/2026-05-12-strided-rs-publish-prep.md create mode 100644 strided-rs/Cargo.toml create mode 100644 strided-rs/README.md create mode 100644 strided-rs/src/lib.rs create mode 100644 strided-traits/README.md diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f81f669..e55979e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,6 +40,9 @@ jobs: - name: Run tests run: cargo test + - name: Run facade README doctests + run: cargo test -p strided-rs --doc + coverage: name: coverage runs-on: ubuntu-latest diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index b028f08..3cbbde3 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -34,7 +34,10 @@ jobs: strided-rs docs

strided-rs

+ strided-rs + strided-traits strided-view + strided-perm strided-kernel strided-einsum2 strided-opteinsum diff --git a/Cargo.toml b/Cargo.toml index 5df3331..cbcd5ad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,3 +1,49 @@ [workspace] -members = ["strided-traits", "strided-view", "strided-perm", "strided-kernel", "strided-einsum2", "strided-opteinsum", "mdarray-opteinsum", "ndarray-opteinsum"] +members = [ + "strided-rs", + "strided-traits", + "strided-view", + "strided-perm", + "strided-kernel", + "strided-einsum2", + "strided-opteinsum", + "mdarray-opteinsum", + "ndarray-opteinsum", +] resolver = "2" + +[workspace.package] +version = "0.1.0" +edition = "2021" +license = "MIT OR Apache-2.0" +authors = ["Satoshi Terasaki", "Hiroshi Shinaoka"] +repository = "https://github.com/tensor4all/strided-rs" + +[workspace.dependencies] +strided-rs = { version = "0.1.0", path = "strided-rs" } +strided-traits = { version = "0.1.0", path = "strided-traits" } +strided-view = { version = "0.1.0", path = "strided-view" } +strided-perm = { version = "0.1.0", path = "strided-perm" } +strided-kernel = { version = "0.1.0", path = "strided-kernel" } +strided-einsum2 = { version = "0.1.0", path = "strided-einsum2", default-features = false } +strided-opteinsum = { version = "0.1.0", path = "strided-opteinsum", default-features = false } +mdarray-opteinsum = { version = "0.1.0", path = "mdarray-opteinsum", default-features = false } +ndarray-opteinsum = { version = "0.1.0", path = "ndarray-opteinsum", default-features = false } + +approx = "0.5" +cblas-inject = "0.1" +cblas-sys = "0.2" +criterion = "0.5" +faer = "0.24" +faer-traits = "0.24" +mdarray = "0.8.0" +ndarray = "0.17" +num-complex = "0.4" +num-traits = "0.2" +omeco = "0.2" +pulp = "0.22" +rand = "0.8" +rand_distr = "0.4" +rayon = "1.10" +smallvec = "1" +thiserror = "1.0" diff --git a/README.md b/README.md index d6af150..5a07ad1 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,17 @@ It is inspired by Julia's [Strided.jl](https://github.com/Jutho/Strided.jl), [StridedViews.jl](https://github.com/Jutho/StridedViews.jl), and [OMEinsum.jl](https://github.com/under-Peter/OMEinsum.jl). +The recommended user-facing crate is [`strided-rs`](strided-rs/README.md). +Use individual crates such as `strided-perm`, `strided-view`, or +`strided-kernel` directly when you need a smaller dependency surface or a +lower-level API. + ## Workspace Layout +- [`strided-rs`](strided-rs/README.md): facade crate that re-exports the main workspace APIs +- [`strided-traits`](strided-traits/): shared scalar and element-operation traits - [`strided-view`](strided-view/README.md): core dynamic-rank strided view/array types and metadata ops +- [`strided-perm`](strided-perm/README.md): cache-efficient tensor permutation / transpose - [`strided-kernel`](strided-kernel/README.md): cache-optimized elementwise/reduction kernels over strided views - [`strided-einsum2`](strided-einsum2/README.md): binary einsum (`einsum2_into`) on strided tensors - [`strided-opteinsum`](strided-opteinsum/README.md): N-ary einsum frontend with nested notation and contraction-order optimization @@ -25,15 +33,20 @@ It is inspired by Julia's [Strided.jl](https://github.com/Jutho/Strided.jl), ## Installation -These crates are currently **not published to crates.io** (`publish = false`). -Use workspace path dependencies: +These crates are being prepared for crates.io publication, but this repository +does not publish them automatically. Until a release is published, use workspace +path dependencies: ```toml [dependencies] -strided-view = { path = "../strided-rs/strided-view" } -strided-kernel = { path = "../strided-rs/strided-kernel" } -strided-einsum2 = { path = "../strided-rs/strided-einsum2" } -strided-opteinsum = { path = "../strided-rs/strided-opteinsum" } +strided-rs = { path = "../strided-rs/strided-rs" } +``` + +After publication, use: + +```toml +[dependencies] +strided-rs = "0.1" ``` ## Documentation @@ -54,22 +67,13 @@ CI also builds rustdoc on PRs and deploys workspace docs to GitHub Pages on `mai ## Quick Start -```rust -use strided_kernel::{StridedArray, map_into}; - -// Create a row-major 2D array -let src = StridedArray::::from_fn_row_major(&[2, 3], |idx| { - (idx[0] * 10 + idx[1]) as f64 -}); -let mut dest = StridedArray::::row_major(&[2, 3]); - -// Element-wise map: dest[i] = src[i] * 2 -map_into(&mut dest.view_mut(), &src.view(), |x| x * 2.0).unwrap(); -assert_eq!(dest.get(&[1, 2]), 24.0); // (1*10 + 2) * 2 -``` +See the [`strided-rs` Quick Start](strided-rs/README.md#quick-start). The Rust +example there is included in crate docs and verified by doctests in CI. See each sub-crate README for detailed API examples and benchmarks: +- [`strided-rs`](strided-rs/README.md) — recommended facade crate and executable Quick Start - [`strided-view`](strided-view/README.md) — types, view operations +- [`strided-perm`](strided-perm/README.md) — permutation and transpose kernels - [`strided-kernel`](strided-kernel/README.md) — map/reduce/broadcast kernels, [benchmarks](strided-kernel/README.md#benchmarks) - [`strided-einsum2`](strided-einsum2/README.md) — binary einsum with GEMM backend - [`strided-opteinsum`](strided-opteinsum/README.md) — N-ary einsum, [benchmarks](strided-opteinsum/README.md#benchmarks) diff --git a/docs/plans/2026-05-12-strided-rs-publish-prep.md b/docs/plans/2026-05-12-strided-rs-publish-prep.md new file mode 100644 index 0000000..81d570f --- /dev/null +++ b/docs/plans/2026-05-12-strided-rs-publish-prep.md @@ -0,0 +1,62 @@ +# strided-rs Publish Preparation Implementation Plan + +> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. + +**Goal:** Add a user-facing `strided-rs` facade crate and prepare the workspace metadata, dependencies, README examples, and CI checks for a future crates.io release without publishing anything. + +**Architecture:** The workspace will continue to publish individual low-level crates, while `strided-rs` becomes the recommended entry point that re-exports the core APIs. README examples will live in `strided-rs/README.md` and be included in crate docs so `cargo test -p strided-rs --doc` verifies them. + +**Tech Stack:** Rust workspace, Cargo workspace metadata/dependencies, rustdoc doctests, GitHub Actions. + +--- + +### Task 1: Add the Facade Crate + +**Files:** +- Create: `strided-rs/Cargo.toml` +- Create: `strided-rs/src/lib.rs` +- Create: `strided-rs/README.md` +- Modify: `Cargo.toml` + +**Steps:** +1. Add `strided-rs` to `workspace.members`. +2. Create a package named `strided-rs` with library crate `strided_rs`. +3. Re-export core APIs from `strided-view`, `strided-kernel`, `strided-perm`, `strided-einsum2`, and `strided-opteinsum`. +4. Add optional `mdarray` and `ndarray` features that re-export `mdarray-opteinsum` and `ndarray-opteinsum`. +5. Include `README.md` as crate docs with `#![doc = include_str!("../README.md")]`. + +### Task 2: Centralize Cargo Metadata and Dependencies + +**Files:** +- Modify: `Cargo.toml` +- Modify: all workspace member `Cargo.toml` files + +**Steps:** +1. Add `[workspace.package]` for version, authors, license, repository, and edition. +2. Add `[workspace.dependencies]` for shared external dependencies and internal crates with `version + path`. +3. Convert package metadata and dependency declarations to `workspace = true` where practical. +4. Keep explicit `rust-version` where current crates already need different MSRV values. +5. Do not run `cargo publish`. + +### Task 3: Make README Examples Executable + +**Files:** +- Modify: `README.md` +- Create/Modify: `strided-rs/README.md` +- Modify: `.github/workflows/ci.yml` + +**Steps:** +1. Move the user-facing Quick Start to `strided-rs/README.md`. +2. Keep root README as workspace guidance and link to the facade crate README. +3. Ensure Rust examples in `strided-rs/README.md` are complete doctests. +4. Add an explicit CI step for `cargo test -p strided-rs --doc`. + +### Task 4: Verify + +**Commands:** +- `cargo fmt --check` +- `cargo test --workspace` +- `cargo test -p strided-rs --doc` +- `cargo publish --workspace --dry-run` only as a dry-run, never without `--dry-run` + +**Expected Result:** Formatting and tests pass. Publish dry-run either passes or reports only issues that require actual registry state or final release decisions. diff --git a/mdarray-opteinsum/Cargo.toml b/mdarray-opteinsum/Cargo.toml index 5e94fd6..89f7315 100644 --- a/mdarray-opteinsum/Cargo.toml +++ b/mdarray-opteinsum/Cargo.toml @@ -1,22 +1,21 @@ [package] name = "mdarray-opteinsum" -version = "0.1.0" +version.workspace = true edition = "2024" rust-version = "1.89" -license = "MIT OR Apache-2.0" -authors = ["Satoshi Terasaki", "Hiroshi Shinaoka"] -repository = "https://github.com/tensor4all/strided-rs" +license.workspace = true +authors.workspace = true +repository.workspace = true description = "N-ary einsum frontend for mdarray arrays, powered by strided-opteinsum." -publish = false [dependencies] -mdarray = "0.8.0" -strided-opteinsum = { path = "../strided-opteinsum", default-features = false } -strided-view = { path = "../strided-view" } -strided-kernel = { path = "../strided-kernel" } -num-complex = "0.4" -num-traits = "0.2" -thiserror = "1.0" +mdarray.workspace = true +strided-opteinsum = { workspace = true, default-features = false } +strided-view.workspace = true +strided-kernel.workspace = true +num-complex.workspace = true +num-traits.workspace = true +thiserror.workspace = true [features] default = ["faer"] @@ -24,5 +23,5 @@ faer = ["strided-opteinsum/faer"] blas = ["strided-opteinsum/blas"] [dev-dependencies] -approx = "0.5" -num-complex = "0.4" +approx.workspace = true +num-complex.workspace = true diff --git a/ndarray-opteinsum/Cargo.toml b/ndarray-opteinsum/Cargo.toml index fd08cf2..c31a1d7 100644 --- a/ndarray-opteinsum/Cargo.toml +++ b/ndarray-opteinsum/Cargo.toml @@ -1,22 +1,21 @@ [package] name = "ndarray-opteinsum" -version = "0.1.0" -edition = "2021" +version.workspace = true +edition.workspace = true rust-version = "1.64" -license = "MIT OR Apache-2.0" -authors = ["Satoshi Terasaki", "Hiroshi Shinaoka"] -repository = "https://github.com/tensor4all/strided-rs" +license.workspace = true +authors.workspace = true +repository.workspace = true description = "N-ary einsum frontend for ndarray arrays, powered by strided-opteinsum." -publish = false [dependencies] -ndarray = "0.17" -strided-opteinsum = { path = "../strided-opteinsum", default-features = false } -strided-view = { path = "../strided-view" } -strided-kernel = { path = "../strided-kernel" } -num-complex = "0.4" -num-traits = "0.2" -thiserror = "1.0" +ndarray.workspace = true +strided-opteinsum = { workspace = true, default-features = false } +strided-view.workspace = true +strided-kernel.workspace = true +num-complex.workspace = true +num-traits.workspace = true +thiserror.workspace = true [features] default = ["faer"] @@ -24,5 +23,5 @@ faer = ["strided-opteinsum/faer"] blas = ["strided-opteinsum/blas"] [dev-dependencies] -approx = "0.5" -num-complex = "0.4" +approx.workspace = true +num-complex.workspace = true diff --git a/strided-einsum2/Cargo.toml b/strided-einsum2/Cargo.toml index 8968bb6..b32befc 100644 --- a/strided-einsum2/Cargo.toml +++ b/strided-einsum2/Cargo.toml @@ -1,37 +1,36 @@ [package] name = "strided-einsum2" -version = "0.1.0" -edition = "2021" -license = "MIT OR Apache-2.0" -authors = ["Satoshi Terasaki", "Hiroshi Shinaoka"] -repository = "https://github.com/tensor4all/strided-rs" +version.workspace = true +edition.workspace = true +license.workspace = true +authors.workspace = true +repository.workspace = true description = "Binary einsum (pairwise tensor contraction) on strided views." -publish = false [dependencies] -strided-traits = { path = "../strided-traits" } -strided-view = { path = "../strided-view" } -strided-kernel = { path = "../strided-kernel" } -strided-perm = { path = "../strided-perm" } -num-traits = "0.2" -thiserror = "1.0" -faer = { version = "0.24", optional = true } -faer-traits = { version = "0.24", optional = true } -cblas-sys = { version = "0.2", optional = true } -cblas-inject = { version = "0.1", optional = true } -num-complex = { version = "0.4", optional = true } -rayon = { version = "1.10", optional = true } +strided-traits.workspace = true +strided-view.workspace = true +strided-kernel.workspace = true +strided-perm.workspace = true +num-traits.workspace = true +thiserror.workspace = true +faer = { workspace = true, optional = true } +faer-traits = { workspace = true, optional = true } +cblas-sys = { workspace = true, optional = true } +cblas-inject = { workspace = true, optional = true } +num-complex = { workspace = true, optional = true } +rayon = { workspace = true, optional = true } [features] default = ["faer", "faer-traits"] -parallel = ["rayon", "strided-kernel/parallel", "strided-perm/parallel"] +parallel = ["dep:rayon", "strided-kernel/parallel", "strided-perm/parallel"] blas = ["dep:cblas-sys", "dep:num-complex"] blas-inject = ["dep:cblas-inject", "dep:num-complex"] [dev-dependencies] -approx = "0.5" -num-complex = "0.4" -rand = "0.8" +approx.workspace = true +num-complex.workspace = true +rand.workspace = true [lib] bench = false diff --git a/strided-einsum2/src/backend.rs b/strided-einsum2/src/backend.rs index 5d0a6a0..0c35e90 100644 --- a/strided-einsum2/src/backend.rs +++ b/strided-einsum2/src/backend.rs @@ -1,7 +1,7 @@ //! Backend abstraction for batched GEMM dispatch. //! //! This module defines the [`Backend`] trait, marker structs for each backend, -//! and the [`ActiveBackend`] type alias that serves as the single point of +//! and the `ActiveBackend` type alias that serves as the single point of //! backend selection based on Cargo features. /// Trait for backends that can execute batched GEMM on contiguous operands. @@ -95,10 +95,10 @@ impl Backend for NaiveBackend { /// The active GEMM backend, selected by Cargo features. /// -/// - `faer` (without blas/blas-inject) -> [`FaerBackend`] -/// - `blas` or `blas-inject` (without faer) -> [`BlasBackend`] -/// - no backend feature -> [`NaiveBackend`] -/// - invalid combos -> [`NaiveBackend`] (placeholder; `compile_error!` fires first) +/// - `faer` (without blas/blas-inject) -> `FaerBackend` +/// - `blas` or `blas-inject` (without faer) -> `BlasBackend` +/// - no backend feature -> `NaiveBackend` +/// - invalid combos -> `NaiveBackend` (placeholder; `compile_error!` fires first) #[cfg(all(feature = "faer", not(any(feature = "blas", feature = "blas-inject"))))] pub type ActiveBackend = FaerBackend; diff --git a/strided-kernel/Cargo.toml b/strided-kernel/Cargo.toml index 37ce38c..caa449a 100644 --- a/strided-kernel/Cargo.toml +++ b/strided-kernel/Cargo.toml @@ -1,33 +1,32 @@ [package] name = "strided-kernel" -version = "0.1.0" -edition = "2021" -license = "MIT OR Apache-2.0" -authors = ["Satoshi Terasaki", "Hiroshi Shinaoka"] -repository = "https://github.com/tensor4all/strided-rs" +version.workspace = true +edition.workspace = true +license.workspace = true +authors.workspace = true +repository.workspace = true description = "Cache-optimized kernels for strided multidimensional array operations in Rust (ported from Julia Strided.jl/StridedViews.jl)." -publish = false [dependencies] -strided-view = { path = "../strided-view" } -strided-perm = { path = "../strided-perm" } -num-traits = "0.2" -num-complex = "0.4" -rayon = { version = "1.10", optional = true } -smallvec = { version = "1", optional = true } -pulp = { version = "0.22", optional = true } +strided-view.workspace = true +strided-perm.workspace = true +num-traits.workspace = true +num-complex.workspace = true +rayon = { workspace = true, optional = true } +smallvec = { workspace = true, optional = true } +pulp = { workspace = true, optional = true } [features] default = ["simd"] -parallel = ["rayon", "smallvec", "strided-perm/parallel"] +parallel = ["dep:rayon", "dep:smallvec", "strided-perm/parallel"] simd = ["dep:pulp"] [dev-dependencies] -criterion = "0.5" -approx = "0.5" -rand = "0.8" -rand_distr = "0.4" -num-complex = "0.4" +criterion.workspace = true +approx.workspace = true +rand.workspace = true +rand_distr.workspace = true +num-complex.workspace = true [lib] bench = false diff --git a/strided-opteinsum/Cargo.toml b/strided-opteinsum/Cargo.toml index aa2ad99..2e20e15 100644 --- a/strided-opteinsum/Cargo.toml +++ b/strided-opteinsum/Cargo.toml @@ -1,16 +1,21 @@ [package] name = "strided-opteinsum" -version = "0.1.0" -edition = "2021" +version.workspace = true +edition.workspace = true +license.workspace = true +authors.workspace = true +repository.workspace = true +description = "N-ary einsum frontend with contraction-order optimization for strided tensors." +readme = "README.md" [dependencies] -strided-view = { path = "../strided-view" } -strided-kernel = { path = "../strided-kernel" } -strided-einsum2 = { path = "../strided-einsum2", default-features = false } -omeco = "0.2" -num-complex = "0.4" -num-traits = "0.2" -thiserror = "1.0" +strided-view.workspace = true +strided-kernel.workspace = true +strided-einsum2 = { workspace = true, default-features = false } +omeco.workspace = true +num-complex.workspace = true +num-traits.workspace = true +thiserror.workspace = true [features] default = ["faer"] @@ -20,10 +25,10 @@ blas = ["strided-einsum2/blas"] blas-inject = ["strided-einsum2/blas-inject"] [dev-dependencies] -approx = "0.5" -num-complex = "0.4" -rand = "0.8" -strided-view = { path = "../strided-view" } +approx.workspace = true +num-complex.workspace = true +rand.workspace = true +strided-view.workspace = true [lib] bench = false diff --git a/strided-perm/Cargo.toml b/strided-perm/Cargo.toml index 79cdcdd..13a8021 100644 --- a/strided-perm/Cargo.toml +++ b/strided-perm/Cargo.toml @@ -1,25 +1,24 @@ [package] name = "strided-perm" -version = "0.1.0" -edition = "2021" -license = "MIT OR Apache-2.0" -authors = ["Satoshi Terasaki", "Hiroshi Shinaoka"] -repository = "https://github.com/tensor4all/strided-rs" +version.workspace = true +edition.workspace = true +license.workspace = true +authors.workspace = true +repository.workspace = true description = "Cache-efficient tensor permutation / transpose (HPTT-inspired)." -publish = false [dependencies] -strided-view = { path = "../strided-view" } -rayon = { version = "1.10", optional = true } +strided-view.workspace = true +rayon = { workspace = true, optional = true } [features] -parallel = ["rayon"] +parallel = ["dep:rayon"] [dev-dependencies] -criterion = "0.5" -rand = "0.8" -rand_distr = "0.4" -rayon = "1.10" +criterion.workspace = true +rand.workspace = true +rand_distr.workspace = true +rayon.workspace = true [lib] bench = false diff --git a/strided-rs/Cargo.toml b/strided-rs/Cargo.toml new file mode 100644 index 0000000..3046c35 --- /dev/null +++ b/strided-rs/Cargo.toml @@ -0,0 +1,53 @@ +[package] +name = "strided-rs" +version.workspace = true +edition.workspace = true +license.workspace = true +authors.workspace = true +repository.workspace = true +description = "User-facing facade crate for the strided-rs workspace." +readme = "README.md" + +[dependencies] +strided-traits.workspace = true +strided-view.workspace = true +strided-perm.workspace = true +strided-kernel.workspace = true +strided-einsum2 = { workspace = true, default-features = false, optional = true } +strided-opteinsum = { workspace = true, default-features = false, optional = true } +mdarray-opteinsum = { workspace = true, default-features = false, optional = true } +ndarray-opteinsum = { workspace = true, default-features = false, optional = true } + +[features] +default = ["faer"] +faer = [ + "dep:strided-einsum2", + "dep:strided-opteinsum", + "strided-einsum2/faer", + "strided-einsum2/faer-traits", + "strided-opteinsum/faer", + "mdarray-opteinsum?/faer", + "ndarray-opteinsum?/faer", +] +parallel = [ + "strided-perm/parallel", + "strided-kernel/parallel", + "strided-einsum2?/parallel", + "strided-opteinsum?/parallel", +] +blas = [ + "dep:strided-einsum2", + "dep:strided-opteinsum", + "strided-einsum2/blas", + "strided-opteinsum/blas", + "mdarray-opteinsum?/blas", + "ndarray-opteinsum?/blas", +] +blas-inject = [ + "dep:strided-einsum2", + "dep:strided-opteinsum", + "strided-einsum2/blas-inject", + "strided-opteinsum/blas-inject", +] +mdarray = ["dep:mdarray-opteinsum"] +ndarray = ["dep:ndarray-opteinsum"] diff --git a/strided-rs/README.md b/strided-rs/README.md new file mode 100644 index 0000000..65df1ff --- /dev/null +++ b/strided-rs/README.md @@ -0,0 +1,63 @@ +# strided-rs + +`strided-rs` is the recommended entry point for the strided-rs workspace. It +re-exports the core strided view, kernel, permutation, and einsum crates so most +users can depend on one package. + +## Installation + +```toml +[dependencies] +strided-rs = "0.1" +``` + +Use individual crates such as `strided-perm`, `strided-view`, or +`strided-kernel` directly when you want a smaller dependency surface or a +lower-level API. + +## Quick Start + +```rust +use strided_rs::{map_into, StridedArray}; + +let src = StridedArray::::from_fn_row_major(&[2, 3], |idx| { + (idx[0] * 10 + idx[1]) as f64 +}); +let mut dest = StridedArray::::row_major(&[2, 3]); + +map_into(&mut dest.view_mut(), &src.view(), |x| x * 2.0).unwrap(); + +assert_eq!(dest.get(&[1, 2]), 24.0); +``` + +## Feature Flags + +- `faer` (default): enables the `faer` backend for einsum contractions. +- `parallel`: enables Rayon-backed parallel kernels where available. +- `blas`: enables the CBLAS backend for einsum contractions. +- `blas-inject`: enables BLAS through `cblas-inject`. +- `mdarray`: re-exports the `mdarray-opteinsum` frontend as `strided_rs::mdarray`. +- `ndarray`: re-exports the `ndarray-opteinsum` frontend as `strided_rs::ndarray`. + +`faer`, `blas`, and `blas-inject` are mutually exclusive at the einsum backend +level. Disable default features when selecting a BLAS backend. If default +features are disabled, enable one backend feature when using einsum APIs or the +`mdarray` / `ndarray` frontends: + +```toml +[dependencies] +strided-rs = { version = "0.1", default-features = false, features = ["blas"] } +``` + +## Namespaced APIs + +The facade exposes lower-level crates under modules: + +- `strided_rs::traits` +- `strided_rs::view` +- `strided_rs::perm` +- `strided_rs::kernel` +- `strided_rs::einsum2` +- `strided_rs::opteinsum` + +The individual crates remain public and can be used directly. diff --git a/strided-rs/src/lib.rs b/strided-rs/src/lib.rs new file mode 100644 index 0000000..2b9aa6a --- /dev/null +++ b/strided-rs/src/lib.rs @@ -0,0 +1,63 @@ +#![doc = include_str!("../README.md")] + +/// Shared scalar and element-operation traits. +pub mod traits { + pub use strided_traits::*; +} + +/// Strided view and owned strided array types. +pub mod view { + pub use strided_view::*; +} + +/// Cache-efficient tensor permutation and transpose routines. +pub mod perm { + pub use strided_perm::*; +} + +/// Cache-optimized map, reduce, and elementwise kernels. +pub mod kernel { + pub use strided_kernel::*; +} + +/// Binary einsum contractions on strided views. +#[cfg(any(feature = "faer", feature = "blas", feature = "blas-inject"))] +pub mod einsum2 { + pub use strided_einsum2::*; +} + +/// N-ary optimized einsum frontend. +#[cfg(any(feature = "faer", feature = "blas", feature = "blas-inject"))] +pub mod opteinsum { + pub use strided_opteinsum::*; +} + +/// `mdarray` einsum frontend. +#[cfg(feature = "mdarray")] +pub mod mdarray { + pub use mdarray_opteinsum::*; +} + +/// `ndarray` einsum frontend. +#[cfg(feature = "ndarray")] +pub mod ndarray { + pub use ndarray_opteinsum::*; +} + +pub use strided_kernel::{ + add, axpy, copy_conj, copy_into, copy_into_col_major, copy_scale, copy_transpose_scale_into, + dot, fma, map_into, mul, reduce, reduce_axis, sum, symmetrize_conj_into, symmetrize_into, + zip_map2_into, zip_map3_into, zip_map4_into, MaybeSimdOps, +}; +#[cfg(any(feature = "faer", feature = "blas", feature = "blas-inject"))] +pub use strided_opteinsum::{ + einsum, einsum_into, einsum_into_with_pool, einsum_with_pool, BufferPool, EinsumCode, + EinsumError, EinsumNode, EinsumOperand, EinsumScalar, StridedData, TypedTensor, +}; +pub use strided_traits::{ + Adjoint, ComposableElementOp, Compose, Conj, ElementOp, ElementOpApply, Identity, ScalarBase, + Transpose, +}; +pub use strided_view::{ + col_major_strides, row_major_strides, StridedArray, StridedError, StridedView, StridedViewMut, +}; diff --git a/strided-traits/Cargo.toml b/strided-traits/Cargo.toml index 8cb30b5..129eaa1 100644 --- a/strided-traits/Cargo.toml +++ b/strided-traits/Cargo.toml @@ -1,13 +1,12 @@ [package] name = "strided-traits" -version = "0.1.0" -edition = "2021" -license = "MIT OR Apache-2.0" -authors = ["Satoshi Terasaki", "Hiroshi Shinaoka"] -repository = "https://github.com/tensor4all/strided-rs" +version.workspace = true +edition.workspace = true +license.workspace = true +authors.workspace = true +repository.workspace = true description = "Shared traits for strided-rs: element operations, scalar bounds, and type-level composition." -publish = false [dependencies] -num-traits = "0.2" -num-complex = "0.4" +num-traits.workspace = true +num-complex.workspace = true diff --git a/strided-traits/README.md b/strided-traits/README.md new file mode 100644 index 0000000..37899ba --- /dev/null +++ b/strided-traits/README.md @@ -0,0 +1,10 @@ +# strided-traits + +Shared traits for the strided-rs ecosystem. + +This crate contains scalar bounds and lazy element-operation traits used by +`strided-view`, `strided-kernel`, `strided-einsum2`, and downstream extension +crates. Most users should depend on the `strided-rs` facade crate instead. + +Depend on `strided-traits` directly when implementing custom scalar types or +element operations for the lower-level crates. diff --git a/strided-view/Cargo.toml b/strided-view/Cargo.toml index bc389d0..bdcbc74 100644 --- a/strided-view/Cargo.toml +++ b/strided-view/Cargo.toml @@ -1,15 +1,14 @@ [package] name = "strided-view" -version = "0.1.0" -edition = "2021" -license = "MIT OR Apache-2.0" -authors = ["Satoshi Terasaki", "Hiroshi Shinaoka"] -repository = "https://github.com/tensor4all/strided-rs" +version.workspace = true +edition.workspace = true +license.workspace = true +authors.workspace = true +repository.workspace = true description = "Device-agnostic strided view types and metadata operations (ported from Julia StridedViews.jl)." -publish = false [dependencies] -strided-traits = { path = "../strided-traits" } -num-traits = "0.2" -num-complex = "0.4" -thiserror = "1.0" +strided-traits.workspace = true +num-traits.workspace = true +num-complex.workspace = true +thiserror.workspace = true