diff options
author | Don Stewart <dons@galois.com> | 2008-06-10 00:53:03 +0000 |
---|---|---|
committer | Don Stewart <dons@galois.com> | 2008-06-10 00:53:03 +0000 |
commit | 9cb72979acc7bcd9df2fa8eab05169d9c5ca84f5 (patch) | |
tree | 52cb0810dc6fbcd199d40146df1f7afebb2171ef | |
parent | 8fdd2158ab7a122e9c72a7f41c8bac1a794cf53c (diff) |
Unpack Matrix type, and add -funsafe flag
-funsafe optionally compiles out the bounds checks on indexing matrices
and vectors. Yields good speedups on tight loops. Not enabled by default.
-rw-r--r-- | hmatrix.cabal | 11 | ||||
-rw-r--r-- | lib/Data/Packed/Internal/Matrix.hs | 25 | ||||
-rw-r--r-- | lib/Data/Packed/Internal/Vector.hs | 18 |
3 files changed, 43 insertions, 11 deletions
diff --git a/hmatrix.cabal b/hmatrix.cabal index 2633980..f39b862 100644 --- a/hmatrix.cabal +++ b/hmatrix.cabal | |||
@@ -25,6 +25,10 @@ flag mkl | |||
25 | description: Link with Intel's MKL optimized libraries. | 25 | description: Link with Intel's MKL optimized libraries. |
26 | default: False | 26 | default: False |
27 | 27 | ||
28 | flag unsafe | ||
29 | description: Compile the library with bound checking disabled. | ||
30 | default: False | ||
31 | |||
28 | library | 32 | library |
29 | if flag(splitBase) | 33 | if flag(splitBase) |
30 | build-depends: base >= 3, array, QuickCheck, HUnit, storable-complex | 34 | build-depends: base >= 3, array, QuickCheck, HUnit, storable-complex |
@@ -36,7 +40,8 @@ library | |||
36 | ghc-options: -fvia-C | 40 | ghc-options: -fvia-C |
37 | 41 | ||
38 | Build-Depends: haskell98 | 42 | Build-Depends: haskell98 |
39 | Extensions: ForeignFunctionInterface | 43 | Extensions: ForeignFunctionInterface, |
44 | CPP | ||
40 | 45 | ||
41 | hs-source-dirs: lib | 46 | hs-source-dirs: lib |
42 | Exposed-modules: Data.Packed, | 47 | Exposed-modules: Data.Packed, |
@@ -107,3 +112,7 @@ library | |||
107 | 112 | ||
108 | cc-options: -O4 | 113 | cc-options: -O4 |
109 | ghc-prof-options: -auto-all | 114 | ghc-prof-options: -auto-all |
115 | |||
116 | if flag(unsafe) | ||
117 | cpp-options: -DUNSAFE | ||
118 | |||
diff --git a/lib/Data/Packed/Internal/Matrix.hs b/lib/Data/Packed/Internal/Matrix.hs index c6129c6..7a35a61 100644 --- a/lib/Data/Packed/Internal/Matrix.hs +++ b/lib/Data/Packed/Internal/Matrix.hs | |||
@@ -1,4 +1,5 @@ | |||
1 | {-# OPTIONS_GHC -fglasgow-exts #-} | 1 | {-# OPTIONS_GHC -fglasgow-exts #-} |
2 | {-# LANGUAGE CPP #-} | ||
2 | ----------------------------------------------------------------------------- | 3 | ----------------------------------------------------------------------------- |
3 | -- | | 4 | -- | |
4 | -- Module : Data.Packed.Internal.Matrix | 5 | -- Module : Data.Packed.Internal.Matrix |
@@ -61,8 +62,13 @@ import Data.List(transpose) | |||
61 | data MatrixOrder = RowMajor | ColumnMajor deriving (Show,Eq) | 62 | data MatrixOrder = RowMajor | ColumnMajor deriving (Show,Eq) |
62 | 63 | ||
63 | -- | Matrix representation suitable for GSL and LAPACK computations. | 64 | -- | Matrix representation suitable for GSL and LAPACK computations. |
64 | data Matrix t = MC { rows :: Int, cols :: Int, cdat :: Vector t } | 65 | data Matrix t = MC { rows :: {-# UNPACK #-} !Int |
65 | | MF { rows :: Int, cols :: Int, fdat :: Vector t } | 66 | , cols :: {-# UNPACK #-} !Int |
67 | , cdat :: {-# UNPACK #-} !(Vector t) } | ||
68 | |||
69 | | MF { rows :: {-# UNPACK #-} !Int | ||
70 | , cols :: {-# UNPACK #-} !Int | ||
71 | , fdat :: {-# UNPACK #-} !(Vector t) } | ||
66 | 72 | ||
67 | -- MC: preferred by C, fdat may require a transposition | 73 | -- MC: preferred by C, fdat may require a transposition |
68 | -- MF: preferred by LAPACK, cdat may require a transposition | 74 | -- MF: preferred by LAPACK, cdat may require a transposition |
@@ -100,7 +106,6 @@ withMatrix MF {rows = r, cols = c, fdat = d } f = | |||
100 | flatten :: Element t => Matrix t -> Vector t | 106 | flatten :: Element t => Matrix t -> Vector t |
101 | flatten = cdat . cmat | 107 | flatten = cdat . cmat |
102 | 108 | ||
103 | |||
104 | type Mt t s = Int -> Int -> Ptr t -> s | 109 | type Mt t s = Int -> Int -> Ptr t -> s |
105 | -- not yet admitted by my haddock version | 110 | -- not yet admitted by my haddock version |
106 | -- infixr 6 ::> | 111 | -- infixr 6 ::> |
@@ -133,7 +138,6 @@ fromColumns m = trans . fromRows $ m | |||
133 | toColumns :: Element t => Matrix t -> [Vector t] | 138 | toColumns :: Element t => Matrix t -> [Vector t] |
134 | toColumns m = toRows . trans $ m | 139 | toColumns m = toRows . trans $ m |
135 | 140 | ||
136 | |||
137 | -- | Reads a matrix position. | 141 | -- | Reads a matrix position. |
138 | (@@>) :: Storable t => Matrix t -> (Int,Int) -> t | 142 | (@@>) :: Storable t => Matrix t -> (Int,Int) -> t |
139 | infixl 9 @@> | 143 | infixl 9 @@> |
@@ -142,12 +146,17 @@ infixl 9 @@> | |||
142 | -- | otherwise = cdat m `at` (i*c+j) | 146 | -- | otherwise = cdat m `at` (i*c+j) |
143 | 147 | ||
144 | MC {rows = r, cols = c, cdat = v} @@> (i,j) | 148 | MC {rows = r, cols = c, cdat = v} @@> (i,j) |
145 | | i<0 || i>=r || j<0 || j>=c = error "matrix indexing out of range" | 149 | | safe = if i<0 || i>=r || j<0 || j>=c |
146 | | otherwise = v `at` (i*c+j) | 150 | then error "matrix indexing out of range" |
151 | else v `at` (i*c+j) | ||
152 | | otherwise = v `at` (i*c+j) | ||
147 | 153 | ||
148 | MF {rows = r, cols = c, fdat = v} @@> (i,j) | 154 | MF {rows = r, cols = c, fdat = v} @@> (i,j) |
149 | | i<0 || i>=r || j<0 || j>=c = error "matrix indexing out of range" | 155 | | safe = if i<0 || i>=r || j<0 || j>=c |
150 | | otherwise = v `at` (j*r+i) | 156 | then error "matrix indexing out of range" |
157 | else v `at` (j*r+i) | ||
158 | | otherwise = v `at` (j*r+i) | ||
159 | {-# INLINE (@@>) #-} | ||
151 | 160 | ||
152 | ------------------------------------------------------------------ | 161 | ------------------------------------------------------------------ |
153 | 162 | ||
diff --git a/lib/Data/Packed/Internal/Vector.hs b/lib/Data/Packed/Internal/Vector.hs index 8723367..6274e48 100644 --- a/lib/Data/Packed/Internal/Vector.hs +++ b/lib/Data/Packed/Internal/Vector.hs | |||
@@ -100,10 +100,24 @@ n |> l = if length l == n then fromList l else error "|> with wrong size" | |||
100 | at' :: Storable a => Vector a -> Int -> a | 100 | at' :: Storable a => Vector a -> Int -> a |
101 | at' v n = safeRead v $ flip peekElemOff n | 101 | at' v n = safeRead v $ flip peekElemOff n |
102 | 102 | ||
103 | -- | ||
104 | -- turn off bounds checking with -funsafe at configure time. | ||
105 | -- ghc will optimise away the salways true case at compile time. | ||
106 | -- | ||
107 | #if defined(UNSAFE) | ||
108 | safe :: Bool | ||
109 | safe = False | ||
110 | #else | ||
111 | safe = True | ||
112 | #endif | ||
113 | |||
103 | -- | access to Vector elements with range checking. | 114 | -- | access to Vector elements with range checking. |
104 | at :: Storable a => Vector a -> Int -> a | 115 | at :: Storable a => Vector a -> Int -> a |
105 | at v n | n >= 0 && n < dim v = at' v n | 116 | at v n |
106 | | otherwise = error "vector index out of range" | 117 | | safe = if n >= 0 && n < dim v |
118 | then at' v n | ||
119 | else error "vector index out of range" | ||
120 | | otherwise = at' v n | ||
107 | {-# INLINE at #-} | 121 | {-# INLINE at #-} |
108 | 122 | ||
109 | {- | takes a number of consecutive elements from a Vector | 123 | {- | takes a number of consecutive elements from a Vector |