primesieve (empty) → 0.1.0.0
raw patch · 7 files changed
+357/−0 lines, 7 filesdep +basedep +foundationdep +primesievesetup-changed
Dependencies added: base, foundation, primesieve
Files
- LICENSE +20/−0
- README.md +7/−0
- Setup.hs +2/−0
- example/Main.hs +16/−0
- primesieve.cabal +37/−0
- src/Math/Prime/FastSieve.hs +23/−0
- src/Math/Prime/FastSieve/FFI.hs +252/−0
+ LICENSE view
@@ -0,0 +1,20 @@+Copyright (c) 2017 HE, Tao (sighingnow@gmail.com)++Permission is hereby granted, free of charge, to any person obtaining+a copy of this software and associated documentation files (the+"Software"), to deal in the Software without restriction, including+without limitation the rights to use, copy, modify, merge, publish,+distribute, sublicense, and/or sell copies of the Software, and to+permit persons to whom the Software is furnished to do so, subject to+the following conditions:++The above copyright notice and this permission notice shall be included+in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ README.md view
@@ -0,0 +1,7 @@+# primesieve++FFI bindings for the primesieve library.++## License++Copyright (c) 2017 HE, Tao (sighingnow@gmail.com)
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ example/Main.hs view
@@ -0,0 +1,16 @@+module Main where++import Foundation++import Math.Prime.FastSieve++main :: IO ()+main = do+ primesieveVersion >>= putStrLn . ("Version of primesieve: " <>)+ + ns <- generateNPrimes 10 0 :: IO (UArray Int32)+ putStrLn $ "The first 10 primes: " <> show ns++ putStrLn $ "Count of primes between 100 and 1000000: " <> show (countPrimes 100 1000000)++ putStrLn $ "The 12345678th prime number (from 0): " <> show (nthPrime 12345678 0)
+ primesieve.cabal view
@@ -0,0 +1,37 @@+name: primesieve+version: 0.1.0.0+synopsis: FFI bindings for the primesieve library.+description: FFI bindings for the primesieve library.+homepage: https://github.com/sighingnow/computations/tree/master/primesieve#readme+author: Tao He+maintainer: sighingnow@gmail.com+copyright: Copyright: (c) 2017 Tao He+category: Algorithms, Foreign, Math, Number Theory+build-type: Simple+cabal-version: >=1.10+license: MIT+license-file: LICENSE+extra-source-files: README.md++library+ hs-source-dirs: src+ exposed-modules:+ Math.Prime.FastSieve+ other-modules:+ Math.Prime.FastSieve.FFI+ default-language: Haskell2010+ default-extensions: NoImplicitPrelude+ , OverloadedStrings+ build-depends: base >= 4.7 && < 5+ , foundation++executable prime-example+ hs-source-dirs: example+ main-is: Main.hs+ default-language: Haskell2010+ default-extensions: NoImplicitPrelude+ , OverloadedStrings+ build-depends: base >= 4.7 && < 5+ , foundation+ , primesieve+ extra-libraries: primesieve
+ src/Math/Prime/FastSieve.hs view
@@ -0,0 +1,23 @@+module Math.Prime.FastSieve+ ( generatePrimes+ , generateNPrimes+ , nthPrime+ , countPrimes+ , countTwins+ , countTriplets+ , countQuadruplets+ , countQuintuplets+ , countSextuplets+ , printPrimes+ , printTwins+ , printTriplets+ , printQuadruplets+ , printQuintuplets+ , printSextuplets+ , getMaxStop+ , setSieveSize+ , setNumThreads+ , primesieveVersion+ ) where++import Math.Prime.FastSieve.FFI
+ src/Math/Prime/FastSieve/FFI.hs view
@@ -0,0 +1,252 @@+{-# OPTIONS_GHC -Wno-missing-methods #-}+{-# OPTIONS_GHC -Wno-missing-pattern-synonym-signatures #-}+{-# OPTIONS_GHC -Wno-missing-signatures #-}+{-# OPTIONS_GHC -Wno-orphans #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE PatternSynonyms #-}+{-# LANGUAGE ScopedTypeVariables #-}++module Math.Prime.FastSieve.FFI where++import Foundation+import Foundation.Foreign+import Foundation.Class.Storable+import Foundation.String (fromBytesUnsafe)++import Foreign.Marshal.Alloc (alloca)++class (PrimType ty, StorableFixed ty) => Prime ty where+ tcode :: Proxy ty -> CInt++pattern SHORT = 0+pattern USHORT = 1+pattern INT = 2+pattern UINT = 3+pattern LONG = 4+pattern ULONG = 5+pattern LONGLONG = 6+pattern ULONGLONG = 7+pattern INT16 = 8+pattern UINT16 = 9+pattern INT32 = 10+pattern UINT32 = 11+pattern INT64 = 12+pattern UINT64 = 13++instance Prime Int16 where+ tcode _ = INT16++instance Prime Int32 where+ tcode _ = INT32++instance Prime Int64 where+ tcode _ = INT64++instance Prime Word16 where+ tcode _ = UINT16++instance Prime Word32 where+ tcode _ = UINT32++instance Prime Word64 where+ tcode _ = UINT64++-- | Orphan instance for CSize as Storable.+instance Storable CSize++foreign import ccall unsafe "primesieve_generate_primes" c_generate_primes+ :: Word64 -> Word64 -> Ptr CSize -> CInt -> IO (Ptr ())++foreign import ccall unsafe "primesieve_generate_n_primes" c_generate_n_primes+ :: Word64 -> Word64 -> CInt -> IO (Ptr ())++foreign import ccall unsafe "primesieve_nth_prime" c_nth_prime+ :: Int64 -> Word64 -> Word64++foreign import ccall unsafe "primesieve_count_primes" c_count_primes+ :: Word64 -> Word64 -> Word64++foreign import ccall unsafe "primesieve_count_twins" c_count_twins+ :: Word64 -> Word64 -> Word64++foreign import ccall unsafe "primesieve_count_triplets" c_count_triplets+ :: Word64 -> Word64 -> Word64++foreign import ccall unsafe "primesieve_count_quadruplets" c_count_quadruplets+ :: Word64 -> Word64 -> Word64++foreign import ccall unsafe "primesieve_count_quintuplets" c_count_quintuplets+ :: Word64 -> Word64 -> Word64++foreign import ccall unsafe "primesieve_count_sextuplets" c_count_sextuplets+ :: Word64 -> Word64 -> Word64++foreign import ccall unsafe "primesieve_print_primes" c_print_primes+ :: Word64 -> Word64 -> IO ()++foreign import ccall unsafe "primesieve_print_twins" c_print_twins+ :: Word64 -> Word64 -> IO ()++foreign import ccall unsafe "primesieve_print_triplets" c_print_triplets+ :: Word64 -> Word64 -> IO ()++foreign import ccall unsafe "primesieve_print_quadruplets" c_print_quadruplets+ :: Word64 -> Word64 -> IO ()++foreign import ccall unsafe "primesieve_print_quintuplets" c_print_quintuplets+ :: Word64 -> Word64 -> IO ()++foreign import ccall unsafe "primesieve_print_sextuplets" c_print_sextuplets+ :: Word64 -> Word64 -> IO ()++foreign import ccall unsafe "primesieve_get_max_stop" c_get_max_stop+ :: Word64++foreign import ccall unsafe "primesieve_set_sieve_size" c_set_sieve_size+ :: CInt -> IO ()++foreign import ccall unsafe "primesieve_set_num_threads" c_set_num_threads+ :: CInt -> IO ()++-- | Deallocate a primes array created using the primesieve_generate_primes() or primesieve_generate_n_primes()+foreign import ccall unsafe "primesieve_free" c_primesieve_free+ :: Ptr () -> IO ()++foreign import ccall unsafe "primesieve_version" c_version+ :: IO (Ptr Word8)++-- | Get an array with the primes inside the interval [start, stop].+generatePrimes :: forall ty. Prime ty+ => Word64 -- ^ start+ -> Word64 -- ^ end+ -> IO (UArray ty)+generatePrimes start end = alloca $ \psz -> do+ p <- c_generate_primes start end psz (tcode (Proxy :: Proxy ty))+ sz <- peek psz+ arr <- peekArray (CountOf . fromIntegral $ sz) (castPtr p)+ c_primesieve_free p -- free the memory allocated by primesieve.+ return arr++-- | Get an array with the first n primes >= start.+generateNPrimes :: forall ty. Prime ty+ => Word64 -- ^ n+ -> Word64 -- ^ start+ -> IO (UArray ty)+generateNPrimes n start = do+ p <- c_generate_n_primes n start (tcode (Proxy :: Proxy ty))+ arr <- peekArray (CountOf . fromIntegral $ n) (castPtr p)+ c_primesieve_free p -- free the memory allocated by primesieve.+ return arr++-- | Find the nth prime.+--+-- * if n = 0 finds the 1st prime >= start,+-- * if n > 0 finds the nth prime > start,+-- * if n < 0 finds the nth prime < start (backwards).+nthPrime ::+ Int64 -- ^ n+ -> Word64 -- ^ start+ -> Word64+nthPrime = c_nth_prime++-- | Count the primes within the interval [start, stop].+countPrimes ::+ Word64 -- ^ start+ -> Word64 -- ^ end+ -> Word64+countPrimes = c_count_primes++-- | Count the twins within the interval [start, stop].+countTwins ::+ Word64 -- ^ start+ -> Word64 -- ^ end+ -> Word64+countTwins = c_count_twins++-- | Count the triplets within the interval [start, stop].+countTriplets ::+ Word64 -- ^ start+ -> Word64 -- ^ end+ -> Word64+countTriplets = c_count_triplets++-- | Count the quadruplets within the interval [start, stop].+countQuadruplets ::+ Word64 -- ^ start+ -> Word64 -- ^ end+ -> Word64+countQuadruplets = c_count_quadruplets++-- | Count the quintuplets within the interval [start, stop].+countQuintuplets ::+ Word64 -- ^ start+ -> Word64 -- ^ end+ -> Word64+countQuintuplets = c_count_quintuplets++-- | Count the sextuplets within the interval [start, stop].+countSextuplets ::+ Word64 -- ^ start+ -> Word64 -- ^ end+ -> Word64+countSextuplets = c_count_sextuplets++-- | Print the primes within the interval [start, stop] to the standard output.+printPrimes ::+ Word64 -- ^ start+ -> Word64 -- ^ end+ -> IO ()+printPrimes = c_print_primes++-- | Print the prime twins within the interval [start, stop] to the standard output.+printTwins ::+ Word64 -- ^ start+ -> Word64 -- ^ end+ -> IO ()+printTwins = c_print_twins++-- | Print the prime triplets within the interval [start, stop] to the standard output.+printTriplets ::+ Word64 -- ^ start+ -> Word64 -- ^ end+ -> IO ()+printTriplets = c_print_triplets++-- | Print the prime quadruplets within the interval [start, stop] to the standard output.+printQuadruplets ::+ Word64 -- ^ start+ -> Word64 -- ^ end+ -> IO ()+printQuadruplets = c_print_quadruplets++-- | Print the prime quintuplets within the interval [start, stop] to the standard output.+printQuintuplets ::+ Word64 -- ^ start+ -> Word64 -- ^ end+ -> IO ()+printQuintuplets = c_print_quintuplets++-- | Print the prime sextuplets within the interval [start, stop] to the standard output.+printSextuplets ::+ Word64 -- ^ start+ -> Word64 -- ^ end+ -> IO ()+printSextuplets = c_print_sextuplets++-- | Returns the largest valid stop number for primesieve, 2^64-1 (UINT64_MAX).+getMaxStop :: Word64+getMaxStop = c_get_max_stop++-- | Set the sieve size in kilobytes.+-- The best sieving performance is achieved with a sieve size of your CPU's L1 or L2 cache size (per core).+setSieveSize :: Int -> IO ()+setSieveSize = c_set_sieve_size . fromIntegral++-- | Set the number of threads for use in primesieve_count_*() and primesieve_nth_prime().+-- By default all CPU cores are used.+setNumThreads :: Int -> IO ()+setNumThreads = c_set_num_threads . fromIntegral++-- | Get the primesieve version number, in the form "i.j".+primesieveVersion :: IO String+primesieveVersion = c_version >>= (fromBytesUnsafe <$>) . peekArrayEndedBy 0