Skip to content

Commit 72df4c4

Browse files
portable-simd#261: Rename horizontal_* to reduce_*
2 parents 49043f4 + b6e03f5 commit 72df4c4

File tree

6 files changed

+53
-53
lines changed

6 files changed

+53
-53
lines changed

beginners-guide.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ SIMD has a few special vocabulary terms you should know:
3333

3434
* **Vertical:** When an operation is "vertical", each lane processes individually without regard to the other lanes in the same vector. For example, a "vertical add" between two vectors would add lane 0 in `a` with lane 0 in `b`, with the total in lane 0 of `out`, and then the same thing for lanes 1, 2, etc. Most SIMD operations are vertical operations, so if your problem is a vertical problem then you can probably solve it with SIMD.
3535

36-
* **Horizontal:** When an operation is "horizontal", the lanes within a single vector interact in some way. A "horizontal add" might add up lane 0 of `a` with lane 1 of `a`, with the total in lane 0 of `out`.
36+
* **Reducing/Reduce:** When an operation is "reducing" (functions named `reduce_*`), the lanes within a single vector are merged using some operation such as addition, returning the merged value as a scalar. For instance, a reducing add would return the sum of all the lanes' values.
3737

3838
* **Target Feature:** Rust calls a CPU architecture extension a `target_feature`. Proper SIMD requires various CPU extensions to be enabled (details below). Don't confuse this with `feature`, which is a Cargo crate concept.
3939

@@ -83,4 +83,4 @@ Fortunately, most SIMD types have a fairly predictable size. `i32x4` is bit-equi
8383
However, this is not the same as alignment. Computer architectures generally prefer aligned accesses, especially when moving data between memory and vector registers, and while some support specialized operations that can bend the rules to help with this, unaligned access is still typically slow, or even undefined behavior. In addition, different architectures can require different alignments when interacting with their native SIMD types. For this reason, any `#[repr(simd)]` type has a non-portable alignment. If it is necessary to directly interact with the alignment of these types, it should be via [`mem::align_of`].
8484

8585
[`mem::transmute`]: https://doc.rust-lang.org/core/mem/fn.transmute.html
86-
[`mem::align_of`]: https://doc.rust-lang.org/core/mem/fn.align_of.html
86+
[`mem::align_of`]: https://doc.rust-lang.org/core/mem/fn.align_of.html

crates/core_simd/examples/matrix_inversion.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ pub fn simd_inv4x4(m: Matrix4x4) -> Option<Matrix4x4> {
233233
let det = det.rotate_lanes_right::<2>() + det;
234234
let det = det.reverse().rotate_lanes_right::<2>() + det;
235235

236-
if det.horizontal_sum() == 0. {
236+
if det.reduce_sum() == 0. {
237237
return None;
238238
}
239239
// calculate the reciprocal

crates/core_simd/examples/nbody.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,10 @@ mod nbody {
107107
let mut e = 0.;
108108
for i in 0..N_BODIES {
109109
let bi = &bodies[i];
110-
e += bi.mass * (bi.v * bi.v).horizontal_sum() * 0.5;
110+
e += bi.mass * (bi.v * bi.v).reduce_sum() * 0.5;
111111
for bj in bodies.iter().take(N_BODIES).skip(i + 1) {
112112
let dx = bi.x - bj.x;
113-
e -= bi.mass * bj.mass / (dx * dx).horizontal_sum().sqrt()
113+
e -= bi.mass * bj.mass / (dx * dx).reduce_sum().sqrt()
114114
}
115115
}
116116
e
@@ -134,8 +134,8 @@ mod nbody {
134134
let mut mag = [0.0; N];
135135
for i in (0..N).step_by(2) {
136136
let d2s = f64x2::from_array([
137-
(r[i] * r[i]).horizontal_sum(),
138-
(r[i + 1] * r[i + 1]).horizontal_sum(),
137+
(r[i] * r[i]).reduce_sum(),
138+
(r[i + 1] * r[i + 1]).reduce_sum(),
139139
]);
140140
let dmags = f64x2::splat(dt) / (d2s * d2s.sqrt());
141141
mag[i] = dmags[0];

crates/core_simd/examples/spectral_norm.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ fn mult_av(v: &[f64], out: &mut [f64]) {
2020
sum += b / a;
2121
j += 2
2222
}
23-
*out = sum.horizontal_sum();
23+
*out = sum.reduce_sum();
2424
}
2525
}
2626

@@ -38,7 +38,7 @@ fn mult_atv(v: &[f64], out: &mut [f64]) {
3838
sum += b / a;
3939
j += 2
4040
}
41-
*out = sum.horizontal_sum();
41+
*out = sum.reduce_sum();
4242
}
4343
}
4444

crates/core_simd/src/reduction.rs

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,30 +11,30 @@ macro_rules! impl_integer_reductions {
1111
where
1212
LaneCount<LANES>: SupportedLaneCount,
1313
{
14-
/// Horizontal wrapping add. Returns the sum of the lanes of the vector, with wrapping addition.
14+
/// Reducing wrapping add. Returns the sum of the lanes of the vector, with wrapping addition.
1515
#[inline]
16-
pub fn horizontal_sum(self) -> $scalar {
16+
pub fn reduce_sum(self) -> $scalar {
1717
// Safety: `self` is an integer vector
1818
unsafe { simd_reduce_add_ordered(self, 0) }
1919
}
2020

21-
/// Horizontal wrapping multiply. Returns the product of the lanes of the vector, with wrapping multiplication.
21+
/// Reducing wrapping multiply. Returns the product of the lanes of the vector, with wrapping multiplication.
2222
#[inline]
23-
pub fn horizontal_product(self) -> $scalar {
23+
pub fn reduce_product(self) -> $scalar {
2424
// Safety: `self` is an integer vector
2525
unsafe { simd_reduce_mul_ordered(self, 1) }
2626
}
2727

28-
/// Horizontal maximum. Returns the maximum lane in the vector.
28+
/// Reducing maximum. Returns the maximum lane in the vector.
2929
#[inline]
30-
pub fn horizontal_max(self) -> $scalar {
30+
pub fn reduce_max(self) -> $scalar {
3131
// Safety: `self` is an integer vector
3232
unsafe { simd_reduce_max(self) }
3333
}
3434

35-
/// Horizontal minimum. Returns the minimum lane in the vector.
35+
/// Reducing minimum. Returns the minimum lane in the vector.
3636
#[inline]
37-
pub fn horizontal_min(self) -> $scalar {
37+
pub fn reduce_min(self) -> $scalar {
3838
// Safety: `self` is an integer vector
3939
unsafe { simd_reduce_min(self) }
4040
}
@@ -60,9 +60,9 @@ macro_rules! impl_float_reductions {
6060
LaneCount<LANES>: SupportedLaneCount,
6161
{
6262

63-
/// Horizontal add. Returns the sum of the lanes of the vector.
63+
/// Reducing add. Returns the sum of the lanes of the vector.
6464
#[inline]
65-
pub fn horizontal_sum(self) -> $scalar {
65+
pub fn reduce_sum(self) -> $scalar {
6666
// LLVM sum is inaccurate on i586
6767
if cfg!(all(target_arch = "x86", not(target_feature = "sse2"))) {
6868
self.as_array().iter().sum()
@@ -72,9 +72,9 @@ macro_rules! impl_float_reductions {
7272
}
7373
}
7474

75-
/// Horizontal multiply. Returns the product of the lanes of the vector.
75+
/// Reducing multiply. Returns the product of the lanes of the vector.
7676
#[inline]
77-
pub fn horizontal_product(self) -> $scalar {
77+
pub fn reduce_product(self) -> $scalar {
7878
// LLVM product is inaccurate on i586
7979
if cfg!(all(target_arch = "x86", not(target_feature = "sse2"))) {
8080
self.as_array().iter().product()
@@ -84,22 +84,22 @@ macro_rules! impl_float_reductions {
8484
}
8585
}
8686

87-
/// Horizontal maximum. Returns the maximum lane in the vector.
87+
/// Reducing maximum. Returns the maximum lane in the vector.
8888
///
8989
/// Returns values based on equality, so a vector containing both `0.` and `-0.` may
9090
/// return either. This function will not return `NaN` unless all lanes are `NaN`.
9191
#[inline]
92-
pub fn horizontal_max(self) -> $scalar {
92+
pub fn reduce_max(self) -> $scalar {
9393
// Safety: `self` is a float vector
9494
unsafe { simd_reduce_max(self) }
9595
}
9696

97-
/// Horizontal minimum. Returns the minimum lane in the vector.
97+
/// Reducing minimum. Returns the minimum lane in the vector.
9898
///
9999
/// Returns values based on equality, so a vector containing both `0.` and `-0.` may
100100
/// return either. This function will not return `NaN` unless all lanes are `NaN`.
101101
#[inline]
102-
pub fn horizontal_min(self) -> $scalar {
102+
pub fn reduce_min(self) -> $scalar {
103103
// Safety: `self` is a float vector
104104
unsafe { simd_reduce_min(self) }
105105
}
@@ -116,10 +116,10 @@ where
116116
T: SimdElement + BitAnd<T, Output = T>,
117117
LaneCount<LANES>: SupportedLaneCount,
118118
{
119-
/// Horizontal bitwise "and". Returns the cumulative bitwise "and" across the lanes of
119+
/// Reducing bitwise "and". Returns the cumulative bitwise "and" across the lanes of
120120
/// the vector.
121121
#[inline]
122-
pub fn horizontal_and(self) -> T {
122+
pub fn reduce_and(self) -> T {
123123
unsafe { simd_reduce_and(self) }
124124
}
125125
}
@@ -130,10 +130,10 @@ where
130130
T: SimdElement + BitOr<T, Output = T>,
131131
LaneCount<LANES>: SupportedLaneCount,
132132
{
133-
/// Horizontal bitwise "or". Returns the cumulative bitwise "or" across the lanes of
133+
/// Reducing bitwise "or". Returns the cumulative bitwise "or" across the lanes of
134134
/// the vector.
135135
#[inline]
136-
pub fn horizontal_or(self) -> T {
136+
pub fn reduce_or(self) -> T {
137137
unsafe { simd_reduce_or(self) }
138138
}
139139
}
@@ -144,10 +144,10 @@ where
144144
T: SimdElement + BitXor<T, Output = T>,
145145
LaneCount<LANES>: SupportedLaneCount,
146146
{
147-
/// Horizontal bitwise "xor". Returns the cumulative bitwise "xor" across the lanes of
147+
/// Reducing bitwise "xor". Returns the cumulative bitwise "xor" across the lanes of
148148
/// the vector.
149149
#[inline]
150-
pub fn horizontal_xor(self) -> T {
150+
pub fn reduce_xor(self) -> T {
151151
unsafe { simd_reduce_xor(self) }
152152
}
153153
}

crates/core_simd/tests/ops_macros.rs

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -94,70 +94,70 @@ macro_rules! impl_binary_checked_op_test {
9494
macro_rules! impl_common_integer_tests {
9595
{ $vector:ident, $scalar:ident } => {
9696
test_helpers::test_lanes! {
97-
fn horizontal_sum<const LANES: usize>() {
97+
fn reduce_sum<const LANES: usize>() {
9898
test_helpers::test_1(&|x| {
9999
test_helpers::prop_assert_biteq! (
100-
$vector::<LANES>::from_array(x).horizontal_sum(),
100+
$vector::<LANES>::from_array(x).reduce_sum(),
101101
x.iter().copied().fold(0 as $scalar, $scalar::wrapping_add),
102102
);
103103
Ok(())
104104
});
105105
}
106106

107-
fn horizontal_product<const LANES: usize>() {
107+
fn reduce_product<const LANES: usize>() {
108108
test_helpers::test_1(&|x| {
109109
test_helpers::prop_assert_biteq! (
110-
$vector::<LANES>::from_array(x).horizontal_product(),
110+
$vector::<LANES>::from_array(x).reduce_product(),
111111
x.iter().copied().fold(1 as $scalar, $scalar::wrapping_mul),
112112
);
113113
Ok(())
114114
});
115115
}
116116

117-
fn horizontal_and<const LANES: usize>() {
117+
fn reduce_and<const LANES: usize>() {
118118
test_helpers::test_1(&|x| {
119119
test_helpers::prop_assert_biteq! (
120-
$vector::<LANES>::from_array(x).horizontal_and(),
120+
$vector::<LANES>::from_array(x).reduce_and(),
121121
x.iter().copied().fold(-1i8 as $scalar, <$scalar as core::ops::BitAnd>::bitand),
122122
);
123123
Ok(())
124124
});
125125
}
126126

127-
fn horizontal_or<const LANES: usize>() {
127+
fn reduce_or<const LANES: usize>() {
128128
test_helpers::test_1(&|x| {
129129
test_helpers::prop_assert_biteq! (
130-
$vector::<LANES>::from_array(x).horizontal_or(),
130+
$vector::<LANES>::from_array(x).reduce_or(),
131131
x.iter().copied().fold(0 as $scalar, <$scalar as core::ops::BitOr>::bitor),
132132
);
133133
Ok(())
134134
});
135135
}
136136

137-
fn horizontal_xor<const LANES: usize>() {
137+
fn reduce_xor<const LANES: usize>() {
138138
test_helpers::test_1(&|x| {
139139
test_helpers::prop_assert_biteq! (
140-
$vector::<LANES>::from_array(x).horizontal_xor(),
140+
$vector::<LANES>::from_array(x).reduce_xor(),
141141
x.iter().copied().fold(0 as $scalar, <$scalar as core::ops::BitXor>::bitxor),
142142
);
143143
Ok(())
144144
});
145145
}
146146

147-
fn horizontal_max<const LANES: usize>() {
147+
fn reduce_max<const LANES: usize>() {
148148
test_helpers::test_1(&|x| {
149149
test_helpers::prop_assert_biteq! (
150-
$vector::<LANES>::from_array(x).horizontal_max(),
150+
$vector::<LANES>::from_array(x).reduce_max(),
151151
x.iter().copied().max().unwrap(),
152152
);
153153
Ok(())
154154
});
155155
}
156156

157-
fn horizontal_min<const LANES: usize>() {
157+
fn reduce_min<const LANES: usize>() {
158158
test_helpers::test_1(&|x| {
159159
test_helpers::prop_assert_biteq! (
160-
$vector::<LANES>::from_array(x).horizontal_min(),
160+
$vector::<LANES>::from_array(x).reduce_min(),
161161
x.iter().copied().min().unwrap(),
162162
);
163163
Ok(())
@@ -528,29 +528,29 @@ macro_rules! impl_float_tests {
528528
})
529529
}
530530

531-
fn horizontal_sum<const LANES: usize>() {
531+
fn reduce_sum<const LANES: usize>() {
532532
test_helpers::test_1(&|x| {
533533
test_helpers::prop_assert_biteq! (
534-
Vector::<LANES>::from_array(x).horizontal_sum(),
534+
Vector::<LANES>::from_array(x).reduce_sum(),
535535
x.iter().sum(),
536536
);
537537
Ok(())
538538
});
539539
}
540540

541-
fn horizontal_product<const LANES: usize>() {
541+
fn reduce_product<const LANES: usize>() {
542542
test_helpers::test_1(&|x| {
543543
test_helpers::prop_assert_biteq! (
544-
Vector::<LANES>::from_array(x).horizontal_product(),
544+
Vector::<LANES>::from_array(x).reduce_product(),
545545
x.iter().product(),
546546
);
547547
Ok(())
548548
});
549549
}
550550

551-
fn horizontal_max<const LANES: usize>() {
551+
fn reduce_max<const LANES: usize>() {
552552
test_helpers::test_1(&|x| {
553-
let vmax = Vector::<LANES>::from_array(x).horizontal_max();
553+
let vmax = Vector::<LANES>::from_array(x).reduce_max();
554554
let smax = x.iter().copied().fold(Scalar::NAN, Scalar::max);
555555
// 0 and -0 are treated the same
556556
if !(x.contains(&0.) && x.contains(&-0.) && vmax.abs() == 0. && smax.abs() == 0.) {
@@ -560,9 +560,9 @@ macro_rules! impl_float_tests {
560560
});
561561
}
562562

563-
fn horizontal_min<const LANES: usize>() {
563+
fn reduce_min<const LANES: usize>() {
564564
test_helpers::test_1(&|x| {
565-
let vmax = Vector::<LANES>::from_array(x).horizontal_min();
565+
let vmax = Vector::<LANES>::from_array(x).reduce_min();
566566
let smax = x.iter().copied().fold(Scalar::NAN, Scalar::min);
567567
// 0 and -0 are treated the same
568568
if !(x.contains(&0.) && x.contains(&-0.) && vmax.abs() == 0. && smax.abs() == 0.) {

0 commit comments

Comments
 (0)