packages feed

hw-simd 0.1.0.3 → 0.1.1.0

raw patch · 8 files changed

+179/−17 lines, 8 filesdep ~hw-primPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: hw-prim

API changes (from Hackage documentation)

+ HaskellWorks.Data.Simd.ChunkString: class ToChunkString a
+ HaskellWorks.Data.Simd.ChunkString: data ChunkString
+ HaskellWorks.Data.Simd.ChunkString: hGetContents :: Handle -> IO ChunkString
+ HaskellWorks.Data.Simd.ChunkString: toChunkString :: ToChunkString a => a -> ChunkString
+ HaskellWorks.Data.Simd.Comparison.Avx2: instance HaskellWorks.Data.Simd.Comparison.Avx2.CmpEqWord8s [Data.ByteString.Internal.ByteString]
+ HaskellWorks.Data.Simd.Comparison.Avx2: type family Target a;
+ HaskellWorks.Data.Simd.Comparison.Avx2: }
+ HaskellWorks.Data.Simd.Comparison.Stock: instance HaskellWorks.Data.Simd.Comparison.Stock.CmpEqWord8s HaskellWorks.Data.Simd.Internal.ChunkString.ChunkString
+ HaskellWorks.Data.Simd.Comparison.Stock: instance HaskellWorks.Data.Simd.Comparison.Stock.CmpEqWord8s [Data.ByteString.Internal.ByteString]
+ HaskellWorks.Data.Simd.Internal.ChunkString: ChunkString :: [ByteString] -> ChunkString
+ HaskellWorks.Data.Simd.Internal.ChunkString: [chunks] :: ChunkString -> [ByteString]
+ HaskellWorks.Data.Simd.Internal.ChunkString: chunkSize :: Int
+ HaskellWorks.Data.Simd.Internal.ChunkString: class ToChunkString a
+ HaskellWorks.Data.Simd.Internal.ChunkString: instance GHC.Classes.Eq HaskellWorks.Data.Simd.Internal.ChunkString.ChunkString
+ HaskellWorks.Data.Simd.Internal.ChunkString: instance GHC.Show.Show HaskellWorks.Data.Simd.Internal.ChunkString.ChunkString
+ HaskellWorks.Data.Simd.Internal.ChunkString: instance HaskellWorks.Data.ByteString.Lazy.ToLazyByteString HaskellWorks.Data.Simd.Internal.ChunkString.ChunkString
+ HaskellWorks.Data.Simd.Internal.ChunkString: instance HaskellWorks.Data.ByteString.ToByteStrings HaskellWorks.Data.Simd.Internal.ChunkString.ChunkString
+ HaskellWorks.Data.Simd.Internal.ChunkString: instance HaskellWorks.Data.Simd.Internal.ChunkString.ToChunkString (Data.Vector.Storable.Vector GHC.Word.Word16)
+ HaskellWorks.Data.Simd.Internal.ChunkString: instance HaskellWorks.Data.Simd.Internal.ChunkString.ToChunkString (Data.Vector.Storable.Vector GHC.Word.Word32)
+ HaskellWorks.Data.Simd.Internal.ChunkString: instance HaskellWorks.Data.Simd.Internal.ChunkString.ToChunkString (Data.Vector.Storable.Vector GHC.Word.Word64)
+ HaskellWorks.Data.Simd.Internal.ChunkString: instance HaskellWorks.Data.Simd.Internal.ChunkString.ToChunkString (Data.Vector.Storable.Vector GHC.Word.Word8)
+ HaskellWorks.Data.Simd.Internal.ChunkString: instance HaskellWorks.Data.Simd.Internal.ChunkString.ToChunkString Data.ByteString.Lazy.Internal.ByteString
+ HaskellWorks.Data.Simd.Internal.ChunkString: instance HaskellWorks.Data.Simd.Internal.ChunkString.ToChunkString [Data.ByteString.Internal.ByteString]
+ HaskellWorks.Data.Simd.Internal.ChunkString: instance HaskellWorks.Data.Simd.Internal.ChunkString.ToChunkString [Data.Vector.Storable.Vector GHC.Word.Word16]
+ HaskellWorks.Data.Simd.Internal.ChunkString: instance HaskellWorks.Data.Simd.Internal.ChunkString.ToChunkString [Data.Vector.Storable.Vector GHC.Word.Word32]
+ HaskellWorks.Data.Simd.Internal.ChunkString: instance HaskellWorks.Data.Simd.Internal.ChunkString.ToChunkString [Data.Vector.Storable.Vector GHC.Word.Word64]
+ HaskellWorks.Data.Simd.Internal.ChunkString: instance HaskellWorks.Data.Simd.Internal.ChunkString.ToChunkString [Data.Vector.Storable.Vector GHC.Word.Word8]
+ HaskellWorks.Data.Simd.Internal.ChunkString: newtype ChunkString
+ HaskellWorks.Data.Simd.Internal.ChunkString: toChunkString :: ToChunkString a => a -> ChunkString
- HaskellWorks.Data.Simd.Comparison.Avx2: class CmpEqWord8s a
+ HaskellWorks.Data.Simd.Comparison.Avx2: class CmpEqWord8s a where {
- HaskellWorks.Data.Simd.Comparison.Avx2: cmpEqWord8s :: CmpEqWord8s a => Word8 -> a -> a
+ HaskellWorks.Data.Simd.Comparison.Avx2: cmpEqWord8s :: CmpEqWord8s a => Word8 -> a -> Target a
- HaskellWorks.Data.Simd.Internal.Foreign: avx2Cmpeq8 :: UInt8 -> Ptr UInt64 -> Size -> Ptr UInt8 -> IO ()
+ HaskellWorks.Data.Simd.Internal.Foreign: avx2Cmpeq8 :: UInt8 -> Ptr UInt8 -> Size -> Ptr UInt8 -> IO ()
- HaskellWorks.Data.Simd.Internal.Foreign: c_cmpeq8 :: (CUChar -> ((Ptr CULong) -> (CULong -> ((Ptr CUChar) -> (IO ())))))
+ HaskellWorks.Data.Simd.Internal.Foreign: c_cmpeq8 :: (CUChar -> ((Ptr CUChar) -> (CULong -> ((Ptr CUChar) -> (IO ())))))

Files

cbits/simd.h view
@@ -11,13 +11,7 @@  void avx2_cmpeq8(     uint8_t byte,-    uint64_t *target,-    size_t target_length,-    uint8_t *source);--void avx2_cmpeq8(-    uint8_t byte,-    uint64_t *target,+    uint8_t *target,     size_t target_length,     uint8_t *source); 
cbits/simd_avx2.c view
@@ -33,7 +33,7 @@  void avx2_cmpeq8(     uint8_t byte,-    uint64_t *target,+    uint8_t *target,     size_t target_length,     uint8_t *source) { #if defined(AVX2_ENABLED)
hw-simd.cabal view
@@ -3,7 +3,7 @@ -- see: https://github.com/sol/hpack  name:           hw-simd-version:        0.1.0.3+version:        0.1.1.0 synopsis:       SIMD library description:    Please see the README on Github at <https://github.com/haskell-works/hw-simd#readme> category:       Data, Bit, SIMD@@ -60,7 +60,7 @@     , hw-bits               >= 0.7.0.2  && < 0.8     , hw-rankselect         >= 0.12.0.2 && < 0.13     , hw-rankselect-base    >= 0.3.2.0  && < 0.4-    , hw-prim               >= 0.6.2.0  && < 0.7+    , hw-prim               >= 0.6.2.12 && < 0.7     , vector                >= 0.12.0.1 && < 0.13   build-tools:       c2hs@@ -84,11 +84,13 @@       , semigroups            >= 0.8.4      && < 0.19   exposed-modules:       HaskellWorks.Data.Simd.Capabilities+      HaskellWorks.Data.Simd.ChunkString       HaskellWorks.Data.Simd.Comparison       HaskellWorks.Data.Simd.Comparison.Avx2       HaskellWorks.Data.Simd.Comparison.Stock       HaskellWorks.Data.Simd.Internal.Bits       HaskellWorks.Data.Simd.Internal.Broadword+      HaskellWorks.Data.Simd.Internal.ChunkString       HaskellWorks.Data.Simd.Internal.Foreign       HaskellWorks.Data.Simd.Internal.Marshal       HaskellWorks.Data.Simd.Logical@@ -112,7 +114,7 @@     , hw-bits               >= 0.7.0.2  && < 0.8     , hw-rankselect         >= 0.12.0.2 && < 0.13     , hw-rankselect-base    >= 0.3.2.0  && < 0.4-    , hw-prim               >= 0.6.2.0  && < 0.7+    , hw-prim               >= 0.6.2.12 && < 0.7     , vector                >= 0.12.0.1 && < 0.13     , directory               >= 1.2.2      && < 1.4     , lens@@ -160,7 +162,7 @@     , hw-bits               >= 0.7.0.2  && < 0.8     , hw-rankselect         >= 0.12.0.2 && < 0.13     , hw-rankselect-base    >= 0.3.2.0  && < 0.4-    , hw-prim               >= 0.6.2.0  && < 0.7+    , hw-prim               >= 0.6.2.12 && < 0.7     , vector                >= 0.12.0.1 && < 0.13     , cassava               >= 0.5.1.0    && < 0.6     , containers
+ src/HaskellWorks/Data/Simd/ChunkString.hs view
@@ -0,0 +1,14 @@+module HaskellWorks.Data.Simd.ChunkString+  ( ChunkString+  , ToChunkString(..)+  , hGetContents+  ) where++import HaskellWorks.Data.Simd.Internal.ChunkString++import qualified HaskellWorks.Data.ByteString as BS+import qualified System.IO                    as IO++hGetContents :: IO.Handle -> IO ChunkString+hGetContents = (ChunkString <$>) . BS.hGetContentsChunkedBy chunkSize+{-# INLINE hGetContents #-}
src/HaskellWorks/Data/Simd/Comparison/Avx2.hs view
@@ -1,26 +1,53 @@ {-# LANGUAGE CPP               #-} {-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE TypeFamilies      #-}  module HaskellWorks.Data.Simd.Comparison.Avx2 where -import Data.Monoid ((<>))+import Control.Monad+import Data.Monoid   ((<>)) import Data.Word +import qualified Data.ByteString                         as BS import qualified Data.Vector.Storable                    as DVS import qualified Foreign.ForeignPtr                      as F import qualified Foreign.Marshal.Unsafe                  as F import qualified Foreign.Ptr                             as F+import qualified HaskellWorks.Data.ByteString            as BS import qualified HaskellWorks.Data.Simd.Internal.Foreign as F+import qualified HaskellWorks.Data.Vector.AsVector8      as V+import qualified HaskellWorks.Data.Vector.Storable       as DVS  {-# ANN module ("HLint: ignore Redundant do"        :: String) #-}  class CmpEqWord8s a where-  cmpEqWord8s :: Word8 -> a -> a+  type Target a+  cmpEqWord8s :: Word8 -> a -> Target a  instance CmpEqWord8s (DVS.Vector Word8) where-  cmpEqWord8s w8 v = DVS.unsafeCast (cmpEqWord8s w8 (DVS.unsafeCast v :: DVS.Vector Word64))+  type Target (DVS.Vector Word8) = DVS.Vector Word8+  cmpEqWord8s w8 v = F.unsafeLocalState $ do+    tgtFptr <- F.mallocForeignPtrBytes bufLen+    F.withForeignPtr srcFptr $ \srcPtr -> do+      F.withForeignPtr tgtFptr $ \tgtPtr -> do+        _ <- F.avx2Cmpeq8 (fromIntegral w8) (F.castPtr tgtPtr) (fromIntegral w64sLen) (srcPtr `F.plusPtr` srcOffset)+        when (disalignment /= 0) $ do+          let ending = DVS.padded ((DVS.length v + 63) `div` 64)  (DVS.drop alignment v)+          let (endFptr, _, _) = DVS.unsafeToForeignPtr ending+          F.withForeignPtr endFptr $ \endPtr -> do+            void $ F.avx2Cmpeq8 (fromIntegral w8) (tgtPtr `F.plusPtr` (w64sLen * 64)) (fromIntegral w64sLen) (F.castPtr endPtr) +        return $ DVS.unsafeFromForeignPtr tgtFptr 0 tgtLen+    where (srcFptr, srcOffset, srcLen) = DVS.unsafeToForeignPtr v+          bufLen        = (srcLen + 63) `div` 8+          tgtLen        = (srcLen + 7) `div` 8+          w64sLen       = srcLen `div` 64+          alignment     = w64sLen * 64+          disalignment  = srcLen - alignment+  {-# INLINE cmpEqWord8s #-}+ instance CmpEqWord8s (DVS.Vector Word64) where+  type Target (DVS.Vector Word64) = DVS.Vector Word64   cmpEqWord8s w8 v = case DVS.unsafeCast v :: DVS.Vector Word8 of     u -> case DVS.unsafeToForeignPtr u of       (srcFptr, srcOffset, srcLength) -> if disalignment == 0@@ -40,9 +67,21 @@   {-# INLINE cmpEqWord8s #-}  instance CmpEqWord8s [DVS.Vector Word64] where+  type Target [DVS.Vector Word64] = [DVS.Vector Word64]   cmpEqWord8s w8 vs = cmpEqWord8s w8 <$> vs   {-# INLINE cmpEqWord8s #-}  instance CmpEqWord8s [DVS.Vector Word8] where+  type Target [DVS.Vector Word8] = [DVS.Vector Word8]   cmpEqWord8s w8 vs = cmpEqWord8s w8 <$> vs   {-# INLINE cmpEqWord8s #-}++instance CmpEqWord8s [BS.ByteString] where+  type Target [BS.ByteString] = [BS.ByteString]+  cmpEqWord8s w8 vs = BS.toByteString . cmpEqWord8s w8 . V.asVector8 <$> vs+  {-# INLINE cmpEqWord8s #-}++-- instance CmpEqWord8s CS.ChunkString where+--   type Target CS.ChunkString = CS.ChunkString+--   cmpEqWord8s w8 = CS.toChunkString . cmpEqWord8s w8 . BS.toByteStrings+--   {-# INLINE cmpEqWord8s #-}
src/HaskellWorks/Data/Simd/Comparison/Stock.hs view
@@ -10,7 +10,11 @@ import HaskellWorks.Data.Simd.Internal.Bits import HaskellWorks.Data.Simd.Internal.Broadword -import qualified Data.Vector.Storable as DVS+import qualified Data.ByteString                    as BS+import qualified Data.Vector.Storable               as DVS+import qualified HaskellWorks.Data.ByteString       as BS+import qualified HaskellWorks.Data.Simd.ChunkString as CS+import qualified HaskellWorks.Data.Vector.AsVector8 as V  class CmpEqWord8s a where   cmpEqWord8s :: Word8 -> a -> a@@ -70,3 +74,10 @@   cmpEqWord8s w8 vs = cmpEqWord8s w8 <$> vs   {-# INLINE cmpEqWord8s #-} +instance CmpEqWord8s [BS.ByteString] where+  cmpEqWord8s w8 vs = BS.toByteString . cmpEqWord8s w8 . V.asVector8 <$> vs+  {-# INLINE cmpEqWord8s #-}++instance CmpEqWord8s CS.ChunkString where+  cmpEqWord8s w8 = CS.toChunkString . cmpEqWord8s w8 . BS.toByteStrings+  {-# INLINE cmpEqWord8s #-}
+ src/HaskellWorks/Data/Simd/Internal/ChunkString.hs view
@@ -0,0 +1,102 @@+{-# LANGUAGE CPP               #-}+{-# LANGUAGE FlexibleInstances #-}++module HaskellWorks.Data.Simd.Internal.ChunkString where++import Data.Word+import HaskellWorks.Data.AtIndex+import HaskellWorks.Data.Bits.BitWise+import HaskellWorks.Data.ByteString+import HaskellWorks.Data.ByteString.Lazy++import qualified Data.ByteString              as BS+import qualified Data.ByteString.Lazy         as LBS+import qualified Data.Vector.Storable         as DVS+import qualified HaskellWorks.Data.ByteString as BS++newtype ChunkString = ChunkString+  { chunks :: [BS.ByteString]+  } deriving (Eq, Show)++instance ToLazyByteString ChunkString where+  toLazyByteString (ChunkString cs) = LBS.fromChunks cs++instance ToByteStrings ChunkString where+  toByteStrings (ChunkString bss) = bss++class ToChunkString a where+  toChunkString :: a -> ChunkString++instance ToChunkString LBS.ByteString where+  toChunkString = toChunkString . LBS.toChunks++instance ToChunkString [BS.ByteString] where+  toChunkString = ChunkString . BS.rechunk chunkSize++instance ToChunkString [DVS.Vector Word8] where+  toChunkString = toChunkString . (toByteString <$>)++instance ToChunkString [DVS.Vector Word16] where+  toChunkString = toChunkString . (toByteString <$>)++instance ToChunkString [DVS.Vector Word32] where+  toChunkString = toChunkString . (toByteString <$>)++instance ToChunkString [DVS.Vector Word64] where+  toChunkString = toChunkString . (toByteString <$>)++instance ToChunkString (DVS.Vector Word8) where+  toChunkString v = toChunkString [toByteString v]++instance ToChunkString (DVS.Vector Word16) where+  toChunkString v = toChunkString [toByteString v]++instance ToChunkString (DVS.Vector Word32) where+  toChunkString v = toChunkString [toByteString v]++instance ToChunkString (DVS.Vector Word64) where+  toChunkString v = toChunkString [toByteString v]++#if 0+instance BitWise ChunkString where+  ChunkString (a:as) .&. ChunkString (b:bs) = ChunkString (c:cs)+    where len             = end a `min` end b+          c               = toByteString $ DVS.constructN (fromIntegral len) go+          ChunkString cs  = ChunkString as .&. ChunkString bs+          go u            = let ui = end u in (a !!! ui) .&. (b !!! ui)+  ChunkString _ .&. ChunkString _ = ChunkString []+  {-# INLINE (.&.) #-}++  ChunkString (a:as) .|. ChunkString (b:bs) = ChunkString (c:cs)+    where len             = end a `min` end b+          c               = toByteString $ DVS.constructN (fromIntegral len) go+          ChunkString cs  = ChunkString as .|. ChunkString bs+          go u            = let ui = end u in (a !!! ui) .&. (b !!! ui)+  ChunkString _ .|. ChunkString _ = ChunkString []+  {-# INLINE (.|.) #-}++  ChunkString (a:as) .^. ChunkString (b:bs) = ChunkString (c:cs)+    where len             = end a `min` end b+          c               = toByteString $ DVS.constructN (fromIntegral len) go+          ChunkString cs  = ChunkString as .^. ChunkString bs+          go u            = let ui = end u in (a !!! ui) .&. (b !!! ui)+  ChunkString _ .^. ChunkString _ = ChunkString []+  {-# INLINE (.^.) #-}++  comp (ChunkString (a:as)) = ChunkString (c:cs)+    where c               = toByteString $ DVS.constructN (fromIntegral (end a)) go+          ChunkString cs  = comp (ChunkString as)+          go u            = let ui = end u in comp (a !!! ui)+  comp (ChunkString _) = ChunkString []+  {-# INLINE comp #-}++  all0s = ChunkString $ repeat $ toByteString $ DVS.replicate chunkSize (0x00 :: Word8)+  {-# INLINE all0s #-}++  all1s = ChunkString $ repeat $ toByteString $ DVS.replicate chunkSize (0xff :: Word8)+  {-# INLINE all1s #-}+#endif++chunkSize :: Int+chunkSize = 32 * 1024 - 64+{-# INLINE chunkSize #-}
src/HaskellWorks/Data/Simd/Internal/Foreign.chs view
@@ -16,7 +16,7 @@   {#call unsafe avx2_memcpy as c_build_ibs#} target source len {-# INLINE avx2Memcpy #-} -avx2Cmpeq8 :: UInt8 -> Ptr UInt64 -> Size -> Ptr UInt8 -> IO ()+avx2Cmpeq8 :: UInt8 -> Ptr UInt8 -> Size -> Ptr UInt8 -> IO () avx2Cmpeq8 byte target targetLength source = requireAvx2 $ do   {#call unsafe avx2_cmpeq8 as c_cmpeq8#} byte target targetLength source {-# INLINE avx2Cmpeq8 #-}