Skip to content

Commit 5ac51cd

Browse files
committed
review: doc examples on every andnot/ternlog across all six backends
CodeRabbit round 2, first finding: per the repo guideline every public API carries an example. Added compact # Examples blocks (andnot set difference; ternlog MAJ3 via the named facade immediate) to U64x8/U32x16 on scalar, avx2, avx512, nightly, and to U32x16 on neon and wasm. The avx512 examples execute in this environment's doc-test run (512 passed); the cfg-gated arms compile their examples only under their own targets. The second finding (do not extend the nightly-only backend) is declined with reasons on the PR thread: the nightly arm pre-exists behind the off-by-default nightly-simd feature, and codex's P1 in the same review round requires the methods on every dispatched arm precisely so no feature combination compiles into E0599. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KCGhDYoQBXs3poaR7sFuqp
1 parent b865b70 commit 5ac51cd

6 files changed

Lines changed: 180 additions & 0 deletions

File tree

src/simd_avx2.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3523,6 +3523,15 @@ impl U64x8 {
35233523
///
35243524
/// Total function: no saturation, no overflow, no UB. `x.andnot(x)` is
35253525
/// zero; `x.andnot(U64x8::splat(0))` is `x`.
3526+
///
3527+
/// # Examples
3528+
///
3529+
/// ```
3530+
/// use ndarray::simd::U64x8;
3531+
/// let a = U64x8::splat(0b1100);
3532+
/// let b = U64x8::splat(0b1010);
3533+
/// assert_eq!(a.andnot(b).to_array()[0], 0b0100); // a & !b
3534+
/// ```
35263535
#[inline(always)]
35273536
pub fn andnot(self, other: Self) -> Self {
35283537
self & !other
@@ -3537,6 +3546,15 @@ impl U64x8 {
35373546
/// `0..=255` is legal, enforced at compile time on the AVX-512 backend by
35383547
/// the intrinsic's own static assert. Within that domain: total function,
35393548
/// no lane interaction.
3549+
///
3550+
/// # Examples
3551+
///
3552+
/// ```
3553+
/// use ndarray::simd::{ternlog, U64x8};
3554+
/// let (a, b, c) = (U64x8::splat(0b1100), U64x8::splat(0b1010), U64x8::splat(0b1001));
3555+
/// let maj = a.ternlog::<{ ternlog::MAJ3 }>(b, c); // two-of-three majority
3556+
/// assert_eq!(maj.to_array()[0], 0b1000);
3557+
/// ```
35403558
#[inline(always)]
35413559
pub fn ternlog<const IMM: i32>(self, b: Self, c: Self) -> Self {
35423560
const { assert!(IMM >= 0 && IMM <= 255, "ternlog IMM is an 8-bit truth table") }
@@ -3572,12 +3590,30 @@ impl U64x8 {
35723590

35733591
impl U32x16 {
35743592
/// Set difference: `self & !other`. See [`U64x8::andnot`].
3593+
///
3594+
/// # Examples
3595+
///
3596+
/// ```
3597+
/// use ndarray::simd::U32x16;
3598+
/// let a = U32x16::splat(0b1100);
3599+
/// let b = U32x16::splat(0b1010);
3600+
/// assert_eq!(a.andnot(b).to_array()[0], 0b0100); // a & !b
3601+
/// ```
35753602
#[inline(always)]
35763603
pub fn andnot(self, other: Self) -> Self {
35773604
self & !other
35783605
}
35793606

35803607
/// Any 3-input boolean function, 32-bit lanes. See [`U64x8::ternlog`].
3608+
///
3609+
/// # Examples
3610+
///
3611+
/// ```
3612+
/// use ndarray::simd::{ternlog, U32x16};
3613+
/// let (a, b, c) = (U32x16::splat(0b1100), U32x16::splat(0b1010), U32x16::splat(0b1001));
3614+
/// let maj = a.ternlog::<{ ternlog::MAJ3 }>(b, c); // two-of-three majority
3615+
/// assert_eq!(maj.to_array()[0], 0b1000);
3616+
/// ```
35813617
#[inline(always)]
35823618
pub fn ternlog<const IMM: i32>(self, b: Self, c: Self) -> Self {
35833619
const { assert!(IMM >= 0 && IMM <= 255, "ternlog IMM is an 8-bit truth table") }

src/simd_avx512.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4892,6 +4892,15 @@ impl U64x8 {
48924892
///
48934893
/// Total function: no saturation, no overflow, no UB. `x.andnot(x)` is
48944894
/// zero; `x.andnot(U64x8::splat(0))` is `x`.
4895+
///
4896+
/// # Examples
4897+
///
4898+
/// ```
4899+
/// use ndarray::simd::U64x8;
4900+
/// let a = U64x8::splat(0b1100);
4901+
/// let b = U64x8::splat(0b1010);
4902+
/// assert_eq!(a.andnot(b).to_array()[0], 0b0100); // a & !b
4903+
/// ```
48954904
#[inline(always)]
48964905
pub fn andnot(self, other: Self) -> Self {
48974906
// SAFETY: this module is only reachable under `target_feature =
@@ -4912,6 +4921,15 @@ impl U64x8 {
49124921
/// legal, and the intrinsic's own `static_assert_uimm_bits!` rejects
49134922
/// anything wider **at compile time**. Within that domain this is a total
49144923
/// function: no saturation, no overflow, no UB, no lane interaction.
4924+
///
4925+
/// # Examples
4926+
///
4927+
/// ```
4928+
/// use ndarray::simd::{ternlog, U64x8};
4929+
/// let (a, b, c) = (U64x8::splat(0b1100), U64x8::splat(0b1010), U64x8::splat(0b1001));
4930+
/// let maj = a.ternlog::<{ ternlog::MAJ3 }>(b, c); // two-of-three majority
4931+
/// assert_eq!(maj.to_array()[0], 0b1000);
4932+
/// ```
49154933
#[inline(always)]
49164934
pub fn ternlog<const IMM: i32>(self, b: Self, c: Self) -> Self {
49174935
// SAFETY: avx512f is enabled at compile time (see `andnot`). IMM is a
@@ -4923,6 +4941,15 @@ impl U64x8 {
49234941
impl U32x16 {
49244942
/// Set difference: `self & !other`, lane-wise (VPANDND). See
49254943
/// [`U64x8::andnot`] for the argument-order note.
4944+
///
4945+
/// # Examples
4946+
///
4947+
/// ```
4948+
/// use ndarray::simd::U32x16;
4949+
/// let a = U32x16::splat(0b1100);
4950+
/// let b = U32x16::splat(0b1010);
4951+
/// assert_eq!(a.andnot(b).to_array()[0], 0b0100); // a & !b
4952+
/// ```
49264953
#[inline(always)]
49274954
pub fn andnot(self, other: Self) -> Self {
49284955
// SAFETY: avx512f enabled at compile time; arguments swapped so this
@@ -4932,6 +4959,15 @@ impl U32x16 {
49324959

49334960
/// Any 3-input boolean function, 32-bit lanes — a single VPTERNLOGD.
49344961
/// See [`U64x8::ternlog`] for the truth-table convention and IMM domain.
4962+
///
4963+
/// # Examples
4964+
///
4965+
/// ```
4966+
/// use ndarray::simd::{ternlog, U32x16};
4967+
/// let (a, b, c) = (U32x16::splat(0b1100), U32x16::splat(0b1010), U32x16::splat(0b1001));
4968+
/// let maj = a.ternlog::<{ ternlog::MAJ3 }>(b, c); // two-of-three majority
4969+
/// assert_eq!(maj.to_array()[0], 0b1000);
4970+
/// ```
49354971
#[inline(always)]
49364972
pub fn ternlog<const IMM: i32>(self, b: Self, c: Self) -> Self {
49374973
// SAFETY: avx512f enabled at compile time; IMM validated by the

src/simd_neon.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1845,6 +1845,15 @@ impl U32x16 {
18451845
/// Elementwise over the fanned array — the codegen shape this file's own
18461846
/// oracle blessed: LLVM vectorizes the loop over the aligned array, no
18471847
/// intrinsic override earned.
1848+
///
1849+
/// # Examples
1850+
///
1851+
/// ```
1852+
/// use ndarray::simd::U32x16;
1853+
/// let a = U32x16::splat(0b1100);
1854+
/// let b = U32x16::splat(0b1010);
1855+
/// assert_eq!(a.andnot(b).to_array()[0], 0b0100); // a & !b
1856+
/// ```
18481857
#[inline(always)]
18491858
pub fn andnot(self, other: Self) -> Self {
18501859
let (a, b) = (self.to_array(), other.to_array());
@@ -1860,6 +1869,15 @@ impl U32x16 {
18601869
/// matched exactly by every backend. Named immediates:
18611870
/// `crate::simd::ternlog`. Only `0..=255` is legal, enforced at compile
18621871
/// time on every backend.
1872+
///
1873+
/// # Examples
1874+
///
1875+
/// ```
1876+
/// use ndarray::simd::{ternlog, U32x16};
1877+
/// let (a, b, c) = (U32x16::splat(0b1100), U32x16::splat(0b1010), U32x16::splat(0b1001));
1878+
/// let maj = a.ternlog::<{ ternlog::MAJ3 }>(b, c); // two-of-three majority
1879+
/// assert_eq!(maj.to_array()[0], 0b1000);
1880+
/// ```
18631881
#[inline(always)]
18641882
pub fn ternlog<const IMM: i32>(self, b: Self, c: Self) -> Self {
18651883
const { assert!(IMM >= 0 && IMM <= 255, "ternlog IMM is an 8-bit truth table") }

src/simd_nightly/u_word_types.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -886,6 +886,15 @@ mod tests {
886886
impl U64x8 {
887887
/// Set difference: `self & !other`, lane-wise. Same direction as every
888888
/// other backend (`simd_avx512::U64x8::andnot` is the reference doc).
889+
///
890+
/// # Examples
891+
///
892+
/// ```
893+
/// use ndarray::simd::U64x8;
894+
/// let a = U64x8::splat(0b1100);
895+
/// let b = U64x8::splat(0b1010);
896+
/// assert_eq!(a.andnot(b).to_array()[0], 0b0100); // a & !b
897+
/// ```
889898
#[inline(always)]
890899
pub fn andnot(self, other: Self) -> Self {
891900
Self(self.0 & !other.0)
@@ -896,6 +905,15 @@ impl U64x8 {
896905
/// matched exactly by every backend (64-bit lanes). Named immediates:
897906
/// `crate::simd::ternlog`. Only `0..=255` is legal, enforced at compile
898907
/// time on every backend. The minterm branches fold at compile time.
908+
///
909+
/// # Examples
910+
///
911+
/// ```
912+
/// use ndarray::simd::{ternlog, U64x8};
913+
/// let (a, b, c) = (U64x8::splat(0b1100), U64x8::splat(0b1010), U64x8::splat(0b1001));
914+
/// let maj = a.ternlog::<{ ternlog::MAJ3 }>(b, c); // two-of-three majority
915+
/// assert_eq!(maj.to_array()[0], 0b1000);
916+
/// ```
899917
#[inline(always)]
900918
pub fn ternlog<const IMM: i32>(self, b: Self, c: Self) -> Self {
901919
const { assert!(IMM >= 0 && IMM <= 255, "ternlog IMM is an 8-bit truth table") }
@@ -932,6 +950,15 @@ impl U64x8 {
932950
impl U32x16 {
933951
/// Set difference: `self & !other`, lane-wise. Same direction as every
934952
/// other backend (`simd_avx512::U32x16::andnot` is the reference doc).
953+
///
954+
/// # Examples
955+
///
956+
/// ```
957+
/// use ndarray::simd::U32x16;
958+
/// let a = U32x16::splat(0b1100);
959+
/// let b = U32x16::splat(0b1010);
960+
/// assert_eq!(a.andnot(b).to_array()[0], 0b0100); // a & !b
961+
/// ```
935962
#[inline(always)]
936963
pub fn andnot(self, other: Self) -> Self {
937964
Self(self.0 & !other.0)
@@ -942,6 +969,15 @@ impl U32x16 {
942969
/// matched exactly by every backend (32-bit lanes). Named immediates:
943970
/// `crate::simd::ternlog`. Only `0..=255` is legal, enforced at compile
944971
/// time on every backend. The minterm branches fold at compile time.
972+
///
973+
/// # Examples
974+
///
975+
/// ```
976+
/// use ndarray::simd::{ternlog, U32x16};
977+
/// let (a, b, c) = (U32x16::splat(0b1100), U32x16::splat(0b1010), U32x16::splat(0b1001));
978+
/// let maj = a.ternlog::<{ ternlog::MAJ3 }>(b, c); // two-of-three majority
979+
/// assert_eq!(maj.to_array()[0], 0b1000);
980+
/// ```
945981
#[inline(always)]
946982
pub fn ternlog<const IMM: i32>(self, b: Self, c: Self) -> Self {
947983
const { assert!(IMM >= 0 && IMM <= 255, "ternlog IMM is an 8-bit truth table") }

src/simd_scalar.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2051,6 +2051,15 @@ impl U64x8 {
20512051
///
20522052
/// Total function: no saturation, no overflow, no UB. `x.andnot(x)` is
20532053
/// zero; `x.andnot(U64x8::splat(0))` is `x`.
2054+
///
2055+
/// # Examples
2056+
///
2057+
/// ```
2058+
/// use ndarray::simd::U64x8;
2059+
/// let a = U64x8::splat(0b1100);
2060+
/// let b = U64x8::splat(0b1010);
2061+
/// assert_eq!(a.andnot(b).to_array()[0], 0b0100); // a & !b
2062+
/// ```
20542063
#[inline(always)]
20552064
pub fn andnot(self, other: Self) -> Self {
20562065
self & !other
@@ -2065,6 +2074,15 @@ impl U64x8 {
20652074
/// `0..=255` is legal, enforced at compile time on the AVX-512 backend by
20662075
/// the intrinsic's own static assert. Within that domain: total function,
20672076
/// no lane interaction.
2077+
///
2078+
/// # Examples
2079+
///
2080+
/// ```
2081+
/// use ndarray::simd::{ternlog, U64x8};
2082+
/// let (a, b, c) = (U64x8::splat(0b1100), U64x8::splat(0b1010), U64x8::splat(0b1001));
2083+
/// let maj = a.ternlog::<{ ternlog::MAJ3 }>(b, c); // two-of-three majority
2084+
/// assert_eq!(maj.to_array()[0], 0b1000);
2085+
/// ```
20682086
#[inline(always)]
20692087
pub fn ternlog<const IMM: i32>(self, b: Self, c: Self) -> Self {
20702088
let (a, z) = (self, Self::splat(0));
@@ -2099,12 +2117,30 @@ impl U64x8 {
20992117

21002118
impl U32x16 {
21012119
/// Set difference: `self & !other`. See [`U64x8::andnot`].
2120+
///
2121+
/// # Examples
2122+
///
2123+
/// ```
2124+
/// use ndarray::simd::U32x16;
2125+
/// let a = U32x16::splat(0b1100);
2126+
/// let b = U32x16::splat(0b1010);
2127+
/// assert_eq!(a.andnot(b).to_array()[0], 0b0100); // a & !b
2128+
/// ```
21022129
#[inline(always)]
21032130
pub fn andnot(self, other: Self) -> Self {
21042131
self & !other
21052132
}
21062133

21072134
/// Any 3-input boolean function, 32-bit lanes. See [`U64x8::ternlog`].
2135+
///
2136+
/// # Examples
2137+
///
2138+
/// ```
2139+
/// use ndarray::simd::{ternlog, U32x16};
2140+
/// let (a, b, c) = (U32x16::splat(0b1100), U32x16::splat(0b1010), U32x16::splat(0b1001));
2141+
/// let maj = a.ternlog::<{ ternlog::MAJ3 }>(b, c); // two-of-three majority
2142+
/// assert_eq!(maj.to_array()[0], 0b1000);
2143+
/// ```
21082144
#[inline(always)]
21092145
pub fn ternlog<const IMM: i32>(self, b: Self, c: Self) -> Self {
21102146
const { assert!(IMM >= 0 && IMM <= 255, "ternlog IMM is an 8-bit truth table") }

src/simd_wasm.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -960,6 +960,15 @@ pub mod wasm32_simd {
960960
/// Set difference: `self & !other`, lane-wise — one `v128.andnot` per
961961
/// 128-bit part (the wasm intrinsic's argument order already matches
962962
/// this crate's direction). Reference doc: `simd_avx512::U32x16::andnot`.
963+
///
964+
/// # Examples
965+
///
966+
/// ```
967+
/// use ndarray::simd::U32x16;
968+
/// let a = U32x16::splat(0b1100);
969+
/// let b = U32x16::splat(0b1010);
970+
/// assert_eq!(a.andnot(b).to_array()[0], 0b0100); // a & !b
971+
/// ```
963972
#[inline(always)]
964973
pub fn andnot(self, other: Self) -> Self {
965974
Self([
@@ -976,6 +985,15 @@ pub mod wasm32_simd {
976985
/// enforced at compile time on every backend. Composed per 128-bit
977986
/// part from `v128` bit ops; the minterm branches fold at compile
978987
/// time, so only the truth table's terms survive.
988+
///
989+
/// # Examples
990+
///
991+
/// ```
992+
/// use ndarray::simd::{ternlog, U32x16};
993+
/// let (a, b, c) = (U32x16::splat(0b1100), U32x16::splat(0b1010), U32x16::splat(0b1001));
994+
/// let maj = a.ternlog::<{ ternlog::MAJ3 }>(b, c); // two-of-three majority
995+
/// assert_eq!(maj.to_array()[0], 0b1000);
996+
/// ```
979997
#[inline(always)]
980998
pub fn ternlog<const IMM: i32>(self, b: Self, c: Self) -> Self {
981999
const { assert!(IMM >= 0 && IMM <= 255, "ternlog IMM is an 8-bit truth table") }

0 commit comments

Comments
 (0)