packages feed

repa-io 1.1.0.0 → 2.0.0.1

raw patch · 5 files changed

+159/−33 lines, 5 filesdep +old-timedep −dph-prim-pardep ~repadep ~repa-bytestringPVP ok

version bump matches the API change (PVP)

Dependencies added: old-time

Dependencies removed: dph-prim-par

Dependency ranges changed: repa, repa-bytestring

API changes (from Hackage documentation)

+ Data.Array.Repa.IO.BMP: readComponentsListFromBMP :: FilePath -> IO (Either Error [Array DIM2 Word8])
+ Data.Array.Repa.IO.BMP: writeComponentsListToBMP :: FilePath -> [Array DIM2 Word8] -> IO ()
+ Data.Array.Repa.IO.Timing: cpuTime :: TimeUnit -> Time -> Integer
+ Data.Array.Repa.IO.Timing: data Time
+ Data.Array.Repa.IO.Timing: milliseconds :: TimeUnit
+ Data.Array.Repa.IO.Timing: minus :: Time -> Time -> Time
+ Data.Array.Repa.IO.Timing: plus :: Time -> Time -> Time
+ Data.Array.Repa.IO.Timing: prettyTime :: Time -> String
+ Data.Array.Repa.IO.Timing: showTime :: Time -> String
+ Data.Array.Repa.IO.Timing: time :: IO a -> IO (a, Time)
+ Data.Array.Repa.IO.Timing: wallTime :: TimeUnit -> Time -> Integer
- Data.Array.Repa.IO.BMP: writeMatrixToGreyscaleBMP :: FilePath -> Array DIM2 Double -> IO ()
+ Data.Array.Repa.IO.BMP: writeMatrixToGreyscaleBMP :: (Num a, Elt a, Fractional a, RealFrac a) => FilePath -> Array DIM2 a -> IO ()

Files

Data/Array/Repa/IO/BMP.hs view
@@ -1,21 +1,29 @@-{-# LANGUAGE PackageImports #-} +{-# LANGUAGE PackageImports, PatternGuards, ExplicitForAll  #-}   -- | Reading and writing arrays as uncompressed 24 and 32 bit Windows BMP files. module Data.Array.Repa.IO.BMP 	( readImageFromBMP 	, readComponentsFromBMP+	, readComponentsListFromBMP 	, readMatrixFromGreyscaleBMP++	-- Writing. 	, writeImageToBMP 	, writeComponentsToBMP+	, writeComponentsListToBMP 	, writeMatrixToGreyscaleBMP) where-import qualified  Data.Array.Parallel.Unlifted 	as U import Data.Array.Repa				as A import Data.Array.Repa.ByteString               as A import Prelude					as P import Codec.BMP import Data.Word +-- NOTE: We set most of these functions as NOINLINE so it's easier to understand+--       what's going on in the core programs. The top-level IO functions are+--       only called a few times each, so it doesn't matter if they're not+--       worker/wrappered etc.+	 -- Read ------------------------------------------------------------------------------------------- -- | Read a matrix from a `BMP` file. --	Each pixel is converted to greyscale, normalised to [0..1] and used@@ -24,19 +32,35 @@ 	:: FilePath 	-> IO (Either Error (Array DIM2 Double)) +{-# NOINLINE readMatrixFromGreyscaleBMP #-} readMatrixFromGreyscaleBMP filePath  = do	eComps	<- readComponentsFromBMP filePath 	case eComps of  	 Left err	-> return $ Left err   	 Right (arrRed, arrGreen, arrBlue)- 	  -> let arr	= force + 	  -> let arr	= force2  			$ A.fromFunction (extent arrRed)-			   (\ix -> sqrt ( (fromIntegral (arrRed   !: ix) / 255) ^ (2 :: Int)-					+ (fromIntegral (arrGreen !: ix) / 255) ^ (2 :: Int)-					+ (fromIntegral (arrBlue  !: ix) / 255) ^ (2 :: Int)))+			   (\ix -> sqrt ( (fromIntegral (arrRed   ! ix) / 255) ^ (2 :: Int)+					+ (fromIntegral (arrGreen ! ix) / 255) ^ (2 :: Int)+					+ (fromIntegral (arrBlue  ! ix) / 255) ^ (2 :: Int))) 	     in	arr `deepSeqArray` return (Right arr)-		 ++-- | Like `readComponentsFromBMP`, but return the components as a list.+readComponentsListFromBMP+	:: FilePath+	-> IO (Either Error [Array DIM2 Word8])++readComponentsListFromBMP filePath+ = do	eComps	<- readComponentsFromBMP filePath+	case eComps of+	 Left err+	  -> return $ Left err++	 Right (arrRed, arrGreen, arrBlue)	+	  -> return $ Right [arrRed, arrGreen, arrBlue]++ -- | Read RGB components from a BMP file. --	Returns arrays of red, green and blue components, all with the same extent. --	If anything goes wrong when loading the file then then `Error`.@@ -44,7 +68,7 @@ 	:: FilePath 	-> IO (Either Error (Array DIM2 Word8, Array DIM2 Word8, Array DIM2 Word8)) -{-# INLINE readComponentsFromBMP #-}+{-# NOINLINE readComponentsFromBMP #-} readComponentsFromBMP filePath  = do	ebmp	<- readBMP filePath 	case ebmp of@@ -60,18 +84,18 @@ 	shapeFn _ 	= Z :. height :. width  	arrRed	-	 = traverse arr shapeFn+	 = force2 $ traverse arr shapeFn 		(\get (sh :. x) -> get (sh :. (x * 4)))  	arrGreen-	 = traverse arr shapeFn+	 = force2 $ traverse arr shapeFn 		(\get (sh :. x) -> get (sh :. (x * 4 + 1)))  	arrBlue-	 = traverse arr shapeFn+	 = force2 $ traverse arr shapeFn 		(\get (sh :. x) -> get (sh :. (x * 4 + 2))) 	-   in	(arrRed, arrGreen, arrBlue)+   in	[arrRed, arrGreen, arrBlue] `deepSeqArrays` (arrRed, arrGreen, arrBlue)   -- | Read a RGBA image from a BMP file.@@ -83,6 +107,7 @@ 	:: FilePath 	-> IO (Either Error (Array DIM3 Word8)) +{-# NOINLINE readImageFromBMP #-} readImageFromBMP filePath  = do	ebmp	<- readBMP filePath 	case ebmp of@@ -102,20 +127,37 @@ --	Negative values are discarded. Positive values are normalised to the maximum  --	value in the matrix and used as greyscale pixels. writeMatrixToGreyscaleBMP -	:: FilePath-	-> Array DIM2 Double+	:: forall a. (Num a, Elt a, Fractional a, RealFrac a)+	=> FilePath+	-> Array DIM2 a 	-> IO () +{-# NOINLINE   writeMatrixToGreyscaleBMP #-}+{-# SPECIALISE writeMatrixToGreyscaleBMP :: FilePath -> Array DIM2 Float  -> IO () #-}+{-# SPECIALISE writeMatrixToGreyscaleBMP :: FilePath -> Array DIM2 Double -> IO () #-} writeMatrixToGreyscaleBMP fileName arr  = let	arrNorm		= normalisePositive01 arr--	scale :: Double -> Word8 	scale x		= fromIntegral (truncate (x * 255) :: Int)- 	arrWord8	= A.map scale arrNorm    in	writeComponentsToBMP fileName arrWord8 arrWord8 arrWord8 		+		+-- | Like `writeComponentsToBMP` but take the components as a list.+--   The list must have 3 arrays, for the red, green blue components+--   respectively, else `error`.+writeComponentsListToBMP+	:: FilePath +	-> [Array DIM2 Word8]+	-> IO () +writeComponentsListToBMP filePath comps+	| [red, green, blue]	<- comps+	= writeComponentsToBMP filePath red green blue+	+	| otherwise+	= error "Data.Array.Repa.IO.BMP.writeComponentsListToBMP: wrong number of components"+	+ -- | Write RGB components to a BMP file. --	All arrays must have the same extent, else `error`. writeComponentsToBMP@@ -125,6 +167,7 @@ 	-> Array DIM2 Word8 	-> IO () +{-# NOINLINE writeComponentsToBMP #-} writeComponentsToBMP fileName arrRed arrGreen arrBlue  | not $ (  extent arrRed   == extent arrGreen                 && extent arrGreen == extent arrBlue)@@ -152,6 +195,7 @@ 	-> Array DIM3 Word8 	-> IO () +{-# NOINLINE writeImageToBMP #-} writeImageToBMP fileName arrImage 	| comps /= 4 	= error "Data.Array.Repa.IO.BMP: lowest order dimension must be 4"@@ -169,7 +213,7 @@ -- | Normalise a matrix to to [0 .. 1], discarding negative values. --	If the maximum value is 0 then return the array unchanged. normalisePositive01-	:: (Shape sh, U.Elt a, Fractional a, Ord a)+	:: (Shape sh, Elt a, Fractional a, Ord a) 	=> Array sh a 	-> Array sh a 
Data/Array/Repa/IO/Matrix.hs view
@@ -19,7 +19,6 @@ import Data.List				as L import Data.Array.Repa				as A import Prelude					as P-import qualified "dph-prim-par" Data.Array.Parallel.Unlifted	as U   -- | Read a matrix from a text file.@@ -27,7 +26,7 @@ --   WARNING: This doesn't do graceful error handling. If the file has the wrong format --   you'll get a confusing `error`. readMatrixFromTextFile-	:: (U.Elt a, Num a, Read a)+	:: (Elt a, Num a, Read a) 	=> FilePath 	-> IO (Array DIM2 a)	 @@ -47,7 +46,7 @@  -- | Write a matrix as a text file. writeMatrixToTextFile -	:: (U.Elt a, Show a)+	:: (Elt a, Show a) 	=> FilePath 	-> Array DIM2 a 	-> IO ()@@ -60,7 +59,7 @@ 	let Z :. width :. height	 		= extent arr -	hPutStrLn file $ show width ++ " " ++ show height+	hPutStrLn file $ show width P.++ " " P.++ show height 		 	hWriteValues file $ toList arr 	hClose file
+ Data/Array/Repa/IO/Timing.hs view
@@ -0,0 +1,86 @@+module Data.Array.Repa.IO.Timing+	( Time+	, milliseconds, cpuTime, wallTime+	, time, minus, plus+	, showTime+	, prettyTime)+where+import GHC.Exts	(traceEvent)+import System.CPUTime+import System.Time+++-- Time -----------------------------------------------------------------------+-- | Abstract representation of process time.+data Time +	= Time +	{ cpu_time  :: Integer+        , wall_time :: Integer+        }++zipT :: (Integer -> Integer -> Integer) -> Time -> Time -> Time+zipT f (Time cpu1 wall1) (Time cpu2 wall2) +	= Time (f cpu1 cpu2) (f wall1 wall2)++-- | Subtract second time from the first.+minus :: Time -> Time -> Time+minus = zipT (-)+++-- | Add two times.+plus :: Time -> Time -> Time+plus  = zipT (+)+++-- TimeUnit -------------------------------------------------------------------+-- | Conversion +type TimeUnit +	= Integer -> Integer++milliseconds :: TimeUnit+milliseconds n = n `div` 1000000000++cpuTime :: TimeUnit -> Time -> Integer+cpuTime f = f . cpu_time++wallTime :: TimeUnit -> Time -> Integer+wallTime f = f . wall_time+++-- | Get the current time.+getTime :: IO Time+getTime =+  do+    cpu          <- getCPUTime+    TOD sec pico <- getClockTime+    return $ Time cpu (pico + sec * 1000000000000)+++-- | Show a time as a string, in milliseconds.+showTime :: Time -> String+showTime t = (show $ wallTime milliseconds t)+          ++ "/"+          ++ (show $ cpuTime  milliseconds t)++-- | Pretty print the times, in milliseconds.+prettyTime :: Time -> String+prettyTime t+	= unlines+	[ "elapsedTimeMS   = " ++ (show $ wallTime milliseconds t)+	, "cpuTimeMS       = " ++ (show $ cpuTime  milliseconds t) ]++-- Timing benchmarks ----------------------------------------------------------++-- | Time some IO action.+--   Make sure to deepseq the result before returning it from the action. If you+--   don't do this then there's a good chance that you'll just pass a suspension+--   out of the action, and the computation time will be zero.+time :: IO a -> IO (a, Time)+{-# NOINLINE time #-}+time p = do+           start <- getTime+           traceEvent "Bench.Benchmark: start timing"+           x     <- p+           traceEvent "Bench.Benchmark: finished timing"+           end   <- getTime+           return (x, end `minus` start)
Data/Array/Repa/IO/Vector.hs view
@@ -20,14 +20,13 @@ import System.IO import Control.Monad import Data.Char-import qualified "dph-prim-par" Data.Array.Parallel.Unlifted	as U   -- | Read a vector from a text file. --   WARNING: This doesn't do graceful error handling. If the file has the wrong format --   you'll get a confusing `error`. readVectorFromTextFile-	:: (U.Elt a, Num a, Read a)+	:: (Elt a, Num a, Read a) 	=> FilePath 	-> IO (Array DIM1 a)	 @@ -55,7 +54,7 @@ 	 -- | Write a vector as a text file. writeVectorToTextFile -	:: (U.Elt a, Show a)+	:: (Elt a, Show a) 	=> Array DIM1 a 	-> FilePath 	-> IO ()
repa-io.cabal view
@@ -1,5 +1,5 @@ Name:                repa-io-Version:             1.1.0.0+Version:             2.0.0.1 License:             BSD3 License-file:        LICENSE Author:              The DPH Team@@ -11,21 +11,18 @@ Homepage:            http://trac.haskell.org/repa Bug-reports:         http://trac.haskell.org/repa/newticket Description:-        NOTE: You must use the GHC head branch > 6.13.20100309 to get decent performance.         Read and write Repa arrays in various formats.  Synopsis:         Read and write Repa arrays in various formats. -Tested-with: GHC == 6.13.20100309, GHC == 6.12.1- Library   Build-Depends:          base                 == 4.*,-        dph-prim-par         == 0.4.*,-        repa                 == 1.1.*,-        repa-bytestring      == 1.1.*,-        bmp                  == 1.1.*+        repa                 == 2.0.*,+        repa-bytestring      == 2.0.*,+        bmp                  == 1.1.*,+        old-time             == 1.0.*    ghc-options:         -Odph -Wall -fno-warn-missing-signatures@@ -35,6 +32,7 @@         Data.Array.Repa.IO.BMP         Data.Array.Repa.IO.Vector         Data.Array.Repa.IO.Matrix+        Data.Array.Repa.IO.Timing          Other-modules:         Data.Array.Repa.IO.Internals.Text