{-# 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
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 ()
foreign import ccall unsafe "primesieve_free" c_primesieve_free
:: Ptr () -> IO ()
foreign import ccall unsafe "primesieve_version" c_version
:: IO (Ptr Word8)
generatePrimes :: forall ty. Prime ty
=> Word64
-> Word64
-> 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
return arr
generateNPrimes :: forall ty. Prime ty
=> Word64
-> Word64
-> 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
return arr
nthPrime ::
Int64
-> Word64
-> Word64
nthPrime = c_nth_prime
countPrimes ::
Word64
-> Word64
-> Word64
countPrimes = c_count_primes
countTwins ::
Word64
-> Word64
-> Word64
countTwins = c_count_twins
countTriplets ::
Word64
-> Word64
-> Word64
countTriplets = c_count_triplets
countQuadruplets ::
Word64
-> Word64
-> Word64
countQuadruplets = c_count_quadruplets
countQuintuplets ::
Word64
-> Word64
-> Word64
countQuintuplets = c_count_quintuplets
countSextuplets ::
Word64
-> Word64
-> Word64
countSextuplets = c_count_sextuplets
printPrimes ::
Word64
-> Word64
-> IO ()
printPrimes = c_print_primes
printTwins ::
Word64
-> Word64
-> IO ()
printTwins = c_print_twins
printTriplets ::
Word64
-> Word64
-> IO ()
printTriplets = c_print_triplets
printQuadruplets ::
Word64
-> Word64
-> IO ()
printQuadruplets = c_print_quadruplets
printQuintuplets ::
Word64
-> Word64
-> IO ()
printQuintuplets = c_print_quintuplets
printSextuplets ::
Word64
-> Word64
-> IO ()
printSextuplets = c_print_sextuplets
getMaxStop :: Word64
getMaxStop = c_get_max_stop
setSieveSize :: Int -> IO ()
setSieveSize = c_set_sieve_size . fromIntegral
setNumThreads :: Int -> IO ()
setNumThreads = c_set_num_threads . fromIntegral
primesieveVersion :: IO String
primesieveVersion = c_version >>= (fromBytesUnsafe <$>) . peekArrayEndedBy 0