From 42fdc38395ae230ec7d763e55f67377fea27e8ba Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 30 Oct 2026 16:20:45 +0000 Subject: [PATCH 1/2] simd: re-export checked i64 arithmetic through the facade checked_binary_i64, checked_i64, range_i64, range_len_i64, I64Op and I64ArithError were reachable only as ndarray::hpc::checked_i64, so a consumer (the DT64 bind store binding XLOG's count, ONNX int64 Mul) had to name hpc. Plain re-exports: same functions, same refusal policy. The test imports through the facade path, so dropping the re-export fails to build. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01XAqKMPh2Seh2WLccCksAdY --- src/simd.rs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/simd.rs b/src/simd.rs index 2b297fba..4b0b0105 100644 --- a/src/simd.rs +++ b/src/simd.rs @@ -714,6 +714,10 @@ pub use crate::hpc::fingerprint::{ }; pub use crate::hpc::phase::{phase_lut_4096, radians_from_turns, turns_from_radians, PhaseLut, PhaseStep}; pub use crate::hpc::statistics::{moments_u32, MomentsU32}; +// Checked i64 arithmetic (ONNX int64 Add/Sub/Mul/Div and Range), surfaced so +// consumers name it through the facade, never through `hpc`. Plain re-exports: +// same functions, same refusal policy. +pub use crate::hpc::checked_i64::{checked_binary_i64, checked_i64, range_i64, range_len_i64, I64ArithError, I64Op}; // Element-wise f32 math (VML), activations and the batched f32 matmul, // surfaced so consumers stay on the one `ndarray::simd::*` import path. // Plain re-exports of the `hpc` items: same functions, same behaviour. @@ -2754,3 +2758,27 @@ mod reinterpret_bits_parity { assert_eq!(r, [-512; 16]); } } + +#[cfg(test)] +mod checked_i64_facade { + // Imported through the facade path, so a missing re-export fails to build. + use super::{checked_binary_i64, checked_i64, I64ArithError, I64Op}; + + #[test] + fn the_facade_word_multiplies_and_refuses_overflow() { + let mut out = [0i64; 3]; + checked_binary_i64(I64Op::Mul, &[4, 1, 1], &[1, 1, 1], &mut out).unwrap(); + assert_eq!(out, [4, 1, 1]); + assert_eq!( + checked_binary_i64(I64Op::Mul, &[i64::MAX, 2, 3], &[2], &mut out), + Err(I64ArithError::Overflow { + op: I64Op::Mul, + position: 0, + lhs: i64::MAX, + rhs: 2 + }) + ); + assert_eq!(out, [4, 1, 1], "nothing is written on refusal"); + assert_eq!(checked_i64(I64Op::Mul, -3, 7), Ok(-21)); + } +} From 8f67171f5427ce45752757dc3b4aa95b0413e975 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 30 Oct 2026 16:23:10 +0000 Subject: [PATCH 2/2] simd: doctest the checked i64 re-export from outside the crate The in-crate test sees a private use; the doctest is a consumer, so it fails to build if the re-export is not public. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01XAqKMPh2Seh2WLccCksAdY --- src/simd.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/simd.rs b/src/simd.rs index 4b0b0105..8c6d9628 100644 --- a/src/simd.rs +++ b/src/simd.rs @@ -717,6 +717,17 @@ pub use crate::hpc::statistics::{moments_u32, MomentsU32}; // Checked i64 arithmetic (ONNX int64 Add/Sub/Mul/Div and Range), surfaced so // consumers name it through the facade, never through `hpc`. Plain re-exports: // same functions, same refusal policy. +/// +/// ``` +/// use ndarray::simd::{checked_binary_i64, I64ArithError, I64Op}; +/// let mut out = [0i64; 2]; +/// checked_binary_i64(I64Op::Mul, &[4, 3], &[2], &mut out).unwrap(); +/// assert_eq!(out, [8, 6]); +/// assert!(matches!( +/// checked_binary_i64(I64Op::Mul, &[i64::MAX, 1], &[2], &mut out), +/// Err(I64ArithError::Overflow { .. }) +/// )); +/// ``` pub use crate::hpc::checked_i64::{checked_binary_i64, checked_i64, range_i64, range_len_i64, I64ArithError, I64Op}; // Element-wise f32 math (VML), activations and the batched f32 matmul, // surfaced so consumers stay on the one `ndarray::simd::*` import path.