Skip to content
CAI
Software that uses CAICheck a score

rust-ndarray/ndarray

69.9

Adequate · 30 September 2026

29.6k

lines of production code

Rust

primary language

2

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

This system is the ndarray library, a high-performance, n-dimensional array container for Rust that supports linear algebra, numerical operations, and parallel processing. It provides core capabilities for array construction, manipulation, and iteration, with optional BLAS acceleration for matrix operations and Rayon-based parallelism for scalable computation. The library also includes utilities for random array generation, serialization, and comprehensive testing to ensure numerical accuracy and performance.

How it got here

2014–2016 — API expansion and structural refactoring

14 changes.

This period focused on expanding the ndarray API with new features such as fixed-dimensional array aliases, a linear algebra module with BLAS support, and a dedicated crate for random array generation. The codebase underwent significant structural refactoring, including the reorganization of dimension and iterator modules, while comprehensive test suites and benchmarks were added to ensure correctness and performance.

2017–2024 — Parallel iteration and testing infrastructure

11 changes.

This period focused on introducing parallel processing capabilities through the new \ndarray::parallel\ module and \Zip\ system, enabling efficient multi-array operations via Rayon. The work also involved significant improvements to the CI infrastructure, migrating to \cargo nextest\ and expanding test coverage with dedicated crates for BLAS, serialization, and numeric accuracy.

Features

Add dot product support for ArrayD

The \ndarray\ crate now supports the \.dot()\ method on \ArrayD\ (n-dimensional arrays) for 1D and 2D data, enabling matrix multiplication and vector dot products on generic-dimensional arrays. This change includes test coverage in \crates/blas-tests\ that verifies correct results for 1D dot products, 2D matrix multiplication, and matrix-vector multiplication, while ensuring that unsupported dimensions (e.g., 3D) and incompatible shapes trigger appropriate panics.

crates/blas-tests · high confidence

Add ndarray-gen crate for test array generation

A new internal \ndarray-gen\ crate has been added to provide utilities for generating test arrays. It exposes an \ArrayBuilder\ that allows tests to construct \ndarray::Array\ instances with configurable dimensions, memory order (C or F), and element generation strategies (sequential, checkerboard, or zero-filled). This simplifies the creation of consistent test data across the project.

crates/ndarray-gen · high confidence

Add type aliases and constructors for fixed-dimensional arrays

The library now provides explicit type aliases (such as \Array1\, \Array2\, \ArrayView1\, \ArrayView2\, and \ArrayD\) and corresponding constructor functions (\Ix1\, \Ix2\, \IxDyn\) for arrays with 0 to 6 dimensions. This allows users to work with specific dimensionalities without manually specifying the generic dimension parameter, simplifying the API for common use cases.

src · high confidence

Initial project configuration and documentation scaffolding

The repository is initialized with essential project metadata and developer tooling. This includes the Apache 2.0 and MIT license files, a main README with installation and BLAS integration instructions, a quick-start tutorial, and a crates.io-specific README. Configuration files for Rust tooling (rustfmt.toml, clippy.toml) and a .gitignore for IDE and build artifacts are added. A .git-blame-ignore-revs file is created to exclude automated formatting and linting commits from blame history, and a RELEASES.md changelog is introduced to track version history.

(repo-wide) · high confidence

Introduce ndarray-rand for random array generation and sampling

Adds the ndarray-rand crate, providing the RandomExt trait to construct n-dimensional arrays with random elements drawn from distributions (e.g., Uniform) and the RandomRefExt trait to sample lanes along specific axes with or without replacement. The library integrates with rand 0.9 and rand\_distr 0.5, re-exporting these dependencies for version compatibility, and supports custom random number generators via methods like random\_using and sample\_axis\_using.

ndarray-rand/src · high confidence

Introduction of the Zip parallel iteration system

This change introduces the \Zip\ struct and the \azip!()\ macro, enabling lock-step function application across multiple n-dimensional arrays or producers. The implementation includes the \NdProducer\ and \IntoNdProducer\ traits to define how arrays and views are iterated, supporting parallel execution via \rayon\ and broadcasting capabilities. Users can now perform element-wise operations on multiple arrays simultaneously with improved performance and flexibility.

src/zip · high confidence

New 'ndarray for NumPy users' documentation guide

Added a comprehensive introductory guide for users migrating from NumPy to ndarray. The documentation covers key similarities and differences (such as ownership models and slicing behavior), provides rough equivalents for common NumPy operations, and includes detailed code examples for coordinate transformations, Runge-Kutta numerical integration, and basic array mathematics.

_src/doc/ndarray\_for\_numpy\users · high confidence

New and updated examples demonstrating ndarray API usage

The examples directory has been refreshed with new and updated files that showcase current ndarray capabilities. New examples include \axis\_ops.rs\ for array regularization (inverting, swapping, and merging axes), \bounds\_check\_elim.rs\ for demonstrating bounds-check elimination patterns, \column\_standardize.rs\ for statistical normalization using \mean\_axis\ and \std\_axis\, \convo.rs\ for convolution operations, \functions\_and\_traits.rs\ for writing generic functions with \ArrayRef\, \RawRef\, and \LayoutRef\, \life.rs\ for a Game of Life simulation, \rollaxis.rs\ for axis rotation, \sort-axis.rs\ for custom axis sorting, \type\_conversion.rs\ for safe and lossy type casting, and \zip\_many.rs\ for multi-array iteration with \Zip\ and \azip!\. These examples reflect recent API changes such as the introduction of \ArrayRef\, the deprecation of older iteration methods, and the use of \mean\_axis\/\std\_axis\.

examples · high confidence

New element-wise math and numeric aggregation methods for arrays

This change introduces a new \src/numeric\ module containing implementations for additional array operations. For float arrays, it adds a comprehensive suite of element-wise mathematical functions (such as \sin\, \cos\, \exp\, \log\, \sqrt\, \floor\, \ceil\, etc.) and boolean checks (like \is\_nan\, \is\_infinite\). It also adds core numeric aggregation methods to \ArrayRef\, including \sum\, \mean\, \product\, \cumprod\, and \var\ (variance with configurable degrees of freedom).

src/numeric · high confidence

New linear algebra module with BLAS-accelerated operations

A new \src/linalg\ module has been introduced, exposing \general\_mat\_mul\, \general\_mat\_vec\_mul\, \kron\ (Kronecker product), and the \Dot\ trait. For users with the \blas\ feature enabled, dot products and matrix-vector multiplications on \f32\ and \f64\ arrays now utilize BLAS routines (e.g., \cblas\_sdot\, \cblas\_ddot\) when vector lengths exceed specific cutoffs, providing performance improvements for large arrays. The module also includes support for complex number operations and handles edge cases such as negative strides and zero-length arrays.

src/linalg · high confidence

New ndarray::parallel module for Rayon-based parallel iteration

This change introduces the \ndarray::parallel\ module, enabling parallel processing of arrays and iterators via the Rayon library (behind the \rayon\ feature gate). It provides parallel iterator implementations for \Array\, \ArcArray\, \ArrayView\, \ArrayViewMut\, and axis iterators (\AxisIter\, \AxisChunksIter\, etc.), allowing users to use \.into\_par\_iter()\ and standard Rayon combinators. Additionally, it adds specific parallel methods to \Zip\ such as \par\_for\_each\, \par\_map\_collect\, \par\_map\_assign\_into\, and \par\_fold\, along with a \par\_azip!\ macro for concise parallel element-wise operations. The module also includes a \Parallel\ wrapper type that supports \with\_min\_len\ to control task splitting granularity.

src/parallel · high confidence

Restructured array view implementation and added new view capabilities

The \src/impl\_views\ module has been reorganized into dedicated files for constructors, conversions, indexing, and splitting, improving code maintainability. This change introduces several new capabilities for array views: \ArrayView\ and \ArrayViewMut\ now support \into\_cell\_view()\ to treat elements as \MathCell\ types for non-exclusive access, and \into\_scalar()\ for zero-dimensional views to extract single elements with extended lifetimes. Additionally, \split\_complex()\ is now available for views of complex numbers to separate real and imaginary parts, and \multi\_slice\_move()\ allows consuming a mutable view to produce multiple disjoint slices with lifetimes tied to the original data. The indexing trait \IndexLonger\ has been implemented to allow references with lifetimes matching the underlying data rather than just the view, and internal pointer arithmetic has been updated to use \offset\_from\_low\_addr\_ptr\_to\_logical\_ptr\ for correctness.

_src/impl\views · high confidence

ndarray-rand adds Apache-2.0 license and initial documentation

The ndarray-rand crate now includes an Apache-2.0 license file (dual-licensed with MIT) and a README explaining how to use the library's random array generation features, such as \Array::random\ with \Uniform\ distributions. The release log confirms this is the initial public release (0.11.0) requiring ndarray 0.13 and rand 0.7, with re-exports of \rand\ and \rand\_distr\ for version compatibility.

ndarray-rand · high confidence

Architecture

Refactor dimension module into separate files

The internal dimension module has been reorganized into distinct source files (axes, axis, broadcast, conversion, dim, dimension\_trait, dynindeximpl, macros, mod, ndindex, ops, remove\_axis, reshape, sequence) to improve code maintainability and prepare for further splitting. This change is purely structural and does not alter the public API or behavior of the library.

src/dimension · high confidence

Behavioural changes

CI scripts migrated to nextest and reorganized

The project's CI testing infrastructure has been refactored to use \cargo nextest\ instead of the standard \cargo test\, improving test execution efficiency and reporting. Several shell scripts in the \scripts/\ directory have been restructured: \all-tests.sh\ now orchestrates builds and tests across various feature combinations (including \no\_std\, \approx\, \blas\, and \ndarray-rand\), \blas-integ-tests.sh\ handles specific BLAS integration checks, \cross-tests.sh\ manages cross-compilation testing, \miri-tests.sh\ runs Miri safety checks (excluding BLAS features due to cblas limitations), and \makechangelog.sh\ automates changelog generation using the GitHub CLI. This change also introduces dedicated scripts for Miri and BLAS integration, separating concerns from the main test runner.

scripts · high confidence

Internal layout representation refactored with improved debug formatting

The internal \Layout\ type, used to describe array memory ordering (C vs F order), has been restructured into its own module with a new \layoutfmt.rs\ file. This change introduces a \Debug\ implementation that displays layouts as readable names (e.g., "C", "F", "Custom") alongside their hex bitset values, improving diagnostics for developers. The core \Layout\ struct remains a private bitset (\u32\) with \pub(crate)\ constructors and methods, ensuring users continue to interact with arrays normally while the library gains better internal clarity and test coverage for layout detection.

src/layout · high confidence

Refactored iterator module structure and renamed chunk/window iterators

The iterator implementation has been reorganized into a dedicated \src/iterators\ module with separate files for chunks, lanes, windows, and into-iterators. As part of this refactor, \whole\_chunks\ has been renamed to \exact\_chunks\ (with \ExactChunks\ and \ExactChunksIter\ types), and \inners\ has been renamed to \lanes\ (with \Lanes\ and \LanesIter\ types). The \Baseiter\ internal iterator now uses \NonNull\ for its pointer storage, and new iterator types like \IntoIter\ for owned arrays and \AxisWindows\ with stride support have been introduced.

src/iterators · high confidence

Test coverage

Add comprehensive benchmark suite for ndarray operations; Add numeric accuracy tests for matrix operations; Added benchmarks for random array generation; Added comprehensive test suite for ndarray core functionality; Added serialization tests for ndarray arrays; Added tests for ndarray-rand sampling and random array generation; Added tests to verify BLAS usage in matrix multiplication.

Dependencies

ndarray 0.17.2 release with workspace restructuring and dependency updates

This release updates the ndarray crate to version 0.17.2 and reorganizes the project into a Cargo workspace. The main crate now depends on num-integer 0.1.39, num-traits 0.2, num-complex 0.4, approx 0.5, and itertools 0.13.0, while integrating matrixmultiply 0.3.2 for matrix operations. The workspace includes new sub-crates for testing: ndarray-rand (0.16.0), ndarray-gen, blas-tests, blas-mock-tests, numeric-tests, and serialization-tests. The serialization-tests crate pins rmp-serde to versions \>=1.1.1 to address a security vulnerability in earlier versions. The project also updates its Minimum Supported Rust Version (MSRV) to 1.87 and uses the Cargo resolver version 2.

(dependencies) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

Score

  • CAI 70 → 70 (-0.2)
  • Rubric changed (rubric-2026.09.11 → rubric-2026.09.18) — scores are not directly comparable.

Lenses

  • Code Health 96 → 96 (+0.0)
  • Architecture 100 → 95 (-5.2)
  • Maturity 53 → 52 (-0.1)
  • Readiness 76 → 80 (+3.5)
  • Security 88 → 93 (+4.3)
  • Performance 85 (new)

Resolved (3)

  • Concentrated knowledge decay
  • Documentation: no installation or build instructions (README.rst)
  • Off-boarding risk: anonymized user #1

New (22)

  • Confusing overlap: to_owned and into_owned are present on ArrayBase. In Rust, to_owned typically clones data (borrowing self), while into_owned consumes self. However, ArrayBase is often generic over its data representation. If ArrayBase is already owned, to_owned might be a no-op clone, while into_owned consumes. If ArrayBase is a view, both might behave similarly but with different ownership semantics. The presence of both on the same type without clear distinction in the signature (e.g., &self vs self) in the summary suggests potential confusion, especially since Data trait also has into_owned and try_into_owned_nocopy. Specifically, ArrayBase having both to_owned and into_owned is standard, but Data trait also exposes into_owned. The inconsistency is more about the trait vs impl duplication, but within ArrayBase, having both is acceptable IF signatures differ by receiver. Assuming standard Rust conventions, this is likely consistent. However, looking at Data trait: Data.into_owned vs Data.try_into_owned_nocopy. This is fine. Let's look closer at ArrayBase. to_owned takes &self, into_owned takes self. This is consistent. I will remove this from inconsistencies if I am sure. Wait, Data trait has into_owned. ArrayBase has into_owned and to_owned. This is consistent. I will skip this one.
  • Documentation: no architecture or design documentation (README.rst)
  • Dormant codebase
  • Duplicate intent: See first inconsistency. These are likely the same operation.
  • Duplicate intent: See second inconsistency. These are likely the same operation.
  • Duplicate intent: permuted_axes and permute_axes appear to perform the same axis permutation operation. The naming convention is inconsistent (one uses the past participle 'permuted', the other the verb 'permute'), and both likely return a new array with reordered axes.
  • Duplicate intent: reshape and into_shape both change the shape of the array. reshape typically allows for non-contiguous views (if possible) or clones, while into_shape consumes the array. However, into_shape_clone also exists. The existence of reshape, into_shape, and into_shape_clone creates a confusing triad. reshape is often a view, into_shape is a move, into_shape_clone is a clone. This is actually a distinct set of operations based on ownership and contiguity. I will skip this as they are likely distinct.
  • Duplicate intent: reversed_axes and reverse_axes appear to perform the same axis reversal operation. Similar to the previous issue, the naming is inconsistent (noun/adjective vs verb), suggesting redundant methods.
  • Inverted test pyramid
  • Low cohesion: ArrayRef (LCOM4 25) (src/lib.rs)
  • Low cohesion: Dim (LCOM4 24) (src/dimension/dim.rs)
  • Low cohesion: RawRef (LCOM4 4) (src/lib.rs)
  • Medium vulnerability: RUSTSEC-2026-0285 (Cargo.lock)
  • Naming inconsistency: random vs random_using. The random method likely uses a default/global RNG, while random_using takes an explicit RNG. This is a common pattern (e.g., map vs map_with), but the suffix _using is less idiomatic than _with or just overloading if possible. However, since Rust doesn't support overloading, this is a minor stylistic issue. Is it an inconsistency? sample_axis vs sample_axis_using. It is consistent within the module. I will skip this as it is internally consistent.
  • Off the main sequence: ndarray-rand
  • Off-boarding risk: anonymized user #1
  • Outdated: libc
  • Outdated: matrixmultiply
  • Outdated: portable-atomic
  • Outdated: portable-atomic-util
  • …and 2 more

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

rust-ndarray/ndarray was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 30 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit bd3ade99c1f6d1fbd0f31866153e2d155e7b75ab — the exact code this score is about.
  • Scored under rubric-2026.09.18 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-cb25ca4feafa.