Graph500-0.4.0: src/G500/Read.hs
-- |
-- Module : G500.Read
-- Copyright : (C) 2013 Parallel Scientific Labs, LLC.
-- License : GPLv2
--
-- A module that reads files generated by Gen (graph500gen) program
-- one directory level above.
--
module G500.Read
( Graph500Reader
, mkGraph500Reader
) where
import Control.Monad
import Data.Array.IO
import Data.Array.Unboxed
import Data.Word
import System.IO
import G500
-- |A synonym for IO action that performs a read.
type Graph500Reader = IO (Maybe (UArray Int Index))
-- |Create a graph reader structure.
-- The @handle@ should be opened to read as a binary file.
-- Also the handle gets captured in result of the function and will
-- be closed at the end of operation.
mkGraph500Reader :: Handle -- ^ File handle.
-> Int -- ^ Size of a read.
-> IO Graph500Reader
mkGraph500Reader handle portionSize = do
buf <- newArray (0,bytesCount-1) 0
return $ graph500Reader handle buf
where
vertexSize = 8
edgeSize = 2*vertexSize
bytesCount = edgeSize*portionSize
graph500Reader h buf = do
eof <- hIsEOF h
if eof then do
hClose h
return Nothing
else readBatchPortion h buf
readVertexIndex :: IOUArray Int Word8 -> Int -> IO Index
readVertexIndex a i = do
bytes <- forM [i*vertexSize..(i+1)*vertexSize-1] $ readArray a
return $ foldr (\x j -> j*256 + fromIntegral x) 0 $ bytes
readBatchPortion :: Handle -> IOUArray Int Word8 -> IO (Maybe (UArray Int Index))
readBatchPortion h buf = do
n <- hGetArray h buf bytesCount
let edgesCount = n `div` edgeSize
let indicesCount = edgesCount*2
let maxIndex = indicesCount-1
result <- (newArray (0,maxIndex) (0 :: Index)) :: IO (IOUArray Int Index)
forM_ [0..indicesCount-1] $ \i -> do
idx <- readVertexIndex buf i
writeArray result i idx
pairs <- freeze result
return $ Just pairs