dph-lifted-vseg-0.6.0.1: Data/Array/Parallel/Prim.hs
{-# LANGUAGE CPP #-}
#include "fusion-phases.h"
-- | This is the API used by the vectoriser.
-- The vectoriser wants a slightly different interface to the one used
-- natively by the library. This module performs the impedance matching.
module Data.Array.Parallel.Prim
-- Core types
( PData, PDatas, PRepr, PA(..), PR(..)
-- Array Functions
, emptyPD
, replicatePD
, packByTagPD
, combine2PD
-- Scalar primitives
, Scalar(..)
, scalar_map
, scalar_zipWith
, scalar_zipWith3
-- Types used in the generic representation
, Void, void, fromVoid, pvoid, pvoids#
, punit
, Wrap(..)
, Sum2(..), Sum3(..)
-- Closures, and closure functions
, (:->)(..)
, closure, ($:)
, liftedClosure, liftedApply
, closure1, closure2, closure3
-- Selectors
, Sel2
, tagsSel2
, pickSel2#
, replicateSel2#
, elementsSel2_0#
, elementsSel2_1#
, Sels2
, lengthSels2#
-- Scalar constructors
, emptyPA_Int#, emptyPA_Double#
, replicatePA_Int#, replicatePA_Double#
, packByTagPA_Int#, packByTagPA_Double#
, combine2PA_Int#, combine2PA_Double#
-- Tuple constructors
, tup2, tup3, tup4, tup5)
where
import Data.Array.Parallel.PArray.PData.Base
(PArray(..), PData, PDatas, PR(..))
import Data.Array.Parallel.PArray.PData.Void
( Void, void, pvoid, pvoids, fromVoid )
import Data.Array.Parallel.PArray.PData.Unit
( punit )
import Data.Array.Parallel.PArray.PData.Sum2
( Sels2, lengthSels2 )
import Data.Array.Parallel.PArray.PRepr
( PRepr, PA(..)
, emptyPA, replicatePA, packByTagPA, combine2PA)
import Data.Array.Parallel.PArray.Scalar
( Scalar(..))
import Data.Array.Parallel.PArray.Types
( Wrap(..)
, Sum2(..), Sum3(..))
import Data.Array.Parallel.Lifted.Closure
( (:->)(..))
import Data.Array.Parallel.Prelude.Tuple
( tup2, tup3, tup4, tup5)
import Data.Array.Parallel.Base (Tag, intToTag)
import qualified Data.Array.Parallel.Unlifted as U
import qualified Data.Array.Parallel.PArray.Scalar as Scalar
import qualified Data.Array.Parallel.Lifted.Closure as C
import GHC.Exts
-- Array functions ------------------------------------------------------------
emptyPD :: PA a => PData a
emptyPD = emptyPA
{-# INLINE_PA emptyPD #-}
replicatePD :: PA a => Int# -> a -> PData a
replicatePD i# x
= replicatePA (I# i#) x
{-# INLINE_PA replicatePD #-}
packByTagPD :: PA a => PData a -> Int# -> U.Array Tag -> Int# -> PData a
packByTagPD xs _ tags tag#
= packByTagPA xs tags (I# tag#)
{-# INLINE_PA packByTagPD #-}
combine2PD :: PA a => Int# -> U.Sel2 -> PData a -> PData a -> PData a
combine2PD _ sel xs ys
= combine2PA sel xs ys
{-# INLINE_PA combine2PD #-}
-- Generic Representation ----------------------------------------------------
pvoids# :: Int# -> PDatas Void
pvoids# n# = pvoids (I# n#)
{-# INLINE_PA pvoids# #-}
-- Closures -------------------------------------------------------------------
-- The vectoriser wants versions of these functions that take unboxed
-- integers for the first argument of the lifted function.
-- | Construct a closure.
closure :: forall a b e
. PA e
=> (e -> a -> b)
-> (Int# -> PData e -> PData a -> PData b)
-> e
-> (a :-> b)
closure fv fl e
= Clo fv
(\(I# c) v x -> fl c v x)
e
{-# INLINE_CLOSURE closure #-}
-- | Apply a closure.
($:) :: forall a b. (a :-> b) -> a -> b
($:) = (C.$:)
{-# INLINE_CLOSURE ($:) #-}
-- | Construct a lifted closure.
liftedClosure
:: forall a b e
. PA e
=> (e -> a -> b)
-> (Int# -> PData e -> PData a -> PData b)
-> PData e
-> PData (a :-> b)
{-# INLINE_CLOSURE liftedClosure #-}
liftedClosure fv fl es
= C.AClo fv
(\(I# c) v x -> fl c v x)
es
-- | Apply a lifted closure.
liftedApply :: Int# -> PData (a :-> b) -> PData a -> PData b
liftedApply n# arr xs
= C.liftedApply (I# n#) arr xs
{-# INLINE_CLOSURE liftedApply #-}
closure1 :: forall a b
. (a -> b)
-> (PArray a -> PArray b)
-> (a :-> b)
closure1 fv fl
= let fl' :: Int -> PData a -> PData b
fl' (I# c#) pdata
= case fl (PArray c# pdata) of
PArray _ pdata' -> pdata'
in C.closure1 fv fl'
{-# INLINE_CLOSURE closure1 #-}
closure2 :: forall a b c. PA a
=> (a -> b -> c)
-> (PArray a -> PArray b -> PArray c)
-> (a :-> b :-> c)
closure2 fv fl
= let fl' :: Int -> PData a -> PData b -> PData c
fl' (I# c#) pdata1 pdata2
= case fl (PArray c# pdata1) (PArray c# pdata2) of
PArray _ pdata' -> pdata'
in C.closure2 fv fl'
{-# INLINE_CLOSURE closure2 #-}
closure3 :: forall a b c d. (PA a, PA b)
=> (a -> b -> c -> d)
-> (PArray a -> PArray b -> PArray c -> PArray d)
-> (a :-> b :-> c :-> d)
closure3 fv fl
= let fl' :: Int -> PData a -> PData b -> PData c -> PData d
fl' (I# c#) pdata1 pdata2 pdata3
= case fl (PArray c# pdata1) (PArray c# pdata2) (PArray c# pdata3) of
PArray _ pdata' -> pdata'
in C.closure3 fv fl'
{-# INLINE_CLOSURE closure3 #-}
-- Selector functions ---------------------------------------------------------
-- The vectoriser wants versions of these that take unboxed integers
-- for some arguments.
type Sel2 = U.Sel2
replicateSel2# :: Int# -> Int# -> Sel2
replicateSel2# n# tag#
= U.mkSel2
(U.replicate n (intToTag tag))
(U.enumFromStepLen 0 1 n)
(if tag == 0 then n else 0)
(if tag == 0 then 0 else n)
(U.mkSelRep2 (U.replicate n (intToTag tag)))
where
n = I# n#
tag = I# tag#
{-# INLINE_PA replicateSel2# #-}
pickSel2# :: Sel2 -> Int# -> U.Array Bool
pickSel2# sel tag#
= U.pick (U.tagsSel2 sel) (intToTag (I# tag#))
{-# INLINE_PA pickSel2# #-}
tagsSel2 :: Sel2 -> U.Array Tag
tagsSel2 = U.tagsSel2
{-# INLINE_PA tagsSel2 #-}
elementsSel2_0# :: Sel2 -> Int#
elementsSel2_0# sel
= case U.elementsSel2_0 sel of { I# n# -> n# }
{-# INLINE_PA elementsSel2_0# #-}
elementsSel2_1# :: Sel2 -> Int#
elementsSel2_1# sel
= case U.elementsSel2_1 sel of { I# n# -> n# }
{-# INLINE_PA elementsSel2_1# #-}
lengthSels2# :: Sels2 -> Int#
lengthSels2# sels2
= case lengthSels2 sels2 of { I# n# -> n# }
{-# INLINE_PA lengthSels2# #-}
-- Scalar functions -----------------------------------------------------------
scalar_map
:: (Scalar a, Scalar b)
=> (a -> b) -> PArray a -> PArray b
scalar_map = Scalar.map
{-# INLINE scalar_map #-}
scalar_zipWith
:: (Scalar a, Scalar b, Scalar c)
=> (a -> b -> c) -> PArray a -> PArray b -> PArray c
scalar_zipWith = Scalar.zipWith
{-# INLINE scalar_zipWith #-}
scalar_zipWith3
:: (Scalar a, Scalar b, Scalar c, Scalar d)
=> (a -> b -> c -> d) -> PArray a -> PArray b -> PArray c -> PArray d
scalar_zipWith3 = Scalar.zipWith3
{-# INLINE scalar_zipWith3 #-}
-- Int functions --------------------------------------------------------------
type PArray_Int# = U.Array Int
replicatePA_Int# :: Int# -> Int# -> PArray_Int#
replicatePA_Int# n# i# = U.replicate (I# n#) (I# i#)
{-# INLINE_PA replicatePA_Int# #-}
emptyPA_Int# :: PArray_Int#
emptyPA_Int# = U.empty
{-# INLINE_PA emptyPA_Int# #-}
{-# RULES
"replicatePA_Int#" forall n# i#.
replicatePA_Int# n# i# = U.replicate (I# n#) (I# i#)
#-}
packByTagPA_Int# :: a
packByTagPA_Int#
= error "Data.Array.Parallel.Prim: 'packByTagPA_Int#' not implemented"
{-# NOINLINE packByTagPA_Int# #-}
combine2'PA_Int# :: PArray_Int# -> PArray_Int# -> PArray_Int# -> PArray_Int#
combine2'PA_Int# sel xs ys = U.combine (U.map (== 0) sel) xs ys
{-# INLINE_PA combine2'PA_Int# #-}
combine2PA_Int#
:: Int#
-> PArray_Int# -> PArray_Int#
-> PArray_Int# -> PArray_Int# -> PArray_Int#
combine2PA_Int# _ sel _ xs ys = combine2'PA_Int# sel xs ys
{-# INLINE_PA combine2PA_Int# #-}
-- Double functions -----------------------------------------------------------
type PArray_Double# = U.Array Double
replicatePA_Double# :: Int# -> Double# -> PArray_Double#
replicatePA_Double# n# d# = U.replicate (I# n#) (D# d#)
{-# INLINE_PA replicatePA_Double# #-}
emptyPA_Double# :: PArray_Double#
emptyPA_Double# = U.empty
{-# INLINE_PA emptyPA_Double# #-}
packByTagPA_Double# :: a
packByTagPA_Double#
= error "Data.Array.Parallel.Prim: 'packByTagPA_Double#' not implemented"
{-# NOINLINE packByTagPA_Double# #-}
combine2'PA_Double#
:: PArray_Int#
-> PArray_Double# -> PArray_Double# -> PArray_Double#
combine2'PA_Double# sel xs ys = U.combine (U.map (== 0) sel) xs ys
{-# INLINE_PA combine2'PA_Double# #-}
combine2PA_Double#
:: Int#
-> PArray_Int# -> PArray_Int#
-> PArray_Double# -> PArray_Double# -> PArray_Double#
combine2PA_Double# _ sel _ xs ys = combine2'PA_Double# sel xs ys
{-# INLINE_PA combine2PA_Double# #-}