summaryrefslogtreecommitdiff
path: root/testsuite/tests
diff options
context:
space:
mode:
authorbenl <benl@ouroborus.net>2010-03-16 04:20:56 +0000
committerbenl <benl@ouroborus.net>2010-03-16 04:20:56 +0000
commitb30df6ee5caf77971b60bfda27e9b9774733271e (patch)
treec3c6c265201a9b8ab0394223fc21212628feb116 /testsuite/tests
parent62d5a1f38396b99a32b70f9406167441747350a6 (diff)
downloadhaskell-b30df6ee5caf77971b60bfda27e9b9774733271e.tar.gz
Add dph-words test
I've only set this to run with the "normal" way atm because it takes about 1.5 min to compile on my machine. SpecConstr blows out the size of the core program to about 400k, which is probably a good enough reason to have it in the testsuite.
Diffstat (limited to 'testsuite/tests')
-rw-r--r--testsuite/tests/ghc-regress/dph/words/Main.hs37
-rw-r--r--testsuite/tests/ghc-regress/dph/words/Makefile3
-rw-r--r--testsuite/tests/ghc-regress/dph/words/WordsVect.hs123
-rw-r--r--testsuite/tests/ghc-regress/dph/words/dph-words.T10
-rw-r--r--testsuite/tests/ghc-regress/dph/words/dph-words.stdout3
5 files changed, 176 insertions, 0 deletions
diff --git a/testsuite/tests/ghc-regress/dph/words/Main.hs b/testsuite/tests/ghc-regress/dph/words/Main.hs
new file mode 100644
index 0000000000..bc706fb751
--- /dev/null
+++ b/testsuite/tests/ghc-regress/dph/words/Main.hs
@@ -0,0 +1,37 @@
+
+import WordsVect
+import Data.Array.Parallel.Prelude
+import qualified Data.Array.Parallel.Prelude.Word8 as W
+import qualified Data.Array.Parallel.PArray as P
+import qualified Data.Array.Parallel.Unlifted as U
+import Data.Char
+
+main
+ = do -- take the filename containing the words as the first arg
+ let str = "When I look into the looking glass I'm always sure to see"
+ ++ " no matter how I dodge about, me looking back at me."
+
+ -- convert string to a PArray
+ let paStr :: PArray W.Word8
+ paStr = fromUArrPA' $ U.map W.fromInt $ U.fromList $ map ord str
+
+
+ -- break the string into words then flatten it back
+ let str' :: String
+ str' = map chr
+ $ map fromIntegral
+ $ P.toList
+ $ wordsOfPArray paStr
+
+
+ -- count the number of words in the string, using the vectorised program
+ let wordCountVect = fromIntegral $ wordCountOfPArray paStr
+
+ -- count the number of words with the ye'olde list way
+ let wordCountList = length $ words str
+
+ --
+ putStr $ show str' ++ "\n"
+ ++ "word count vect = " ++ show wordCountVect ++ "\n"
+ ++ "word count lists = " ++ show wordCountList ++ "\n"
+ \ No newline at end of file
diff --git a/testsuite/tests/ghc-regress/dph/words/Makefile b/testsuite/tests/ghc-regress/dph/words/Makefile
new file mode 100644
index 0000000000..1c39d1c1fe
--- /dev/null
+++ b/testsuite/tests/ghc-regress/dph/words/Makefile
@@ -0,0 +1,3 @@
+TOP=../../../..
+include $(TOP)/mk/boilerplate.mk
+include $(TOP)/mk/test.mk
diff --git a/testsuite/tests/ghc-regress/dph/words/WordsVect.hs b/testsuite/tests/ghc-regress/dph/words/WordsVect.hs
new file mode 100644
index 0000000000..9ceeeb32b5
--- /dev/null
+++ b/testsuite/tests/ghc-regress/dph/words/WordsVect.hs
@@ -0,0 +1,123 @@
+
+-- Break up a string into words in parallel.
+-- Based on the presentation "Breaking Sequential Habits of Thought", Guy Steele.
+-- http://groups.csail.mit.edu/mac/users/gjs/6.945/readings/MITApril2009Steele.pdf
+--
+-- NOTE: This is a naive implementation, and I haven't benchmarked it.
+-- Using parallel arrays in Seg probably isn't helpful for performance,
+-- but it's a stress test for the vectoriser.
+--
+-- If we actually cared about performance we wouldn't want to recursively
+-- subdivide the string right down to individual characters.
+--
+{-# LANGUAGE PArr, ParallelListComp #-}
+{-# OPTIONS -fvectorise #-}
+
+module WordsVect
+ ( wordsOfPArray
+ , wordCountOfPArray )
+where
+import qualified Data.Array.Parallel.Prelude.Word8 as W
+import Data.Array.Parallel.Prelude.Word8 (Word8)
+import Data.Array.Parallel.Prelude.Int
+import Data.Array.Parallel.Prelude
+
+import qualified Prelude as Prel
+
+
+-- We can't use the Prelude Char and String types in vectorised code yet..
+type Char = Word8
+char_space = W.fromInt 32
+
+type String = [: Char :]
+
+
+-- | Word state
+data State
+ = Chunk String
+ | Seg String -- initial word chunk
+ [:String:] -- complete words in the middle of the segment
+ String -- final word chunk
+
+
+-- | Compose two wordstates.
+plusState :: State -> State -> State
+plusState str1 str2
+ = case (str1, str2) of
+ (Chunk as, Chunk bs) -> Chunk (as +:+ bs)
+ (Chunk as, Seg bl bss br) -> Seg (as +:+ bl) bss br
+ (Seg al ass ar, Chunk bs) -> Seg al ass (ar +:+ bs)
+ (Seg al ass ar, Seg bl bss br) -> Seg al (ass +:+ joinEmpty [:ar +:+ bl:] +:+ bss) br
+
+joinEmpty :: [:[:Word8:]:] -> [:[:Word8:]:]
+joinEmpty ws
+ | lengthP ws == 1 && lengthP (ws !: 0) == 0 = [::]
+ | otherwise = ws
+
+
+-- | Convert a single char to a wordstate.
+stateOfChar :: Char -> State
+stateOfChar c
+ | c W.== char_space = Seg [::] [::] [::]
+ | otherwise = Chunk [:c:]
+
+
+-- | Break this string into words.
+stateOfString :: String -> State
+stateOfString str
+ = let len = lengthP str
+ result
+ | len == 0 = Chunk [::]
+ | len == 1 = stateOfChar (str !: 0)
+ | otherwise
+ = let half = len `div` 2
+ s1 = sliceP 0 half str
+ s2 = sliceP half len str
+ in plusState (stateOfString s1) (stateOfString s2)
+ in result
+
+
+-- | Count the number of words in a string.
+countWordsOfState :: State -> Int
+countWordsOfState state
+ = case state of
+ Chunk c -> wordsInChunkArr c
+ Seg c1 ws c2 -> wordsInChunkArr c1 + lengthP ws + wordsInChunkArr c2
+
+wordsInChunkArr :: [:Word8:] -> Int
+wordsInChunkArr arr
+ | lengthP arr == 0 = 0
+ | otherwise = 1
+
+
+-- | Flatten a state back to an array of Word8s,
+-- inserting spaces between the words.
+flattenState :: State -> [:Word8:]
+flattenState ss
+ = case ss of
+ Chunk s -> s
+
+ Seg w1 ws w2
+ -> w1
+ +:+ [:char_space:]
+ +:+ concatP [: w +:+ [:char_space:] | w <- ws :]
+ +:+ w2
+
+-- Interface ------------------------------------------------------------------
+
+-- | Break up an array of chars into words then flatten it back.
+wordsOfPArray :: PArray Word8 -> PArray Word8
+wordsOfPArray arr
+ = let str = fromPArrayP arr
+ state = stateOfString str
+ strOut = flattenState state
+ in toPArrayP strOut
+
+
+-- | Count the number of words in an array
+wordCountOfPArray :: PArray Word8 -> Int
+wordCountOfPArray arr
+ = let str = fromPArrayP arr
+ state = stateOfString str
+ in countWordsOfState state
+
diff --git a/testsuite/tests/ghc-regress/dph/words/dph-words.T b/testsuite/tests/ghc-regress/dph/words/dph-words.T
new file mode 100644
index 0000000000..3ec22b0a2b
--- /dev/null
+++ b/testsuite/tests/ghc-regress/dph/words/dph-words.T
@@ -0,0 +1,10 @@
+
+test ('dph-words'
+ , [ reqlib('dph-par')
+ , reqlib('dph-prim-par')
+ , only_ways(['normal']) ]
+ , multimod_compile_and_run
+ , [ 'Main'
+ , '-Odph -funbox-strict-fields -fcpr-off -package dph-par -package dph-prim-par'])
+
+
diff --git a/testsuite/tests/ghc-regress/dph/words/dph-words.stdout b/testsuite/tests/ghc-regress/dph/words/dph-words.stdout
new file mode 100644
index 0000000000..a7ad9be6b6
--- /dev/null
+++ b/testsuite/tests/ghc-regress/dph/words/dph-words.stdout
@@ -0,0 +1,3 @@
+"When I look into the looking glass I'm always sure to see no matter how I dodge about, me looking back at me."
+word count vect = 23
+word count lists = 23