module Data.Array.Repa.IO.Binary
( readArrayFromStorableFile
, writeArrayToStorableFile)
where
import Foreign.Storable
import Foreign.Ptr
import Foreign.ForeignPtr
import Foreign.Marshal.Alloc
import System.IO
import Data.Array.Repa as R
import Prelude as P
import Control.Monad
readArrayFromStorableFile
:: forall a sh
. (Shape sh, Storable a, Elt a)
=> FilePath
-> sh
-> IO (Array sh a)
readArrayFromStorableFile filePath sh
= do
let (fake :: Array sh a) = R.fromList R.zeroDim []
let (bytes1 :: Integer) = fromIntegral $ sizeOf (fake R.! R.zeroDim)
h :: Handle <- openBinaryFile filePath ReadMode
bytesTotal <- hFileSize h
let lenTotal = bytesTotal `div` bytes1
let bytesExpected = bytes1 * lenTotal
when (bytesTotal /= bytesExpected)
$ error $ unlines
["Data.Array.Repa.IO.Binary.readArrayFromStorableFile: not a whole number of elements in file"
, "element length = " P.++ show bytes1
, "file size = " P.++ show bytesTotal
, "slack space = " P.++ show (bytesTotal `mod` bytes1) ]
let bytesTotal' = fromIntegral bytesTotal
buf :: Ptr a <- mallocBytes bytesTotal'
bytesRead <- hGetBuf h buf bytesTotal'
when (bytesTotal' /= bytesRead)
$ error "Data.Array.Repa.IO.Binary.readArrayFromStorableFile: read failed"
hClose h
fptr <- newForeignPtr finalizerFree buf
let arr = R.unsafeFromForeignPtr sh fptr
return $ arr `asTypeOf` fake
writeArrayToStorableFile
:: forall sh a
. (Shape sh, Storable a, Elt a)
=> FilePath
-> Array sh a
-> IO ()
writeArrayToStorableFile filePath arr
= do let bytes1 = sizeOf (arr R.! R.zeroDim)
let bytesTotal = bytes1 * (R.size $ R.extent arr)
buf :: Ptr a <- mallocBytes bytesTotal
R.forceWith (pokeElemOff buf) arr
h <- openBinaryFile filePath WriteMode
hPutBuf h buf bytesTotal
hClose h