rust-ndarray / ndarray

ndarray: an N-dimensional array with array views, multidimensional slicing, and efficient operations

Home Page:https://docs.rs/ndarray/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Panic in linear algebra with rustc 1.70

Luthaf opened this issue · comments

Rustc started to add runtime checks for pointer alignment when running with debug assertions (rust-lang/rust#98112), and I'm hitting this with pure ndarray code (the assertion comes from inside matrixmultiply, I can move the issue there if you prefer). Here is the code to reproduce:

# file: Cargo.toml
[package]
name = "unaligned-ndarray"
version = "0.1.0"
edition = "2021"

[dependencies]
ndarray = "=0.15.6"
matrixmultiply = "=0.3.7"
// file: src/main.rs
use ndarray::arr2;

fn main() {
    let eigenvalues = arr2(&[
        [18.116246041742507, 0.0, 0.0, 0.0, 0.0, 0.0],
        [0.0, 5.805039200355111, 0.0, 0.0, 0.0, 0.0],
        [0.0, 0.0, 2.927806035063571, 0.0, 0.0, 0.0],
        [0.0, 0.0, 0.0, 1.2613436289637108, 0.0, 0.0],
        [0.0, 0.0, 0.0, 0.0, 0.7165245981172256, 0.0],
        [0.0, 0.0, 0.0, 0.0, 0.0, 0.5526372670286159],
    ]);

    let eigenvectors = arr2(&[
        [-0.10351332412686326, -0.4623184729990635, 0.46449894659535196, -0.4203749636311023, -0.5470018106358486, 0.2895880850053783],
        [0.20981505566105116, 0.6470517590244376, -0.3132200413226277, -0.1691738276421041, -0.5396669852908671, 0.34544844811226105],
        [-0.358982796007903, -0.3525936483472587, -0.4379262883013029, 0.5500889201658851, -0.18043800962037712, 0.4689071783680957],
        [0.6169286555756925, 0.00961938345319455, 0.42590724690207227, 0.39057345164956947, 0.19907003544487653, 0.4957146540928189],
        [-0.6072205669943727, 0.39430954416709896, 0.3038644014916453, -0.15477956133038978, 0.3966660481310112, 0.4496319890292384],
        [0.25899073972848086, -0.29612635926759445, -0.46970623040654336, -0.5617499017932381, 0.42428511178276024, 0.3592049901572456],
    ]);

    let a = eigenvectors.dot(&eigenvalues);
    let a = a.dot(&eigenvectors.t());

    println!("{:?}", a);
}
$ rustc -vV
rustc 1.72.0 (5680fa18f 2023-08-23)
binary: rustc
commit-hash: 5680fa18feaa87f3ff04063800aec256c3d4b4be
commit-date: 2023-08-23
host: aarch64-apple-darwin
release: 1.72.0
LLVM version: 16.0.5

Running this give this panic & backtrace:

$ RUST_BACKTRACE=1 cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.01s
     Running `target/debug/unaligned-ndarray`
thread 'main' panicked at 'misaligned pointer dereference: address must be a multiple of 0x10 but is 0x13df040d8', ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/matrixmultiply-0.3.7/src/gemm.rs:395:43
stack backtrace:
   0: rust_begin_unwind
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library/std/src/panicking.rs:593:5
   1: core::panicking::panic_nounwind_fmt
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library/core/src/panicking.rs:96:14
   2: core::panicking::panic_misaligned_pointer_dereference
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library/core/src/panicking.rs:175:5
   3: matrixmultiply::gemm::gemm_packed::{{closure}}::{{closure}}
             at ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/matrixmultiply-0.3.7/src/gemm.rs:395:43
   4: std::thread::local::LocalKey<T>::try_with
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library/std/src/thread/local.rs:270:16
   5: std::thread::local::LocalKey<T>::with
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library/std/src/thread/local.rs:246:9
   6: matrixmultiply::gemm::gemm_packed::{{closure}}
             at ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/matrixmultiply-0.3.7/src/gemm.rs:395:23
   7: matrixmultiply::threading::RangeChunkParallel<G>::for_each
             at ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/matrixmultiply-0.3.7/src/threading.rs:220:25
   8: matrixmultiply::gemm::gemm_packed
             at ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/matrixmultiply-0.3.7/src/gemm.rs:384:5
   9: matrixmultiply::gemm::gemm_loop::{{closure}}
             at ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/matrixmultiply-0.3.7/src/gemm.rs:327:21
  10: matrixmultiply::threading::RangeChunkParallel<G>::for_each
             at ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/matrixmultiply-0.3.7/src/threading.rs:222:13
  11: matrixmultiply::gemm::gemm_loop
             at ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/matrixmultiply-0.3.7/src/gemm.rs:310:13
  12: <matrixmultiply::gemm::GemmParameters<T> as matrixmultiply::kernel::GemmSelect<T>>::select
             at ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/matrixmultiply-0.3.7/src/gemm.rs:211:13
  13: matrixmultiply::dgemm_kernel::detect
             at ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/matrixmultiply-0.3.7/src/dgemm_kernel.rs:65:20
  14: matrixmultiply::gemm::dgemm
             at ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/matrixmultiply-0.3.7/src/gemm.rs:91:5
  15: ndarray::linalg::impl_linalg::mat_mul_general
             at ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ndarray-0.15.6/src/linalg/impl_linalg.rs:527:13
  16: <ndarray::ArrayBase<S,ndarray::dimension::dim::Dim<[usize; 2]>> as ndarray::linalg::impl_linalg::Dot<ndarray::ArrayBase<S2,ndarray::dimension::dim::Dim<[usize; 2]>>>>::dot
             at ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ndarray-0.15.6/src/linalg/impl_linalg.rs:286:9
  17: ndarray::linalg::impl_linalg::<impl ndarray::ArrayBase<S,ndarray::dimension::dim::Dim<[usize; 2]>>>::dot
             at ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ndarray-0.15.6/src/linalg/impl_linalg.rs:257:9
  18: unaligned_ndarray::main
             at ./src/main.rs:22:13
  19: core::ops::function::FnOnce::call_once
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library/core/src/ops/function.rs:250:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
thread caused non-unwinding panic. aborting.
commented

Thanks for the report, I think the error is a bit frustrating since matrixmultiply handles the pointer alignment correctly if it just can be allowed to continue on the next line of code. I have a bit of deja vu, thought I had handled this once before.

(turns out it's deja vu since I lowered it to 16-byte before, "worked - and still did - for me")

Thanks for the very quick fix!