Skip to content

Commit 9b34495

Browse files
committed
test(hpc/activations): F-order × C-order symmetric counterpart for sigmoid_f32
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 (0774bdb) — 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 25bcafb (includes both test_sigmoid_f32_c_in_f_out_mismatched_strides and the new test_sigmoid_f32_f_in_c_out_mismatched_strides).
1 parent 25bcafb commit 9b34495

1 file changed

Lines changed: 37 additions & 0 deletions

File tree

src/hpc/activations.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,43 @@ mod tests {
441441
assert!((out[[1, 1]] - 0.5).abs() < 1e-6, "sigmoid(0) at [1,1] = {}", out[[1, 1]]);
442442
}
443443

444+
// Symmetric companion to `test_sigmoid_f32_c_in_f_out_mismatched_strides`:
445+
// F-order INPUT + C-order OUTPUT. The upstream test only covers the
446+
// C-in-F-out direction; if a future refactor accidentally guards only
447+
// the asymmetric case where x is C-order (e.g. `if x.is_standard_layout()
448+
// != out.is_standard_layout()`), the C→F test would still pass while
449+
// F→C silently regressed. Pinning both directions keeps the
450+
// strides-equality guard symmetric.
451+
#[test]
452+
fn test_sigmoid_f32_f_in_c_out_mismatched_strides() {
453+
use crate::{Array, Array2, ShapeBuilder};
454+
// Build an F-order input via `from_shape_vec` with the `.f()` shape
455+
// builder. Logical contents [[0, 100], [-100, 0]] same as the C-order
456+
// test — column-major buffer is [0, -100, 100, 0].
457+
let x: Array2<f32> =
458+
Array2::from_shape_vec((2, 2).f(), vec![0.0_f32, -100.0, 100.0, 0.0]).expect("F-order shape_vec");
459+
assert!(!x.is_standard_layout(), "x should be F-order");
460+
// Sanity-check the logical layout independent of memory order.
461+
assert!((x[[0, 0]] - 0.0).abs() < 1e-7);
462+
assert!((x[[0, 1]] - 100.0).abs() < 1e-7);
463+
assert!((x[[1, 0]] - (-100.0)).abs() < 1e-7);
464+
assert!((x[[1, 1]] - 0.0).abs() < 1e-7);
465+
466+
// C-order output (the default for `Array::zeros((r, c))`).
467+
let mut out: Array2<f32> = Array::zeros((2, 2));
468+
assert!(out.is_standard_layout(), "out should be C-order");
469+
assert_ne!(x.strides(), out.strides(), "test setup: strides must differ");
470+
471+
sigmoid_f32(x.view(), out.view_mut());
472+
473+
// Logical coordinates must carry the right sigmoid values regardless
474+
// of memory order direction.
475+
assert!((out[[0, 0]] - 0.5).abs() < 1e-6, "sigmoid(0) at [0,0] = {}", out[[0, 0]]);
476+
assert!((out[[0, 1]] - 1.0).abs() < 1e-4, "sigmoid(100) at [0,1] = {}", out[[0, 1]]);
477+
assert!((out[[1, 0]] - 0.0).abs() < 1e-4, "sigmoid(-100) at [1,0] = {}", out[[1, 0]]);
478+
assert!((out[[1, 1]] - 0.5).abs() < 1e-6, "sigmoid(0) at [1,1] = {}", out[[1, 1]]);
479+
}
480+
444481
#[test]
445482
fn test_sigmoid_f32_2d() {
446483
// Generic-D verification: 2-D contiguous input works

0 commit comments

Comments
 (0)