shape_runtime/simd_rolling/
clip.rs1use wide::f64x4;
4
5use super::SIMD_THRESHOLD;
6
7#[cfg(feature = "simd")]
11#[inline]
12pub fn clip(data: &mut [f64], min: f64, max: f64) {
13 clip_simd(data, min, max)
14}
15
16#[cfg(not(feature = "simd"))]
17#[inline]
18pub fn clip(data: &mut [f64], min: f64, max: f64) {
19 clip_scalar(data, min, max)
20}
21
22fn clip_simd(data: &mut [f64], min: f64, max: f64) {
26 if data.len() < SIMD_THRESHOLD {
27 for val in data.iter_mut() {
28 *val = val.clamp(min, max);
29 }
30 return;
31 }
32
33 let min_vec = f64x4::splat(min);
34 let max_vec = f64x4::splat(max);
35
36 let chunks = data.len() / 4;
37 for chunk in 0..chunks {
38 let i = chunk * 4;
39 let vals = f64x4::new([data[i], data[i + 1], data[i + 2], data[i + 3]]);
40 let clamped = vals.max(min_vec).min(max_vec);
41 let arr = clamped.to_array();
42 data[i..i + 4].copy_from_slice(&arr);
43 }
44
45 for i in (chunks * 4)..data.len() {
47 data[i] = data[i].clamp(min, max);
48 }
49}
50
51#[cfg(not(feature = "simd"))]
53fn clip_scalar(data: &mut [f64], min: f64, max: f64) {
54 for val in data.iter_mut() {
55 *val = val.clamp(min, max);
56 }
57}
58
59#[cfg(test)]
60mod tests {
61 use super::*;
62
63 #[test]
64 fn test_clip() {
65 let mut data = vec![-10.0, 5.0, 15.0, 20.0, 0.0];
66 clip(&mut data, 0.0, 10.0);
67
68 assert_eq!(data[0], 0.0); assert_eq!(data[1], 5.0); assert_eq!(data[2], 10.0); assert_eq!(data[3], 10.0); assert_eq!(data[4], 0.0); }
74}