commit ed25904267663fd6b484b23d1b9499d26ff6af1d
parent 59f9d6b4bd5c18f91c30a959749592e2347e5949
Author: Jared Tobin <jared@jtobin.io>
Date: Fri, 24 Jan 2025 13:49:07 +0400
lib: test and bench cases
Diffstat:
6 files changed, 66 insertions(+), 24 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -1,2 +1,3 @@
dist-newstyle/
*.prof
+*.hp
diff --git a/bench/Main.hs b/bench/Main.hs
@@ -121,6 +121,13 @@ div = bench "div" $ nf (W.div w0) w1 where
!w1 = W.to_word256
0x066bd4c3c10e30260cb6e7832af25f15527b089b258a1fef13b6eec3ce73bf06
+div_pure :: Benchmark
+div_pure = bench "div_pure" $ nf (W.div_pure w0) w1 where
+ !w0 = W.to_word256
+ 0x41cf50c7d0d65afabcf5ba37750dba71c7db29ec9f20a216d3ef013a59b9188a
+ !w1 = W.to_word256
+ 0x066bd4c3c10e30260cb6e7832af25f15527b089b258a1fef13b6eec3ce73bf06
+
div_baseline_small :: Benchmark
div_baseline_small =
bench "div, small (baseline)" $ nf (Prelude.div w0) w1
@@ -169,12 +176,13 @@ quotrem_by1_gen =
main :: IO ()
main = defaultMain [
- quotrem_by1
- , quotrem_by1_gen
- , mul_baseline
- , mul
- , div_baseline
+ -- quotrem_by1
+ -- , quotrem_by1_gen
+ div_baseline
+ , div_pure
, div
+ --, mul_baseline
+ --, mul
--, mod_baseline
--, mod
--, div_baseline_small
diff --git a/bench/Weight.hs b/bench/Weight.hs
@@ -55,6 +55,7 @@ main = do
W.func "mul" (E.mul w0) w1
W.func "div (baseline)" (Prelude.div i2) i3
W.func "div" (E.div w2) w3
+ W.func "div_pure" (E.div_pure w2) w3
W.io "quotrem_by1" (E.quotrem_by1 q u) d
W.func "quotrem_by1_gen"
(E.quotrem_by1_gen (E.Word576 300 200 100 0 0 0 0 0 0) 3) (B.complement 50)
diff --git a/lib/Data/Word/Extended.hs b/lib/Data/Word/Extended.hs
@@ -799,6 +799,16 @@ div a@(Word256 a0 a1 a2 a3) b@(Word256 b0 b1 b2 b3)
z3 <- PA.readPrimArray quo 3
pure (Word256 z0 z1 z2 z3)
+div_pure :: Word256 -> Word256 -> Word256
+div_pure a@(Word256 a0 a1 a2 a3) b@(Word256 b0 _ _ _)
+ | is_zero b || b `gt` a = zero -- ?
+ | a == b = one
+ | is_word64 a = Word256 (a0 `quot` b0) 0 0 0
+ | otherwise =
+ let !u = Word576 a0 a1 a2 a3 0 0 0 0 0
+ !(Word832 (Word576 q0 q1 q2 q3 _ _ _ _ _) _) = quotrem_gen u b
+ in Word256 q0 q1 q2 q3
+
-- primarray
mod :: Word256 -> Word256 -> Word256
mod a@(Word256 a0 a1 a2 a3) b@(Word256 b0 b1 b2 b3)
@@ -822,3 +832,12 @@ mod a@(Word256 a0 a1 a2 a3) b@(Word256 b0 b1 b2 b3)
y <- PA.unsafeFreezePrimArray my
quotrem quo x y
+mod_pure :: Word256 -> Word256 -> Word256
+mod_pure a@(Word256 a0 a1 a2 a3) b@(Word256 b0 _ _ _)
+ | is_zero b || a == b = zero -- ?
+ | a `lt` b = a
+ | is_word64 a = Word256 (a0 `Prelude.rem` b0) 0 0 0
+ | otherwise =
+ let !u = Word576 a0 a1 a2 a3 0 0 0 0 0
+ !(Word832 _ r) = quotrem_gen u b
+ in r
diff --git a/src/Main.hs b/src/Main.hs
@@ -7,28 +7,25 @@ import Data.Word.Extended
main :: IO ()
main = do
- let !u = PA.primArrayFromList [
- 5152276743337338587
- , 6823823105342984773
- , 12649096328525870222
- , 8811572179372364942
- ]
- !d = PA.primArrayFromList [
+ let !u = Word576
+ 5152276743337338587
+ 6823823105342984773
+ 12649096328525870222
+ 8811572179372364942
+ 0 0 0 0 0
+
+ !d = Word256
8849385646123010679
- , 653197174784954101
- , 1286679968202709238
- , 3741537094902495500
- ]
+ 653197174784954101
+ 1286679968202709238
+ 3741537094902495500
- quo <- PA.newPrimArray 5
let go !j !acc
- | j == 10000 = pure ()
- | otherwise = do
- PA.setPrimArray quo 0 5 0
- w <- quotrem quo u d
- go (succ j) w
- r <- go 0 zero
- q <- PA.unsafeFreezePrimArray quo
+ | j == 10000 = acc
+ | otherwise =
+ let !(Word832 q r) = quotrem_gen u d
+ in go (succ j) (q, r)
+ (q, r) = go 0 (zero576, zero)
print r
print q
diff --git a/test/Main.hs b/test/Main.hs
@@ -148,12 +148,24 @@ div_matches (DivMonotonic (a, b)) =
!rite = to_word256 (a `Prelude.div` b)
in left == rite
+div_pure_matches :: DivMonotonic -> Bool
+div_pure_matches (DivMonotonic (a, b)) =
+ let !left = to_word256 a `div_pure` to_word256 b
+ !rite = to_word256 (a `Prelude.div` b)
+ in left == rite
+
mod_matches :: DivMonotonic -> Bool
mod_matches (DivMonotonic (a, b)) =
let !left = to_word256 a `mod` to_word256 b
!rite = to_word256 (a `rem` b)
in left == rite
+mod_pure_matches :: DivMonotonic -> Bool
+mod_pure_matches (DivMonotonic (a, b)) =
+ let !left = to_word256 a `mod_pure` to_word256 b
+ !rite = to_word256 (a `rem` b)
+ in left == rite
+
-- assertions ------------------------------------------------------------------
quotrem_r_case0 :: H.Assertion
@@ -422,8 +434,12 @@ arithmetic = testGroup "arithmetic" [
Q.withMaxSuccess 1000 mul_512_matches
, Q.testProperty "division matches" $
Q.withMaxSuccess 1000 div_matches
+ , Q.testProperty "pure division matches" $
+ Q.withMaxSuccess 1000 div_pure_matches
, Q.testProperty "mod matches" $
Q.withMaxSuccess 1000 mod_matches
+ , Q.testProperty "pure mod matches" $
+ Q.withMaxSuccess 1000 mod_pure_matches
]
utils :: TestTree