-- | -- 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