-
-
Notifications
You must be signed in to change notification settings - Fork 444
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add basic SIMD support #523
Conversation
src/distributions/float.rs
Outdated
// those are usually more random. | ||
let float_size = mem::size_of::<$f_scalar>() * 8; | ||
let precision = $fraction_bits + 1; | ||
let scale = $ty::splat(1.0 / ((1 as $u_scalar << precision) as $f_scalar)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: most arithmetic and bitwise operations allow you to just use scalar values:
let scale = $ty::splat(1.0 / ((1 as $u_scalar << precision) as $f_scalar));
scale * value
// is the same as
let scale = 1.0 / ((1 as $u_scalar << precision) as $f_scalar);
scale * value
src/distributions/float.rs
Outdated
|
||
let value: $uty = rng.gen(); | ||
let fraction = value >> (float_size - $fraction_bits); | ||
fraction.into_float_with_exponent(0) - $ty::splat(1.0 - EPSILON / 2.0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here. This would be the same:
fraction.into_float_with_exponent(0) - (1.0 - EPSILON / 2.0)
assert!(low < high, "Uniform::new called with `low >= high`");
This will be fine on most inputs, but for inputs like The assertions need to be of the form |
O wow, that is something easy to get wrong! Thank you for reviewing. I have added a
|
e6e7734
to
4dab1e3
Compare
The CI fails because of rust-lang/rust#51699. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, just some nits; meant to post this a couple of days ago
src/distributions/mod.rs
Outdated
@@ -214,6 +214,7 @@ mod float; | |||
mod integer; | |||
#[cfg(feature="std")] | |||
mod log_gamma; | |||
mod math_helpers; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this any more mathematical than other parts of the library? You could just call it num_utils
(i.e. Number Theory, though arguably that still covers most of the library) or arithmetic
.
src/distributions/math_helpers.rs
Outdated
|
||
/// `PartialOrd` for vectors compares lexicographically. We want natural order. | ||
/// Only the comparison functions we need are implemented. | ||
pub trait NaturalCompare { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is natural depends on the context which is how PartialOrd
confused you. How about SimultaneousOrd
?
@TheIronBorn do you think this is ready? I'd like to go over it in more detail myself still, but I think it's pretty neat that we can do this (it's well beyond what most random libs can offer)! |
Looks good! I'll make an SIMD |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But other than those two things looks good.
BTW @TheIronBorn you can make a commit on top of @pitdicker's branch and push to your own branch if you have a fix, but best coordinate between yourselves.
unsafe { | ||
let ptr = &mut vec; | ||
let b_ptr = &mut *(ptr as *mut $ty as *mut [u8; $bits/8]); | ||
rng.fill_bytes(b_ptr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't look portable to me. Elsewhere we've made an effort to keep things portable; I don't think this needs to be an exception?
Unfortunately it doesn't look like the SIMD types support to_le
. @TheIronBorn is this what you mean about using swap_bytes
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes that’s exactly where we’d use it
macro_rules! simd_impl { | ||
($bits:expr,) => {}; | ||
($bits:expr, $ty:ty, $($ty_more:ty,)*) => { | ||
simd_impl!($bits, $($ty_more,)*); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Neat usage of recursive macros.
But why do we need to pass $bits
here instead of just using mem::size_of
? It seems like an unnecessary risk of underfill/overfill.
Since @TheIronBorn has already addressed my comments, lets merge this and make a second PR for the fixes. |
This is a rebased version of the branch from #377 (comment).
@TheIronBorn Do you want to review?