packages feed

hw-rankselect 0.8.0.2 → 0.9.0.0

raw patch · 11 files changed

+827/−425 lines, 11 filesdep +bytestringdep +conduitdep +criteriondep ~basedep ~hw-bitsdep ~hw-primnew-component:exe:hw-rankselect-exePVP ok

version bump matches the API change (PVP)

Dependencies added: bytestring, conduit, criterion, deepseq, directory, hedgehog, hw-hedgehog, hw-hspec-hedgehog, mmap, resourcet

Dependency ranges changed: base, hw-bits, hw-prim

API changes (from Hackage documentation)

- HaskellWorks.Data.RankSelect.CsPoppy: [csPoppy512Index] :: CsPoppy -> Vector Word64
- HaskellWorks.Data.RankSelect.CsPoppy: [csPoppyLayer0] :: CsPoppy -> Vector Word64
- HaskellWorks.Data.RankSelect.CsPoppy: [csPoppyLayer1] :: CsPoppy -> Vector Word64
- HaskellWorks.Data.RankSelect.CsPoppy: sampleRange :: CsPoppy -> Count -> (Word64, Word64)
- HaskellWorks.Data.RankSelect.CsPoppy2: CsPoppy2 :: Vector Word64 -> Vector Word64 -> Vector Word64 -> Vector Word64 -> Vector Word64 -> CsPoppy2
- HaskellWorks.Data.RankSelect.CsPoppy2: [csPoppy2512Index] :: CsPoppy2 -> Vector Word64
- HaskellWorks.Data.RankSelect.CsPoppy2: [csPoppy2Bits] :: CsPoppy2 -> Vector Word64
- HaskellWorks.Data.RankSelect.CsPoppy2: [csPoppy2Layer0] :: CsPoppy2 -> Vector Word64
- HaskellWorks.Data.RankSelect.CsPoppy2: [csPoppy2Layer1] :: CsPoppy2 -> Vector Word64
- HaskellWorks.Data.RankSelect.CsPoppy2: [csPoppy2LayerS] :: CsPoppy2 -> Vector Word64
- HaskellWorks.Data.RankSelect.CsPoppy2: class Rank1 v
- HaskellWorks.Data.RankSelect.CsPoppy2: data CsPoppy2
- HaskellWorks.Data.RankSelect.CsPoppy2: instance GHC.Classes.Eq HaskellWorks.Data.RankSelect.CsPoppy2.CsPoppy2
- HaskellWorks.Data.RankSelect.CsPoppy2: instance GHC.Show.Show HaskellWorks.Data.RankSelect.CsPoppy2.CsPoppy2
- HaskellWorks.Data.RankSelect.CsPoppy2: instance HaskellWorks.Data.Bits.BitLength.BitLength HaskellWorks.Data.RankSelect.CsPoppy2.CsPoppy2
- HaskellWorks.Data.RankSelect.CsPoppy2: instance HaskellWorks.Data.Bits.BitRead.BitRead HaskellWorks.Data.RankSelect.CsPoppy2.CsPoppy2
- HaskellWorks.Data.RankSelect.CsPoppy2: instance HaskellWorks.Data.RankSelect.Base.Rank1.Rank1 HaskellWorks.Data.RankSelect.CsPoppy2.CsPoppy2
- HaskellWorks.Data.RankSelect.CsPoppy2: instance HaskellWorks.Data.RankSelect.Base.Select1.Select1 HaskellWorks.Data.RankSelect.CsPoppy2.CsPoppy2
- HaskellWorks.Data.RankSelect.CsPoppy2: instance HaskellWorks.Data.Vector.AsVector64.AsVector64 HaskellWorks.Data.RankSelect.CsPoppy2.CsPoppy2
- HaskellWorks.Data.RankSelect.CsPoppy2: makeCsPoppy2 :: Vector Word64 -> CsPoppy2
- HaskellWorks.Data.RankSelect.CsPoppy2: rank1 :: Rank1 v => v -> Count -> Count
- HaskellWorks.Data.RankSelect.CsPoppy2: sampleRange :: CsPoppy2 -> Count -> (Word64, Word64)
+ HaskellWorks.Data.RankSelect.CsPoppy: Nice :: a -> Nice a
+ HaskellWorks.Data.RankSelect.CsPoppy: [csPoppyLayerM] :: CsPoppy -> !(Vector Word64)
+ HaskellWorks.Data.RankSelect.CsPoppy: instance Control.DeepSeq.NFData HaskellWorks.Data.RankSelect.CsPoppy.CsPoppy
+ HaskellWorks.Data.RankSelect.CsPoppy: instance GHC.Classes.Eq a => GHC.Classes.Eq (HaskellWorks.Data.RankSelect.CsPoppy.Nice a)
+ HaskellWorks.Data.RankSelect.CsPoppy: instance GHC.Generics.Generic HaskellWorks.Data.RankSelect.CsPoppy.CsPoppy
+ HaskellWorks.Data.RankSelect.CsPoppy: instance GHC.Show.Show (HaskellWorks.Data.RankSelect.CsPoppy.Nice HaskellWorks.Data.RankSelect.CsPoppy.CsPoppy)
+ HaskellWorks.Data.RankSelect.CsPoppy: instance HaskellWorks.Data.BalancedParens.BalancedParens.BalancedParens HaskellWorks.Data.RankSelect.CsPoppy.CsPoppy
+ HaskellWorks.Data.RankSelect.CsPoppy: instance HaskellWorks.Data.BalancedParens.CloseAt.CloseAt HaskellWorks.Data.RankSelect.CsPoppy.CsPoppy
+ HaskellWorks.Data.RankSelect.CsPoppy: instance HaskellWorks.Data.BalancedParens.Enclose.Enclose HaskellWorks.Data.RankSelect.CsPoppy.CsPoppy
+ HaskellWorks.Data.RankSelect.CsPoppy: instance HaskellWorks.Data.BalancedParens.FindClose.FindClose HaskellWorks.Data.RankSelect.CsPoppy.CsPoppy
+ HaskellWorks.Data.RankSelect.CsPoppy: instance HaskellWorks.Data.BalancedParens.FindCloseN.FindCloseN HaskellWorks.Data.RankSelect.CsPoppy.CsPoppy
+ HaskellWorks.Data.RankSelect.CsPoppy: instance HaskellWorks.Data.BalancedParens.FindOpen.FindOpen HaskellWorks.Data.RankSelect.CsPoppy.CsPoppy
+ HaskellWorks.Data.RankSelect.CsPoppy: instance HaskellWorks.Data.BalancedParens.FindOpenN.FindOpenN HaskellWorks.Data.RankSelect.CsPoppy.CsPoppy
+ HaskellWorks.Data.RankSelect.CsPoppy: instance HaskellWorks.Data.BalancedParens.NewCloseAt.NewCloseAt HaskellWorks.Data.RankSelect.CsPoppy.CsPoppy
+ HaskellWorks.Data.RankSelect.CsPoppy: instance HaskellWorks.Data.BalancedParens.OpenAt.OpenAt HaskellWorks.Data.RankSelect.CsPoppy.CsPoppy
+ HaskellWorks.Data.RankSelect.CsPoppy: instance HaskellWorks.Data.Bits.PopCount.PopCount1.PopCount1 HaskellWorks.Data.RankSelect.CsPoppy.CsPoppy
+ HaskellWorks.Data.RankSelect.CsPoppy: instance HaskellWorks.Data.RankSelect.Base.Rank0.Rank0 HaskellWorks.Data.RankSelect.CsPoppy.CsPoppy
+ HaskellWorks.Data.RankSelect.CsPoppy: newtype Nice a
+ HaskellWorks.Data.RankSelect.CsPoppy.Internal: CsInterleaved :: Word64 -> CsInterleaved
+ HaskellWorks.Data.RankSelect.CsPoppy.Internal: [unCsInterleaved] :: CsInterleaved -> Word64
+ HaskellWorks.Data.RankSelect.CsPoppy.Internal: getCsiA :: CsInterleaved -> Word64
+ HaskellWorks.Data.RankSelect.CsPoppy.Internal: getCsiB :: CsInterleaved -> Word64
+ HaskellWorks.Data.RankSelect.CsPoppy.Internal: getCsiC :: CsInterleaved -> Word64
+ HaskellWorks.Data.RankSelect.CsPoppy.Internal: getCsiTotal :: CsInterleaved -> Word64
+ HaskellWorks.Data.RankSelect.CsPoppy.Internal: getCsiX :: CsInterleaved -> Word64
+ HaskellWorks.Data.RankSelect.CsPoppy.Internal: instance Foreign.Storable.Storable HaskellWorks.Data.RankSelect.CsPoppy.Internal.CsInterleaved
+ HaskellWorks.Data.RankSelect.CsPoppy.Internal: instance GHC.Classes.Eq HaskellWorks.Data.RankSelect.CsPoppy.Internal.CsInterleaved
+ HaskellWorks.Data.RankSelect.CsPoppy.Internal: instance GHC.Show.Show HaskellWorks.Data.RankSelect.CsPoppy.Internal.CsInterleaved
+ HaskellWorks.Data.RankSelect.CsPoppy.Internal: mkCsi :: Word64 -> Word64 -> Word64 -> Word64 -> CsInterleaved
+ HaskellWorks.Data.RankSelect.CsPoppy.Internal: newtype CsInterleaved
+ HaskellWorks.Data.RankSelect.CsPoppy.Internal: putCsiA :: Word64 -> CsInterleaved -> CsInterleaved
+ HaskellWorks.Data.RankSelect.CsPoppy.Internal: putCsiB :: Word64 -> CsInterleaved -> CsInterleaved
+ HaskellWorks.Data.RankSelect.CsPoppy.Internal: putCsiC :: Word64 -> CsInterleaved -> CsInterleaved
+ HaskellWorks.Data.RankSelect.CsPoppy.Internal: putCsiX :: Word64 -> CsInterleaved -> CsInterleaved
+ HaskellWorks.Data.RankSelect.Poppy512: instance Control.DeepSeq.NFData HaskellWorks.Data.RankSelect.Poppy512.Poppy512
+ HaskellWorks.Data.RankSelect.Poppy512: instance GHC.Generics.Generic HaskellWorks.Data.RankSelect.Poppy512.Poppy512
+ HaskellWorks.Data.RankSelect.Poppy512: instance HaskellWorks.Data.Bits.PopCount.PopCount1.PopCount1 HaskellWorks.Data.RankSelect.Poppy512.Poppy512
+ HaskellWorks.Data.RankSelect.Poppy512S: instance Control.DeepSeq.NFData HaskellWorks.Data.RankSelect.Poppy512S.Poppy512S
+ HaskellWorks.Data.RankSelect.Poppy512S: instance GHC.Generics.Generic HaskellWorks.Data.RankSelect.Poppy512S.Poppy512S
+ HaskellWorks.Data.RankSelect.Poppy512S: instance HaskellWorks.Data.Bits.PopCount.PopCount1.PopCount1 HaskellWorks.Data.RankSelect.Poppy512S.Poppy512S
- HaskellWorks.Data.RankSelect.CsPoppy: CsPoppy :: Vector Word64 -> Vector Word64 -> Vector Word64 -> Vector Word64 -> Vector Word64 -> CsPoppy
+ HaskellWorks.Data.RankSelect.CsPoppy: CsPoppy :: !(Vector Word64) -> !(Vector Word64) -> !(Vector Word32) -> CsPoppy
- HaskellWorks.Data.RankSelect.CsPoppy: [csPoppyBits] :: CsPoppy -> Vector Word64
+ HaskellWorks.Data.RankSelect.CsPoppy: [csPoppyBits] :: CsPoppy -> !(Vector Word64)
- HaskellWorks.Data.RankSelect.CsPoppy: [csPoppyLayerS] :: CsPoppy -> Vector Word64
+ HaskellWorks.Data.RankSelect.CsPoppy: [csPoppyLayerS] :: CsPoppy -> !(Vector Word32)
- HaskellWorks.Data.RankSelect.Poppy512: Poppy512 :: Vector Word64 -> Vector Word64 -> Poppy512
+ HaskellWorks.Data.RankSelect.Poppy512: Poppy512 :: !(Vector Word64) -> !(Vector Word64) -> Poppy512
- HaskellWorks.Data.RankSelect.Poppy512: [poppy512Bits] :: Poppy512 -> Vector Word64
+ HaskellWorks.Data.RankSelect.Poppy512: [poppy512Bits] :: Poppy512 -> !(Vector Word64)
- HaskellWorks.Data.RankSelect.Poppy512: [poppy512Index] :: Poppy512 -> Vector Word64
+ HaskellWorks.Data.RankSelect.Poppy512: [poppy512Index] :: Poppy512 -> !(Vector Word64)

Files

+ app/Main.hs view
@@ -0,0 +1,112 @@+{-# LANGUAGE BangPatterns         #-}+{-# LANGUAGE ScopedTypeVariables  #-}++module Main where++import Control.Monad+import Data.List+import Data.Monoid ((<>))+import Foreign+import HaskellWorks.Data.Bits.PopCount.PopCount1+import HaskellWorks.Data.FromForeignRegion+import HaskellWorks.Data.RankSelect.Base.Select1+import System.Directory+import System.Environment+import System.IO.MMap++import qualified Data.Vector.Storable                   as DVS+import qualified HaskellWorks.Data.RankSelect.CsPoppy   as CS+import qualified HaskellWorks.Data.RankSelect.Poppy512  as P512+import qualified HaskellWorks.Data.RankSelect.Poppy512S as P512S++{-# ANN module ("HLint: ignore Redundant do" :: String) #-}+{-# ANN module ("HLint: ignore Reduce duplication"  :: String) #-}++loadVector64 :: FilePath -> IO (DVS.Vector Word64)+loadVector64 filename = fromForeignRegion <$> mmapFileForeignPtr filename ReadOnly Nothing++loadCsPoppy :: FilePath -> IO CS.CsPoppy+loadCsPoppy filename = CS.makeCsPoppy <$> loadVector64 filename++loadPoppy512 :: FilePath -> IO P512.Poppy512+loadPoppy512 filename = P512.makePoppy512 <$> loadVector64 filename++loadPoppy512S :: FilePath -> IO P512S.Poppy512S+loadPoppy512S filename = P512S.makePoppy512S <$> loadVector64 filename++runCsPoppyBuild :: IO ()+runCsPoppyBuild = do+  entries <- listDirectory "data"+  let files = ("data/" ++) <$> (".ib" `isSuffixOf`) `filter` entries+  forM_ files $ \file -> do+    putStrLn $ "Loading cspoppy for " <> file+    CS.CsPoppy !_ !_ !_ <- loadCsPoppy file+    return ()++runPoppy512Build :: IO ()+runPoppy512Build = do+  entries <- listDirectory "data"+  let files = ("data/" ++) <$> (".ib" `isSuffixOf`) `filter` entries+  forM_ files $ \file -> do+    putStrLn $ "Loading cspoppy for " <> file+    P512.Poppy512 !_ !_ <- loadPoppy512 file+    -- let !_ = select1 msbs 1+    return ()++runPoppy512SBuild :: IO ()+runPoppy512SBuild = do+  entries <- listDirectory "data"+  let files = ("data/" ++) <$> (".ib" `isSuffixOf`) `filter` entries+  forM_ files $ \file -> do+    putStrLn $ "Loading cspoppy for " <> file+    P512S.Poppy512S !_ !_ !_ <- loadPoppy512S file+    -- let !_ = select1 msbs 1+    return ()++runPoppy512SelectAll :: IO ()+runPoppy512SelectAll = do+  entries <- listDirectory "data"+  let files = ("data/" ++) <$> (".ib" `isSuffixOf`) `filter` entries+  forM_ files $ \file -> do+    putStrLn $ "Loading cspoppy for " <> file+    v <- loadPoppy512 file+    forM_ [1..popCount1 v] $ \i -> do+      let !_ = select1 v i+      return ()+    return ()++runPoppy512SSelectAll :: IO ()+runPoppy512SSelectAll = do+  entries <- listDirectory "data"+  let files = ("data/" ++) <$> (".ib" `isSuffixOf`) `filter` entries+  forM_ files $ \file -> do+    putStrLn $ "Loading cspoppy for " <> file+    v <- loadPoppy512S file+    forM_ [1..popCount1 v] $ \i -> do+      let !_ = select1 v i+      return ()+    return ()++runCsPoppySelectAll :: IO ()+runCsPoppySelectAll = do+  entries <- listDirectory "data"+  let files = ("data/" ++) <$> (".ib" `isSuffixOf`) `filter` entries+  forM_ files $ \file -> do+    putStrLn $ "Loading cspoppy for " <> file+    v <- loadCsPoppy file+    forM_ [1..popCount1 v] $ \i -> do+      let !_ = select1 v i+      return ()+    return ()++main :: IO ()+main = do+  args <- getArgs+  case args of+    ["cspoppy-load"]          -> runCsPoppyBuild+    ["cspoppy-select-all"]    -> runCsPoppySelectAll+    ["poppy512-load"]         -> runPoppy512Build+    ["poppy512-select-all"]   -> runPoppy512SelectAll+    ["poppy512s-load"]        -> runPoppy512SBuild+    ["poppy512s-select-all"]  -> runPoppy512SSelectAll+    _                         -> putStrLn "Invalid arguments"
+ bench/Main.hs view
@@ -0,0 +1,160 @@+{-# LANGUAGE BangPatterns         #-}+{-# LANGUAGE ScopedTypeVariables  #-}++module Main where++import Control.Monad+import Criterion.Main+import Data.List+import Foreign+import HaskellWorks.Data.Bits.PopCount.PopCount1+import HaskellWorks.Data.FromForeignRegion+import HaskellWorks.Data.Positioning+import HaskellWorks.Data.RankSelect.Base.Select1+import System.Directory+import System.Environment+import System.IO.MMap++import qualified Data.Vector.Storable                   as DVS+import qualified HaskellWorks.Data.RankSelect.CsPoppy   as CS+import qualified HaskellWorks.Data.RankSelect.Poppy512  as P512+import qualified HaskellWorks.Data.RankSelect.Poppy512S as P512S++{-# ANN module ("HLint: ignore Redundant do" :: String) #-}+{-# ANN module ("HLint: ignore Reduce duplication"  :: String) #-}++selectStep :: Count+selectStep = 1000++loadVector64 :: FilePath -> IO (DVS.Vector Word64)+loadVector64 filename = fromForeignRegion <$> mmapFileForeignPtr filename ReadOnly Nothing++loadCsPoppy :: FilePath -> IO CS.CsPoppy+loadCsPoppy filename = CS.makeCsPoppy <$> loadVector64 filename++loadPoppy512 :: FilePath -> IO P512.Poppy512+loadPoppy512 filename = P512.makePoppy512 <$> loadVector64 filename++loadPoppy512S :: FilePath -> IO P512S.Poppy512S+loadPoppy512S filename = P512S.makePoppy512S <$> loadVector64 filename++benchCsPoppyBuild :: IO [Benchmark]+benchCsPoppyBuild = do+  entries <- listDirectory "data"+  let files = ("data/" ++) <$> (".ib" `isSuffixOf`) `filter` entries+  return (mkBenchmark <$> files)+  where mkBenchmark filename = env (loadVector64 filename) $ \bitString -> bgroup filename+          [ bench "CsPoppy Build"  (whnf CS.makeCsPoppy bitString)+          ]++benchCsPoppyRank1 :: IO [Benchmark]+benchCsPoppyRank1 = do+  entries <- listDirectory "data"+  let files = ("data/" ++) <$> (".ib" `isSuffixOf`) `filter` entries+  return (mkBenchmark <$> files)+  where mkBenchmark filename = env (loadCsPoppy filename) $ \csPoppy -> bgroup filename+          [ bench "CsPoppy Rank1"  (whnf (CS.rank1 csPoppy) 100)+          ]++benchCsPoppySelect1 :: IO [Benchmark]+benchCsPoppySelect1 = do+  entries <- listDirectory "data"+  let files = ("data/" ++) <$> (".ib" `isSuffixOf`) `filter` entries+  return (mkBenchmark <$> files)+  where mkBenchmark filename = env (loadCsPoppy filename) $ \rsbs -> bgroup filename+          [ bench "CsPoppy Select1"  (whnf (go rsbs 1 (popCount1 rsbs) ((popCount1 rsbs `div` 100) + 1)) 0)+          ]+        go rsbs a z step acc | a <= z  = go rsbs (a + step) z step (select1 rsbs a + acc)+        go _    _ _ _    acc           = acc+        {-# INLINE go #-}++benchPoppy512Build :: IO [Benchmark]+benchPoppy512Build = do+  entries <- listDirectory "data"+  let files = ("data/" ++) <$> (".ib" `isSuffixOf`) `filter` entries+  return (mkBenchmark <$> files)+  where mkBenchmark filename = env (loadVector64 filename) $ \bitString -> bgroup filename+          [ bench "Poppy512 Build"  (whnf P512.makePoppy512 bitString)+          ]++benchPoppy512Rank1 :: IO [Benchmark]+benchPoppy512Rank1 = do+  entries <- listDirectory "data"+  let files = ("data/" ++) <$> (".ib" `isSuffixOf`) `filter` entries+  return (mkBenchmark <$> files)+  where mkBenchmark filename = env (loadPoppy512 filename) $ \csPoppy -> bgroup filename+          [ bench "Poppy512 Rank1"  (whnf (CS.rank1 csPoppy) 100)+          ]++benchPoppy512Select1 :: IO [Benchmark]+benchPoppy512Select1 = do+  entries <- listDirectory "data"+  let files = ("data/" ++) <$> (".ib" `isSuffixOf`) `filter` entries+  return (mkBenchmark <$> files)+  where mkBenchmark filename = env (loadPoppy512 filename) $ \rsbs -> bgroup filename+          [ bench "Poppy512 Select1"  (whnf (go rsbs 1 (popCount1 rsbs) ((popCount1 rsbs `div` 100) + 1)) 0)+          ]+        go rsbs a z step acc | a <= z  = go rsbs (a + step) z step (select1 rsbs a + acc)+        go _    _ _ _    acc           = acc+        {-# INLINE go #-}++benchPoppy512SBuild :: IO [Benchmark]+benchPoppy512SBuild = do+  entries <- listDirectory "data"+  let files = ("data/" ++) <$> (".ib" `isSuffixOf`) `filter` entries+  return (mkBenchmark <$> files)+  where mkBenchmark filename = env (loadVector64 filename) $ \bitString -> bgroup filename+          [ bench "Poppy512S Build"  (whnf P512S.makePoppy512S bitString)+          ]++benchPoppy512SRank1 :: IO [Benchmark]+benchPoppy512SRank1 = do+  entries <- listDirectory "data"+  let files = ("data/" ++) <$> (".ib" `isSuffixOf`) `filter` entries+  return (mkBenchmark <$> files)+  where mkBenchmark filename = env (loadPoppy512S filename) $ \csPoppy -> bgroup filename+          [ bench "Poppy512S Rank1"  (whnf (CS.rank1 csPoppy) 100)+          ]++benchPoppy512SSelect1 :: IO [Benchmark]+benchPoppy512SSelect1 = do+  entries <- listDirectory "data"+  let files = ("data/" ++) <$> (".ib" `isSuffixOf`) `filter` entries+  return (mkBenchmark <$> files)+  where mkBenchmark filename = env (loadPoppy512S filename) $ \rsbs -> bgroup filename+          [ bench "Poppy512S Select1"  (whnf (go rsbs 1 (popCount1 rsbs) ((popCount1 rsbs `div` 100) + 1)) 0)+          ]+        go rsbs a z step acc | a <= z  = go rsbs (a + step) z step (select1 rsbs a + acc)+        go _    _ _ _    acc           = acc+        {-# INLINE go #-}++runCsPoppyBuild :: IO ()+runCsPoppyBuild = do+  entries <- listDirectory "data"+  let files = ("data/" ++) <$> (".ib" `isSuffixOf`) `filter` entries+  forM_ files $ \file -> do+    msbs <- loadPoppy512S file+    let !_ = select1 msbs 1+    return ()++runBenchmarks :: IO ()+runBenchmarks = (defaultMain =<<) . (concat <$>) $ sequence+  [ benchCsPoppyBuild+  , benchCsPoppyRank1+  , benchCsPoppySelect1+  , benchPoppy512Build+  , benchPoppy512Rank1+  , benchPoppy512Select1+  , benchPoppy512SBuild+  , benchPoppy512SRank1+  , benchPoppy512SSelect1+  ]+++main :: IO ()+main = do+  args <- getArgs+  case args of+    []                -> runBenchmarks+    ["load-cspoppy"]  -> runCsPoppyBuild+    _                 -> putStrLn "Invalid arguments"
hw-rankselect.cabal view
@@ -1,5 +1,5 @@ name:                   hw-rankselect-version:                0.8.0.2+version:                0.9.0.0 synopsis:               Rank-select description:            Please see README.md homepage:               http://github.com/haskell-works/hw-rankselect#readme@@ -16,10 +16,11 @@ library   hs-source-dirs:       src   exposed-modules:      HaskellWorks.Data.RankSelect.CsPoppy-                      , HaskellWorks.Data.RankSelect.CsPoppy2+                      , HaskellWorks.Data.RankSelect.CsPoppy.Internal                       , HaskellWorks.Data.RankSelect.Poppy512                       , HaskellWorks.Data.RankSelect.Poppy512S   build-depends:        base                          >= 4          && < 5+                      , deepseq                       , hw-balancedparens             >= 0.1.0.0                       , hw-bits                       >= 0.3.0.0                       , hw-prim                       >= 0.4.0.0@@ -29,27 +30,71 @@   default-language:     Haskell2010   ghc-options:          -Wall -O2 -msse4.2 +executable hw-rankselect-exe+  hs-source-dirs:       app+  main-is:              Main.hs+  default-language:     Haskell2010+  build-depends:        base >= 4.7 && < 5+                      -- , bytestring+                      -- , conduit+                      , directory+                      , hw-bits                       >= 0.4.0.0+                      , hw-prim                       >= 0.4.0.0+                      , hw-rankselect+                      , hw-rankselect-base            >= 0.2.0.0+                      , mmap+                      -- , resourcet+                      , vector+  ghc-options:       -threaded -rtsopts -O2 -msse4.2+  default-extensions: OverloadedStrings, TupleSections+  if os(darwin)+    cpp-options: -D__attribute__(A)= -D_Nullable= -D_Nonnull=+ test-suite hw-rankselect-test   type:                 exitcode-stdio-1.0   hs-source-dirs:       test   main-is:              Spec.hs   other-modules:        HaskellWorks.Data.RankSelect.BasicGen                       , HaskellWorks.Data.RankSelect.CsPoppySpec-                      , HaskellWorks.Data.RankSelect.CsPoppy2Spec+                      , HaskellWorks.Data.RankSelect.CsPoppy.InternalSpec                       , HaskellWorks.Data.RankSelect.Poppy512Spec                       , HaskellWorks.Data.RankSelect.Poppy512SSpec                       , HaskellWorks.Data.RankSelect.InternalSpec                       , HaskellWorks.Data.RankSelect.SimpleSpec   build-depends:        base                          >= 4          && < 5+                      , directory+                      , hedgehog                       , hspec-                      , hw-bits                       >= 0.3.0.0+                      , hw-bits                       >= 0.4.0.0+                      , hw-hedgehog                   >= 0.1.0.1+                      , hw-hspec-hedgehog                       , hw-prim                       >= 0.4.0.0                       , hw-rankselect                       , hw-rankselect-base            >= 0.2.0.0+                      , mmap                       , QuickCheck                       , vector   ghc-options:          -threaded -rtsopts -with-rtsopts=-N -Wall   default-language:     Haskell2010++benchmark bench+    Type: exitcode-stdio-1.0+    HS-Source-Dirs: bench+    Main-Is: Main.hs+    GHC-Options: -O2 -Wall -msse4.2+    Default-Language: Haskell2010+    Build-Depends:      base                          >= 4          && < 5+                      , bytestring+                      , conduit+                      , criterion+                      , directory+                      , hw-bits                       >= 0.4.0.0+                      , hw-prim                       >= 0.4.0.0+                      , hw-rankselect+                      , hw-rankselect-base            >= 0.2.0.0+                      , mmap+                      , resourcet+                      , vector  source-repository head   type:     git
src/HaskellWorks/Data/RankSelect/CsPoppy.hs view
@@ -1,31 +1,64 @@+{-# OPTIONS_GHC-funbox-strict-fields #-}++{-# LANGUAGE BangPatterns      #-}+{-# LANGUAGE DeriveAnyClass    #-}+{-# LANGUAGE DeriveGeneric     #-}+{-# LANGUAGE FlexibleContexts  #-}+{-# LANGUAGE FlexibleInstances #-}+ module HaskellWorks.Data.RankSelect.CsPoppy     ( CsPoppy(..)+    , Nice(..)     , Rank1(..)     , makeCsPoppy-    , sampleRange     ) where -import qualified Data.Vector.Storable                                       as DVS-import           Data.Word-import           HaskellWorks.Data.AtIndex-import           HaskellWorks.Data.Bits.BitLength-import           HaskellWorks.Data.Bits.BitRead-import           HaskellWorks.Data.Bits.BitWise-import           HaskellWorks.Data.Bits.PopCount.PopCount1-import           HaskellWorks.Data.Positioning-import           HaskellWorks.Data.RankSelect.Base.Rank1-import           HaskellWorks.Data.RankSelect.Base.Select1-import           HaskellWorks.Data.Search-import           HaskellWorks.Data.Vector.AsVector64+import Control.DeepSeq+import Data.Monoid                                     ((<>))+import Data.Word+import GHC.Generics+import HaskellWorks.Data.AtIndex+import HaskellWorks.Data.BalancedParens.BalancedParens+import HaskellWorks.Data.BalancedParens.CloseAt+import HaskellWorks.Data.BalancedParens.Enclose+import HaskellWorks.Data.BalancedParens.FindClose+import HaskellWorks.Data.BalancedParens.FindCloseN+import HaskellWorks.Data.BalancedParens.FindOpen+import HaskellWorks.Data.BalancedParens.FindOpenN+import HaskellWorks.Data.BalancedParens.NewCloseAt+import HaskellWorks.Data.BalancedParens.OpenAt+import HaskellWorks.Data.Bits.BitLength+import HaskellWorks.Data.Bits.BitRead+import HaskellWorks.Data.Bits.BitShow+import HaskellWorks.Data.Bits.BitWise+import HaskellWorks.Data.Bits.PopCount.PopCount1+import HaskellWorks.Data.Drop+import HaskellWorks.Data.Positioning+import HaskellWorks.Data.RankSelect.Base.Rank0+import HaskellWorks.Data.RankSelect.Base.Rank1+import HaskellWorks.Data.RankSelect.Base.Select1+import HaskellWorks.Data.RankSelect.CsPoppy.Internal+import HaskellWorks.Data.Take+import HaskellWorks.Data.Vector.AsVector64+import Prelude                                         hiding (drop, length, pi, take) +import qualified Data.Vector.Storable as DVS++newtype Nice a = Nice a deriving Eq+ data CsPoppy = CsPoppy-  { csPoppyBits     :: DVS.Vector Word64-  , csPoppy512Index :: DVS.Vector Word64-  , csPoppyLayer0   :: DVS.Vector Word64-  , csPoppyLayer1   :: DVS.Vector Word64-  , csPoppyLayerS   :: DVS.Vector Word64 -- Sampling position of each 8192 1-bit-  } deriving (Eq, Show)+  { csPoppyBits   :: !(DVS.Vector Word64)+  , csPoppyLayerM :: !(DVS.Vector Word64)+  , csPoppyLayerS :: !(DVS.Vector Word32) -- Sampling lookup of each 8192 1-bit+  } deriving (Eq, Show, NFData, Generic) +instance Show (Nice CsPoppy) where+  showsPrec _ (Nice rsbs) = showString "CsPoppy "+    <> showString "{ csPoppyBits = "   <> shows (bitShow <$> DVS.toList (csPoppyBits     rsbs))+    <> showString ", csPoppyLayer0 = " <> shows (CsInterleaved <$> DVS.toList (csPoppyLayerM rsbs))+    <> showString ", csPoppyLayerS = " <> shows (csPoppyLayerS rsbs)+    <> showString " }"+ instance AsVector64 CsPoppy where   asVector64 = asVector64 . csPoppyBits   {-# INLINE asVector64 #-}@@ -34,49 +67,55 @@   bitLength = bitLength . csPoppyBits   {-# INLINE bitLength #-} -popCount1Range :: (DVS.Storable a, PopCount1 a) => Int -> Int -> DVS.Vector a -> Count-popCount1Range start len = popCount1 . DVS.take len . DVS.drop start+instance PopCount1 CsPoppy where+  popCount1 v = getCsiTotal (CsInterleaved (lastOrZero (csPoppyLayerM v)))+  {-# INLINE popCount1 #-} +indexOrZero :: DVS.Vector Word64 -> Position -> Word64+indexOrZero _ i | i < 0     = 0+indexOrZero v i | i < end v = v !!! i+indexOrZero _ _ = 0+{-# INLINE indexOrZero #-}++lastOrZero :: DVS.Vector Word64 -> Word64+lastOrZero v | 0 < end v  = DVS.last v+lastOrZero _ = 0+{-# INLINE lastOrZero #-}+ makeCsPoppy :: DVS.Vector Word64 -> CsPoppy makeCsPoppy v = CsPoppy-  { csPoppyBits     = v-  , csPoppy512Index = DVS.constructN (((DVS.length v +           8 - 1) `div`           8) + 1) gen512Index-  , csPoppyLayer0   = DVS.constructN (((DVS.length v + 0x100000000 - 1) `div` 0x100000000) + 1) genLayer0-  , csPoppyLayer1   = DVS.constructN (((DVS.length v +          32 - 1) `div`          32) + 1) genLayer1-  , csPoppyLayerS   = DVS.unfoldrN (fromIntegral (popCount1 v `div` 8192) + 1) genS (0, 0)+  { csPoppyBits   = v+  , csPoppyLayerM = layerM+  , csPoppyLayerS = layerS   }-  where csPoppyCum2048  = DVS.constructN (((DVS.length v +          32 - 1) `div`          32) + 1) genCum2048-        gen512Index u = let indexN = DVS.length u - 1 in-          if indexN == -1-            then 0-            else popCount1Range (indexN *           8)           8 v + DVS.last u-        genCum2048 u = let indexN = DVS.length u in-          if indexN .&. 0xffffffff == 0-            then 0-            else popCount1Range ((indexN - 1) *    32)          32 v + DVS.last u-        genLayer0 u = let indexN = DVS.length u in-          if indexN == 0-            then 0-            else popCount1Range (indexN * 0x100000000) 0x100000000 v + DVS.last u-        genLayer1 u = let indexN = DVS.length u in-          let cum = if indexN == 0 -- TODO Check boundary at 4G???-              then  0-              else  csPoppyCum2048 !!! fromIntegral indexN in-          let a = popCount1Range (indexN * 32 +  0) 8 v in-          let b = popCount1Range (indexN * 32 +  8) 8 v in-          let c = popCount1Range (indexN * 32 + 16) 8 v in-          (   ( cum       .&. 0x00000000ffffffff)-          .|. ((a .<. 32) .&. 0x000003ff00000000)-          .|. ((b .<. 42) .&. 0x000ffc0000000000)-          .|. ((c .<. 52) .&. 0x3ff0000000000000)) -- zhou-sea2013 fig 5 (c)-        genS :: (Count, Position) -> Maybe (Word64, (Count, Position))-        genS (pca, n) = if n < end v-          then  let w = v !!! n in-                let pcz = pca + popCount1 w in-                if (8192 - 1 + pca) `div` 8192 /= (8192 - 1 + pcz) `div` 8192-                  then Just (fromIntegral n * 64 + fromIntegral (select1 w (fromIntegral (8192 - (pca `mod` 8192)))), (pcz, n + 1))-                  else genS (pcz, n + 1)-          else Nothing+  where blocks  = DVS.constructN (((DVS.length v      + 8 - 1) `div` 8) + 1) genBlocks+        layerM  = DVS.constructN (((DVS.length blocks + 4 - 1) `div` 4) + 1) genLayer1+        layerMPopCount = getCsiTotal (CsInterleaved (lastOrZero layerM))+        layerS = DVS.unfoldrN (fromIntegral layerMPopCount) genSample (0, 1)+        genBlocks u = let i = length u in popCount1 (take 8 (drop (i * 8) v))+        genLayer1 :: DVS.Vector Word64 -> Word64+        genLayer1 u =+          let i  = end u                          in+          let lx = lastOrZero u                   in+          let la = indexOrZero blocks (i * 4 - 4) in+          let lb = indexOrZero blocks (i * 4 - 3) in+          let lc = indexOrZero blocks (i * 4 - 2) in+          let ld = indexOrZero blocks (i * 4 - 1) in+          let nx = lx + (la + lb + lc + ld)       in+          let na = indexOrZero blocks (i * 4 + 0) in+          let nb = indexOrZero blocks (i * 4 + 1) in+          let nc = indexOrZero blocks (i * 4 + 2) in+          (   ( nx         .&. 0x00000000ffffffff)+          .|. ((na .<. 32) .&. 0x000003ff00000000)+          .|. ((nb .<. 42) .&. 0x000ffc0000000000)+          .|. ((nc .<. 52) .&. 0x3ff0000000000000))+        mLookup :: Position -> Word64+        mLookup i = getCsiX (CsInterleaved (layerM !!! i))+        genSample :: (Position, Position) -> Maybe (Word32, (Position, Position))+        genSample (mi, _) | mi == maxBound                                            = Nothing+        genSample (mi, _) | mi >= end layerM                                          = Just (fromIntegral (DVS.length layerM - 1), (maxBound, maxBound))+        genSample (mi, s) | s < toPosition (getCsiTotal (CsInterleaved (mLookup mi))) = Just (fromIntegral mi - 1, (mi, s + 8192))+        genSample (mi, s) = genSample (fromIntegral mi + 1, s)  instance TestBit CsPoppy where   (.?.) = (.?.) . csPoppyBits@@ -86,40 +125,98 @@   bitRead = fmap makeCsPoppy . bitRead  instance Rank1 CsPoppy where-  rank1 (CsPoppy v _ layer0 layer1 _) p = rankPrior + rankInBasicBlock-    where rankLayer0              = layer0  !!! toPosition (p `div` 0x100000000)-          rankLayer1Word          = layer1  !!! toPosition (p `div` 2048)-          rankLayer1A             =  rankLayer1Word .&. 0x00000000ffffffff-          rankLayer1B             = (rankLayer1Word .&. 0x000003ff00000000) .>. 32-          rankLayer1C             = (rankLayer1Word .&. 0x000ffc0000000000) .>. 42-          rankLayer1D             = (rankLayer1Word .&. 0x3ff0000000000000) .>. 52-          q                       = (p `div` 512) `mod` 4 -- quarter-          rankLayer1  | q == 0    = rankLayer1A-                      | q == 1    = rankLayer1A + rankLayer1B-                      | q == 2    = rankLayer1A + rankLayer1B + rankLayer1C-                      | q == 3    = rankLayer1A + rankLayer1B + rankLayer1C + rankLayer1D-                      | otherwise = undefined-          rankPrior               = (rankLayer0 + rankLayer1) :: Count-          rankInBasicBlock        = rank1 (DVS.drop (fromIntegral p `div` 512) v) (p `mod` 512)+  rank1 (CsPoppy !v !layerM !_) p = rankPrior + rankInBasicBlock+    where mw  = layerM !!! toPosition (p `div` 2048)+          mx  =  mw .&. 0x00000000ffffffff+          ma  = (mw .&. 0x000003ff00000000) .>. 32+          mb  = (mw .&. 0x000ffc0000000000) .>. 42+          mc  = (mw .&. 0x3ff0000000000000) .>. 52+          q   = (p `div` 512) `mod` 4 -- quarter+          mi  | q == 0    = mx+              | q == 1    = mx + ma+              | q == 2    = mx + ma + mb+              | q == 3    = mx + ma + mb + mc+              | otherwise = error "Invalid interleaved entry index"+          rankPrior         = mi :: Count+          rankInBasicBlock  = rank1 (DVS.drop (fromIntegral (p `div` 512) * 8) v) (p `mod` 512)+  {-# INLINE rank1 #-} +mBinarySearch :: Word64 -> DVS.Vector Word64 -> Position -> Position -> Position+mBinarySearch !w !m !p !q = if p + 1 >= q+  then p+  else let !o = (p + q) `div` 2 in+    if w <= getCsiX (CsInterleaved (m !!! o))+      then mBinarySearch w m p o+      else mBinarySearch w m o q+{-# INLINE mBinarySearch #-}+ instance Select1 CsPoppy where-  select1 iv@(CsPoppy v i _ _ _) p = if DVS.length v /= 0-      then toCount q * 512 + select1 (DVS.drop (fromIntegral q * 8) v) (p - s)-      else 0-    where q = binarySearch (fromIntegral p) wordAt iMin iMax-          s = (i !!! q) :: Count-          wordAt = (i !!!)-          (sampleMin, sampleMax) = sampleRange iv p-          iMin = fromIntegral $  (sampleMin - 1) `div` 512      :: Position-          iMax = fromIntegral $ ((sampleMax - 1) `div` 512) + 1 :: Position+  select1 _                             p | p == 0  = 0+  select1 (CsPoppy !v !layerM !layerS)  p           =+    let !pi                 = toPosition $ (p - 1) `div` 8192                 in+    let !pj                 = (pi + 1) `min` (end layerS - 1)                 in+    let !si                 = fromIntegral   (layerS !!! pi)                  in+    let !sj                 = fromIntegral $ (layerS !!! pj) + 1              in+    let !mIndex             = mBinarySearch (fromIntegral p) layerM si sj     in+    let !me                 = CsInterleaved (layerM !!! fromIntegral mIndex)  in+    let !mx                 = getCsiX me                                      in+    let !ma                 = getCsiA me + mx                                 in+    let !mb                 = getCsiB me + ma                                 in+    let !mc                 = getCsiC me + mb                                 in+    let !bo | p <= ma       = 0+            | p <= mb       = 1+            | p <= mc       = 2+            | otherwise     = 3                                               in+    let !bp | p <= ma       = mx+            | p <= mb       = ma+            | p <= mc       = mb+            | otherwise     = mc                                              in+    let !blockStart          = toCount (mIndex * 4 + bo) * 8                  in+    let !block               = DVS.take 8 (drop blockStart v)                 in+    let !q                   = p - bp                                         in+    select1 block q + blockStart * 64+  {-# INLINE select1 #-} -sampleRange :: CsPoppy -> Count -> (Word64, Word64)-sampleRange (CsPoppy _ index _ _ samples) p =-  let j = (fromIntegral p - 1) `div` 8192 in-  if 0 <= j && j < DVS.length samples-    then  let pa = samples DVS.! j                in-          if j + 1 < DVS.length samples-            then  let pz = samples DVS.! (j + 1)          in-                  (pa, pz)-            else (pa, fromIntegral (DVS.length index - 1))-    else (1, fromIntegral (DVS.length index - 1))+instance OpenAt CsPoppy where+  openAt = openAt . csPoppyBits+  {-# INLINE openAt #-}++instance CloseAt CsPoppy where+  closeAt = closeAt . csPoppyBits+  {-# INLINE closeAt #-}++instance NewCloseAt CsPoppy where+  newCloseAt = newCloseAt . csPoppyBits+  {-# INLINE newCloseAt #-}++instance FindOpenN CsPoppy where+  findOpenN = findOpenN . csPoppyBits+  {-# INLINE findOpenN #-}++instance FindOpen CsPoppy where+  findOpen = findOpen . csPoppyBits+  {-# INLINE findOpen #-}++instance FindClose CsPoppy where+  findClose = findClose . csPoppyBits+  {-# INLINE findClose #-}++instance FindCloseN CsPoppy where+  findCloseN = findCloseN . csPoppyBits+  {-# INLINE findCloseN #-}++instance Enclose CsPoppy where+  enclose = enclose . csPoppyBits+  {-# INLINE enclose #-}++instance Rank0 CsPoppy where+  rank0 rsbs p = p - rank0 rsbs p+  {-# INLINE rank0 #-}++instance BalancedParens CsPoppy where+  firstChild  = firstChild  . csPoppyBits+  nextSibling = nextSibling . csPoppyBits+  parent      = parent      . csPoppyBits+  {-# INLINE firstChild  #-}+  {-# INLINE nextSibling #-}+  {-# INLINE parent      #-}
+ src/HaskellWorks/Data/RankSelect/CsPoppy/Internal.hs view
@@ -0,0 +1,69 @@+{-# OPTIONS_GHC-funbox-strict-fields #-}++module HaskellWorks.Data.RankSelect.CsPoppy.Internal+    ( CsInterleaved(..)+    , getCsiX+    , getCsiA+    , getCsiB+    , getCsiC+    , getCsiTotal+    , mkCsi+    , putCsiX+    , putCsiA+    , putCsiB+    , putCsiC+    ) where++import Data.Word+import Foreign.Ptr+import Foreign.Storable+import HaskellWorks.Data.Bits.BitWise++newtype CsInterleaved = CsInterleaved { unCsInterleaved :: Word64 } deriving Eq++instance Storable CsInterleaved where+  sizeOf = sizeOf . unCsInterleaved+  {-# INLINE sizeOf #-}+  alignment = alignment . unCsInterleaved+  {-# INLINE alignment #-}+  peekElemOff ptr i = CsInterleaved <$> peekElemOff (castPtr ptr) i+  {-# INLINE peekElemOff #-}+  pokeElemOff ptr i = pokeElemOff (castPtr ptr) i . unCsInterleaved+  {-# INLINE pokeElemOff #-}++mkCsi :: Word64 -> Word64 -> Word64 -> Word64 -> CsInterleaved+mkCsi x a b c = CsInterleaved+    $   ((x .&. 0xffffffff) .<.  0)+    .|. ((a .&.      0x3ff) .<. 32)+    .|. ((b .&.      0x3ff) .<. 42)+    .|. ((c .&.      0x3ff) .<. 52)++getCsiX :: CsInterleaved -> Word64+getCsiX (CsInterleaved i) = i .&. 0xffffffff++getCsiA :: CsInterleaved -> Word64+getCsiA (CsInterleaved i) = (i .>. 32) .&. 0x3ff++getCsiB :: CsInterleaved -> Word64+getCsiB (CsInterleaved i) = (i .>. 42) .&. 0x3ff++getCsiC :: CsInterleaved -> Word64+getCsiC (CsInterleaved i) = (i .>. 52) .&. 0x3ff++getCsiTotal :: CsInterleaved -> Word64+getCsiTotal csi = getCsiX csi + getCsiA csi + getCsiB csi + getCsiC csi++putCsiX :: Word64 -> CsInterleaved -> CsInterleaved+putCsiX v (CsInterleaved i) = CsInterleaved (((v .&. 0xffffffff) .<.  0) .|. (i .&. 0xffffffff00000000))++putCsiA :: Word64 -> CsInterleaved -> CsInterleaved+putCsiA v (CsInterleaved i) = CsInterleaved (((v .&.      0x3ff) .<. 32) .|. (i .&. 0xfffffc00ffffffff))++putCsiB :: Word64 -> CsInterleaved -> CsInterleaved+putCsiB v (CsInterleaved i) = CsInterleaved (((v .&.      0x3ff) .<. 42) .|. (i .&. 0xfff003ffffffffff))++putCsiC :: Word64 -> CsInterleaved -> CsInterleaved+putCsiC v (CsInterleaved i) = CsInterleaved (((v .&.      0x3ff) .<. 52) .|. (i .&. 0xc00fffffffffffff))++instance Show CsInterleaved where+  showsPrec _ i = shows (getCsiX i, getCsiA i, getCsiB i, getCsiC i)
− src/HaskellWorks/Data/RankSelect/CsPoppy2.hs
@@ -1,116 +0,0 @@-module HaskellWorks.Data.RankSelect.CsPoppy2-    ( CsPoppy2(..)-    , Rank1(..)-    , makeCsPoppy2-    , sampleRange-    ) where--import qualified Data.Vector.Storable                                       as DVS-import           Data.Word-import           HaskellWorks.Data.AtIndex-import           HaskellWorks.Data.Bits.BitLength-import           HaskellWorks.Data.Bits.BitRead-import           HaskellWorks.Data.Bits.BitWise-import           HaskellWorks.Data.Bits.PopCount.PopCount1-import           HaskellWorks.Data.Positioning-import           HaskellWorks.Data.RankSelect.Base.Rank1-import           HaskellWorks.Data.RankSelect.Base.Select1-import           HaskellWorks.Data.Search-import           HaskellWorks.Data.Vector.AsVector64--data CsPoppy2 = CsPoppy2-  { csPoppy2Bits     :: DVS.Vector Word64-  , csPoppy2512Index :: DVS.Vector Word64-  , csPoppy2Layer0   :: DVS.Vector Word64-  , csPoppy2Layer1   :: DVS.Vector Word64-  , csPoppy2LayerS   :: DVS.Vector Word64 -- Sampling position of each 8192 1-bit-  } deriving (Eq, Show)--instance AsVector64 CsPoppy2 where-  asVector64 = asVector64 . csPoppy2Bits-  {-# INLINE asVector64 #-}--instance BitLength CsPoppy2 where-  bitLength = bitLength . csPoppy2Bits-  {-# INLINE bitLength #-}--popCount1Range :: (DVS.Storable a, PopCount1 a) => Int -> Int -> DVS.Vector a -> Count-popCount1Range start len = popCount1 . DVS.take len . DVS.drop start--makeCsPoppy2 :: DVS.Vector Word64 -> CsPoppy2-makeCsPoppy2 v = CsPoppy2-  { csPoppy2Bits     = v-  , csPoppy2512Index = DVS.constructN (((DVS.length v +           8 - 1) `div`           8) + 1) gen512Index-  , csPoppy2Layer0   = DVS.constructN (((DVS.length v + 0x100000000 - 1) `div` 0x100000000) + 1) genLayer0-  , csPoppy2Layer1   = DVS.constructN (((DVS.length v +          32 - 1) `div`          32) + 1) genLayer1-  , csPoppy2LayerS   = DVS.unfoldrN (fromIntegral (popCount1 v `div` 8192) + 1) genS (0, 0)-  }-  where csPoppy2Cum2048  = DVS.constructN (((DVS.length v +          32 - 1) `div`          32) + 1) genCum2048-        gen512Index u = let indexN = DVS.length u - 1 in-          if indexN == -1-            then 0-            else popCount1Range (indexN *           8)           8 v + DVS.last u-        genCum2048 u = let indexN = DVS.length u in-          if indexN .&. 0xffffffff == 0-            then 0-            else popCount1Range ((indexN - 1) *    32)          32 v + DVS.last u-        genLayer0 u = let indexN = DVS.length u in-          if indexN == 0-            then 0-            else popCount1Range (indexN * 0x100000000) 0x100000000 v + DVS.last u-        genLayer1 u = let indexN = DVS.length u in-          let cum = if indexN == 0 -- TODO Check boundary at 4G???-              then  0-              else  csPoppy2Cum2048 !!! fromIntegral indexN in-          let a = popCount1Range (indexN * 32 +  0) 8 v in-          let b = popCount1Range (indexN * 32 +  8) 8 v in-          let c = popCount1Range (indexN * 32 + 16) 8 v in-          (   ( cum       .&. 0x00000000ffffffff)-          .|. ((a .<. 32) .&. 0x000003ff00000000)-          .|. ((b .<. 42) .&. 0x000ffc0000000000)-          .|. ((c .<. 52) .&. 0x3ff0000000000000)) -- zhou-sea2013 fig 5 (c)-        genS :: (Count, Position) -> Maybe (Word64, (Count, Position))-        genS (pca, n) = if n < end v-          then  let w = v !!! n in-                let pcz = pca + popCount1 w in-                if (8192 - 1 + pca) `div` 8192 /= (8192 - 1 + pcz) `div` 8192-                  then Just (fromIntegral n * 64 + fromIntegral (select1 w (fromIntegral (8192 - (pca `mod` 8192)))), (pcz, n + 1))-                  else genS (pcz, n + 1)-          else Nothing--instance BitRead CsPoppy2 where-  bitRead = fmap makeCsPoppy2 . bitRead--instance Rank1 CsPoppy2 where-  rank1 (CsPoppy2 v _ layer0 layer1 _) p = rankPrior + rankInBasicBlock-    where rankLayer0              = layer0  !!! toPosition (p `div` 0x100000000)-          rankLayer1Word          = layer1  !!! toPosition (p `div` 2048)-          rankLayer1A             =  rankLayer1Word .&. 0x00000000ffffffff-          rankLayer1B             = (rankLayer1Word .&. 0x000003ff00000000) .>. 32-          rankLayer1C             = (rankLayer1Word .&. 0x000ffc0000000000) .>. 42-          rankLayer1D             = (rankLayer1Word .&. 0x3ff0000000000000) .>. 52-          q                       = (p `div` 512) `mod` 4 -- quarter-          rankLayer1  | q == 0    = rankLayer1A-                      | q == 1    = rankLayer1A + rankLayer1B-                      | q == 2    = rankLayer1A + rankLayer1B + rankLayer1C-                      | q == 3    = rankLayer1A + rankLayer1B + rankLayer1C + rankLayer1D-                      | otherwise = undefined-          rankPrior               = (rankLayer0 + rankLayer1) :: Count-          rankInBasicBlock        = rank1 (DVS.drop (fromIntegral p `div` 512) v) (p `mod` 512)--instance Select1 CsPoppy2 where-  select1 (CsPoppy2 v i _ _ _) p = toCount q * 512 + select1 (DVS.drop (fromIntegral q * 8) v) (p - s)-    where q = binarySearch (fromIntegral p) wordAt 0 (fromIntegral $ DVS.length i - 1)-          s = (i !!! q) :: Count-          wordAt = (i !!!)--sampleRange :: CsPoppy2 -> Count -> (Word64, Word64)-sampleRange (CsPoppy2 _ index _ _ samples) p =-  let j = (fromIntegral p - 1) `div` 8192 in-  if 0 <= j && j < DVS.length samples-    then  let pa = samples DVS.! j                in-          if j + 1 < DVS.length samples-            then  let pz = samples DVS.! (j + 1)          in-                  (pa, pz)-            else (pa, fromIntegral (DVS.length index - 1))-    else (1, fromIntegral (DVS.length index - 1))
src/HaskellWorks/Data/RankSelect/Poppy512.hs view
@@ -1,3 +1,7 @@+{-# OPTIONS_GHC-funbox-strict-fields #-}++{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric  #-} {-# LANGUAGE TypeFamilies   #-}  module HaskellWorks.Data.RankSelect.Poppy512@@ -6,35 +10,42 @@     , makePoppy512     ) where -import qualified Data.Vector.Storable                                       as DVS-import           Data.Word-import           HaskellWorks.Data.AtIndex-import           HaskellWorks.Data.Bits.BitLength-import           HaskellWorks.Data.Bits.BitRead-import           HaskellWorks.Data.Bits.BitWise-import           HaskellWorks.Data.Bits.PopCount.PopCount1-import           HaskellWorks.Data.Positioning-import           HaskellWorks.Data.RankSelect.Base.Rank0-import           HaskellWorks.Data.RankSelect.Base.Rank1-import           HaskellWorks.Data.RankSelect.Base.Select0-import           HaskellWorks.Data.RankSelect.Base.Select1-import           HaskellWorks.Data.Search-import           HaskellWorks.Data.BalancedParens.BalancedParens-import           HaskellWorks.Data.BalancedParens.CloseAt-import           HaskellWorks.Data.BalancedParens.Enclose-import           HaskellWorks.Data.BalancedParens.FindClose-import           HaskellWorks.Data.BalancedParens.FindOpen-import           HaskellWorks.Data.BalancedParens.FindCloseN-import           HaskellWorks.Data.BalancedParens.FindOpenN-import           HaskellWorks.Data.BalancedParens.NewCloseAt-import           HaskellWorks.Data.BalancedParens.OpenAt-import           HaskellWorks.Data.Vector.AsVector64-import           Prelude hiding (length)+import Control.DeepSeq+import Data.Word+import GHC.Generics+import HaskellWorks.Data.AtIndex+import HaskellWorks.Data.BalancedParens.BalancedParens+import HaskellWorks.Data.BalancedParens.CloseAt+import HaskellWorks.Data.BalancedParens.Enclose+import HaskellWorks.Data.BalancedParens.FindClose+import HaskellWorks.Data.BalancedParens.FindCloseN+import HaskellWorks.Data.BalancedParens.FindOpen+import HaskellWorks.Data.BalancedParens.FindOpenN+import HaskellWorks.Data.BalancedParens.NewCloseAt+import HaskellWorks.Data.BalancedParens.OpenAt+import HaskellWorks.Data.Bits.BitLength+import HaskellWorks.Data.Bits.BitRead+import HaskellWorks.Data.Bits.BitWise+import HaskellWorks.Data.Bits.PopCount.PopCount1+import HaskellWorks.Data.Positioning+import HaskellWorks.Data.RankSelect.Base.Rank0+import HaskellWorks.Data.RankSelect.Base.Rank1+import HaskellWorks.Data.RankSelect.Base.Select0+import HaskellWorks.Data.RankSelect.Base.Select1+import HaskellWorks.Data.Search+import HaskellWorks.Data.Vector.AsVector64+import Prelude                                         hiding (length) +import qualified Data.Vector.Storable as DVS+ data Poppy512 = Poppy512-  { poppy512Bits  :: DVS.Vector Word64-  , poppy512Index :: DVS.Vector Word64-  } deriving (Eq, Show)+  { poppy512Bits  :: !(DVS.Vector Word64)+  , poppy512Index :: !(DVS.Vector Word64)+  } deriving (Eq, Show, NFData, Generic)++instance PopCount1 Poppy512 where+  popCount1 = popCount1 . poppy512Bits+  {-# INLINE popCount1 #-}  instance AsVector64 Poppy512 where   asVector64 = asVector64 . poppy512Bits
src/HaskellWorks/Data/RankSelect/Poppy512S.hs view
@@ -1,5 +1,9 @@-{-# LANGUAGE BangPatterns #-}+{-# OPTIONS_GHC-funbox-strict-fields #-} +{-# LANGUAGE BangPatterns   #-}+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric  #-}+ module HaskellWorks.Data.RankSelect.Poppy512S     ( Poppy512S(..)     , Rank1(..)@@ -7,39 +11,46 @@     , sampleRange     ) where -import qualified Data.Vector.Storable                                       as DVS-import           Data.Word-import           HaskellWorks.Data.AtIndex-import           HaskellWorks.Data.Bits.BitLength-import           HaskellWorks.Data.Bits.BitRead-import           HaskellWorks.Data.Bits.BitWise-import           HaskellWorks.Data.Bits.PopCount.PopCount1-import           HaskellWorks.Data.Positioning-import           HaskellWorks.Data.RankSelect.Base.Rank0-import           HaskellWorks.Data.RankSelect.Base.Rank1-import           HaskellWorks.Data.RankSelect.Base.Select1-import           HaskellWorks.Data.Search-import           HaskellWorks.Data.BalancedParens.BalancedParens-import           HaskellWorks.Data.BalancedParens.CloseAt-import           HaskellWorks.Data.BalancedParens.Enclose-import           HaskellWorks.Data.BalancedParens.FindClose-import           HaskellWorks.Data.BalancedParens.FindCloseN-import           HaskellWorks.Data.BalancedParens.FindOpen-import           HaskellWorks.Data.BalancedParens.FindOpenN-import           HaskellWorks.Data.BalancedParens.NewCloseAt-import           HaskellWorks.Data.BalancedParens.OpenAt-import           HaskellWorks.Data.Vector.AsVector64-import           Prelude hiding (length)+import Control.DeepSeq+import Data.Word+import GHC.Generics+import HaskellWorks.Data.AtIndex+import HaskellWorks.Data.BalancedParens.BalancedParens+import HaskellWorks.Data.BalancedParens.CloseAt+import HaskellWorks.Data.BalancedParens.Enclose+import HaskellWorks.Data.BalancedParens.FindClose+import HaskellWorks.Data.BalancedParens.FindCloseN+import HaskellWorks.Data.BalancedParens.FindOpen+import HaskellWorks.Data.BalancedParens.FindOpenN+import HaskellWorks.Data.BalancedParens.NewCloseAt+import HaskellWorks.Data.BalancedParens.OpenAt+import HaskellWorks.Data.Bits.BitLength+import HaskellWorks.Data.Bits.BitRead+import HaskellWorks.Data.Bits.BitWise+import HaskellWorks.Data.Bits.PopCount.PopCount1+import HaskellWorks.Data.Positioning+import HaskellWorks.Data.RankSelect.Base.Rank0+import HaskellWorks.Data.RankSelect.Base.Rank1+import HaskellWorks.Data.RankSelect.Base.Select1+import HaskellWorks.Data.Search+import HaskellWorks.Data.Vector.AsVector64+import Prelude                                         hiding (length) +import qualified Data.Vector.Storable as DVS+ data Poppy512S = Poppy512S   { poppy512SBits   :: !(DVS.Vector Word64)   , poppy512Index   :: !(DVS.Vector Word64)   , poppy512Samples :: !(DVS.Vector Word64) -- Sampling position of each 8192 1-bit-  } deriving (Eq, Show)+  } deriving (Eq, Show, NFData, Generic)  instance AsVector64 Poppy512S where   asVector64 = asVector64 . poppy512SBits   {-# INLINE asVector64 #-}++instance PopCount1 Poppy512S where+  popCount1 = popCount1 . poppy512SBits+  {-# INLINE popCount1 #-}  popCount1Range :: (DVS.Storable a, PopCount1 a) => Int -> Int -> DVS.Vector a -> Count popCount1Range start len = popCount1 . DVS.take len . DVS.drop start
+ test/HaskellWorks/Data/RankSelect/CsPoppy/InternalSpec.hs view
@@ -0,0 +1,42 @@+{-# OPTIONS_GHC -fno-warn-incomplete-patterns #-}++module HaskellWorks.Data.RankSelect.CsPoppy.InternalSpec (spec) where++import HaskellWorks.Data.Bits.BitWise+import HaskellWorks.Data.RankSelect.CsPoppy.Internal+import HaskellWorks.Hspec.Hedgehog+import Hedgehog+import Prelude                                        hiding (length)+import Test.Hspec++import qualified Hedgehog.Gen              as G+import qualified Hedgehog.Range            as R++{-# ANN module ("HLint: ignore Redundant do" :: String) #-}+{-# ANN module ("HLint: ignore Reduce duplication"  :: String) #-}++spec :: Spec+spec = describe "HaskellWorks.Data.RankSelect.CsInterleavedSpec" $ do+  describe "Interleaved Level 1 & 2" $ do+    it "have all its fields isolated" $ require $ property $ do+      vx <- forAll $ G.word64 R.constantBounded+      va <- forAll $ G.word64 R.constantBounded+      vb <- forAll $ G.word64 R.constantBounded+      vc <- forAll $ G.word64 R.constantBounded+      let actual =  putCsiX vx .+                    putCsiA va .+                    putCsiB vb .+                    putCsiC vc $ CsInterleaved 0+      getCsiX (putCsiX vx actual) === (vx .&. 0xffffffff)+      getCsiA (putCsiA va actual) === (va .&. 0x3ff)+      getCsiB (putCsiB vb actual) === (vb .&. 0x3ff)+      getCsiC (putCsiC vc actual) === (vc .&. 0x3ff)+    it "have all its fields isolated" $ require $ property $ do+      vx <- forAll $ G.word64 R.constantBounded+      va <- forAll $ G.word64 R.constantBounded+      vb <- forAll $ G.word64 R.constantBounded+      vc <- forAll $ G.word64 R.constantBounded+      getCsiX (putCsiX vx (CsInterleaved 0)) === (vx .&. 0xffffffff)+      getCsiA (putCsiA va (CsInterleaved 0)) === (va .&. 0x3ff)+      getCsiB (putCsiB vb (CsInterleaved 0)) === (vb .&. 0x3ff)+      getCsiC (putCsiC vc (CsInterleaved 0)) === (vc .&. 0x3ff)
− test/HaskellWorks/Data/RankSelect/CsPoppy2Spec.hs
@@ -1,94 +0,0 @@-{-# OPTIONS_GHC -fno-warn-incomplete-patterns #-}-{-# LANGUAGE GeneralizedNewtypeDeriving       #-}-{-# LANGUAGE ScopedTypeVariables              #-}--module HaskellWorks.Data.RankSelect.CsPoppy2Spec (spec) where--import           GHC.Exts-import           Data.Maybe-import qualified Data.Vector.Storable                                       as DVS-import           Data.Word-import           HaskellWorks.Data.AtIndex-import           HaskellWorks.Data.Bits.BitRead-import           HaskellWorks.Data.Bits.BitShow-import           HaskellWorks.Data.Bits.PopCount.PopCount1-import           HaskellWorks.Data.RankSelect.Base.Rank1-import           HaskellWorks.Data.RankSelect.Base.Select1-import           HaskellWorks.Data.RankSelect.BasicGen-import           HaskellWorks.Data.RankSelect.CsPoppy2-import           Prelude hiding (length)-import           Test.Hspec-import           Test.QuickCheck--{-# ANN module ("HLint: ignore Redundant do" :: String) #-}-{-# ANN module ("HLint: ignore Reduce duplication"  :: String) #-}--newtype ShowVector a = ShowVector a deriving (Eq, BitShow)--instance BitShow a => Show (ShowVector a) where-  show = bitShow--vectorSizedBetween :: Int -> Int -> Gen (ShowVector (DVS.Vector Word64))-vectorSizedBetween a b = do-  n   <- choose (a, b)-  xs  <- sequence [ arbitrary | _ <- [1 .. n] ]-  return $ ShowVector (fromList xs)--spec :: Spec-spec = describe "HaskellWorks.Data.RankSelect.CsPoppy2.Rank1Spec" $ do-  genRank1Select1Spec (undefined :: CsPoppy2)-  describe "rank1 for Vector Word64 is equivalent to rank1 for CsPoppy2" $ do-    it "on empty bitvector" $-      let v = DVS.empty in-      let w = makeCsPoppy2 v in-      let i = 0 in-      rank1 v i === rank1 w i-    it "on one basic block" $-      forAll (vectorSizedBetween 1 8) $ \(ShowVector v) ->-      forAll (choose (0, length v * 8)) $ \i ->-      let w = makeCsPoppy2 v in-      rank1 v i === rank1 w i-    it "on two basic blocks" $-      forAll (vectorSizedBetween 9 16) $ \(ShowVector v) ->-      forAll (choose (0, length v * 8)) $ \i ->-      let w = makeCsPoppy2 v in-      rank1 v i === rank1 w i-    it "on three basic blocks" $-      forAll (vectorSizedBetween 17 24) $ \(ShowVector v) ->-      forAll (choose (0, length v * 8)) $ \i ->-      let w = makeCsPoppy2 v in-      rank1 v i === rank1 w i-  describe "select1 for Vector Word64 is equivalent to select1 for CsPoppy2" $ do-    it "on empty bitvector" $-      let v = DVS.empty in-      let w = makeCsPoppy2 v in-      let i = 0 in-      select1 v i === select1 w i-    it "on one full zero basic block" $-      let v = fromList [0, 0, 0, 0, 0, 0, 0, 0] :: DVS.Vector Word64 in-      let w = makeCsPoppy2 v in-      select1 v 0 === select1 w 0-    it "on one basic block" $-      forAll (vectorSizedBetween 1 8) $ \(ShowVector v) ->-      forAll (choose (0, popCount1 v)) $ \i ->-      let w = makeCsPoppy2 v in-      select1 v i === select1 w i-    it "on two basic blocks" $-      forAll (vectorSizedBetween 9 16) $ \(ShowVector v) ->-      forAll (choose (0, popCount1 v)) $ \i ->-      let w = makeCsPoppy2 v in-      select1 v i === select1 w i-    it "on three basic blocks" $-      forAll (vectorSizedBetween 17 24) $ \(ShowVector v) ->-      forAll (choose (0, popCount1 v)) $ \i ->-      let w = makeCsPoppy2 v in-      select1 v i === select1 w i-  describe "Rank select over large buffer" $ do-    it "Rank works" $ do-      let cs = fromJust (bitRead (take 4096 (cycle "10"))) :: DVS.Vector Word64-      let ps = makeCsPoppy2 cs-      (rank1 ps `map` [1 .. 4096]) `shouldBe` [(x - 1) `div` 2 + 1 | x <- [1 .. 4096]]-    it "Select works" $ do-      let cs = fromJust (bitRead (take 4096 (cycle "10"))) :: DVS.Vector Word64-      let ps = makeCsPoppy2 cs-      (select1 ps `map` [1 .. 2048]) `shouldBe` [1, 3 .. 4096]
test/HaskellWorks/Data/RankSelect/CsPoppySpec.hs view
@@ -1,94 +1,159 @@ {-# OPTIONS_GHC -fno-warn-incomplete-patterns #-}+ {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE ScopedTypeVariables        #-}  module HaskellWorks.Data.RankSelect.CsPoppySpec (spec) where -import           GHC.Exts-import           Data.Maybe-import qualified Data.Vector.Storable                                       as DVS-import           Data.Word-import           HaskellWorks.Data.AtIndex-import           HaskellWorks.Data.Bits.BitRead-import           HaskellWorks.Data.Bits.BitShow-import           HaskellWorks.Data.Bits.PopCount.PopCount1-import           HaskellWorks.Data.RankSelect.Base.Rank1-import           HaskellWorks.Data.RankSelect.Base.Select1-import           HaskellWorks.Data.RankSelect.BasicGen-import           HaskellWorks.Data.RankSelect.CsPoppy-import           Prelude hiding (length)-import           Test.Hspec-import           Test.QuickCheck+import Control.Monad+import Control.Monad.IO.Class+import Data.List                                 (isSuffixOf)+import Data.Maybe+import Data.Word+import GHC.Exts+import HaskellWorks.Data.AtIndex+import HaskellWorks.Data.Bits.BitLength+import HaskellWorks.Data.Bits.BitRead+import HaskellWorks.Data.Bits.BitShow+import HaskellWorks.Data.Bits.PopCount.PopCount1+import HaskellWorks.Data.FromForeignRegion+import HaskellWorks.Data.RankSelect.Base.Select1+import HaskellWorks.Data.RankSelect.BasicGen+import HaskellWorks.Data.RankSelect.CsPoppy+import HaskellWorks.Data.Take+import HaskellWorks.Hspec.Hedgehog+import Hedgehog+import Prelude hiding (length, take, drop)+import System.Directory+import System.IO.MMap+import System.IO.Unsafe+import Test.Hspec +import qualified Data.Vector.Storable      as DVS+import qualified HaskellWorks.Hedgehog.Gen as G+import qualified Hedgehog.Gen              as G+import qualified Hedgehog.Range            as R+ {-# ANN module ("HLint: ignore Redundant do" :: String) #-} {-# ANN module ("HLint: ignore Reduce duplication"  :: String) #-}  newtype ShowVector a = ShowVector a deriving (Eq, BitShow) +corpusFiles :: [FilePath]+corpusFiles = unsafePerformIO $ do+  entries <- listDirectory "data"+  let files = ("data/" ++) <$> (".ib" `isSuffixOf`) `filter` entries+  return files+{-# NOINLINE corpusFiles #-}++loadVector64 :: FilePath -> IO (DVS.Vector Word64)+loadVector64 filename = fromForeignRegion <$> mmapFileForeignPtr filename ReadOnly Nothing+ instance BitShow a => Show (ShowVector a) where   show = bitShow -vectorSizedBetween :: Int -> Int -> Gen (ShowVector (DVS.Vector Word64))-vectorSizedBetween a b = do-  n   <- choose (a, b)-  xs  <- sequence [ arbitrary | _ <- [1 .. n] ]-  return $ ShowVector (fromList xs)- spec :: Spec-spec = describe "HaskellWorks.Data.RankSelect.CsPoppy.Rank1Spec" $ do+spec = describe "HaskellWorks.Data.RankSelect.CsPoppySpec" $ do   genRank1Select1Spec (undefined :: CsPoppy)   describe "rank1 for Vector Word64 is equivalent to rank1 for CsPoppy" $ do-    it "on empty bitvector" $-      let v = DVS.empty in-      let w = makeCsPoppy v in-      let i = 0 in+    it "on empty bitvector" $ require $ withTests 1 $ property $ do+      let v = DVS.empty+      Nice w  <- forAll $ pure $ Nice $ makeCsPoppy v+      let i = 0       rank1 v i === rank1 w i-    it "on one basic block" $-      forAll (vectorSizedBetween 1 8) $ \(ShowVector v) ->-      forAll (choose (0, length v * 8)) $ \i ->-      let w = makeCsPoppy v in+    it "on one basic block" $ require $ property $ do+      v       <- forAll $ G.storableVector (R.linear 1 8) (G.word64 R.constantBounded)+      i       <- forAll $ G.word64 (R.linear 0 (length v * 8))+      Nice w  <- forAll $ pure $ Nice $ makeCsPoppy v       rank1 v i === rank1 w i-    it "on two basic blocks" $-      forAll (vectorSizedBetween 9 16) $ \(ShowVector v) ->-      forAll (choose (0, length v * 8)) $ \i ->-      let w = makeCsPoppy v in+    it "on two basic blocks" $ require $ property $ do+      v <- forAll $ G.storableVector (R.linear 9 16) (G.word64 R.constantBounded)+      i <- forAll $ G.word64 (R.linear 0 (length v * 8))+      Nice w  <- forAll $ pure $ Nice $ makeCsPoppy v       rank1 v i === rank1 w i-    it "on three basic blocks" $-      forAll (vectorSizedBetween 17 24) $ \(ShowVector v) ->-      forAll (choose (0, length v * 8)) $ \i ->-      let w = makeCsPoppy v in+    it "on three basic blocks" $ require $ property $ do+      v <- forAll $ G.storableVector (R.linear 17 24) (G.word64 R.constantBounded)+      i <- forAll $ G.word64 (R.linear 0 (length v * 8))+      Nice w  <- forAll $ pure $ Nice $ makeCsPoppy v       rank1 v i === rank1 w i   describe "select1 for Vector Word64 is equivalent to select1 for CsPoppy" $ do-    it "on empty bitvector" $-      let v = DVS.empty in-      let w = makeCsPoppy v in-      let i = 0 in-      select1 v i === select1 w i-    it "on one full zero basic block" $-      let v = fromList [0, 0, 0, 0, 0, 0, 0, 0] :: DVS.Vector Word64 in-      let w = makeCsPoppy v in-      select1 v 0 === select1 w 0-    it "on one basic block" $-      forAll (vectorSizedBetween 1 8) $ \(ShowVector v) ->-      forAll (choose (0, popCount1 v)) $ \i ->-      let w = makeCsPoppy v in-      select1 v i === select1 w i-    it "on two basic blocks" $-      forAll (vectorSizedBetween 9 16) $ \(ShowVector v) ->-      forAll (choose (0, popCount1 v)) $ \i ->-      let w = makeCsPoppy v in-      select1 v i === select1 w i-    it "on three basic blocks" $-      forAll (vectorSizedBetween 17 24) $ \(ShowVector v) ->-      forAll (choose (0, popCount1 v)) $ \i ->-      let w = makeCsPoppy v in-      select1 v i === select1 w i+    xit "on empty bitvector" $ require $ withTests 1 $ property $ do+      let v = DVS.empty+      Nice w  <- forAll $ pure $ Nice $ makeCsPoppy v+      let i = 0+      select1 w i === select1 v i+    xit "on one full zero basic block" $ require $ withTests 1 $ property $ do+      let v = fromList [0, 0, 0, 0, 0, 0, 0, 0] :: DVS.Vector Word64+      Nice w  <- forAll $ pure $ Nice $ makeCsPoppy v+      select1 w 0 === select1 v 0+    xit "on one basic block" $ require $ property $ do+      v <- forAll $ G.storableVector (R.linear 1 8) (G.word64 R.constantBounded)+      i <- forAll $ G.word64 (R.linear 0 (popCount1 v))+      Nice w  <- forAll $ pure $ Nice $ makeCsPoppy v+      select1 w i === select1 v i+    xit "on two basic blocks" $ require $ property $ do+      v <- forAll $ G.storableVector (R.linear 9 16) (G.word64 R.constantBounded)+      i <- forAll $ G.word64 (R.linear 0 (popCount1 v))+      Nice w  <- forAll $ pure $ Nice $ makeCsPoppy v+      select1 w i === select1 v i+    xit "on three basic blocks" $ require $ property $ do+      v <- forAll $ G.storableVector (R.linear 17 24) (G.word64 R.constantBounded)+      i <- forAll $ G.word64 (R.linear 0 (popCount1 v))+      Nice w  <- forAll $ pure $ Nice $ makeCsPoppy v+      select1 w i === select1 v i   describe "Rank select over large buffer" $ do-    it "Rank works" $ do+    xit "Rank works" $ require $ property $ do       let cs = fromJust (bitRead (take 4096 (cycle "10"))) :: DVS.Vector Word64       let ps = makeCsPoppy cs-      (rank1 ps `map` [1 .. 4096]) `shouldBe` [(x - 1) `div` 2 + 1 | x <- [1 .. 4096]]+      (rank1 ps `map` [1 .. 4096]) === [(x - 1) `div` 2 + 1 | x <- [1 .. 4096]]+    xit "Rank is consistent with pop count" $ require $ property $ do+      v         <- forAll $ G.storableVector (R.linear 0 1024) (G.word64 R.constantBounded)+      Nice rsbs <- forAll $ pure $ Nice (makeCsPoppy v)+      rank1 rsbs (bitLength rsbs) === popCount1 rsbs     it "Select works" $ do-      let cs = fromJust (bitRead (take 4096 (cycle "10"))) :: DVS.Vector Word64-      let ps = makeCsPoppy cs-      (select1 ps `map` [1 .. 2048]) `shouldBe` [1, 3 .. 4096]+      let v = DVS.fromList [0x1101001000100001, 0x2202002000200002, 0x3303003000300003] :: DVS.Vector Word64+      let pc = popCount1 v+      require $ property $ do+        Nice csPoppy  <- forAll $ pure $ Nice (makeCsPoppy v)+        s             <- forAll $ G.word64 (R.linear 1 pc)+        select1 csPoppy s === select1 v s+  describe "Corpus" $ do+    describe "Shrunk Rank" $ do+      forM_ corpusFiles $ \corpusFile -> do+        xit corpusFile $ do+          fileV <- liftIO $ loadVector64 corpusFile+          require $ property $ do+            let v = DVS.take 768 fileV+            Nice csPoppy  <- forAll $ pure $ Nice $ makeCsPoppy v+            maxPos        <- forAll $ pure $ fromIntegral $ DVS.length (csPoppyBits csPoppy)+            r <- forAll $ G.word64 (R.linear 1 maxPos)+            rank1 csPoppy r === rank1 v r+    describe "Rank" $ do+      forM_ corpusFiles $ \corpusFile -> do+        it corpusFile $ do+          v <- liftIO $ loadVector64 corpusFile+          let csPoppy = makeCsPoppy v+          let maxPos = fromIntegral $ DVS.length (csPoppyBits csPoppy)+          require $ property $ do+            r <- forAll $ G.word64 (R.linear 1 maxPos)+            rank1 csPoppy r === rank1 v r+    describe "Select" $ do+      forM_ corpusFiles $ \corpusFile -> do+        it corpusFile $ do+          fileV <- liftIO $ loadVector64 corpusFile+          let csPoppy = makeCsPoppy fileV+          let pc = popCount1 (csPoppyBits csPoppy)+          require $ property $ do+            _ <- forAll $ pure $ Nice csPoppy+            s <- forAll $ G.word64 (R.linear 1 pc)+            select1 csPoppy s === select1 fileV s+    describe "Select straw man" $ do+      forM_ corpusFiles $ \corpusFile -> do+        it corpusFile $ do+          fileV <- liftIO $ loadVector64 corpusFile+          let csPoppy = makeCsPoppy fileV+          let pc = popCount1 (csPoppyBits csPoppy)+          require $ property $ do+            _ <- forAll $ pure $ csPoppyLayerS csPoppy+            s <- forAll $ G.word64 (R.linear 1 pc)+            select1 csPoppy s === select1 fileV s