Skip to content

Commit c36d17d

Browse files
Merge pull request rust-lang#152 from rust-lang/feature/const_eval_checked
Feature/const eval checked Adds the const_evaluatable_checked cargo feature for some experimental (but very useful) function implementations. Adds testing all cargo features to CI.
2 parents 82e3405 + cca9102 commit c36d17d

File tree

13 files changed

+239
-218
lines changed

13 files changed

+239
-218
lines changed

.github/workflows/ci.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,3 +196,28 @@ jobs:
196196
- name: Test (release)
197197
run: cross test --verbose --target=${{ matrix.target }} --release
198198

199+
features:
200+
name: "Check cargo features (${{ matrix.features }} ${{ matrix.rustflags }})"
201+
runs-on: ubuntu-latest
202+
strategy:
203+
fail-fast: false
204+
matrix:
205+
rustflags:
206+
- ""
207+
- "-Ctarget-feature=+avx512" # AVX-512 uses packed bit masks, so enable it to test more code paths
208+
features:
209+
- ""
210+
- "--features std"
211+
- "--features const_evaluatable_checked"
212+
- "--features std --features const_evaluatable_checked"
213+
214+
steps:
215+
- uses: actions/checkout@v2
216+
- name: Setup Rust
217+
run: |
218+
rustup update nightly --no-self-update
219+
rustup default nightly
220+
- name: Check build
221+
run: cargo check --all-targets --no-default-features ${{ matrix.features }}
222+
env:
223+
RUSTFLAGS: ${{ matrix.rustflags }}

crates/core_simd/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ categories = ["hardware-support", "no-std"]
1010
license = "MIT OR Apache-2.0"
1111

1212
[features]
13-
default = ["std"]
13+
default = ["std", "const_evaluatable_checked"]
1414
std = []
15+
const_evaluatable_checked = []
1516

1617
[target.'cfg(target_arch = "wasm32")'.dev-dependencies.wasm-bindgen]
1718
version = "0.2"

crates/core_simd/examples/nbody.rs

Lines changed: 151 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -1,169 +1,173 @@
1-
#![feature(portable_simd)]
1+
#![cfg_attr(feature = "std", feature(portable_simd))]
22

33
/// Benchmarks game nbody code
44
/// Taken from the `packed_simd` crate
55
/// Run this benchmark with `cargo test --example nbody`
6-
use core_simd::*;
6+
#[cfg(feature = "std")]
7+
mod nbody {
8+
use core_simd::*;
79

8-
use std::f64::consts::PI;
9-
const SOLAR_MASS: f64 = 4.0 * PI * PI;
10-
const DAYS_PER_YEAR: f64 = 365.24;
10+
use std::f64::consts::PI;
11+
const SOLAR_MASS: f64 = 4.0 * PI * PI;
12+
const DAYS_PER_YEAR: f64 = 365.24;
1113

12-
#[derive(Debug, Clone, Copy)]
13-
pub struct Body {
14-
pub x: f64x4,
15-
pub v: f64x4,
16-
pub mass: f64,
17-
}
14+
#[derive(Debug, Clone, Copy)]
15+
struct Body {
16+
pub x: f64x4,
17+
pub v: f64x4,
18+
pub mass: f64,
19+
}
1820

19-
const N_BODIES: usize = 5;
20-
const BODIES: [Body; N_BODIES] = [
21-
// sun:
22-
Body {
23-
x: f64x4::from_array([0., 0., 0., 0.]),
24-
v: f64x4::from_array([0., 0., 0., 0.]),
25-
mass: SOLAR_MASS,
26-
},
27-
// jupiter:
28-
Body {
29-
x: f64x4::from_array([
30-
4.84143144246472090e+00,
31-
-1.16032004402742839e+00,
32-
-1.03622044471123109e-01,
33-
0.,
34-
]),
35-
v: f64x4::from_array([
36-
1.66007664274403694e-03 * DAYS_PER_YEAR,
37-
7.69901118419740425e-03 * DAYS_PER_YEAR,
38-
-6.90460016972063023e-05 * DAYS_PER_YEAR,
39-
0.,
40-
]),
41-
mass: 9.54791938424326609e-04 * SOLAR_MASS,
42-
},
43-
// saturn:
44-
Body {
45-
x: f64x4::from_array([
46-
8.34336671824457987e+00,
47-
4.12479856412430479e+00,
48-
-4.03523417114321381e-01,
49-
0.,
50-
]),
51-
v: f64x4::from_array([
52-
-2.76742510726862411e-03 * DAYS_PER_YEAR,
53-
4.99852801234917238e-03 * DAYS_PER_YEAR,
54-
2.30417297573763929e-05 * DAYS_PER_YEAR,
55-
0.,
56-
]),
57-
mass: 2.85885980666130812e-04 * SOLAR_MASS,
58-
},
59-
// uranus:
60-
Body {
61-
x: f64x4::from_array([
62-
1.28943695621391310e+01,
63-
-1.51111514016986312e+01,
64-
-2.23307578892655734e-01,
65-
0.,
66-
]),
67-
v: f64x4::from_array([
68-
2.96460137564761618e-03 * DAYS_PER_YEAR,
69-
2.37847173959480950e-03 * DAYS_PER_YEAR,
70-
-2.96589568540237556e-05 * DAYS_PER_YEAR,
71-
0.,
72-
]),
73-
mass: 4.36624404335156298e-05 * SOLAR_MASS,
74-
},
75-
// neptune:
76-
Body {
77-
x: f64x4::from_array([
78-
1.53796971148509165e+01,
79-
-2.59193146099879641e+01,
80-
1.79258772950371181e-01,
81-
0.,
82-
]),
83-
v: f64x4::from_array([
84-
2.68067772490389322e-03 * DAYS_PER_YEAR,
85-
1.62824170038242295e-03 * DAYS_PER_YEAR,
86-
-9.51592254519715870e-05 * DAYS_PER_YEAR,
87-
0.,
88-
]),
89-
mass: 5.15138902046611451e-05 * SOLAR_MASS,
90-
},
91-
];
21+
const N_BODIES: usize = 5;
22+
const BODIES: [Body; N_BODIES] = [
23+
// sun:
24+
Body {
25+
x: f64x4::from_array([0., 0., 0., 0.]),
26+
v: f64x4::from_array([0., 0., 0., 0.]),
27+
mass: SOLAR_MASS,
28+
},
29+
// jupiter:
30+
Body {
31+
x: f64x4::from_array([
32+
4.84143144246472090e+00,
33+
-1.16032004402742839e+00,
34+
-1.03622044471123109e-01,
35+
0.,
36+
]),
37+
v: f64x4::from_array([
38+
1.66007664274403694e-03 * DAYS_PER_YEAR,
39+
7.69901118419740425e-03 * DAYS_PER_YEAR,
40+
-6.90460016972063023e-05 * DAYS_PER_YEAR,
41+
0.,
42+
]),
43+
mass: 9.54791938424326609e-04 * SOLAR_MASS,
44+
},
45+
// saturn:
46+
Body {
47+
x: f64x4::from_array([
48+
8.34336671824457987e+00,
49+
4.12479856412430479e+00,
50+
-4.03523417114321381e-01,
51+
0.,
52+
]),
53+
v: f64x4::from_array([
54+
-2.76742510726862411e-03 * DAYS_PER_YEAR,
55+
4.99852801234917238e-03 * DAYS_PER_YEAR,
56+
2.30417297573763929e-05 * DAYS_PER_YEAR,
57+
0.,
58+
]),
59+
mass: 2.85885980666130812e-04 * SOLAR_MASS,
60+
},
61+
// uranus:
62+
Body {
63+
x: f64x4::from_array([
64+
1.28943695621391310e+01,
65+
-1.51111514016986312e+01,
66+
-2.23307578892655734e-01,
67+
0.,
68+
]),
69+
v: f64x4::from_array([
70+
2.96460137564761618e-03 * DAYS_PER_YEAR,
71+
2.37847173959480950e-03 * DAYS_PER_YEAR,
72+
-2.96589568540237556e-05 * DAYS_PER_YEAR,
73+
0.,
74+
]),
75+
mass: 4.36624404335156298e-05 * SOLAR_MASS,
76+
},
77+
// neptune:
78+
Body {
79+
x: f64x4::from_array([
80+
1.53796971148509165e+01,
81+
-2.59193146099879641e+01,
82+
1.79258772950371181e-01,
83+
0.,
84+
]),
85+
v: f64x4::from_array([
86+
2.68067772490389322e-03 * DAYS_PER_YEAR,
87+
1.62824170038242295e-03 * DAYS_PER_YEAR,
88+
-9.51592254519715870e-05 * DAYS_PER_YEAR,
89+
0.,
90+
]),
91+
mass: 5.15138902046611451e-05 * SOLAR_MASS,
92+
},
93+
];
9294

93-
pub fn offset_momentum(bodies: &mut [Body; N_BODIES]) {
94-
let (sun, rest) = bodies.split_at_mut(1);
95-
let sun = &mut sun[0];
96-
for body in rest {
97-
let m_ratio = body.mass / SOLAR_MASS;
98-
sun.v -= body.v * m_ratio;
95+
fn offset_momentum(bodies: &mut [Body; N_BODIES]) {
96+
let (sun, rest) = bodies.split_at_mut(1);
97+
let sun = &mut sun[0];
98+
for body in rest {
99+
let m_ratio = body.mass / SOLAR_MASS;
100+
sun.v -= body.v * m_ratio;
101+
}
99102
}
100-
}
101103

102-
pub fn energy(bodies: &[Body; N_BODIES]) -> f64 {
103-
let mut e = 0.;
104-
for i in 0..N_BODIES {
105-
let bi = &bodies[i];
106-
e += bi.mass * (bi.v * bi.v).horizontal_sum() * 0.5;
107-
for bj in bodies.iter().take(N_BODIES).skip(i + 1) {
108-
let dx = bi.x - bj.x;
109-
e -= bi.mass * bj.mass / (dx * dx).horizontal_sum().sqrt()
104+
fn energy(bodies: &[Body; N_BODIES]) -> f64 {
105+
let mut e = 0.;
106+
for i in 0..N_BODIES {
107+
let bi = &bodies[i];
108+
e += bi.mass * (bi.v * bi.v).horizontal_sum() * 0.5;
109+
for bj in bodies.iter().take(N_BODIES).skip(i + 1) {
110+
let dx = bi.x - bj.x;
111+
e -= bi.mass * bj.mass / (dx * dx).horizontal_sum().sqrt()
112+
}
110113
}
114+
e
111115
}
112-
e
113-
}
114116

115-
pub fn advance(bodies: &mut [Body; N_BODIES], dt: f64) {
116-
const N: usize = N_BODIES * (N_BODIES - 1) / 2;
117+
fn advance(bodies: &mut [Body; N_BODIES], dt: f64) {
118+
const N: usize = N_BODIES * (N_BODIES - 1) / 2;
119+
120+
// compute distance between bodies:
121+
let mut r = [f64x4::splat(0.); N];
122+
{
123+
let mut i = 0;
124+
for j in 0..N_BODIES {
125+
for k in j + 1..N_BODIES {
126+
r[i] = bodies[j].x - bodies[k].x;
127+
i += 1;
128+
}
129+
}
130+
}
131+
132+
let mut mag = [0.0; N];
133+
for i in (0..N).step_by(2) {
134+
let d2s = f64x2::from_array([
135+
(r[i] * r[i]).horizontal_sum(),
136+
(r[i + 1] * r[i + 1]).horizontal_sum(),
137+
]);
138+
let dmags = f64x2::splat(dt) / (d2s * d2s.sqrt());
139+
mag[i] = dmags[0];
140+
mag[i + 1] = dmags[1];
141+
}
117142

118-
// compute distance between bodies:
119-
let mut r = [f64x4::splat(0.); N];
120-
{
121143
let mut i = 0;
122144
for j in 0..N_BODIES {
123145
for k in j + 1..N_BODIES {
124-
r[i] = bodies[j].x - bodies[k].x;
125-
i += 1;
146+
let f = r[i] * mag[i];
147+
bodies[j].v -= f * bodies[k].mass;
148+
bodies[k].v += f * bodies[j].mass;
149+
i += 1
126150
}
127151
}
152+
for body in bodies {
153+
body.x += dt * body.v
154+
}
128155
}
129156

130-
let mut mag = [0.0; N];
131-
for i in (0..N).step_by(2) {
132-
let d2s = f64x2::from_array([
133-
(r[i] * r[i]).horizontal_sum(),
134-
(r[i + 1] * r[i + 1]).horizontal_sum(),
135-
]);
136-
let dmags = f64x2::splat(dt) / (d2s * d2s.sqrt());
137-
mag[i] = dmags[0];
138-
mag[i + 1] = dmags[1];
139-
}
140-
141-
let mut i = 0;
142-
for j in 0..N_BODIES {
143-
for k in j + 1..N_BODIES {
144-
let f = r[i] * mag[i];
145-
bodies[j].v -= f * bodies[k].mass;
146-
bodies[k].v += f * bodies[j].mass;
147-
i += 1
157+
pub fn run(n: usize) -> (f64, f64) {
158+
let mut bodies = BODIES;
159+
offset_momentum(&mut bodies);
160+
let energy_before = energy(&bodies);
161+
for _ in 0..n {
162+
advance(&mut bodies, 0.01);
148163
}
149-
}
150-
for body in bodies {
151-
body.x += dt * body.v
152-
}
153-
}
164+
let energy_after = energy(&bodies);
154165

155-
pub fn run(n: usize) -> (f64, f64) {
156-
let mut bodies = BODIES;
157-
offset_momentum(&mut bodies);
158-
let energy_before = energy(&bodies);
159-
for _ in 0..n {
160-
advance(&mut bodies, 0.01);
166+
(energy_before, energy_after)
161167
}
162-
let energy_after = energy(&bodies);
163-
164-
(energy_before, energy_after)
165168
}
166169

170+
#[cfg(feature = "std")]
167171
#[cfg(test)]
168172
mod tests {
169173
// Good enough for demonstration purposes, not going for strictness here.
@@ -173,12 +177,17 @@ mod tests {
173177
#[test]
174178
fn test() {
175179
const OUTPUT: [f64; 2] = [-0.169075164, -0.169087605];
176-
let (energy_before, energy_after) = super::run(1000);
180+
let (energy_before, energy_after) = super::nbody::run(1000);
177181
assert!(approx_eq_f64(energy_before, OUTPUT[0]));
178182
assert!(approx_eq_f64(energy_after, OUTPUT[1]));
179183
}
180184
}
181185

182186
fn main() {
183-
// empty main to pass CI
187+
#[cfg(feature = "std")]
188+
{
189+
let (energy_before, energy_after) = nbody::run(1000);
190+
println!("Energy before: {}", energy_before);
191+
println!("Energy after: {}", energy_after);
192+
}
184193
}

crates/core_simd/src/intrinsics.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ extern "platform-intrinsic" {
4747
pub(crate) fn simd_fabs<T>(x: T) -> T;
4848

4949
/// fsqrt
50+
#[cfg(feature = "std")]
5051
pub(crate) fn simd_fsqrt<T>(x: T) -> T;
5152

5253
/// fma

crates/core_simd/src/lane_count.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,14 @@ use sealed::Sealed;
66
/// A type representing a vector lane count.
77
pub struct LaneCount<const LANES: usize>;
88

9+
impl<const LANES: usize> LaneCount<LANES> {
10+
/// The number of bytes in a bitmask with this many lanes.
11+
pub const BITMASK_LEN: usize = (LANES + 7) / 8;
12+
}
13+
914
/// Helper trait for vector lane counts.
1015
pub trait SupportedLaneCount: Sealed {
11-
/// The bitmask representation of a mask.
16+
#[doc(hidden)]
1217
type BitMask: Copy + Default + AsRef<[u8]> + AsMut<[u8]>;
1318

1419
#[doc(hidden)]

0 commit comments

Comments
 (0)