From 9b34495c02e62a95a8210b95fdff6c2ed00d2dd5 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 19 May 2026 17:47:50 +0000 Subject: [PATCH] =?UTF-8?q?test(hpc/activations):=20F-order=20=C3=97=20C-o?= =?UTF-8?q?rder=20symmetric=20counterpart=20for=20sigmoid=5Ff32?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds the F-in / C-out direction to the existing test_sigmoid_f32_c_in_f_out_mismatched_strides coverage. If a future refactor accidentally guards only the asymmetric case (e.g. `if x.is_standard_layout() != out.is_standard_layout()`), the existing C→F test would still pass while F→C silently regressed. Both directions now pin the strides-equality guard symmetrically. Cherry-picked from claude/sigmoid-stride-order-fix-MAOO0-v2 (0774bdba) — the rest of that branch is a destructive rebase pre-dating Phase-2 substrate work and is not safe to land as a PR. Only the +37-line additive test makes it into this branch. Verified: 18/18 hpc::activations tests pass on master tip 25bcafb9 (includes both test_sigmoid_f32_c_in_f_out_mismatched_strides and the new test_sigmoid_f32_f_in_c_out_mismatched_strides). --- src/hpc/activations.rs | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/hpc/activations.rs b/src/hpc/activations.rs index 30072971..77a01973 100644 --- a/src/hpc/activations.rs +++ b/src/hpc/activations.rs @@ -441,6 +441,43 @@ mod tests { assert!((out[[1, 1]] - 0.5).abs() < 1e-6, "sigmoid(0) at [1,1] = {}", out[[1, 1]]); } + // Symmetric companion to `test_sigmoid_f32_c_in_f_out_mismatched_strides`: + // F-order INPUT + C-order OUTPUT. The upstream test only covers the + // C-in-F-out direction; if a future refactor accidentally guards only + // the asymmetric case where x is C-order (e.g. `if x.is_standard_layout() + // != out.is_standard_layout()`), the C→F test would still pass while + // F→C silently regressed. Pinning both directions keeps the + // strides-equality guard symmetric. + #[test] + fn test_sigmoid_f32_f_in_c_out_mismatched_strides() { + use crate::{Array, Array2, ShapeBuilder}; + // Build an F-order input via `from_shape_vec` with the `.f()` shape + // builder. Logical contents [[0, 100], [-100, 0]] same as the C-order + // test — column-major buffer is [0, -100, 100, 0]. + let x: Array2 = + Array2::from_shape_vec((2, 2).f(), vec![0.0_f32, -100.0, 100.0, 0.0]).expect("F-order shape_vec"); + assert!(!x.is_standard_layout(), "x should be F-order"); + // Sanity-check the logical layout independent of memory order. + assert!((x[[0, 0]] - 0.0).abs() < 1e-7); + assert!((x[[0, 1]] - 100.0).abs() < 1e-7); + assert!((x[[1, 0]] - (-100.0)).abs() < 1e-7); + assert!((x[[1, 1]] - 0.0).abs() < 1e-7); + + // C-order output (the default for `Array::zeros((r, c))`). + let mut out: Array2 = Array::zeros((2, 2)); + assert!(out.is_standard_layout(), "out should be C-order"); + assert_ne!(x.strides(), out.strides(), "test setup: strides must differ"); + + sigmoid_f32(x.view(), out.view_mut()); + + // Logical coordinates must carry the right sigmoid values regardless + // of memory order direction. + assert!((out[[0, 0]] - 0.5).abs() < 1e-6, "sigmoid(0) at [0,0] = {}", out[[0, 0]]); + assert!((out[[0, 1]] - 1.0).abs() < 1e-4, "sigmoid(100) at [0,1] = {}", out[[0, 1]]); + assert!((out[[1, 0]] - 0.0).abs() < 1e-4, "sigmoid(-100) at [1,0] = {}", out[[1, 0]]); + assert!((out[[1, 1]] - 0.5).abs() < 1e-6, "sigmoid(0) at [1,1] = {}", out[[1, 1]]); + } + #[test] fn test_sigmoid_f32_2d() { // Generic-D verification: 2-D contiguous input works