Separate length from data in array representation
[packages/dph.git] / dph-prim-interface / interface / DPH_Interface.h
1 import Data.Array.Parallel.Base ( fromBool )
2 import qualified GHC.Base
3 import Prelude ((.), ($), Num(..), Eq(..))
4
5 instance Elt Int
6 instance Elt Word8
7 instance Elt Bool
8 instance Elt Double
9 instance (Elt a, Elt b) => Elt (a :*: b)
10
11 infixl 9 !:
12 infixr 5 +:+
13 --infixr 5 ^+:+^
14 --infixr 9 >:
15
16 length :: Elt a => Array a -> Int
17 {-# INLINE_BACKEND length #-}
18
19 empty :: Elt a => Array a
20 {-# INLINE_BACKEND empty #-}
21
22 replicate :: Elt a => Int -> a -> Array a
23 {-# INLINE CONLIKE PHASE_BACKEND replicate #-}
24
25 repeat :: Elt a => Int -> Int -> Array a -> Array a
26 {-# INLINE_BACKEND repeat #-}
27
28 (!:) :: Elt a => Array a -> Int -> a
29 {-# INLINE_BACKEND (!:) #-}
30
31 extract :: Elt a => Array a -> Int -> Int -> Array a
32 {-# INLINE_BACKEND extract #-}
33
34 drop :: Elt a => Int -> Array a -> Array a
35 {-# INLINE_BACKEND drop #-}
36
37 permute :: Elt a => Array a -> Array Int -> Array a
38 {-# INLINE_BACKEND permute #-}
39
40 bpermute :: Elt a => Array a -> Array Int -> Array a
41 {-# INLINE_BACKEND bpermute #-}
42
43 update :: Elt a => Array a -> Array (Int :*: a) -> Array a
44 {-# INLINE_BACKEND update #-}
45
46 (+:+) :: Elt a => Array a -> Array a -> Array a
47 {-# INLINE_BACKEND (+:+) #-}
48
49
50 pack :: Elt a => Array a -> Array Bool -> Array a
51 {-# INLINE_BACKEND pack #-}
52
53 combine :: Elt a => Array Bool -> Array a -> Array a -> Array a
54 {-# INLINE_BACKEND combine #-}
55
56 map :: (Elt a, Elt b) => (a -> b) -> Array a -> Array b
57 {-# INLINE_BACKEND map #-}
58
59 filter :: Elt a => (a -> Bool) -> Array a -> Array a
60 {-# INLINE_BACKEND filter #-}
61
62 zip :: (Elt a, Elt b) => Array a -> Array b -> Array (a :*: b)
63 {-# INLINE CONLIKE PHASE_BACKEND zip #-}
64
65 unzip :: (Elt a, Elt b) => Array (a :*: b) -> Array a :*: Array b
66 {-# INLINE_BACKEND unzip #-}
67
68 fsts :: (Elt a, Elt b) => Array (a :*: b) -> Array a
69 {-# INLINE_BACKEND fsts #-}
70
71 snds :: (Elt a, Elt b) => Array (a :*: b) -> Array b
72 {-# INLINE_BACKEND snds #-}
73
74 zip3 :: (Elt a, Elt b, Elt c) => Array a -> Array b -> Array c
75 -> Array (a :*: b :*: c)
76 {-# INLINE_BACKEND zip3 #-}
77
78 unzip3 :: (Elt a, Elt b, Elt c)
79 => Array (a :*: b :*: c) -> Array a :*: Array b :*: Array c
80 {-# INLINE_BACKEND unzip3 #-}
81
82 zipWith :: (Elt a, Elt b, Elt c)
83 => (a -> b -> c) -> Array a -> Array b -> Array c
84 {-# INLINE_BACKEND zipWith #-}
85
86 zipWith3 :: (Elt a, Elt b, Elt c, Elt d)
87 => (a -> b -> c -> d) -> Array a -> Array b -> Array c -> Array d
88 {-# INLINE_BACKEND zipWith3 #-}
89
90
91 fold :: Elt a => (a -> a -> a) -> a -> Array a -> a
92 {-# INLINE_BACKEND fold #-}
93
94 fold1 :: Elt a => (a -> a -> a) -> Array a -> a
95 {-# INLINE_BACKEND fold1 #-}
96
97 and :: Array Bool -> Bool
98 {-# INLINE_BACKEND and #-}
99
100 sum :: (Num a, Elt a) => Array a -> a
101 {-# INLINE_BACKEND sum #-}
102
103 scan :: Elt a => (a -> a -> a) -> a -> Array a -> Array a
104 {-# INLINE_BACKEND scan #-}
105
106
107 indexed :: Elt a => Array a -> Array (Int :*: a)
108 {-# INLINE_BACKEND indexed #-}
109
110 enumFromTo :: Int -> Int -> Array Int
111 {-# INLINE_BACKEND enumFromTo #-}
112
113 enumFromThenTo :: Int -> Int -> Int -> Array Int
114 {-# INLINE_BACKEND enumFromThenTo #-}
115
116 enumFromStepLen :: Int -> Int -> Int -> Array Int
117 {-# INLINE_BACKEND enumFromStepLen #-}
118
119 enumFromToEach :: Int -> Array (Int :*: Int) -> Array Int
120 {-# INLINE_BACKEND enumFromToEach #-}
121
122 enumFromStepLenEach :: Int -> Array (Int :*: Int :*: Int) -> Array Int
123 {-# INLINE_BACKEND enumFromStepLenEach #-}
124
125 replicate_s :: Elt a => Segd -> Array a -> Array a
126 {-# INLINE_BACKEND replicate_s #-}
127
128 append_s :: Elt a => Segd -- ^ segment descriptor of first array
129 -> Array a -- ^ data of first array
130 -> Segd -- ^ segment descriptor of second array
131 -> Array a -- ^ data of first array
132 -> Array a
133 {-# INLINE_BACKEND append_s #-}
134
135 repeat_c :: Elt a => Int -- ^ length of the result array
136 -> Array Int -- ^ number of time a segment is repeated
137 -> Segd -- ^ segment descriptor
138 -> Array a -- ^ data array
139 -> Array a
140 {-# INLINE_BACKEND repeat_c #-}
141 repeat_c k ns segd xs
142 = bpermute xs
143 . enumFromStepLenEach k
144 $ zip3 (snds ks) (replicate (elementsSegd segd') 1) (fsts ks)
145 where
146 segd' = lengthsToSegd ns
147 ks = replicate_s segd'
148 $ zip (lengthsSegd segd) (indicesSegd segd)
149
150 fold_s :: Elt a => (a -> a -> a) -> a -> Segd -> Array a -> Array a
151 {-# INLINE_BACKEND fold_s #-}
152
153 fold1_s :: Elt a => (a -> a -> a) -> Segd -> Array a -> Array a
154 {-# INLINE_BACKEND fold1_s #-}
155
156 sum_s :: (Num a, Elt a) => Segd -> Array a -> Array a
157 {-# INLINE sum_s #-}
158 sum_s = fold_s (Prelude.+) 0
159
160 sum_r :: (Num a, Elt a) => Int -> Int ->Array a -> Array a
161 {-# INLINE_BACKEND sum_r #-}
162
163 indices_s :: Int -- ^ number of segments
164 -> Segd -- ^ segment descriptor
165 -> Int -- ^ overall number of indices
166 -> Array Int
167 {-# INLINE indices_s #-}
168 indices_s m segd n = enumFromToEach n
169 . zip (replicate m 0)
170 . map (Prelude.subtract 1)
171 $ lengthsSegd segd
172
173 lengthSegd :: Segd -> Int
174 {-# INLINE_BACKEND lengthSegd #-}
175
176 lengthsSegd :: Segd -> Array Int
177 {-# INLINE_BACKEND lengthsSegd #-}
178
179 indicesSegd :: Segd -> Array Int
180 {-# INLINE_BACKEND indicesSegd #-}
181
182 elementsSegd :: Segd -> Int
183 {-# INLINE_BACKEND elementsSegd #-}
184
185 lengthsToSegd :: Array Int -> Segd
186 {-# INLINE_BACKEND lengthsToSegd #-}
187
188 mkSegd :: Array Int -> Array Int -> Int -> Segd
189 {-# INLINE CONLIKE PHASE_BACKEND mkSegd #-}
190
191 {-# RULES
192
193 "lengthsSegd/mkSegd" forall lens idxs n.
194 lengthsSegd (mkSegd lens idxs n) = lens
195
196 "indicesSegd/mkSegd" forall lens idxs n.
197 indicesSegd (mkSegd lens idxs n) = idxs
198
199 "elementsSegd/mkSegd" forall lens idxs n.
200 elementsSegd (mkSegd lens idxs n) = n
201
202 #-}
203
204
205 selectorToIndices2 :: Array Int -> Array Int
206 {-# INLINE_BACKEND selectorToIndices2 #-}
207 selectorToIndices2 sel
208 = zipWith pick sel
209 . scan idx (0 :*: 0)
210 $ map start sel
211 where
212 start 0 = 1 :*: 0
213 start _ = 0 :*: 1
214
215 idx (i1 :*: j1) (i2 :*: j2) = (i1+i2 :*: j1+j2)
216
217 pick 0 (i :*: j) = i
218 pick _ (i :*: j) = j
219
220 pick :: (Elt a, Eq a) => Array a -> a -> Array Bool
221 {-# INLINE pick #-}
222 pick xs x = map (x==) xs
223
224 count :: (Elt a, Eq a) => Array a -> a -> Int
225 {-# INLINE_BACKEND count #-}
226 count xs x = sum (map (fromBool . (==) x) xs)
227
228 randoms :: (Elt a, System.Random.Random a, System.Random.RandomGen g)
229 => Int -> g -> Array a
230 {-# INLINE_BACKEND randoms #-}
231
232 randomRs :: (Elt a, System.Random.Random a, System.Random.RandomGen g)
233 => Int -> (a,a) -> g -> Array a
234 {-# INLINE_BACKEND randomRs #-}
235
236
237 instance IOElt Int
238 instance IOElt Double
239 instance (IOElt a, IOElt b) => IOElt (a :*: b)
240
241 hPut :: IOElt a => Handle -> Array a -> IO ()
242 {-# INLINE_BACKEND hPut #-}
243
244 hGet :: IOElt a => Handle -> IO (Array a)
245 {-# INLINE_BACKEND hGet #-}
246
247 toList :: Elt a => Array a -> [a]
248 {-# INLINE_BACKEND toList #-}
249
250 fromList :: Elt a => [a] -> Array a
251 {-# INLINE_BACKEND fromList #-}
252
253 dph_mod_index :: Int -> Int -> Int
254 {-# INLINE_BACKEND dph_mod_index #-}
255 dph_mod_index by idx = idx `Prelude.mod` by
256
257 {-# RULES
258
259 "bpermute/repeat" forall n len xs is.
260 bpermute (repeat n len xs) is
261 = len `Prelude.seq` bpermute xs (map (dph_mod_index len) is)
262
263 #-}
264
265 {-# RULES
266
267 "replicate_s/replicate" forall segd k x.
268 replicate_s segd (replicate k x) = replicate (elementsSegd segd) x
269
270 #-}
271
272 {-# RULES
273
274 "repeat_c/repeat" forall k ks n m idxs nm len xs.
275 repeat_c k ks (mkSegd (replicate n m) idxs nm) (repeat n len xs)
276 = repeat (sum ks) len xs
277
278 #-}
279
280 {-# RULES
281
282 "scan/replicate" forall z n x.
283 scan GHC.Base.plusInt z (replicate n x)
284 = enumFromStepLen z x n
285
286 "map/zipWith (+)/enumFromStepLen" forall m n is.
287 map (dph_mod_index m) (zipWith GHC.Base.plusInt (enumFromStepLen 0 m n) is)
288 = map (dph_mod_index m) is
289
290 #-}
291
292 -- These are for Gabi
293 {- RULES
294
295 "repeat/bpermute" forall n len xs is.
296 repeat n len (bpermute xs is)
297 = bpermute xs (repeat n len is)
298
299 "lengthsToSegd/replicate" forall m n.
300 lengthsToSegd (replicate m n)
301 = let { m' = m; n' = n } in toSegd (zip (replicate m' n')
302 (enumFromStepLen 0 n' m'))
303
304 "fromSegd/toSegd" forall ps.
305 fromSegd (toSegd ps) = ps
306
307 "sum/replicate" forall m n.
308 sum (replicate m n) = m Prelude.* n
309
310 "replicateEach/zip" forall n lens xs ys.
311 replicateEach n lens (zip xs ys)
312 = let { n' = n; lens' = lens } in zip (replicateEach n' lens' xs)
313 (replicateEach n' lens' ys)
314
315 "fsts/zip" forall xs ys.
316 fsts (zip xs ys) = xs
317
318 "snds/zip" forall xs ys.
319 snds (zip xs ys) = ys
320
321 "repeat/enumFromStepLenEach" forall n m m' ps.
322 repeat n m (enumFromStepLenEach m' ps)
323 = enumFromStepLenEach (n*m) (repeat n (length ps) ps)
324
325 "repeat/zip3" forall n len xs ys zs.
326 repeat n len (zip3 xs ys zs)
327 = zip3 (repeat n len xs) (repeat n len ys) (repeat n len zs)
328
329 "repeat/replicate" forall n len m x.
330 repeat n len (replicate m x)
331 = replicate len x
332
333 -}
334