Skip to content

Commit 90b5559

Browse files
committed
First implementation of Posit::round_from(quire)
Now we have: `Quire::from(posit)`, `quire += posit`, and `Posit::round_from(quire)`, so we have all the pieces to do a basic summation using the quire! This is illustrated in the updated example in the crate root doc. However: this is a first draft implementation. Although correct it is messy and not optimised enough. Will take this as a perf baseline and use benchmarks to guide the cleanup and optimisations.
1 parent 4440d14 commit 90b5559

File tree

5 files changed

+461
-87
lines changed

5 files changed

+461
-87
lines changed

proptest-regressions/posit/quire/convert.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,13 @@
55
# It is recommended to check this file in to source control so that
66
# everyone who runs the test benefits from these saved cases.
77
cc e4d920422cccfb5f67bd231bafb1ecc5b19450eb97a1f4ea410f0b1d90f6db05 # shrinks to a = Posit(0b11111111111111111111111111111111)
8+
cc 11716b72e748348a9454d6b6958c160e752deec6a219f134d3f5c5095b55a140 # shrinks to q = Quire(0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01)
9+
cc fc28201f1a1061fc8bb7f0399c2831434bf3babf9d84d0df020f1fe665610b8b # shrinks to q = Quire(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
10+
cc 9c451acc1d3514c6b8c25d2f9cec13aa79921ae5c5efe54e170cb4cd01869df9 # shrinks to q = Quire(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
11+
cc 2c51920351638dcc3a9632c5fb6b9de6b072a230bb6c63af42ac354a9b370020 # shrinks to q = Quire(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
12+
cc 5d9a02c2439ea9189c15fa14c7b7af29a51cca93fdcfc499bf0ad6f8ded1f5fb # shrinks to q = Quire(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
13+
cc 83c487d01ab7c1e3458d212f3d77d678fe771d4e3c3b74fba82268157b3cd356 # shrinks to q = Quire(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
14+
cc 150843eb320314bb50f142889066c23ce5f52d2761a1549f280ea45ffd26bff0 # shrinks to p = Posit(0b00000000000000000000000000000000)
15+
cc c534a97df04b8c827048631656743571116e1a56b8261d4fc34d13ee49f44d52 # shrinks to q = Quire(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
16+
cc 58843b9454f641826c2816646a2358c9bba5393d85356c69a2f62f74ee1331e2 # shrinks to q = Quire(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
17+
cc 081a5a26de44e7544b62b8768229825db56efff8d02dad7e996dcb6b9361a550 # shrinks to q = Quire(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)

src/lib.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,13 @@
5555
//! use fast_posit::{q8, q16, q32, q64};
5656
//! let mut quire = q16::ZERO;
5757
//! quire += p16::MAX;
58-
//! quire += p16::round_from(0.001); // Would overflow
58+
//! quire += p16::round_from(0.1);
5959
//! quire -= p16::MAX;
60-
//! //TODO let result = p16::from(quire);
60+
//! let result: p16 = (&quire).round_into();
6161
//! // Correct result with the quire, no issues with rounding errors.
62-
//! //TODO assert_eq!(result, p16::round_from(0.001))
62+
//! assert_eq!(result, p16::round_from(0.1));
6363
//! // The same sum without the quire would give a wrong result, due to double rounding.
64-
//! let posit = p16::MAX + p16::round_from(0.001) - p16::MAX;
64+
//! let posit = p16::MAX + p16::round_from(0.1) - p16::MAX;
6565
//! assert_eq!(posit, p16::ZERO);
6666
//!
6767
//! // Use a quire per thread to ensure the result is the same regardless of parallelisation!
@@ -76,7 +76,7 @@
7676
//! //TODO for thread in 1..8 {
7777
//! //TODO quires[0] += quire[thread]
7878
//! //TODO }
79-
//! //TODO let result: p16 = quires[0].round_into();
79+
//! let result: p16 = (&quires[0]).round_into();
8080
//!
8181
//! // Use mixed-precision with no hassle; it's very cheap when the ES is the same.
8282
//! //TODO let mut quire = q64::ZERO;

src/posit/quire/basics.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,16 @@ impl<
2020
Self(bytes)
2121
}
2222

23-
/// Access the storage as an array of `u64`s.
23+
/// Access the storage as an array of **big-endian** `Int`s.
24+
///
25+
/// Limitation: even though the return size is known, we cannot return an `&[Int; N]` due to
26+
/// limitations in the Rust type system. We have to hope that the compiler will inline and fold
27+
/// the slice len :)
2428
#[inline]
25-
pub(crate) const fn as_u64_array(&self) -> &[u64] {
29+
pub(crate) const fn as_int_array<Int: crate::Int>(&self) -> &[Int] {
2630
const { assert!(SIZE % 8 == 0, "Quire SIZE must be a multiple of 64 bits (8 bytes)"); }
27-
let ptr = self.0.as_ptr() as *const u64;
28-
let len = SIZE / 8;
31+
let ptr = self.0.as_ptr() as *const Int;
32+
let len = SIZE / (Int::BITS as usize / 8);
2933
// SAFETY: ptr and len form a valid slice; the size and alignment is correct, and any bit
3034
// pattern is a valid u64 value.
3135
unsafe { core::slice::from_raw_parts(ptr, len) }
@@ -105,8 +109,8 @@ impl<
105109
// Therefore, for almost all cases where the quire is not NaR, we only need a compare and
106110
// branch. Only on when the quire is NaR, or in the rare cases where it's not NaR but still
107111
// starts with `0b1000…`, will we need to scan through the whole thing.
108-
let quire = self.as_u64_array();
109-
if quire[0] != (i64::MIN as u64).to_be() { return false } // TODO mark likely?
112+
let quire: &[i64] = self.as_int_array();
113+
if quire[0] != i64::MIN.to_be() { return false } // TODO mark likely?
110114
// Written in this awkward way because it's a `const fn`...
111115
let mut i = 1;
112116
while i < quire.len() {

0 commit comments

Comments
 (0)