{- Copyright (C) 2018 Johann Lee This fiel is part of HaskellFAI HaskellFAI is free software: you can redistribute it and/or modify it under the terms of the GNU Less General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Haskell is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warrenty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Less General Public License for more details. You should have received a copy of the GNU Less General Public License along with HaskellFAI. If not, see . -} {-| Module: Foreign.FAI Description: The Haskell Foreign Accelerate Interace. Copyright: (C) 2018 Johann Lee License: LGPL3 Maintainer: me@qinka.pro Stability: experimental Portability: unknown The Haskell Foreign Accelerate Interace. -} {-# LANGUAGE GADTs #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE TypeFamilies #-} module Foreign.FAI ( Pf , Buffer(..) , Context(..) , Accelerate(..) , FAI(..) , FAICopy(..) , FinalizerContextPtr , accelerate , newBuffer , newBufferIO , dupBuffer , dupBufferIO , dupBufferD , liftIO ) where import Control.Monad import Foreign.FAI.Internal import Foreign.FAI.Types import Foreign.Ptr -- | run the @Accelerate@. accelerate :: Context p -> Accelerate p a -> IO a accelerate cc = (fst <$>) . flip doAccelerate cc -- | Allocate new buffer (IO) newBufferIO :: (FAI p, Storable b, (Pf p a) ~ b) => Int -- ^ number of items -> Context p -- ^ platform context -> IO (Buffer p a, Context p) -- ^ Buffer and (new) context newBufferIO n cc = do fin <- faiMemReleaseP cc (ptr, size) <- alloc cc undefined when (nullPtr == ptr) $ error "Can not allocate memory." buf <- autoNewForeignPtr fin cc ptr size return (buf, cc) where alloc :: (FAI p, Storable b) => Context p -> b -> IO (Ptr b, Int) alloc c' u = let size = n * sizeOf u in (\p -> (p, size)) <$> faiMemAllocate c' (n * sizeOf u) -- | Allocate buffer newBuffer :: (FAI p, Storable b, (Pf p a) ~ b) => Int -- ^ number of items -> Accelerate p (Buffer p a) -- ^ buffer newBuffer = Accelerate .newBufferIO -- | Duplicate buffer (IO) dupBufferIO :: ( FAICopy p1 p2, FAI p1, FAI p2 , Storable b, Pf p2 a ~ b, Pf p1 a ~ b) => Bool -- ^ Whether copy data -> Buffer p1 a -- ^ buffer (src) -> Context p2 -- ^ platform context -> IO (Buffer p2 a, Context p2) -- ^ buffer (dst) and context dupBufferIO is buf cc = dup cc is buf -- | Duplicate buffer dupBuffer :: ( FAICopy p1 p2, FAI p1, FAI p2 , Storable b, Pf p2 a ~ b, Pf p1 a ~ b) => Bool -- ^ Whether copy data -> Buffer p1 a -- ^ buffer (src) -> Accelerate p2 (Buffer p2 a) -- ^ buffer (dst) dupBuffer is buf = Accelerate (dupBufferIO is buf) -- | Duplicate buffer (for debug) dupBufferD :: ( FAICopy p2 p1, FAI p1, FAI p2 , Storable b, Pf p2 a ~ b, Pf p1 a ~ b) => Bool -- ^ Whether copy data -> Buffer p2 a -- ^ buffer (src) -> Accelerate p2 (Buffer p1 a) -- ^ buffer (dst) dupBufferD is buf = Accelerate $ \cc -> replaceContext cc <$> dup undefined is buf