diff options
author | David Terei <davidterei@gmail.com> | 2011-07-20 11:09:03 -0700 |
---|---|---|
committer | David Terei <davidterei@gmail.com> | 2011-07-20 11:26:35 -0700 |
commit | 16514f272fb42af6e9c7674a9bd6c9dce369231f (patch) | |
tree | e4f332b45fe65e2a7a2451be5674f887b42bf199 /testsuite/tests/dph | |
parent | ebd422aed41048476aa61dd4c520d43becd78682 (diff) | |
download | haskell-16514f272fb42af6e9c7674a9bd6c9dce369231f.tar.gz |
Move tests from tests/ghc-regress/* to just tests/*
Diffstat (limited to 'testsuite/tests/dph')
50 files changed, 3256 insertions, 0 deletions
diff --git a/testsuite/tests/dph/Makefile b/testsuite/tests/dph/Makefile new file mode 100644 index 0000000000..9a36a1c5fe --- /dev/null +++ b/testsuite/tests/dph/Makefile @@ -0,0 +1,3 @@ +TOP=../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk diff --git a/testsuite/tests/dph/diophantine/DiophantineVect.hs b/testsuite/tests/dph/diophantine/DiophantineVect.hs new file mode 100644 index 0000000000..bef6694b3d --- /dev/null +++ b/testsuite/tests/dph/diophantine/DiophantineVect.hs @@ -0,0 +1,38 @@ +{-# LANGUAGE ParallelArrays #-} +{-# OPTIONS -fvectorise -XParallelListComp #-} +module DiophantineVect (solution3) where + +import Data.Array.Parallel +import Data.Array.Parallel.Prelude.Int + +import qualified Prelude as P + +solution3' + = let + pow x i = productP (replicateP i x) + primes = [: 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73 :] + sumpri xx = productP [: pow p x | p <- primes | x <- xx :] + distinct xx = productP [: x + 1 | x <- xx :] + + series :: [:Int:] -> Int -> [:[:Int:]:] + series xs n + | n == 1 = [: [: 0 :] :] + | otherwise = [: [: x :] +:+ ps + | x <- xs + , ps <- series (enumFromToP 0 x) (n-1) :] + + prob x y + = let xx = [: (sumpri m ,m) + | m <- series (enumFromToP 1 3) x + , distinct [: x * 2 | x <- m :] > y :] + i = minIndexP [: a | (a, b) <- xx :] + in xx !: i + in + prob 7 2000 + +solution3 :: (Int, PArray Int) +{-# NOINLINE solution3 #-} +solution3 + = let (i, is) = solution3' + in + (i, toPArrayP is) diff --git a/testsuite/tests/dph/diophantine/Main.hs b/testsuite/tests/dph/diophantine/Main.hs new file mode 100644 index 0000000000..eb8ae7ac28 --- /dev/null +++ b/testsuite/tests/dph/diophantine/Main.hs @@ -0,0 +1,43 @@ +{-# LANGUAGE ParallelArrays #-} + +import Data.List +import DiophantineVect + +import qualified Data.Array.Parallel.PArray as P +import Data.Array.Parallel.Prelude + + +-- Solution for the 108th Euler problem. +-- From the Haskell Wiki +solution1 + = let primes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73] + series _ 1 = [[0]] + series xs n = [x:ps | x <- xs, ps <- series [0..x] (n-1) ] + distinct = product . map (+1) + sumpri x = product $ zipWith (^) primes x + + prob x y = minimum [ (sumpri m ,m) + | m <- series [1..3] x + , (>y) $ distinct $ map (*2) m] + in prob 7 2000 + +solution2 + = let primes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73] + series _ 1 = [[0]] + series xs n = [x:ps | x <- xs, ps <- series [0..x] (n-1) ] + distinct xx = product [ x + 1 | x <- xx ] + sumpri xx = product $ zipWith (^) primes xx + + prob x y = minimum [ (sumpri m ,m) + | m <- series [1..3] x + , (distinct $ map (*2) m) > y ] + in prob 7 2000 + + +main + = do print solution1 + print solution2 + print solution3 + + +
\ No newline at end of file diff --git a/testsuite/tests/dph/diophantine/Makefile b/testsuite/tests/dph/diophantine/Makefile new file mode 100644 index 0000000000..9101fbd40a --- /dev/null +++ b/testsuite/tests/dph/diophantine/Makefile @@ -0,0 +1,3 @@ +TOP=../../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk diff --git a/testsuite/tests/dph/diophantine/dph-diophantine-fast.stdout b/testsuite/tests/dph/diophantine/dph-diophantine-fast.stdout new file mode 100644 index 0000000000..7088d6ced3 --- /dev/null +++ b/testsuite/tests/dph/diophantine/dph-diophantine-fast.stdout @@ -0,0 +1,3 @@ +(180180,[2,2,1,1,1,1,0]) +(180180,[2,2,1,1,1,1,0]) +(180180,[:2,2,1,1,1,1,0:]) diff --git a/testsuite/tests/dph/diophantine/dph-diophantine-opt.stdout b/testsuite/tests/dph/diophantine/dph-diophantine-opt.stdout new file mode 100644 index 0000000000..7088d6ced3 --- /dev/null +++ b/testsuite/tests/dph/diophantine/dph-diophantine-opt.stdout @@ -0,0 +1,3 @@ +(180180,[2,2,1,1,1,1,0]) +(180180,[2,2,1,1,1,1,0]) +(180180,[:2,2,1,1,1,1,0:]) diff --git a/testsuite/tests/dph/diophantine/dph-diophantine.T b/testsuite/tests/dph/diophantine/dph-diophantine.T new file mode 100644 index 0000000000..c963db9145 --- /dev/null +++ b/testsuite/tests/dph/diophantine/dph-diophantine.T @@ -0,0 +1,20 @@ + +test ('dph-diophantine-opt' + , [ alone + , skip_if_fast + , reqlib('dph-par') + , reqlib('dph-prim-par') + , only_ways(['normal', 'threaded1', 'threaded2']) ] + , multimod_compile_and_run + , [ 'Main' + , '-Odph -fdph-par']) + +test ('dph-diophantine-fast' + , [ reqlib('dph-par') + , reqlib('dph-prim-par') + , expect_broken(5065) + , only_ways(['normal', 'threaded1', 'threaded2']) ] + , multimod_compile_and_run + , [ 'Main' + , '-O -fno-enable-rewrite-rules -fdph-par']) + diff --git a/testsuite/tests/dph/dotp/DotPVect.hs b/testsuite/tests/dph/dotp/DotPVect.hs new file mode 100644 index 0000000000..5b623017d9 --- /dev/null +++ b/testsuite/tests/dph/dotp/DotPVect.hs @@ -0,0 +1,15 @@ +{-# LANGUAGE ParallelArrays #-} +{-# OPTIONS -fvectorise #-} +module DotPVect ( dotp ) where + +import Data.Array.Parallel +import Data.Array.Parallel.Prelude.Double as D + +import qualified Prelude + +dotp :: PArray Double -> PArray Double -> Double +{-# NOINLINE dotp #-} +dotp v w = dotp' (fromPArrayP v) (fromPArrayP w) + +dotp' :: [:Double:] -> [:Double:] -> Double +dotp' v w = D.sumP (zipWithP (*) v w) diff --git a/testsuite/tests/dph/dotp/Main.hs b/testsuite/tests/dph/dotp/Main.hs new file mode 100644 index 0000000000..436beb07fd --- /dev/null +++ b/testsuite/tests/dph/dotp/Main.hs @@ -0,0 +1,54 @@ +import DotPVect ( dotp ) + +import Control.Exception (evaluate) +import System.Console.GetOpt +import qualified System.Random as R + +import qualified Data.Array.Parallel.Unlifted as U +import qualified Data.Array.Parallel.PArray as P +import Data.Array.Parallel.PArray (PArray) + + + +generateVectorU :: Int -> IO (U.Array Double) +generateVectorU n = + do + let seed = 42742 + let rg = R.mkStdGen seed + let -- The std random function is too slow to generate really big vectors + -- with. Instead, we generate a short random vector and repeat that. + randvec = U.randomRs k (-100, 100) rg + vec = U.map (\i -> randvec U.!: (i `mod` k)) (U.enumFromTo 0 (n-1)) + evaluate vec + return vec + where + k = 1000 + +generateVector :: Int -> IO (PArray Double) +generateVector n + = do + vec <- generateVectorU n + return $ P.fromUArrPA' vec + +generateVectors :: Int -> IO (PArray Double, PArray Double) +generateVectors n = + do + v <- generateVector n + w <- generateVector n + return (v,w) + +main + = do -- compute dot product with NDP + vectors <- generateVectors 100000 + let resultViaNDP = (uncurry dotp) vectors + + -- compute with lists + let (aVecX, aVecY) = vectors + let vecX = P.toList aVecX + let vecY = P.toList aVecY + let resultViaList = sum $ zipWith (*) vecX vecY + + -- ignore wibbles in low order bits + putStr $ (take 12 $ show resultViaNDP) ++ "\n" + putStr $ (take 12 $ show resultViaList) ++ "\n" + diff --git a/testsuite/tests/dph/dotp/Makefile b/testsuite/tests/dph/dotp/Makefile new file mode 100644 index 0000000000..9101fbd40a --- /dev/null +++ b/testsuite/tests/dph/dotp/Makefile @@ -0,0 +1,3 @@ +TOP=../../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk diff --git a/testsuite/tests/dph/dotp/dph-dotp-fast.stdout b/testsuite/tests/dph/dotp/dph-dotp-fast.stdout new file mode 100644 index 0000000000..e8f012cbc6 --- /dev/null +++ b/testsuite/tests/dph/dotp/dph-dotp-fast.stdout @@ -0,0 +1,2 @@ +3.3659625259 +3.3659625259 diff --git a/testsuite/tests/dph/dotp/dph-dotp-opt.stdout b/testsuite/tests/dph/dotp/dph-dotp-opt.stdout new file mode 100644 index 0000000000..e8f012cbc6 --- /dev/null +++ b/testsuite/tests/dph/dotp/dph-dotp-opt.stdout @@ -0,0 +1,2 @@ +3.3659625259 +3.3659625259 diff --git a/testsuite/tests/dph/dotp/dph-dotp.T b/testsuite/tests/dph/dotp/dph-dotp.T new file mode 100644 index 0000000000..2ebab9da24 --- /dev/null +++ b/testsuite/tests/dph/dotp/dph-dotp.T @@ -0,0 +1,20 @@ + +test ('dph-dotp-opt' + , [ alone + , skip_if_fast + , reqlib('dph-par') + , reqlib('dph-prim-par') + , only_ways(['normal', 'threaded1', 'threaded2']) ] + , multimod_compile_and_run + , [ 'Main' + , '-Odph -fdph-par']) + +test ('dph-dotp-fast' + , [ reqlib('dph-par') + , reqlib('dph-prim-par') + , only_ways(['normal', 'threaded1', 'threaded2']) ] + , multimod_compile_and_run + , [ 'Main' + , '-O -fno-enable-rewrite-rules -fdph-par']) + + diff --git a/testsuite/tests/dph/primespj/Main.hs b/testsuite/tests/dph/primespj/Main.hs new file mode 100644 index 0000000000..049e6a3e04 --- /dev/null +++ b/testsuite/tests/dph/primespj/Main.hs @@ -0,0 +1,30 @@ +import Control.Exception (evaluate) +import System.Console.GetOpt + +import Data.Array.Parallel.PArray (PArray) +import qualified Data.Array.Parallel.PArray as P + +import PrimesVect (primesVect) +import Debug.Trace + + +primesList :: Int -> [Int] +primesList 1 = [] +primesList n = sps ++ [ i | i <- [sq+1..n], multiple sps i ] + where + sps = primesList sq + sq = floor $ sqrt $ fromIntegral n + + multiple :: [Int] -> Int -> Bool + multiple ps i = and [i `mod` p /= 0 | p <- ps] + + +main + = do let n = 1000 + let resultViaNDP = P.toList $ primesVect n + let resultViaLists = primesList n + + print resultViaNDP + print resultViaLists + print $ resultViaNDP == resultViaLists + diff --git a/testsuite/tests/dph/primespj/Makefile b/testsuite/tests/dph/primespj/Makefile new file mode 100644 index 0000000000..9101fbd40a --- /dev/null +++ b/testsuite/tests/dph/primespj/Makefile @@ -0,0 +1,3 @@ +TOP=../../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk diff --git a/testsuite/tests/dph/primespj/PrimesVect.hs b/testsuite/tests/dph/primespj/PrimesVect.hs new file mode 100644 index 0000000000..34b3a568b7 --- /dev/null +++ b/testsuite/tests/dph/primespj/PrimesVect.hs @@ -0,0 +1,25 @@ +{-# LANGUAGE ParallelArrays #-} +{-# OPTIONS -fvectorise #-} +module PrimesVect (primesVect) + +where +import Data.Array.Parallel +import Data.Array.Parallel.Prelude.Int +import qualified Prelude + +primesVect:: Int -> PArray Int +primesVect n = toPArrayP (primesVect' n) + +primesVect':: Int -> [:Int:] +primesVect' n + | n == 1 = emptyP + | n == 2 = singletonP 2 + | otherwise = sps +:+ [: i | i <- enumFromToP (sq+1) n, notMultiple sps i:] + where + + sps = primesVect' sq + sq = sqrt n + + notMultiple :: [:Int:] -> Int -> Bool + notMultiple ps i = andP [: mod i p /= 0 | p <- ps:] + diff --git a/testsuite/tests/dph/primespj/dph-primespj-fast.stdout b/testsuite/tests/dph/primespj/dph-primespj-fast.stdout new file mode 100644 index 0000000000..d935f68b11 --- /dev/null +++ b/testsuite/tests/dph/primespj/dph-primespj-fast.stdout @@ -0,0 +1,3 @@ +[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997] +[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997] +True diff --git a/testsuite/tests/dph/primespj/dph-primespj-opt.stdout b/testsuite/tests/dph/primespj/dph-primespj-opt.stdout new file mode 100644 index 0000000000..d935f68b11 --- /dev/null +++ b/testsuite/tests/dph/primespj/dph-primespj-opt.stdout @@ -0,0 +1,3 @@ +[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997] +[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997] +True diff --git a/testsuite/tests/dph/primespj/dph-primespj.T b/testsuite/tests/dph/primespj/dph-primespj.T new file mode 100644 index 0000000000..458490456b --- /dev/null +++ b/testsuite/tests/dph/primespj/dph-primespj.T @@ -0,0 +1,20 @@ + +test ('dph-primespj-opt' + , [ alone + , skip_if_fast + , reqlib('dph-par') + , reqlib('dph-prim-par') + , only_ways(['normal', 'threaded1', 'threaded2']) ] + , multimod_compile_and_run + , [ 'Main' + , '-Odph -fdph-par']) + +test ('dph-primespj-fast' + , [ reqlib('dph-par') + , reqlib('dph-prim-par') + , only_ways(['normal', 'threaded1', 'threaded2']) ] + , multimod_compile_and_run + , [ 'Main' + , '-O -fno-enable-rewrite-rules -fdph-par']) + + diff --git a/testsuite/tests/dph/quickhull/Main.hs b/testsuite/tests/dph/quickhull/Main.hs new file mode 100644 index 0000000000..ec59390850 --- /dev/null +++ b/testsuite/tests/dph/quickhull/Main.hs @@ -0,0 +1,43 @@ + +import qualified Types as QH +import QuickHullVect (quickhull) + +import qualified Data.Array.Parallel.Unlifted as U +import qualified Data.Array.Parallel.Prelude as P + +import qualified Data.Array.Parallel.PArray as P +import Data.Array.Parallel.PArray (PArray) + +import System.Environment +import Data.List + +import SVG +import TestData + + +----- +runQuickhull :: PArray QH.Point -> [(Double, Double)] +runQuickhull pts + = let result = quickhull pts + resxs = P.toUArrPA (QH.xsOf result) + resys = P.toUArrPA (QH.ysOf result) + in resxs U.!: 0 `seq` (zip (U.toList resxs) (U.toList resys)) + + +-- Main Program --------------------------------------------------------------- +main + = do args <- getArgs + let n = case args of + [s] -> read s + _ -> 1000 + + paInput <- toPArrayPoints + $ genPointsCombo n + + let psHull = runQuickhull paInput + psInput = P.toList paInput + + putStr + $ makeSVG + (roundPoints psInput) + (roundPoints psHull) diff --git a/testsuite/tests/dph/quickhull/Makefile b/testsuite/tests/dph/quickhull/Makefile new file mode 100644 index 0000000000..9101fbd40a --- /dev/null +++ b/testsuite/tests/dph/quickhull/Makefile @@ -0,0 +1,3 @@ +TOP=../../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk diff --git a/testsuite/tests/dph/quickhull/QuickHullVect.hs b/testsuite/tests/dph/quickhull/QuickHullVect.hs new file mode 100644 index 0000000000..29aaa4a823 --- /dev/null +++ b/testsuite/tests/dph/quickhull/QuickHullVect.hs @@ -0,0 +1,41 @@ +{-# LANGUAGE ParallelArrays #-} +{-# OPTIONS -fvectorise #-} + +module QuickHullVect (quickhull) where + +import Types + +import Data.Array.Parallel +import Data.Array.Parallel.Prelude.Double +import qualified Data.Array.Parallel.Prelude.Int as Int + +import qualified Prelude as P + +distance :: Point -> Line -> Double +distance (xo, yo) ((x1, y1), (x2, y2)) + = (x1-xo) * (y2 - yo) - (y1 - yo) * (x2 - xo) + +hsplit :: [:Point:] -> Line -> [:Point:] +hsplit points line@(p1, p2) + | lengthP packed Int.< 2 = singletonP p1 +:+ packed + | otherwise + = concatP [: hsplit packed ends | ends <- [:(p1, pm), (pm, p2):] :] + where + cross = [: distance p line | p <- points :] + packed = [: p | (p,c) <- zipP points cross, c > 0.0 :] + pm = points !: maxIndexP cross + +quickHull' :: [:Point:] -> [:Point:] +quickHull' points + | lengthP points Int.== 0 = points + | otherwise + = concatP [: hsplit points ends | ends <- [: (minx, maxx), (maxx, minx) :] :] + where + xs = [: x | (x, y) <- points :] + minx = points !: minIndexP xs + maxx = points !: maxIndexP xs + +quickhull :: PArray Point -> PArray Point +{-# NOINLINE quickhull #-} +quickhull ps = toPArrayP (quickHull' (fromPArrayP ps)) + diff --git a/testsuite/tests/dph/quickhull/SVG.hs b/testsuite/tests/dph/quickhull/SVG.hs new file mode 100644 index 0000000000..f4183a77d6 --- /dev/null +++ b/testsuite/tests/dph/quickhull/SVG.hs @@ -0,0 +1,34 @@ + +module SVG where + +-- Making a SVG diagram of the points and hull +makeSVG :: [(Int, Int)] -> [(Int, Int)] -> String +makeSVG points hull + = unlines + $ [ "<svg width=\"100%\" height=\"100%\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">" ] + ++ [svgPolygon hull] + ++ map svgPoint points + ++ map svgPointHull hull + ++ ["</svg>"] + +svgPolygon :: [(Int, Int)] -> String +svgPolygon points + = "<polygon" + ++ " points=\"" ++ (concat [show x ++ "," ++ show y ++ " " | (x, y) <- points]) ++ "\"" + ++ " style=\"fill:#d0d0ff;stroke:#000000;stroke-width:1\"" + ++ "/>" + +svgPoint :: (Int, Int) -> String +svgPoint (x, y) + = "<circle cx=\"" ++ show x ++ "\" cy=\"" ++ show y ++ "\" r=\"0.5\"" + ++ " style=\"stroke:#000000\"" + ++ "/>" + +svgPointHull :: (Int, Int) -> String +svgPointHull (x, y) + = "<circle cx=\"" ++ show x ++ "\" cy=\"" ++ show y ++ "\" r=\"1\"" + ++ " style=\"stroke:#ff0000\"" + ++ "/>" + +roundPoints :: [(Double, Double)] -> [(Int, Int)] +roundPoints ps = [(round x, round y) | (x, y) <- ps] diff --git a/testsuite/tests/dph/quickhull/TestData.hs b/testsuite/tests/dph/quickhull/TestData.hs new file mode 100644 index 0000000000..6317927259 --- /dev/null +++ b/testsuite/tests/dph/quickhull/TestData.hs @@ -0,0 +1,92 @@ + +module TestData + ( genPointsUniform + , genPointsDisc + , genPointsCombo + , toPArrayPoints ) +where + +import qualified Types as QH +import qualified Data.Array.Parallel.Unlifted as U +import qualified Data.Array.Parallel.Prelude as P +import qualified Data.Array.Parallel.Prelude.Double as D +import qualified Data.Array.Parallel.PArray as P +import Data.Array.Parallel.PArray (PArray) + +import System.Random +import Control.Exception + +-- Random points generation +-- IMPORTANT: We use the same seed with the same random generator in all +-- quickhull codes. The asymptotic work complexity of quickhull +-- is between O (N) and O (N^2) depending on the input. +-- To compare benchmark results, they always need to use the same +-- input. +seed = 42742 + +-- | Some uniformly distributed points +genPointsUniform + :: Int -- ^ number of points + -> Double -- ^ minimum coordinate + -> Double -- ^ maximum coordinate + -> [(Double, Double)] + +genPointsUniform n minXY maxXY + = let + pointMin = 10 + pointMax = 510 + gen = mkStdGen seed + in toPairs $ take (2*n) $ randomRs (pointMin, pointMax) gen + +toPairs [] = [] +toPairs (x:y:pts) = (x, y) : toPairs pts + + +-- | Some points distributed as a disc +genPointsDisc + :: Int -- ^ number of points + -> (Double, Double) -- ^ center of disc + -> Double -- ^ radius of disc + -> [(Double, Double)] + +genPointsDisc n (originX, originY) radiusMax + = let (genRadius, genAngle) + = split $ mkStdGen seed + + radius = take n $ randomRs (0, radiusMax) genRadius + angle = take n $ randomRs (- pi, pi) genAngle + + makeXY (r, a) + = ( originX + r * cos a + , originY + r * sin a) + + in map makeXY $ zip radius angle + + +-- | A point cloud with areas of high an low density +genPointsCombo + :: Int -- ^ number of points + -> [(Double, Double)] + +genPointsCombo n + = genPointsDisc (n `div` 5) (250, 250) 200 + ++ genPointsDisc (n `div` 5) (100, 100) 80 + ++ genPointsDisc (n `div` 5) (150, 300) 30 + ++ genPointsDisc (n `div` 5) (500, 120) 30 + ++ genPointsDisc (n `div` 5) (300, 200) 150 + + +-- | Convert a list of points to a PArray +toPArrayPoints :: [(Double, Double)] -> IO (PArray QH.Point) +toPArrayPoints ps + = do let pts = QH.points (P.fromList (map fst ps)) + (P.fromList (map snd ps)) + evaluate $ force pts + return pts + +-- | Force points to be evaluated +force pts + = P.toUArrPA (QH.xsOf pts) U.!: 0 D.+ + P.toUArrPA (QH.ysOf pts) U.!: 0 + + diff --git a/testsuite/tests/dph/quickhull/Types.hs b/testsuite/tests/dph/quickhull/Types.hs new file mode 100644 index 0000000000..162458f424 --- /dev/null +++ b/testsuite/tests/dph/quickhull/Types.hs @@ -0,0 +1,32 @@ +{-# LANGUAGE ParallelArrays #-} +{-# OPTIONS -fvectorise #-} + +module Types ( Point, Line, points, xsOf, ysOf) where + +import Data.Array.Parallel + +type Point = (Double, Double) +type Line = (Point, Point) + +points' :: [:Double:] -> [:Double:] -> [:Point:] +points' = zipP + +points :: PArray Double -> PArray Double -> PArray Point +{-# NOINLINE points #-} +points xs ys = toPArrayP (points' (fromPArrayP xs) (fromPArrayP ys)) + +xsOf' :: [:Point:] -> [:Double:] +xsOf' ps = [: x | (x, _) <- ps :] + +xsOf :: PArray Point -> PArray Double +{-# NOINLINE xsOf #-} +xsOf ps = toPArrayP (xsOf' (fromPArrayP ps)) + +ysOf' :: [:Point:] -> [:Double:] +ysOf' ps = [: y | (_, y) <- ps :] + +ysOf :: PArray Point -> PArray Double +{-# NOINLINE ysOf #-} +ysOf ps = toPArrayP (ysOf' (fromPArrayP ps)) + + diff --git a/testsuite/tests/dph/quickhull/dph-quickhull-fast.stdout b/testsuite/tests/dph/quickhull/dph-quickhull-fast.stdout new file mode 100644 index 0000000000..f6b2d92e9a --- /dev/null +++ b/testsuite/tests/dph/quickhull/dph-quickhull-fast.stdout @@ -0,0 +1,1019 @@ +<svg width="100%" height="100%" version="1.1" xmlns="http://www.w3.org/2000/svg"> +<polygon points="20,98 50,246 83,354 164,416 236,434 343,427 366,412 379,402 519,143 528,126 529,115 510,96 506,95 117,33 85,28 40,64 " style="fill:#d0d0ff;stroke:#000000;stroke-width:1"/> +<circle cx="217" cy="201" r="0.5" style="stroke:#000000"/> +<circle cx="310" cy="266" r="0.5" style="stroke:#000000"/> +<circle cx="191" cy="353" r="0.5" style="stroke:#000000"/> +<circle cx="164" cy="416" r="0.5" style="stroke:#000000"/> +<circle cx="232" cy="257" r="0.5" style="stroke:#000000"/> +<circle cx="266" cy="398" r="0.5" style="stroke:#000000"/> +<circle cx="350" cy="201" r="0.5" style="stroke:#000000"/> +<circle cx="334" cy="202" r="0.5" style="stroke:#000000"/> +<circle cx="189" cy="151" r="0.5" style="stroke:#000000"/> +<circle cx="308" cy="307" r="0.5" style="stroke:#000000"/> +<circle cx="347" cy="160" r="0.5" style="stroke:#000000"/> +<circle cx="251" cy="251" r="0.5" style="stroke:#000000"/> +<circle cx="275" cy="241" r="0.5" style="stroke:#000000"/> +<circle cx="275" cy="398" r="0.5" style="stroke:#000000"/> +<circle cx="167" cy="292" r="0.5" style="stroke:#000000"/> +<circle cx="351" cy="397" r="0.5" style="stroke:#000000"/> +<circle cx="257" cy="254" r="0.5" style="stroke:#000000"/> +<circle cx="248" cy="220" r="0.5" style="stroke:#000000"/> +<circle cx="250" cy="252" r="0.5" style="stroke:#000000"/> +<circle cx="191" cy="222" r="0.5" style="stroke:#000000"/> +<circle cx="93" cy="200" r="0.5" style="stroke:#000000"/> +<circle cx="155" cy="195" r="0.5" style="stroke:#000000"/> +<circle cx="287" cy="84" r="0.5" style="stroke:#000000"/> +<circle cx="90" cy="198" r="0.5" style="stroke:#000000"/> +<circle cx="149" cy="175" r="0.5" style="stroke:#000000"/> +<circle cx="342" cy="311" r="0.5" style="stroke:#000000"/> +<circle cx="391" cy="360" r="0.5" style="stroke:#000000"/> +<circle cx="277" cy="310" r="0.5" style="stroke:#000000"/> +<circle cx="341" cy="421" r="0.5" style="stroke:#000000"/> +<circle cx="274" cy="136" r="0.5" style="stroke:#000000"/> +<circle cx="187" cy="278" r="0.5" style="stroke:#000000"/> +<circle cx="343" cy="427" r="0.5" style="stroke:#000000"/> +<circle cx="255" cy="170" r="0.5" style="stroke:#000000"/> +<circle cx="158" cy="329" r="0.5" style="stroke:#000000"/> +<circle cx="306" cy="196" r="0.5" style="stroke:#000000"/> +<circle cx="315" cy="261" r="0.5" style="stroke:#000000"/> +<circle cx="214" cy="361" r="0.5" style="stroke:#000000"/> +<circle cx="306" cy="304" r="0.5" style="stroke:#000000"/> +<circle cx="229" cy="219" r="0.5" style="stroke:#000000"/> +<circle cx="227" cy="351" r="0.5" style="stroke:#000000"/> +<circle cx="228" cy="196" r="0.5" style="stroke:#000000"/> +<circle cx="314" cy="280" r="0.5" style="stroke:#000000"/> +<circle cx="209" cy="195" r="0.5" style="stroke:#000000"/> +<circle cx="367" cy="217" r="0.5" style="stroke:#000000"/> +<circle cx="176" cy="212" r="0.5" style="stroke:#000000"/> +<circle cx="117" cy="194" r="0.5" style="stroke:#000000"/> +<circle cx="318" cy="116" r="0.5" style="stroke:#000000"/> +<circle cx="250" cy="251" r="0.5" style="stroke:#000000"/> +<circle cx="355" cy="406" r="0.5" style="stroke:#000000"/> +<circle cx="252" cy="246" r="0.5" style="stroke:#000000"/> +<circle cx="219" cy="299" r="0.5" style="stroke:#000000"/> +<circle cx="217" cy="232" r="0.5" style="stroke:#000000"/> +<circle cx="283" cy="220" r="0.5" style="stroke:#000000"/> +<circle cx="239" cy="207" r="0.5" style="stroke:#000000"/> +<circle cx="266" cy="255" r="0.5" style="stroke:#000000"/> +<circle cx="310" cy="324" r="0.5" style="stroke:#000000"/> +<circle cx="200" cy="248" r="0.5" style="stroke:#000000"/> +<circle cx="387" cy="360" r="0.5" style="stroke:#000000"/> +<circle cx="147" cy="186" r="0.5" style="stroke:#000000"/> +<circle cx="126" cy="236" r="0.5" style="stroke:#000000"/> +<circle cx="257" cy="300" r="0.5" style="stroke:#000000"/> +<circle cx="255" cy="250" r="0.5" style="stroke:#000000"/> +<circle cx="50" cy="246" r="0.5" style="stroke:#000000"/> +<circle cx="231" cy="340" r="0.5" style="stroke:#000000"/> +<circle cx="189" cy="287" r="0.5" style="stroke:#000000"/> +<circle cx="188" cy="186" r="0.5" style="stroke:#000000"/> +<circle cx="366" cy="412" r="0.5" style="stroke:#000000"/> +<circle cx="183" cy="139" r="0.5" style="stroke:#000000"/> +<circle cx="305" cy="113" r="0.5" style="stroke:#000000"/> +<circle cx="286" cy="146" r="0.5" style="stroke:#000000"/> +<circle cx="399" cy="241" r="0.5" style="stroke:#000000"/> +<circle cx="289" cy="404" r="0.5" style="stroke:#000000"/> +<circle cx="346" cy="157" r="0.5" style="stroke:#000000"/> +<circle cx="287" cy="143" r="0.5" style="stroke:#000000"/> +<circle cx="223" cy="236" r="0.5" style="stroke:#000000"/> +<circle cx="181" cy="159" r="0.5" style="stroke:#000000"/> +<circle cx="134" cy="249" r="0.5" style="stroke:#000000"/> +<circle cx="238" cy="274" r="0.5" style="stroke:#000000"/> +<circle cx="246" cy="250" r="0.5" style="stroke:#000000"/> +<circle cx="201" cy="395" r="0.5" style="stroke:#000000"/> +<circle cx="192" cy="116" r="0.5" style="stroke:#000000"/> +<circle cx="260" cy="296" r="0.5" style="stroke:#000000"/> +<circle cx="244" cy="399" r="0.5" style="stroke:#000000"/> +<circle cx="256" cy="303" r="0.5" style="stroke:#000000"/> +<circle cx="202" cy="221" r="0.5" style="stroke:#000000"/> +<circle cx="361" cy="406" r="0.5" style="stroke:#000000"/> +<circle cx="275" cy="235" r="0.5" style="stroke:#000000"/> +<circle cx="180" cy="305" r="0.5" style="stroke:#000000"/> +<circle cx="258" cy="241" r="0.5" style="stroke:#000000"/> +<circle cx="253" cy="237" r="0.5" style="stroke:#000000"/> +<circle cx="239" cy="408" r="0.5" style="stroke:#000000"/> +<circle cx="247" cy="254" r="0.5" style="stroke:#000000"/> +<circle cx="223" cy="265" r="0.5" style="stroke:#000000"/> +<circle cx="244" cy="253" r="0.5" style="stroke:#000000"/> +<circle cx="174" cy="346" r="0.5" style="stroke:#000000"/> +<circle cx="373" cy="334" r="0.5" style="stroke:#000000"/> +<circle cx="292" cy="82" r="0.5" style="stroke:#000000"/> +<circle cx="240" cy="388" r="0.5" style="stroke:#000000"/> +<circle cx="263" cy="225" r="0.5" style="stroke:#000000"/> +<circle cx="252" cy="207" r="0.5" style="stroke:#000000"/> +<circle cx="233" cy="287" r="0.5" style="stroke:#000000"/> +<circle cx="234" cy="245" r="0.5" style="stroke:#000000"/> +<circle cx="285" cy="264" r="0.5" style="stroke:#000000"/> +<circle cx="176" cy="259" r="0.5" style="stroke:#000000"/> +<circle cx="284" cy="256" r="0.5" style="stroke:#000000"/> +<circle cx="233" cy="258" r="0.5" style="stroke:#000000"/> +<circle cx="108" cy="336" r="0.5" style="stroke:#000000"/> +<circle cx="379" cy="402" r="0.5" style="stroke:#000000"/> +<circle cx="260" cy="256" r="0.5" style="stroke:#000000"/> +<circle cx="232" cy="265" r="0.5" style="stroke:#000000"/> +<circle cx="432" cy="286" r="0.5" style="stroke:#000000"/> +<circle cx="347" cy="197" r="0.5" style="stroke:#000000"/> +<circle cx="248" cy="249" r="0.5" style="stroke:#000000"/> +<circle cx="176" cy="213" r="0.5" style="stroke:#000000"/> +<circle cx="330" cy="370" r="0.5" style="stroke:#000000"/> +<circle cx="249" cy="253" r="0.5" style="stroke:#000000"/> +<circle cx="249" cy="243" r="0.5" style="stroke:#000000"/> +<circle cx="119" cy="320" r="0.5" style="stroke:#000000"/> +<circle cx="280" cy="263" r="0.5" style="stroke:#000000"/> +<circle cx="317" cy="287" r="0.5" style="stroke:#000000"/> +<circle cx="304" cy="209" r="0.5" style="stroke:#000000"/> +<circle cx="315" cy="193" r="0.5" style="stroke:#000000"/> +<circle cx="304" cy="109" r="0.5" style="stroke:#000000"/> +<circle cx="119" cy="179" r="0.5" style="stroke:#000000"/> +<circle cx="188" cy="215" r="0.5" style="stroke:#000000"/> +<circle cx="263" cy="218" r="0.5" style="stroke:#000000"/> +<circle cx="196" cy="228" r="0.5" style="stroke:#000000"/> +<circle cx="371" cy="307" r="0.5" style="stroke:#000000"/> +<circle cx="285" cy="263" r="0.5" style="stroke:#000000"/> +<circle cx="130" cy="217" r="0.5" style="stroke:#000000"/> +<circle cx="250" cy="250" r="0.5" style="stroke:#000000"/> +<circle cx="335" cy="201" r="0.5" style="stroke:#000000"/> +<circle cx="211" cy="145" r="0.5" style="stroke:#000000"/> +<circle cx="242" cy="182" r="0.5" style="stroke:#000000"/> +<circle cx="221" cy="256" r="0.5" style="stroke:#000000"/> +<circle cx="177" cy="398" r="0.5" style="stroke:#000000"/> +<circle cx="333" cy="158" r="0.5" style="stroke:#000000"/> +<circle cx="199" cy="297" r="0.5" style="stroke:#000000"/> +<circle cx="342" cy="153" r="0.5" style="stroke:#000000"/> +<circle cx="273" cy="419" r="0.5" style="stroke:#000000"/> +<circle cx="227" cy="173" r="0.5" style="stroke:#000000"/> +<circle cx="169" cy="242" r="0.5" style="stroke:#000000"/> +<circle cx="294" cy="292" r="0.5" style="stroke:#000000"/> +<circle cx="303" cy="155" r="0.5" style="stroke:#000000"/> +<circle cx="211" cy="124" r="0.5" style="stroke:#000000"/> +<circle cx="253" cy="116" r="0.5" style="stroke:#000000"/> +<circle cx="254" cy="246" r="0.5" style="stroke:#000000"/> +<circle cx="377" cy="388" r="0.5" style="stroke:#000000"/> +<circle cx="130" cy="285" r="0.5" style="stroke:#000000"/> +<circle cx="273" cy="215" r="0.5" style="stroke:#000000"/> +<circle cx="438" cy="229" r="0.5" style="stroke:#000000"/> +<circle cx="446" cy="216" r="0.5" style="stroke:#000000"/> +<circle cx="242" cy="238" r="0.5" style="stroke:#000000"/> +<circle cx="224" cy="229" r="0.5" style="stroke:#000000"/> +<circle cx="133" cy="181" r="0.5" style="stroke:#000000"/> +<circle cx="270" cy="222" r="0.5" style="stroke:#000000"/> +<circle cx="275" cy="237" r="0.5" style="stroke:#000000"/> +<circle cx="160" cy="202" r="0.5" style="stroke:#000000"/> +<circle cx="416" cy="302" r="0.5" style="stroke:#000000"/> +<circle cx="366" cy="244" r="0.5" style="stroke:#000000"/> +<circle cx="279" cy="186" r="0.5" style="stroke:#000000"/> +<circle cx="134" cy="353" r="0.5" style="stroke:#000000"/> +<circle cx="99" cy="159" r="0.5" style="stroke:#000000"/> +<circle cx="177" cy="198" r="0.5" style="stroke:#000000"/> +<circle cx="239" cy="253" r="0.5" style="stroke:#000000"/> +<circle cx="298" cy="190" r="0.5" style="stroke:#000000"/> +<circle cx="213" cy="70" r="0.5" style="stroke:#000000"/> +<circle cx="122" cy="236" r="0.5" style="stroke:#000000"/> +<circle cx="318" cy="92" r="0.5" style="stroke:#000000"/> +<circle cx="196" cy="362" r="0.5" style="stroke:#000000"/> +<circle cx="234" cy="235" r="0.5" style="stroke:#000000"/> +<circle cx="250" cy="250" r="0.5" style="stroke:#000000"/> +<circle cx="321" cy="367" r="0.5" style="stroke:#000000"/> +<circle cx="251" cy="249" r="0.5" style="stroke:#000000"/> +<circle cx="141" cy="154" r="0.5" style="stroke:#000000"/> +<circle cx="152" cy="308" r="0.5" style="stroke:#000000"/> +<circle cx="110" cy="178" r="0.5" style="stroke:#000000"/> +<circle cx="229" cy="216" r="0.5" style="stroke:#000000"/> +<circle cx="421" cy="250" r="0.5" style="stroke:#000000"/> +<circle cx="215" cy="269" r="0.5" style="stroke:#000000"/> +<circle cx="131" cy="157" r="0.5" style="stroke:#000000"/> +<circle cx="238" cy="245" r="0.5" style="stroke:#000000"/> +<circle cx="264" cy="224" r="0.5" style="stroke:#000000"/> +<circle cx="79" cy="327" r="0.5" style="stroke:#000000"/> +<circle cx="424" cy="266" r="0.5" style="stroke:#000000"/> +<circle cx="237" cy="232" r="0.5" style="stroke:#000000"/> +<circle cx="142" cy="253" r="0.5" style="stroke:#000000"/> +<circle cx="156" cy="355" r="0.5" style="stroke:#000000"/> +<circle cx="239" cy="239" r="0.5" style="stroke:#000000"/> +<circle cx="238" cy="322" r="0.5" style="stroke:#000000"/> +<circle cx="177" cy="396" r="0.5" style="stroke:#000000"/> +<circle cx="310" cy="152" r="0.5" style="stroke:#000000"/> +<circle cx="83" cy="354" r="0.5" style="stroke:#000000"/> +<circle cx="236" cy="434" r="0.5" style="stroke:#000000"/> +<circle cx="439" cy="287" r="0.5" style="stroke:#000000"/> +<circle cx="173" cy="232" r="0.5" style="stroke:#000000"/> +<circle cx="181" cy="143" r="0.5" style="stroke:#000000"/> +<circle cx="404" cy="232" r="0.5" style="stroke:#000000"/> +<circle cx="173" cy="177" r="0.5" style="stroke:#000000"/> +<circle cx="362" cy="161" r="0.5" style="stroke:#000000"/> +<circle cx="87" cy="81" r="0.5" style="stroke:#000000"/> +<circle cx="124" cy="106" r="0.5" style="stroke:#000000"/> +<circle cx="76" cy="141" r="0.5" style="stroke:#000000"/> +<circle cx="65" cy="166" r="0.5" style="stroke:#000000"/> +<circle cx="93" cy="103" r="0.5" style="stroke:#000000"/> +<circle cx="107" cy="159" r="0.5" style="stroke:#000000"/> +<circle cx="140" cy="80" r="0.5" style="stroke:#000000"/> +<circle cx="134" cy="81" r="0.5" style="stroke:#000000"/> +<circle cx="76" cy="60" r="0.5" style="stroke:#000000"/> +<circle cx="123" cy="123" r="0.5" style="stroke:#000000"/> +<circle cx="139" cy="64" r="0.5" style="stroke:#000000"/> +<circle cx="100" cy="100" r="0.5" style="stroke:#000000"/> +<circle cx="110" cy="96" r="0.5" style="stroke:#000000"/> +<circle cx="110" cy="159" r="0.5" style="stroke:#000000"/> +<circle cx="67" cy="117" r="0.5" style="stroke:#000000"/> +<circle cx="140" cy="159" r="0.5" style="stroke:#000000"/> +<circle cx="103" cy="101" r="0.5" style="stroke:#000000"/> +<circle cx="99" cy="88" r="0.5" style="stroke:#000000"/> +<circle cx="100" cy="101" r="0.5" style="stroke:#000000"/> +<circle cx="76" cy="89" r="0.5" style="stroke:#000000"/> +<circle cx="37" cy="80" r="0.5" style="stroke:#000000"/> +<circle cx="62" cy="78" r="0.5" style="stroke:#000000"/> +<circle cx="115" cy="34" r="0.5" style="stroke:#000000"/> +<circle cx="36" cy="79" r="0.5" style="stroke:#000000"/> +<circle cx="60" cy="70" r="0.5" style="stroke:#000000"/> +<circle cx="137" cy="124" r="0.5" style="stroke:#000000"/> +<circle cx="156" cy="144" r="0.5" style="stroke:#000000"/> +<circle cx="111" cy="124" r="0.5" style="stroke:#000000"/> +<circle cx="137" cy="168" r="0.5" style="stroke:#000000"/> +<circle cx="110" cy="55" r="0.5" style="stroke:#000000"/> +<circle cx="75" cy="111" r="0.5" style="stroke:#000000"/> +<circle cx="137" cy="171" r="0.5" style="stroke:#000000"/> +<circle cx="102" cy="68" r="0.5" style="stroke:#000000"/> +<circle cx="63" cy="131" r="0.5" style="stroke:#000000"/> +<circle cx="122" cy="78" r="0.5" style="stroke:#000000"/> +<circle cx="126" cy="104" r="0.5" style="stroke:#000000"/> +<circle cx="86" cy="144" r="0.5" style="stroke:#000000"/> +<circle cx="123" cy="122" r="0.5" style="stroke:#000000"/> +<circle cx="92" cy="88" r="0.5" style="stroke:#000000"/> +<circle cx="91" cy="140" r="0.5" style="stroke:#000000"/> +<circle cx="91" cy="78" r="0.5" style="stroke:#000000"/> +<circle cx="126" cy="112" r="0.5" style="stroke:#000000"/> +<circle cx="84" cy="78" r="0.5" style="stroke:#000000"/> +<circle cx="147" cy="87" r="0.5" style="stroke:#000000"/> +<circle cx="70" cy="85" r="0.5" style="stroke:#000000"/> +<circle cx="47" cy="77" r="0.5" style="stroke:#000000"/> +<circle cx="127" cy="46" r="0.5" style="stroke:#000000"/> +<circle cx="100" cy="100" r="0.5" style="stroke:#000000"/> +<circle cx="142" cy="163" r="0.5" style="stroke:#000000"/> +<circle cx="101" cy="99" r="0.5" style="stroke:#000000"/> +<circle cx="88" cy="119" r="0.5" style="stroke:#000000"/> +<circle cx="87" cy="93" r="0.5" style="stroke:#000000"/> +<circle cx="113" cy="88" r="0.5" style="stroke:#000000"/> +<circle cx="96" cy="83" r="0.5" style="stroke:#000000"/> +<circle cx="106" cy="102" r="0.5" style="stroke:#000000"/> +<circle cx="124" cy="130" r="0.5" style="stroke:#000000"/> +<circle cx="80" cy="99" r="0.5" style="stroke:#000000"/> +<circle cx="155" cy="144" r="0.5" style="stroke:#000000"/> +<circle cx="59" cy="74" r="0.5" style="stroke:#000000"/> +<circle cx="50" cy="94" r="0.5" style="stroke:#000000"/> +<circle cx="103" cy="120" r="0.5" style="stroke:#000000"/> +<circle cx="102" cy="100" r="0.5" style="stroke:#000000"/> +<circle cx="20" cy="98" r="0.5" style="stroke:#000000"/> +<circle cx="92" cy="136" r="0.5" style="stroke:#000000"/> +<circle cx="75" cy="115" r="0.5" style="stroke:#000000"/> +<circle cx="75" cy="74" r="0.5" style="stroke:#000000"/> +<circle cx="146" cy="165" r="0.5" style="stroke:#000000"/> +<circle cx="73" cy="56" r="0.5" style="stroke:#000000"/> +<circle cx="122" cy="45" r="0.5" style="stroke:#000000"/> +<circle cx="115" cy="59" r="0.5" style="stroke:#000000"/> +<circle cx="160" cy="97" r="0.5" style="stroke:#000000"/> +<circle cx="116" cy="161" r="0.5" style="stroke:#000000"/> +<circle cx="139" cy="63" r="0.5" style="stroke:#000000"/> +<circle cx="115" cy="57" r="0.5" style="stroke:#000000"/> +<circle cx="89" cy="94" r="0.5" style="stroke:#000000"/> +<circle cx="72" cy="64" r="0.5" style="stroke:#000000"/> +<circle cx="53" cy="99" r="0.5" style="stroke:#000000"/> +<circle cx="95" cy="110" r="0.5" style="stroke:#000000"/> +<circle cx="99" cy="100" r="0.5" style="stroke:#000000"/> +<circle cx="81" cy="158" r="0.5" style="stroke:#000000"/> +<circle cx="77" cy="46" r="0.5" style="stroke:#000000"/> +<circle cx="104" cy="118" r="0.5" style="stroke:#000000"/> +<circle cx="98" cy="160" r="0.5" style="stroke:#000000"/> +<circle cx="102" cy="121" r="0.5" style="stroke:#000000"/> +<circle cx="81" cy="88" r="0.5" style="stroke:#000000"/> +<circle cx="145" cy="163" r="0.5" style="stroke:#000000"/> +<circle cx="110" cy="94" r="0.5" style="stroke:#000000"/> +<circle cx="72" cy="122" r="0.5" style="stroke:#000000"/> +<circle cx="103" cy="96" r="0.5" style="stroke:#000000"/> +<circle cx="101" cy="95" r="0.5" style="stroke:#000000"/> +<circle cx="95" cy="163" r="0.5" style="stroke:#000000"/> +<circle cx="99" cy="101" r="0.5" style="stroke:#000000"/> +<circle cx="89" cy="106" r="0.5" style="stroke:#000000"/> +<circle cx="98" cy="101" r="0.5" style="stroke:#000000"/> +<circle cx="70" cy="138" r="0.5" style="stroke:#000000"/> +<circle cx="149" cy="134" r="0.5" style="stroke:#000000"/> +<circle cx="117" cy="33" r="0.5" style="stroke:#000000"/> +<circle cx="96" cy="155" r="0.5" style="stroke:#000000"/> +<circle cx="105" cy="90" r="0.5" style="stroke:#000000"/> +<circle cx="101" cy="83" r="0.5" style="stroke:#000000"/> +<circle cx="93" cy="115" r="0.5" style="stroke:#000000"/> +<circle cx="94" cy="98" r="0.5" style="stroke:#000000"/> +<circle cx="114" cy="105" r="0.5" style="stroke:#000000"/> +<circle cx="70" cy="103" r="0.5" style="stroke:#000000"/> +<circle cx="114" cy="103" r="0.5" style="stroke:#000000"/> +<circle cx="93" cy="103" r="0.5" style="stroke:#000000"/> +<circle cx="43" cy="135" r="0.5" style="stroke:#000000"/> +<circle cx="152" cy="161" r="0.5" style="stroke:#000000"/> +<circle cx="104" cy="102" r="0.5" style="stroke:#000000"/> +<circle cx="93" cy="106" r="0.5" style="stroke:#000000"/> +<circle cx="173" cy="115" r="0.5" style="stroke:#000000"/> +<circle cx="139" cy="79" r="0.5" style="stroke:#000000"/> +<circle cx="99" cy="99" r="0.5" style="stroke:#000000"/> +<circle cx="70" cy="85" r="0.5" style="stroke:#000000"/> +<circle cx="132" cy="148" r="0.5" style="stroke:#000000"/> +<circle cx="99" cy="101" r="0.5" style="stroke:#000000"/> +<circle cx="100" cy="97" r="0.5" style="stroke:#000000"/> +<circle cx="47" cy="128" r="0.5" style="stroke:#000000"/> +<circle cx="112" cy="105" r="0.5" style="stroke:#000000"/> +<circle cx="127" cy="115" r="0.5" style="stroke:#000000"/> +<circle cx="122" cy="84" r="0.5" style="stroke:#000000"/> +<circle cx="126" cy="77" r="0.5" style="stroke:#000000"/> +<circle cx="121" cy="44" r="0.5" style="stroke:#000000"/> +<circle cx="48" cy="72" r="0.5" style="stroke:#000000"/> +<circle cx="75" cy="86" r="0.5" style="stroke:#000000"/> +<circle cx="105" cy="87" r="0.5" style="stroke:#000000"/> +<circle cx="79" cy="91" r="0.5" style="stroke:#000000"/> +<circle cx="148" cy="123" r="0.5" style="stroke:#000000"/> +<circle cx="114" cy="105" r="0.5" style="stroke:#000000"/> +<circle cx="52" cy="87" r="0.5" style="stroke:#000000"/> +<circle cx="100" cy="100" r="0.5" style="stroke:#000000"/> +<circle cx="134" cy="80" r="0.5" style="stroke:#000000"/> +<circle cx="84" cy="58" r="0.5" style="stroke:#000000"/> +<circle cx="97" cy="73" r="0.5" style="stroke:#000000"/> +<circle cx="88" cy="102" r="0.5" style="stroke:#000000"/> +<circle cx="71" cy="159" r="0.5" style="stroke:#000000"/> +<circle cx="133" cy="63" r="0.5" style="stroke:#000000"/> +<circle cx="80" cy="119" r="0.5" style="stroke:#000000"/> +<circle cx="137" cy="61" r="0.5" style="stroke:#000000"/> +<circle cx="109" cy="168" r="0.5" style="stroke:#000000"/> +<circle cx="91" cy="69" r="0.5" style="stroke:#000000"/> +<circle cx="68" cy="97" r="0.5" style="stroke:#000000"/> +<circle cx="117" cy="117" r="0.5" style="stroke:#000000"/> +<circle cx="121" cy="62" r="0.5" style="stroke:#000000"/> +<circle cx="84" cy="50" r="0.5" style="stroke:#000000"/> +<circle cx="101" cy="46" r="0.5" style="stroke:#000000"/> +<circle cx="102" cy="98" r="0.5" style="stroke:#000000"/> +<circle cx="151" cy="155" r="0.5" style="stroke:#000000"/> +<circle cx="52" cy="114" r="0.5" style="stroke:#000000"/> +<circle cx="109" cy="86" r="0.5" style="stroke:#000000"/> +<circle cx="175" cy="91" r="0.5" style="stroke:#000000"/> +<circle cx="178" cy="87" r="0.5" style="stroke:#000000"/> +<circle cx="97" cy="95" r="0.5" style="stroke:#000000"/> +<circle cx="90" cy="92" r="0.5" style="stroke:#000000"/> +<circle cx="53" cy="72" r="0.5" style="stroke:#000000"/> +<circle cx="108" cy="89" r="0.5" style="stroke:#000000"/> +<circle cx="110" cy="95" r="0.5" style="stroke:#000000"/> +<circle cx="64" cy="81" r="0.5" style="stroke:#000000"/> +<circle cx="166" cy="121" r="0.5" style="stroke:#000000"/> +<circle cx="146" cy="97" r="0.5" style="stroke:#000000"/> +<circle cx="112" cy="74" r="0.5" style="stroke:#000000"/> +<circle cx="54" cy="141" r="0.5" style="stroke:#000000"/> +<circle cx="40" cy="64" r="0.5" style="stroke:#000000"/> +<circle cx="71" cy="79" r="0.5" style="stroke:#000000"/> +<circle cx="96" cy="101" r="0.5" style="stroke:#000000"/> +<circle cx="119" cy="76" r="0.5" style="stroke:#000000"/> +<circle cx="85" cy="28" r="0.5" style="stroke:#000000"/> +<circle cx="49" cy="94" r="0.5" style="stroke:#000000"/> +<circle cx="127" cy="37" r="0.5" style="stroke:#000000"/> +<circle cx="78" cy="145" r="0.5" style="stroke:#000000"/> +<circle cx="94" cy="94" r="0.5" style="stroke:#000000"/> +<circle cx="100" cy="100" r="0.5" style="stroke:#000000"/> +<circle cx="128" cy="147" r="0.5" style="stroke:#000000"/> +<circle cx="101" cy="100" r="0.5" style="stroke:#000000"/> +<circle cx="56" cy="62" r="0.5" style="stroke:#000000"/> +<circle cx="61" cy="123" r="0.5" style="stroke:#000000"/> +<circle cx="44" cy="71" r="0.5" style="stroke:#000000"/> +<circle cx="92" cy="86" r="0.5" style="stroke:#000000"/> +<circle cx="169" cy="100" r="0.5" style="stroke:#000000"/> +<circle cx="86" cy="107" r="0.5" style="stroke:#000000"/> +<circle cx="52" cy="63" r="0.5" style="stroke:#000000"/> +<circle cx="95" cy="98" r="0.5" style="stroke:#000000"/> +<circle cx="106" cy="89" r="0.5" style="stroke:#000000"/> +<circle cx="32" cy="131" r="0.5" style="stroke:#000000"/> +<circle cx="170" cy="106" r="0.5" style="stroke:#000000"/> +<circle cx="95" cy="93" r="0.5" style="stroke:#000000"/> +<circle cx="57" cy="101" r="0.5" style="stroke:#000000"/> +<circle cx="62" cy="142" r="0.5" style="stroke:#000000"/> +<circle cx="95" cy="95" r="0.5" style="stroke:#000000"/> +<circle cx="95" cy="129" r="0.5" style="stroke:#000000"/> +<circle cx="71" cy="158" r="0.5" style="stroke:#000000"/> +<circle cx="124" cy="61" r="0.5" style="stroke:#000000"/> +<circle cx="33" cy="142" r="0.5" style="stroke:#000000"/> +<circle cx="94" cy="174" r="0.5" style="stroke:#000000"/> +<circle cx="176" cy="115" r="0.5" style="stroke:#000000"/> +<circle cx="69" cy="93" r="0.5" style="stroke:#000000"/> +<circle cx="73" cy="57" r="0.5" style="stroke:#000000"/> +<circle cx="162" cy="93" r="0.5" style="stroke:#000000"/> +<circle cx="69" cy="71" r="0.5" style="stroke:#000000"/> +<circle cx="145" cy="64" r="0.5" style="stroke:#000000"/> +<circle cx="145" cy="293" r="0.5" style="stroke:#000000"/> +<circle cx="159" cy="302" r="0.5" style="stroke:#000000"/> +<circle cx="141" cy="315" r="0.5" style="stroke:#000000"/> +<circle cx="137" cy="325" r="0.5" style="stroke:#000000"/> +<circle cx="147" cy="301" r="0.5" style="stroke:#000000"/> +<circle cx="152" cy="322" r="0.5" style="stroke:#000000"/> +<circle cx="165" cy="293" r="0.5" style="stroke:#000000"/> +<circle cx="163" cy="293" r="0.5" style="stroke:#000000"/> +<circle cx="141" cy="285" r="0.5" style="stroke:#000000"/> +<circle cx="159" cy="309" r="0.5" style="stroke:#000000"/> +<circle cx="164" cy="287" r="0.5" style="stroke:#000000"/> +<circle cx="150" cy="300" r="0.5" style="stroke:#000000"/> +<circle cx="154" cy="299" r="0.5" style="stroke:#000000"/> +<circle cx="154" cy="322" r="0.5" style="stroke:#000000"/> +<circle cx="138" cy="306" r="0.5" style="stroke:#000000"/> +<circle cx="165" cy="322" r="0.5" style="stroke:#000000"/> +<circle cx="151" cy="301" r="0.5" style="stroke:#000000"/> +<circle cx="150" cy="295" r="0.5" style="stroke:#000000"/> +<circle cx="150" cy="300" r="0.5" style="stroke:#000000"/> +<circle cx="141" cy="296" r="0.5" style="stroke:#000000"/> +<circle cx="126" cy="292" r="0.5" style="stroke:#000000"/> +<circle cx="136" cy="292" r="0.5" style="stroke:#000000"/> +<circle cx="156" cy="275" r="0.5" style="stroke:#000000"/> +<circle cx="126" cy="292" r="0.5" style="stroke:#000000"/> +<circle cx="135" cy="289" r="0.5" style="stroke:#000000"/> +<circle cx="164" cy="309" r="0.5" style="stroke:#000000"/> +<circle cx="171" cy="316" r="0.5" style="stroke:#000000"/> +<circle cx="154" cy="309" r="0.5" style="stroke:#000000"/> +<circle cx="164" cy="326" r="0.5" style="stroke:#000000"/> +<circle cx="154" cy="283" r="0.5" style="stroke:#000000"/> +<circle cx="141" cy="304" r="0.5" style="stroke:#000000"/> +<circle cx="164" cy="326" r="0.5" style="stroke:#000000"/> +<circle cx="151" cy="288" r="0.5" style="stroke:#000000"/> +<circle cx="136" cy="312" r="0.5" style="stroke:#000000"/> +<circle cx="158" cy="292" r="0.5" style="stroke:#000000"/> +<circle cx="160" cy="302" r="0.5" style="stroke:#000000"/> +<circle cx="145" cy="317" r="0.5" style="stroke:#000000"/> +<circle cx="158" cy="308" r="0.5" style="stroke:#000000"/> +<circle cx="147" cy="295" r="0.5" style="stroke:#000000"/> +<circle cx="147" cy="315" r="0.5" style="stroke:#000000"/> +<circle cx="147" cy="292" r="0.5" style="stroke:#000000"/> +<circle cx="160" cy="304" r="0.5" style="stroke:#000000"/> +<circle cx="144" cy="292" r="0.5" style="stroke:#000000"/> +<circle cx="168" cy="295" r="0.5" style="stroke:#000000"/> +<circle cx="139" cy="294" r="0.5" style="stroke:#000000"/> +<circle cx="130" cy="292" r="0.5" style="stroke:#000000"/> +<circle cx="160" cy="280" r="0.5" style="stroke:#000000"/> +<circle cx="150" cy="300" r="0.5" style="stroke:#000000"/> +<circle cx="166" cy="323" r="0.5" style="stroke:#000000"/> +<circle cx="150" cy="299" r="0.5" style="stroke:#000000"/> +<circle cx="145" cy="307" r="0.5" style="stroke:#000000"/> +<circle cx="145" cy="297" r="0.5" style="stroke:#000000"/> +<circle cx="155" cy="296" r="0.5" style="stroke:#000000"/> +<circle cx="148" cy="294" r="0.5" style="stroke:#000000"/> +<circle cx="152" cy="301" r="0.5" style="stroke:#000000"/> +<circle cx="159" cy="311" r="0.5" style="stroke:#000000"/> +<circle cx="142" cy="300" r="0.5" style="stroke:#000000"/> +<circle cx="171" cy="317" r="0.5" style="stroke:#000000"/> +<circle cx="135" cy="290" r="0.5" style="stroke:#000000"/> +<circle cx="131" cy="298" r="0.5" style="stroke:#000000"/> +<circle cx="151" cy="307" r="0.5" style="stroke:#000000"/> +<circle cx="151" cy="300" r="0.5" style="stroke:#000000"/> +<circle cx="120" cy="299" r="0.5" style="stroke:#000000"/> +<circle cx="147" cy="314" r="0.5" style="stroke:#000000"/> +<circle cx="141" cy="305" r="0.5" style="stroke:#000000"/> +<circle cx="141" cy="290" r="0.5" style="stroke:#000000"/> +<circle cx="167" cy="324" r="0.5" style="stroke:#000000"/> +<circle cx="140" cy="283" r="0.5" style="stroke:#000000"/> +<circle cx="158" cy="279" r="0.5" style="stroke:#000000"/> +<circle cx="155" cy="284" r="0.5" style="stroke:#000000"/> +<circle cx="172" cy="299" r="0.5" style="stroke:#000000"/> +<circle cx="156" cy="323" r="0.5" style="stroke:#000000"/> +<circle cx="164" cy="286" r="0.5" style="stroke:#000000"/> +<circle cx="156" cy="284" r="0.5" style="stroke:#000000"/> +<circle cx="146" cy="298" r="0.5" style="stroke:#000000"/> +<circle cx="140" cy="286" r="0.5" style="stroke:#000000"/> +<circle cx="133" cy="300" r="0.5" style="stroke:#000000"/> +<circle cx="148" cy="304" r="0.5" style="stroke:#000000"/> +<circle cx="149" cy="300" r="0.5" style="stroke:#000000"/> +<circle cx="143" cy="322" r="0.5" style="stroke:#000000"/> +<circle cx="141" cy="280" r="0.5" style="stroke:#000000"/> +<circle cx="152" cy="307" r="0.5" style="stroke:#000000"/> +<circle cx="149" cy="322" r="0.5" style="stroke:#000000"/> +<circle cx="151" cy="308" r="0.5" style="stroke:#000000"/> +<circle cx="143" cy="296" r="0.5" style="stroke:#000000"/> +<circle cx="167" cy="323" r="0.5" style="stroke:#000000"/> +<circle cx="154" cy="298" r="0.5" style="stroke:#000000"/> +<circle cx="139" cy="308" r="0.5" style="stroke:#000000"/> +<circle cx="151" cy="299" r="0.5" style="stroke:#000000"/> +<circle cx="150" cy="298" r="0.5" style="stroke:#000000"/> +<circle cx="148" cy="324" r="0.5" style="stroke:#000000"/> +<circle cx="150" cy="301" r="0.5" style="stroke:#000000"/> +<circle cx="146" cy="302" r="0.5" style="stroke:#000000"/> +<circle cx="149" cy="300" r="0.5" style="stroke:#000000"/> +<circle cx="139" cy="314" r="0.5" style="stroke:#000000"/> +<circle cx="168" cy="313" r="0.5" style="stroke:#000000"/> +<circle cx="156" cy="275" r="0.5" style="stroke:#000000"/> +<circle cx="148" cy="321" r="0.5" style="stroke:#000000"/> +<circle cx="152" cy="296" r="0.5" style="stroke:#000000"/> +<circle cx="150" cy="294" r="0.5" style="stroke:#000000"/> +<circle cx="147" cy="305" r="0.5" style="stroke:#000000"/> +<circle cx="148" cy="299" r="0.5" style="stroke:#000000"/> +<circle cx="155" cy="302" r="0.5" style="stroke:#000000"/> +<circle cx="139" cy="301" r="0.5" style="stroke:#000000"/> +<circle cx="155" cy="301" r="0.5" style="stroke:#000000"/> +<circle cx="147" cy="301" r="0.5" style="stroke:#000000"/> +<circle cx="129" cy="313" r="0.5" style="stroke:#000000"/> +<circle cx="169" cy="323" r="0.5" style="stroke:#000000"/> +<circle cx="151" cy="301" r="0.5" style="stroke:#000000"/> +<circle cx="147" cy="302" r="0.5" style="stroke:#000000"/> +<circle cx="177" cy="305" r="0.5" style="stroke:#000000"/> +<circle cx="165" cy="292" r="0.5" style="stroke:#000000"/> +<circle cx="150" cy="300" r="0.5" style="stroke:#000000"/> +<circle cx="139" cy="294" r="0.5" style="stroke:#000000"/> +<circle cx="162" cy="318" r="0.5" style="stroke:#000000"/> +<circle cx="150" cy="300" r="0.5" style="stroke:#000000"/> +<circle cx="150" cy="299" r="0.5" style="stroke:#000000"/> +<circle cx="130" cy="310" r="0.5" style="stroke:#000000"/> +<circle cx="155" cy="302" r="0.5" style="stroke:#000000"/> +<circle cx="160" cy="306" r="0.5" style="stroke:#000000"/> +<circle cx="158" cy="294" r="0.5" style="stroke:#000000"/> +<circle cx="160" cy="291" r="0.5" style="stroke:#000000"/> +<circle cx="158" cy="279" r="0.5" style="stroke:#000000"/> +<circle cx="130" cy="289" r="0.5" style="stroke:#000000"/> +<circle cx="141" cy="295" r="0.5" style="stroke:#000000"/> +<circle cx="152" cy="295" r="0.5" style="stroke:#000000"/> +<circle cx="142" cy="297" r="0.5" style="stroke:#000000"/> +<circle cx="168" cy="309" r="0.5" style="stroke:#000000"/> +<circle cx="155" cy="302" r="0.5" style="stroke:#000000"/> +<circle cx="132" cy="295" r="0.5" style="stroke:#000000"/> +<circle cx="150" cy="300" r="0.5" style="stroke:#000000"/> +<circle cx="163" cy="293" r="0.5" style="stroke:#000000"/> +<circle cx="144" cy="284" r="0.5" style="stroke:#000000"/> +<circle cx="149" cy="290" r="0.5" style="stroke:#000000"/> +<circle cx="146" cy="301" r="0.5" style="stroke:#000000"/> +<circle cx="139" cy="322" r="0.5" style="stroke:#000000"/> +<circle cx="163" cy="286" r="0.5" style="stroke:#000000"/> +<circle cx="142" cy="307" r="0.5" style="stroke:#000000"/> +<circle cx="164" cy="286" r="0.5" style="stroke:#000000"/> +<circle cx="153" cy="325" r="0.5" style="stroke:#000000"/> +<circle cx="147" cy="289" r="0.5" style="stroke:#000000"/> +<circle cx="138" cy="299" r="0.5" style="stroke:#000000"/> +<circle cx="157" cy="306" r="0.5" style="stroke:#000000"/> +<circle cx="158" cy="286" r="0.5" style="stroke:#000000"/> +<circle cx="144" cy="281" r="0.5" style="stroke:#000000"/> +<circle cx="150" cy="280" r="0.5" style="stroke:#000000"/> +<circle cx="151" cy="299" r="0.5" style="stroke:#000000"/> +<circle cx="169" cy="321" r="0.5" style="stroke:#000000"/> +<circle cx="132" cy="305" r="0.5" style="stroke:#000000"/> +<circle cx="153" cy="295" r="0.5" style="stroke:#000000"/> +<circle cx="178" cy="297" r="0.5" style="stroke:#000000"/> +<circle cx="179" cy="295" r="0.5" style="stroke:#000000"/> +<circle cx="149" cy="298" r="0.5" style="stroke:#000000"/> +<circle cx="146" cy="297" r="0.5" style="stroke:#000000"/> +<circle cx="132" cy="290" r="0.5" style="stroke:#000000"/> +<circle cx="153" cy="296" r="0.5" style="stroke:#000000"/> +<circle cx="154" cy="298" r="0.5" style="stroke:#000000"/> +<circle cx="136" cy="293" r="0.5" style="stroke:#000000"/> +<circle cx="175" cy="308" r="0.5" style="stroke:#000000"/> +<circle cx="167" cy="299" r="0.5" style="stroke:#000000"/> +<circle cx="154" cy="290" r="0.5" style="stroke:#000000"/> +<circle cx="133" cy="316" r="0.5" style="stroke:#000000"/> +<circle cx="127" cy="286" r="0.5" style="stroke:#000000"/> +<circle cx="139" cy="292" r="0.5" style="stroke:#000000"/> +<circle cx="148" cy="300" r="0.5" style="stroke:#000000"/> +<circle cx="157" cy="291" r="0.5" style="stroke:#000000"/> +<circle cx="144" cy="273" r="0.5" style="stroke:#000000"/> +<circle cx="131" cy="298" r="0.5" style="stroke:#000000"/> +<circle cx="160" cy="276" r="0.5" style="stroke:#000000"/> +<circle cx="142" cy="317" r="0.5" style="stroke:#000000"/> +<circle cx="148" cy="298" r="0.5" style="stroke:#000000"/> +<circle cx="150" cy="300" r="0.5" style="stroke:#000000"/> +<circle cx="161" cy="318" r="0.5" style="stroke:#000000"/> +<circle cx="150" cy="300" r="0.5" style="stroke:#000000"/> +<circle cx="134" cy="286" r="0.5" style="stroke:#000000"/> +<circle cx="135" cy="309" r="0.5" style="stroke:#000000"/> +<circle cx="129" cy="289" r="0.5" style="stroke:#000000"/> +<circle cx="147" cy="295" r="0.5" style="stroke:#000000"/> +<circle cx="176" cy="300" r="0.5" style="stroke:#000000"/> +<circle cx="145" cy="303" r="0.5" style="stroke:#000000"/> +<circle cx="132" cy="286" r="0.5" style="stroke:#000000"/> +<circle cx="148" cy="299" r="0.5" style="stroke:#000000"/> +<circle cx="152" cy="296" r="0.5" style="stroke:#000000"/> +<circle cx="124" cy="311" r="0.5" style="stroke:#000000"/> +<circle cx="176" cy="302" r="0.5" style="stroke:#000000"/> +<circle cx="148" cy="297" r="0.5" style="stroke:#000000"/> +<circle cx="134" cy="301" r="0.5" style="stroke:#000000"/> +<circle cx="136" cy="316" r="0.5" style="stroke:#000000"/> +<circle cx="148" cy="298" r="0.5" style="stroke:#000000"/> +<circle cx="148" cy="311" r="0.5" style="stroke:#000000"/> +<circle cx="139" cy="322" r="0.5" style="stroke:#000000"/> +<circle cx="159" cy="285" r="0.5" style="stroke:#000000"/> +<circle cx="125" cy="316" r="0.5" style="stroke:#000000"/> +<circle cx="148" cy="328" r="0.5" style="stroke:#000000"/> +<circle cx="178" cy="306" r="0.5" style="stroke:#000000"/> +<circle cx="138" cy="297" r="0.5" style="stroke:#000000"/> +<circle cx="140" cy="284" r="0.5" style="stroke:#000000"/> +<circle cx="173" cy="297" r="0.5" style="stroke:#000000"/> +<circle cx="138" cy="289" r="0.5" style="stroke:#000000"/> +<circle cx="167" cy="287" r="0.5" style="stroke:#000000"/> +<circle cx="495" cy="113" r="0.5" style="stroke:#000000"/> +<circle cx="509" cy="122" r="0.5" style="stroke:#000000"/> +<circle cx="491" cy="135" r="0.5" style="stroke:#000000"/> +<circle cx="487" cy="145" r="0.5" style="stroke:#000000"/> +<circle cx="497" cy="121" r="0.5" style="stroke:#000000"/> +<circle cx="502" cy="142" r="0.5" style="stroke:#000000"/> +<circle cx="515" cy="113" r="0.5" style="stroke:#000000"/> +<circle cx="513" cy="113" r="0.5" style="stroke:#000000"/> +<circle cx="491" cy="105" r="0.5" style="stroke:#000000"/> +<circle cx="509" cy="129" r="0.5" style="stroke:#000000"/> +<circle cx="514" cy="107" r="0.5" style="stroke:#000000"/> +<circle cx="500" cy="120" r="0.5" style="stroke:#000000"/> +<circle cx="504" cy="119" r="0.5" style="stroke:#000000"/> +<circle cx="504" cy="142" r="0.5" style="stroke:#000000"/> +<circle cx="488" cy="126" r="0.5" style="stroke:#000000"/> +<circle cx="515" cy="142" r="0.5" style="stroke:#000000"/> +<circle cx="501" cy="121" r="0.5" style="stroke:#000000"/> +<circle cx="500" cy="115" r="0.5" style="stroke:#000000"/> +<circle cx="500" cy="120" r="0.5" style="stroke:#000000"/> +<circle cx="491" cy="116" r="0.5" style="stroke:#000000"/> +<circle cx="476" cy="112" r="0.5" style="stroke:#000000"/> +<circle cx="486" cy="112" r="0.5" style="stroke:#000000"/> +<circle cx="506" cy="95" r="0.5" style="stroke:#000000"/> +<circle cx="476" cy="112" r="0.5" style="stroke:#000000"/> +<circle cx="485" cy="109" r="0.5" style="stroke:#000000"/> +<circle cx="514" cy="129" r="0.5" style="stroke:#000000"/> +<circle cx="521" cy="136" r="0.5" style="stroke:#000000"/> +<circle cx="504" cy="129" r="0.5" style="stroke:#000000"/> +<circle cx="514" cy="146" r="0.5" style="stroke:#000000"/> +<circle cx="504" cy="103" r="0.5" style="stroke:#000000"/> +<circle cx="491" cy="124" r="0.5" style="stroke:#000000"/> +<circle cx="514" cy="146" r="0.5" style="stroke:#000000"/> +<circle cx="501" cy="108" r="0.5" style="stroke:#000000"/> +<circle cx="486" cy="132" r="0.5" style="stroke:#000000"/> +<circle cx="508" cy="112" r="0.5" style="stroke:#000000"/> +<circle cx="510" cy="122" r="0.5" style="stroke:#000000"/> +<circle cx="495" cy="137" r="0.5" style="stroke:#000000"/> +<circle cx="508" cy="128" r="0.5" style="stroke:#000000"/> +<circle cx="497" cy="115" r="0.5" style="stroke:#000000"/> +<circle cx="497" cy="135" r="0.5" style="stroke:#000000"/> +<circle cx="497" cy="112" r="0.5" style="stroke:#000000"/> +<circle cx="510" cy="124" r="0.5" style="stroke:#000000"/> +<circle cx="494" cy="112" r="0.5" style="stroke:#000000"/> +<circle cx="518" cy="115" r="0.5" style="stroke:#000000"/> +<circle cx="489" cy="114" r="0.5" style="stroke:#000000"/> +<circle cx="480" cy="112" r="0.5" style="stroke:#000000"/> +<circle cx="510" cy="100" r="0.5" style="stroke:#000000"/> +<circle cx="500" cy="120" r="0.5" style="stroke:#000000"/> +<circle cx="516" cy="143" r="0.5" style="stroke:#000000"/> +<circle cx="500" cy="119" r="0.5" style="stroke:#000000"/> +<circle cx="495" cy="127" r="0.5" style="stroke:#000000"/> +<circle cx="495" cy="117" r="0.5" style="stroke:#000000"/> +<circle cx="505" cy="116" r="0.5" style="stroke:#000000"/> +<circle cx="498" cy="114" r="0.5" style="stroke:#000000"/> +<circle cx="502" cy="121" r="0.5" style="stroke:#000000"/> +<circle cx="509" cy="131" r="0.5" style="stroke:#000000"/> +<circle cx="492" cy="120" r="0.5" style="stroke:#000000"/> +<circle cx="521" cy="137" r="0.5" style="stroke:#000000"/> +<circle cx="485" cy="110" r="0.5" style="stroke:#000000"/> +<circle cx="481" cy="118" r="0.5" style="stroke:#000000"/> +<circle cx="501" cy="127" r="0.5" style="stroke:#000000"/> +<circle cx="501" cy="120" r="0.5" style="stroke:#000000"/> +<circle cx="470" cy="119" r="0.5" style="stroke:#000000"/> +<circle cx="497" cy="134" r="0.5" style="stroke:#000000"/> +<circle cx="491" cy="125" r="0.5" style="stroke:#000000"/> +<circle cx="491" cy="110" r="0.5" style="stroke:#000000"/> +<circle cx="517" cy="144" r="0.5" style="stroke:#000000"/> +<circle cx="490" cy="103" r="0.5" style="stroke:#000000"/> +<circle cx="508" cy="99" r="0.5" style="stroke:#000000"/> +<circle cx="505" cy="104" r="0.5" style="stroke:#000000"/> +<circle cx="522" cy="119" r="0.5" style="stroke:#000000"/> +<circle cx="506" cy="143" r="0.5" style="stroke:#000000"/> +<circle cx="514" cy="106" r="0.5" style="stroke:#000000"/> +<circle cx="506" cy="104" r="0.5" style="stroke:#000000"/> +<circle cx="496" cy="118" r="0.5" style="stroke:#000000"/> +<circle cx="490" cy="106" r="0.5" style="stroke:#000000"/> +<circle cx="483" cy="120" r="0.5" style="stroke:#000000"/> +<circle cx="498" cy="124" r="0.5" style="stroke:#000000"/> +<circle cx="499" cy="120" r="0.5" style="stroke:#000000"/> +<circle cx="493" cy="142" r="0.5" style="stroke:#000000"/> +<circle cx="491" cy="100" r="0.5" style="stroke:#000000"/> +<circle cx="502" cy="127" r="0.5" style="stroke:#000000"/> +<circle cx="499" cy="142" r="0.5" style="stroke:#000000"/> +<circle cx="501" cy="128" r="0.5" style="stroke:#000000"/> +<circle cx="493" cy="116" r="0.5" style="stroke:#000000"/> +<circle cx="517" cy="143" r="0.5" style="stroke:#000000"/> +<circle cx="504" cy="118" r="0.5" style="stroke:#000000"/> +<circle cx="489" cy="128" r="0.5" style="stroke:#000000"/> +<circle cx="501" cy="119" r="0.5" style="stroke:#000000"/> +<circle cx="500" cy="118" r="0.5" style="stroke:#000000"/> +<circle cx="498" cy="144" r="0.5" style="stroke:#000000"/> +<circle cx="500" cy="121" r="0.5" style="stroke:#000000"/> +<circle cx="496" cy="122" r="0.5" style="stroke:#000000"/> +<circle cx="499" cy="120" r="0.5" style="stroke:#000000"/> +<circle cx="489" cy="134" r="0.5" style="stroke:#000000"/> +<circle cx="518" cy="133" r="0.5" style="stroke:#000000"/> +<circle cx="506" cy="95" r="0.5" style="stroke:#000000"/> +<circle cx="498" cy="141" r="0.5" style="stroke:#000000"/> +<circle cx="502" cy="116" r="0.5" style="stroke:#000000"/> +<circle cx="500" cy="114" r="0.5" style="stroke:#000000"/> +<circle cx="497" cy="125" r="0.5" style="stroke:#000000"/> +<circle cx="498" cy="119" r="0.5" style="stroke:#000000"/> +<circle cx="505" cy="122" r="0.5" style="stroke:#000000"/> +<circle cx="489" cy="121" r="0.5" style="stroke:#000000"/> +<circle cx="505" cy="121" r="0.5" style="stroke:#000000"/> +<circle cx="497" cy="121" r="0.5" style="stroke:#000000"/> +<circle cx="479" cy="133" r="0.5" style="stroke:#000000"/> +<circle cx="519" cy="143" r="0.5" style="stroke:#000000"/> +<circle cx="501" cy="121" r="0.5" style="stroke:#000000"/> +<circle cx="497" cy="122" r="0.5" style="stroke:#000000"/> +<circle cx="527" cy="125" r="0.5" style="stroke:#000000"/> +<circle cx="515" cy="112" r="0.5" style="stroke:#000000"/> +<circle cx="500" cy="120" r="0.5" style="stroke:#000000"/> +<circle cx="489" cy="114" r="0.5" style="stroke:#000000"/> +<circle cx="512" cy="138" r="0.5" style="stroke:#000000"/> +<circle cx="500" cy="120" r="0.5" style="stroke:#000000"/> +<circle cx="500" cy="119" r="0.5" style="stroke:#000000"/> +<circle cx="480" cy="130" r="0.5" style="stroke:#000000"/> +<circle cx="505" cy="122" r="0.5" style="stroke:#000000"/> +<circle cx="510" cy="126" r="0.5" style="stroke:#000000"/> +<circle cx="508" cy="114" r="0.5" style="stroke:#000000"/> +<circle cx="510" cy="111" r="0.5" style="stroke:#000000"/> +<circle cx="508" cy="99" r="0.5" style="stroke:#000000"/> +<circle cx="480" cy="109" r="0.5" style="stroke:#000000"/> +<circle cx="491" cy="115" r="0.5" style="stroke:#000000"/> +<circle cx="502" cy="115" r="0.5" style="stroke:#000000"/> +<circle cx="492" cy="117" r="0.5" style="stroke:#000000"/> +<circle cx="518" cy="129" r="0.5" style="stroke:#000000"/> +<circle cx="505" cy="122" r="0.5" style="stroke:#000000"/> +<circle cx="482" cy="115" r="0.5" style="stroke:#000000"/> +<circle cx="500" cy="120" r="0.5" style="stroke:#000000"/> +<circle cx="513" cy="113" r="0.5" style="stroke:#000000"/> +<circle cx="494" cy="104" r="0.5" style="stroke:#000000"/> +<circle cx="499" cy="110" r="0.5" style="stroke:#000000"/> +<circle cx="496" cy="121" r="0.5" style="stroke:#000000"/> +<circle cx="489" cy="142" r="0.5" style="stroke:#000000"/> +<circle cx="513" cy="106" r="0.5" style="stroke:#000000"/> +<circle cx="492" cy="127" r="0.5" style="stroke:#000000"/> +<circle cx="514" cy="106" r="0.5" style="stroke:#000000"/> +<circle cx="503" cy="145" r="0.5" style="stroke:#000000"/> +<circle cx="497" cy="109" r="0.5" style="stroke:#000000"/> +<circle cx="488" cy="119" r="0.5" style="stroke:#000000"/> +<circle cx="507" cy="126" r="0.5" style="stroke:#000000"/> +<circle cx="508" cy="106" r="0.5" style="stroke:#000000"/> +<circle cx="494" cy="101" r="0.5" style="stroke:#000000"/> +<circle cx="500" cy="100" r="0.5" style="stroke:#000000"/> +<circle cx="501" cy="119" r="0.5" style="stroke:#000000"/> +<circle cx="519" cy="141" r="0.5" style="stroke:#000000"/> +<circle cx="482" cy="125" r="0.5" style="stroke:#000000"/> +<circle cx="503" cy="115" r="0.5" style="stroke:#000000"/> +<circle cx="528" cy="117" r="0.5" style="stroke:#000000"/> +<circle cx="529" cy="115" r="0.5" style="stroke:#000000"/> +<circle cx="499" cy="118" r="0.5" style="stroke:#000000"/> +<circle cx="496" cy="117" r="0.5" style="stroke:#000000"/> +<circle cx="482" cy="110" r="0.5" style="stroke:#000000"/> +<circle cx="503" cy="116" r="0.5" style="stroke:#000000"/> +<circle cx="504" cy="118" r="0.5" style="stroke:#000000"/> +<circle cx="486" cy="113" r="0.5" style="stroke:#000000"/> +<circle cx="525" cy="128" r="0.5" style="stroke:#000000"/> +<circle cx="517" cy="119" r="0.5" style="stroke:#000000"/> +<circle cx="504" cy="110" r="0.5" style="stroke:#000000"/> +<circle cx="483" cy="136" r="0.5" style="stroke:#000000"/> +<circle cx="477" cy="106" r="0.5" style="stroke:#000000"/> +<circle cx="489" cy="112" r="0.5" style="stroke:#000000"/> +<circle cx="498" cy="120" r="0.5" style="stroke:#000000"/> +<circle cx="507" cy="111" r="0.5" style="stroke:#000000"/> +<circle cx="494" cy="93" r="0.5" style="stroke:#000000"/> +<circle cx="481" cy="118" r="0.5" style="stroke:#000000"/> +<circle cx="510" cy="96" r="0.5" style="stroke:#000000"/> +<circle cx="492" cy="137" r="0.5" style="stroke:#000000"/> +<circle cx="498" cy="118" r="0.5" style="stroke:#000000"/> +<circle cx="500" cy="120" r="0.5" style="stroke:#000000"/> +<circle cx="511" cy="138" r="0.5" style="stroke:#000000"/> +<circle cx="500" cy="120" r="0.5" style="stroke:#000000"/> +<circle cx="484" cy="106" r="0.5" style="stroke:#000000"/> +<circle cx="485" cy="129" r="0.5" style="stroke:#000000"/> +<circle cx="479" cy="109" r="0.5" style="stroke:#000000"/> +<circle cx="497" cy="115" r="0.5" style="stroke:#000000"/> +<circle cx="526" cy="120" r="0.5" style="stroke:#000000"/> +<circle cx="495" cy="123" r="0.5" style="stroke:#000000"/> +<circle cx="482" cy="106" r="0.5" style="stroke:#000000"/> +<circle cx="498" cy="119" r="0.5" style="stroke:#000000"/> +<circle cx="502" cy="116" r="0.5" style="stroke:#000000"/> +<circle cx="474" cy="131" r="0.5" style="stroke:#000000"/> +<circle cx="526" cy="122" r="0.5" style="stroke:#000000"/> +<circle cx="498" cy="117" r="0.5" style="stroke:#000000"/> +<circle cx="484" cy="121" r="0.5" style="stroke:#000000"/> +<circle cx="486" cy="136" r="0.5" style="stroke:#000000"/> +<circle cx="498" cy="118" r="0.5" style="stroke:#000000"/> +<circle cx="498" cy="131" r="0.5" style="stroke:#000000"/> +<circle cx="489" cy="142" r="0.5" style="stroke:#000000"/> +<circle cx="509" cy="105" r="0.5" style="stroke:#000000"/> +<circle cx="475" cy="136" r="0.5" style="stroke:#000000"/> +<circle cx="498" cy="148" r="0.5" style="stroke:#000000"/> +<circle cx="528" cy="126" r="0.5" style="stroke:#000000"/> +<circle cx="488" cy="117" r="0.5" style="stroke:#000000"/> +<circle cx="490" cy="104" r="0.5" style="stroke:#000000"/> +<circle cx="523" cy="117" r="0.5" style="stroke:#000000"/> +<circle cx="488" cy="109" r="0.5" style="stroke:#000000"/> +<circle cx="517" cy="107" r="0.5" style="stroke:#000000"/> +<circle cx="275" cy="163" r="0.5" style="stroke:#000000"/> +<circle cx="345" cy="212" r="0.5" style="stroke:#000000"/> +<circle cx="256" cy="277" r="0.5" style="stroke:#000000"/> +<circle cx="235" cy="324" r="0.5" style="stroke:#000000"/> +<circle cx="286" cy="206" r="0.5" style="stroke:#000000"/> +<circle cx="312" cy="311" r="0.5" style="stroke:#000000"/> +<circle cx="375" cy="163" r="0.5" style="stroke:#000000"/> +<circle cx="363" cy="164" r="0.5" style="stroke:#000000"/> +<circle cx="254" cy="126" r="0.5" style="stroke:#000000"/> +<circle cx="343" cy="243" r="0.5" style="stroke:#000000"/> +<circle cx="372" cy="133" r="0.5" style="stroke:#000000"/> +<circle cx="301" cy="201" r="0.5" style="stroke:#000000"/> +<circle cx="319" cy="193" r="0.5" style="stroke:#000000"/> +<circle cx="319" cy="311" r="0.5" style="stroke:#000000"/> +<circle cx="238" cy="232" r="0.5" style="stroke:#000000"/> +<circle cx="376" cy="310" r="0.5" style="stroke:#000000"/> +<circle cx="305" cy="203" r="0.5" style="stroke:#000000"/> +<circle cx="299" cy="177" r="0.5" style="stroke:#000000"/> +<circle cx="300" cy="201" r="0.5" style="stroke:#000000"/> +<circle cx="256" cy="179" r="0.5" style="stroke:#000000"/> +<circle cx="182" cy="162" r="0.5" style="stroke:#000000"/> +<circle cx="229" cy="158" r="0.5" style="stroke:#000000"/> +<circle cx="328" cy="75" r="0.5" style="stroke:#000000"/> +<circle cx="180" cy="161" r="0.5" style="stroke:#000000"/> +<circle cx="225" cy="144" r="0.5" style="stroke:#000000"/> +<circle cx="369" cy="245" r="0.5" style="stroke:#000000"/> +<circle cx="406" cy="282" r="0.5" style="stroke:#000000"/> +<circle cx="320" cy="245" r="0.5" style="stroke:#000000"/> +<circle cx="369" cy="328" r="0.5" style="stroke:#000000"/> +<circle cx="318" cy="115" r="0.5" style="stroke:#000000"/> +<circle cx="253" cy="221" r="0.5" style="stroke:#000000"/> +<circle cx="369" cy="332" r="0.5" style="stroke:#000000"/> +<circle cx="303" cy="140" r="0.5" style="stroke:#000000"/> +<circle cx="231" cy="259" r="0.5" style="stroke:#000000"/> +<circle cx="342" cy="159" r="0.5" style="stroke:#000000"/> +<circle cx="348" cy="208" r="0.5" style="stroke:#000000"/> +<circle cx="273" cy="283" r="0.5" style="stroke:#000000"/> +<circle cx="342" cy="241" r="0.5" style="stroke:#000000"/> +<circle cx="284" cy="177" r="0.5" style="stroke:#000000"/> +<circle cx="283" cy="276" r="0.5" style="stroke:#000000"/> +<circle cx="284" cy="159" r="0.5" style="stroke:#000000"/> +<circle cx="348" cy="222" r="0.5" style="stroke:#000000"/> +<circle cx="269" cy="159" r="0.5" style="stroke:#000000"/> +<circle cx="388" cy="175" r="0.5" style="stroke:#000000"/> +<circle cx="245" cy="172" r="0.5" style="stroke:#000000"/> +<circle cx="200" cy="158" r="0.5" style="stroke:#000000"/> +<circle cx="351" cy="99" r="0.5" style="stroke:#000000"/> +<circle cx="300" cy="201" r="0.5" style="stroke:#000000"/> +<circle cx="379" cy="317" r="0.5" style="stroke:#000000"/> +<circle cx="301" cy="197" r="0.5" style="stroke:#000000"/> +<circle cx="277" cy="236" r="0.5" style="stroke:#000000"/> +<circle cx="275" cy="187" r="0.5" style="stroke:#000000"/> +<circle cx="324" cy="178" r="0.5" style="stroke:#000000"/> +<circle cx="292" cy="168" r="0.5" style="stroke:#000000"/> +<circle cx="312" cy="204" r="0.5" style="stroke:#000000"/> +<circle cx="345" cy="255" r="0.5" style="stroke:#000000"/> +<circle cx="262" cy="198" r="0.5" style="stroke:#000000"/> +<circle cx="403" cy="283" r="0.5" style="stroke:#000000"/> +<circle cx="223" cy="152" r="0.5" style="stroke:#000000"/> +<circle cx="207" cy="189" r="0.5" style="stroke:#000000"/> +<circle cx="305" cy="237" r="0.5" style="stroke:#000000"/> +<circle cx="303" cy="200" r="0.5" style="stroke:#000000"/> +<circle cx="150" cy="197" r="0.5" style="stroke:#000000"/> +<circle cx="286" cy="268" r="0.5" style="stroke:#000000"/> +<circle cx="254" cy="227" r="0.5" style="stroke:#000000"/> +<circle cx="254" cy="152" r="0.5" style="stroke:#000000"/> +<circle cx="387" cy="322" r="0.5" style="stroke:#000000"/> +<circle cx="250" cy="117" r="0.5" style="stroke:#000000"/> +<circle cx="341" cy="97" r="0.5" style="stroke:#000000"/> +<circle cx="327" cy="122" r="0.5" style="stroke:#000000"/> +<circle cx="412" cy="193" r="0.5" style="stroke:#000000"/> +<circle cx="329" cy="315" r="0.5" style="stroke:#000000"/> +<circle cx="372" cy="130" r="0.5" style="stroke:#000000"/> +<circle cx="328" cy="120" r="0.5" style="stroke:#000000"/> +<circle cx="279" cy="190" r="0.5" style="stroke:#000000"/> +<circle cx="248" cy="132" r="0.5" style="stroke:#000000"/> +<circle cx="213" cy="199" r="0.5" style="stroke:#000000"/> +<circle cx="291" cy="218" r="0.5" style="stroke:#000000"/> +<circle cx="297" cy="200" r="0.5" style="stroke:#000000"/> +<circle cx="264" cy="309" r="0.5" style="stroke:#000000"/> +<circle cx="257" cy="100" r="0.5" style="stroke:#000000"/> +<circle cx="308" cy="235" r="0.5" style="stroke:#000000"/> +<circle cx="296" cy="312" r="0.5" style="stroke:#000000"/> +<circle cx="305" cy="240" r="0.5" style="stroke:#000000"/> +<circle cx="264" cy="178" r="0.5" style="stroke:#000000"/> +<circle cx="383" cy="317" r="0.5" style="stroke:#000000"/> +<circle cx="319" cy="189" r="0.5" style="stroke:#000000"/> +<circle cx="247" cy="241" r="0.5" style="stroke:#000000"/> +<circle cx="306" cy="193" r="0.5" style="stroke:#000000"/> +<circle cx="302" cy="190" r="0.5" style="stroke:#000000"/> +<circle cx="292" cy="319" r="0.5" style="stroke:#000000"/> +<circle cx="298" cy="203" r="0.5" style="stroke:#000000"/> +<circle cx="280" cy="211" r="0.5" style="stroke:#000000"/> +<circle cx="296" cy="202" r="0.5" style="stroke:#000000"/> +<circle cx="243" cy="272" r="0.5" style="stroke:#000000"/> +<circle cx="392" cy="263" r="0.5" style="stroke:#000000"/> +<circle cx="331" cy="74" r="0.5" style="stroke:#000000"/> +<circle cx="292" cy="303" r="0.5" style="stroke:#000000"/> +<circle cx="310" cy="181" r="0.5" style="stroke:#000000"/> +<circle cx="302" cy="168" r="0.5" style="stroke:#000000"/> +<circle cx="287" cy="227" r="0.5" style="stroke:#000000"/> +<circle cx="288" cy="196" r="0.5" style="stroke:#000000"/> +<circle cx="326" cy="210" r="0.5" style="stroke:#000000"/> +<circle cx="244" cy="206" r="0.5" style="stroke:#000000"/> +<circle cx="325" cy="205" r="0.5" style="stroke:#000000"/> +<circle cx="287" cy="206" r="0.5" style="stroke:#000000"/> +<circle cx="194" cy="265" r="0.5" style="stroke:#000000"/> +<circle cx="397" cy="314" r="0.5" style="stroke:#000000"/> +<circle cx="307" cy="204" r="0.5" style="stroke:#000000"/> +<circle cx="286" cy="212" r="0.5" style="stroke:#000000"/> +<circle cx="436" cy="227" r="0.5" style="stroke:#000000"/> +<circle cx="373" cy="161" r="0.5" style="stroke:#000000"/> +<circle cx="298" cy="199" r="0.5" style="stroke:#000000"/> +<circle cx="244" cy="172" r="0.5" style="stroke:#000000"/> +<circle cx="360" cy="290" r="0.5" style="stroke:#000000"/> +<circle cx="299" cy="202" r="0.5" style="stroke:#000000"/> +<circle cx="300" cy="195" r="0.5" style="stroke:#000000"/> +<circle cx="201" cy="252" r="0.5" style="stroke:#000000"/> +<circle cx="323" cy="210" r="0.5" style="stroke:#000000"/> +<circle cx="350" cy="228" r="0.5" style="stroke:#000000"/> +<circle cx="341" cy="170" r="0.5" style="stroke:#000000"/> +<circle cx="349" cy="157" r="0.5" style="stroke:#000000"/> +<circle cx="340" cy="94" r="0.5" style="stroke:#000000"/> +<circle cx="202" cy="147" r="0.5" style="stroke:#000000"/> +<circle cx="254" cy="174" r="0.5" style="stroke:#000000"/> +<circle cx="309" cy="176" r="0.5" style="stroke:#000000"/> +<circle cx="260" cy="183" r="0.5" style="stroke:#000000"/> +<circle cx="391" cy="243" r="0.5" style="stroke:#000000"/> +<circle cx="326" cy="210" r="0.5" style="stroke:#000000"/> +<circle cx="210" cy="175" r="0.5" style="stroke:#000000"/> +<circle cx="300" cy="200" r="0.5" style="stroke:#000000"/> +<circle cx="364" cy="163" r="0.5" style="stroke:#000000"/> +<circle cx="271" cy="121" r="0.5" style="stroke:#000000"/> +<circle cx="294" cy="149" r="0.5" style="stroke:#000000"/> +<circle cx="278" cy="205" r="0.5" style="stroke:#000000"/> +<circle cx="245" cy="311" r="0.5" style="stroke:#000000"/> +<circle cx="363" cy="131" r="0.5" style="stroke:#000000"/> +<circle cx="262" cy="236" r="0.5" style="stroke:#000000"/> +<circle cx="369" cy="128" r="0.5" style="stroke:#000000"/> +<circle cx="317" cy="327" r="0.5" style="stroke:#000000"/> +<circle cx="283" cy="143" r="0.5" style="stroke:#000000"/> +<circle cx="239" cy="194" r="0.5" style="stroke:#000000"/> +<circle cx="333" cy="231" r="0.5" style="stroke:#000000"/> +<circle cx="340" cy="129" r="0.5" style="stroke:#000000"/> +<circle cx="271" cy="105" r="0.5" style="stroke:#000000"/> +<circle cx="302" cy="100" r="0.5" style="stroke:#000000"/> +<circle cx="303" cy="197" r="0.5" style="stroke:#000000"/> +<circle cx="395" cy="303" r="0.5" style="stroke:#000000"/> +<circle cx="210" cy="227" r="0.5" style="stroke:#000000"/> +<circle cx="317" cy="174" r="0.5" style="stroke:#000000"/> +<circle cx="441" cy="184" r="0.5" style="stroke:#000000"/> +<circle cx="447" cy="175" r="0.5" style="stroke:#000000"/> +<circle cx="294" cy="191" r="0.5" style="stroke:#000000"/> +<circle cx="281" cy="184" r="0.5" style="stroke:#000000"/> +<circle cx="212" cy="148" r="0.5" style="stroke:#000000"/> +<circle cx="315" cy="179" r="0.5" style="stroke:#000000"/> +<circle cx="318" cy="190" r="0.5" style="stroke:#000000"/> +<circle cx="232" cy="164" r="0.5" style="stroke:#000000"/> +<circle cx="425" cy="239" r="0.5" style="stroke:#000000"/> +<circle cx="387" cy="195" r="0.5" style="stroke:#000000"/> +<circle cx="322" cy="152" r="0.5" style="stroke:#000000"/> +<circle cx="213" cy="278" r="0.5" style="stroke:#000000"/> +<circle cx="187" cy="132" r="0.5" style="stroke:#000000"/> +<circle cx="245" cy="161" r="0.5" style="stroke:#000000"/> +<circle cx="292" cy="202" r="0.5" style="stroke:#000000"/> +<circle cx="336" cy="155" r="0.5" style="stroke:#000000"/> +<circle cx="272" cy="65" r="0.5" style="stroke:#000000"/> +<circle cx="204" cy="190" r="0.5" style="stroke:#000000"/> +<circle cx="351" cy="82" r="0.5" style="stroke:#000000"/> +<circle cx="259" cy="284" r="0.5" style="stroke:#000000"/> +<circle cx="288" cy="189" r="0.5" style="stroke:#000000"/> +<circle cx="300" cy="200" r="0.5" style="stroke:#000000"/> +<circle cx="353" cy="288" r="0.5" style="stroke:#000000"/> +<circle cx="301" cy="199" r="0.5" style="stroke:#000000"/> +<circle cx="218" cy="128" r="0.5" style="stroke:#000000"/> +<circle cx="226" cy="243" r="0.5" style="stroke:#000000"/> +<circle cx="195" cy="146" r="0.5" style="stroke:#000000"/> +<circle cx="284" cy="174" r="0.5" style="stroke:#000000"/> +<circle cx="428" cy="200" r="0.5" style="stroke:#000000"/> +<circle cx="274" cy="214" r="0.5" style="stroke:#000000"/> +<circle cx="211" cy="131" r="0.5" style="stroke:#000000"/> +<circle cx="291" cy="196" r="0.5" style="stroke:#000000"/> +<circle cx="310" cy="180" r="0.5" style="stroke:#000000"/> +<circle cx="172" cy="257" r="0.5" style="stroke:#000000"/> +<circle cx="431" cy="212" r="0.5" style="stroke:#000000"/> +<circle cx="290" cy="187" r="0.5" style="stroke:#000000"/> +<circle cx="219" cy="203" r="0.5" style="stroke:#000000"/> +<circle cx="230" cy="279" r="0.5" style="stroke:#000000"/> +<circle cx="291" cy="192" r="0.5" style="stroke:#000000"/> +<circle cx="291" cy="254" r="0.5" style="stroke:#000000"/> +<circle cx="245" cy="309" r="0.5" style="stroke:#000000"/> +<circle cx="345" cy="126" r="0.5" style="stroke:#000000"/> +<circle cx="175" cy="278" r="0.5" style="stroke:#000000"/> +<circle cx="289" cy="338" r="0.5" style="stroke:#000000"/> +<circle cx="442" cy="228" r="0.5" style="stroke:#000000"/> +<circle cx="242" cy="186" r="0.5" style="stroke:#000000"/> +<circle cx="249" cy="120" r="0.5" style="stroke:#000000"/> +<circle cx="415" cy="186" r="0.5" style="stroke:#000000"/> +<circle cx="242" cy="145" r="0.5" style="stroke:#000000"/> +<circle cx="384" cy="133" r="0.5" style="stroke:#000000"/> +<circle cx="20" cy="98" r="1" style="stroke:#ff0000"/> +<circle cx="50" cy="246" r="1" style="stroke:#ff0000"/> +<circle cx="83" cy="354" r="1" style="stroke:#ff0000"/> +<circle cx="164" cy="416" r="1" style="stroke:#ff0000"/> +<circle cx="236" cy="434" r="1" style="stroke:#ff0000"/> +<circle cx="343" cy="427" r="1" style="stroke:#ff0000"/> +<circle cx="366" cy="412" r="1" style="stroke:#ff0000"/> +<circle cx="379" cy="402" r="1" style="stroke:#ff0000"/> +<circle cx="519" cy="143" r="1" style="stroke:#ff0000"/> +<circle cx="528" cy="126" r="1" style="stroke:#ff0000"/> +<circle cx="529" cy="115" r="1" style="stroke:#ff0000"/> +<circle cx="510" cy="96" r="1" style="stroke:#ff0000"/> +<circle cx="506" cy="95" r="1" style="stroke:#ff0000"/> +<circle cx="117" cy="33" r="1" style="stroke:#ff0000"/> +<circle cx="85" cy="28" r="1" style="stroke:#ff0000"/> +<circle cx="40" cy="64" r="1" style="stroke:#ff0000"/> +</svg> diff --git a/testsuite/tests/dph/quickhull/dph-quickhull-opt.stdout b/testsuite/tests/dph/quickhull/dph-quickhull-opt.stdout new file mode 100644 index 0000000000..f6b2d92e9a --- /dev/null +++ b/testsuite/tests/dph/quickhull/dph-quickhull-opt.stdout @@ -0,0 +1,1019 @@ +<svg width="100%" height="100%" version="1.1" xmlns="http://www.w3.org/2000/svg"> +<polygon points="20,98 50,246 83,354 164,416 236,434 343,427 366,412 379,402 519,143 528,126 529,115 510,96 506,95 117,33 85,28 40,64 " style="fill:#d0d0ff;stroke:#000000;stroke-width:1"/> +<circle cx="217" cy="201" r="0.5" style="stroke:#000000"/> +<circle cx="310" cy="266" r="0.5" style="stroke:#000000"/> +<circle cx="191" cy="353" r="0.5" style="stroke:#000000"/> +<circle cx="164" cy="416" r="0.5" style="stroke:#000000"/> +<circle cx="232" cy="257" r="0.5" style="stroke:#000000"/> +<circle cx="266" cy="398" r="0.5" style="stroke:#000000"/> +<circle cx="350" cy="201" r="0.5" style="stroke:#000000"/> +<circle cx="334" cy="202" r="0.5" style="stroke:#000000"/> +<circle cx="189" cy="151" r="0.5" style="stroke:#000000"/> +<circle cx="308" cy="307" r="0.5" style="stroke:#000000"/> +<circle cx="347" cy="160" r="0.5" style="stroke:#000000"/> +<circle cx="251" cy="251" r="0.5" style="stroke:#000000"/> +<circle cx="275" cy="241" r="0.5" style="stroke:#000000"/> +<circle cx="275" cy="398" r="0.5" style="stroke:#000000"/> +<circle cx="167" cy="292" r="0.5" style="stroke:#000000"/> +<circle cx="351" cy="397" r="0.5" style="stroke:#000000"/> +<circle cx="257" cy="254" r="0.5" style="stroke:#000000"/> +<circle cx="248" cy="220" r="0.5" style="stroke:#000000"/> +<circle cx="250" cy="252" r="0.5" style="stroke:#000000"/> +<circle cx="191" cy="222" r="0.5" style="stroke:#000000"/> +<circle cx="93" cy="200" r="0.5" style="stroke:#000000"/> +<circle cx="155" cy="195" r="0.5" style="stroke:#000000"/> +<circle cx="287" cy="84" r="0.5" style="stroke:#000000"/> +<circle cx="90" cy="198" r="0.5" style="stroke:#000000"/> +<circle cx="149" cy="175" r="0.5" style="stroke:#000000"/> +<circle cx="342" cy="311" r="0.5" style="stroke:#000000"/> +<circle cx="391" cy="360" r="0.5" style="stroke:#000000"/> +<circle cx="277" cy="310" r="0.5" style="stroke:#000000"/> +<circle cx="341" cy="421" r="0.5" style="stroke:#000000"/> +<circle cx="274" cy="136" r="0.5" style="stroke:#000000"/> +<circle cx="187" cy="278" r="0.5" style="stroke:#000000"/> +<circle cx="343" cy="427" r="0.5" style="stroke:#000000"/> +<circle cx="255" cy="170" r="0.5" style="stroke:#000000"/> +<circle cx="158" cy="329" r="0.5" style="stroke:#000000"/> +<circle cx="306" cy="196" r="0.5" style="stroke:#000000"/> +<circle cx="315" cy="261" r="0.5" style="stroke:#000000"/> +<circle cx="214" cy="361" r="0.5" style="stroke:#000000"/> +<circle cx="306" cy="304" r="0.5" style="stroke:#000000"/> +<circle cx="229" cy="219" r="0.5" style="stroke:#000000"/> +<circle cx="227" cy="351" r="0.5" style="stroke:#000000"/> +<circle cx="228" cy="196" r="0.5" style="stroke:#000000"/> +<circle cx="314" cy="280" r="0.5" style="stroke:#000000"/> +<circle cx="209" cy="195" r="0.5" style="stroke:#000000"/> +<circle cx="367" cy="217" r="0.5" style="stroke:#000000"/> +<circle cx="176" cy="212" r="0.5" style="stroke:#000000"/> +<circle cx="117" cy="194" r="0.5" style="stroke:#000000"/> +<circle cx="318" cy="116" r="0.5" style="stroke:#000000"/> +<circle cx="250" cy="251" r="0.5" style="stroke:#000000"/> +<circle cx="355" cy="406" r="0.5" style="stroke:#000000"/> +<circle cx="252" cy="246" r="0.5" style="stroke:#000000"/> +<circle cx="219" cy="299" r="0.5" style="stroke:#000000"/> +<circle cx="217" cy="232" r="0.5" style="stroke:#000000"/> +<circle cx="283" cy="220" r="0.5" style="stroke:#000000"/> +<circle cx="239" cy="207" r="0.5" style="stroke:#000000"/> +<circle cx="266" cy="255" r="0.5" style="stroke:#000000"/> +<circle cx="310" cy="324" r="0.5" style="stroke:#000000"/> +<circle cx="200" cy="248" r="0.5" style="stroke:#000000"/> +<circle cx="387" cy="360" r="0.5" style="stroke:#000000"/> +<circle cx="147" cy="186" r="0.5" style="stroke:#000000"/> +<circle cx="126" cy="236" r="0.5" style="stroke:#000000"/> +<circle cx="257" cy="300" r="0.5" style="stroke:#000000"/> +<circle cx="255" cy="250" r="0.5" style="stroke:#000000"/> +<circle cx="50" cy="246" r="0.5" style="stroke:#000000"/> +<circle cx="231" cy="340" r="0.5" style="stroke:#000000"/> +<circle cx="189" cy="287" r="0.5" style="stroke:#000000"/> +<circle cx="188" cy="186" r="0.5" style="stroke:#000000"/> +<circle cx="366" cy="412" r="0.5" style="stroke:#000000"/> +<circle cx="183" cy="139" r="0.5" style="stroke:#000000"/> +<circle cx="305" cy="113" r="0.5" style="stroke:#000000"/> +<circle cx="286" cy="146" r="0.5" style="stroke:#000000"/> +<circle cx="399" cy="241" r="0.5" style="stroke:#000000"/> +<circle cx="289" cy="404" r="0.5" style="stroke:#000000"/> +<circle cx="346" cy="157" r="0.5" style="stroke:#000000"/> +<circle cx="287" cy="143" r="0.5" style="stroke:#000000"/> +<circle cx="223" cy="236" r="0.5" style="stroke:#000000"/> +<circle cx="181" cy="159" r="0.5" style="stroke:#000000"/> +<circle cx="134" cy="249" r="0.5" style="stroke:#000000"/> +<circle cx="238" cy="274" r="0.5" style="stroke:#000000"/> +<circle cx="246" cy="250" r="0.5" style="stroke:#000000"/> +<circle cx="201" cy="395" r="0.5" style="stroke:#000000"/> +<circle cx="192" cy="116" r="0.5" style="stroke:#000000"/> +<circle cx="260" cy="296" r="0.5" style="stroke:#000000"/> +<circle cx="244" cy="399" r="0.5" style="stroke:#000000"/> +<circle cx="256" cy="303" r="0.5" style="stroke:#000000"/> +<circle cx="202" cy="221" r="0.5" style="stroke:#000000"/> +<circle cx="361" cy="406" r="0.5" style="stroke:#000000"/> +<circle cx="275" cy="235" r="0.5" style="stroke:#000000"/> +<circle cx="180" cy="305" r="0.5" style="stroke:#000000"/> +<circle cx="258" cy="241" r="0.5" style="stroke:#000000"/> +<circle cx="253" cy="237" r="0.5" style="stroke:#000000"/> +<circle cx="239" cy="408" r="0.5" style="stroke:#000000"/> +<circle cx="247" cy="254" r="0.5" style="stroke:#000000"/> +<circle cx="223" cy="265" r="0.5" style="stroke:#000000"/> +<circle cx="244" cy="253" r="0.5" style="stroke:#000000"/> +<circle cx="174" cy="346" r="0.5" style="stroke:#000000"/> +<circle cx="373" cy="334" r="0.5" style="stroke:#000000"/> +<circle cx="292" cy="82" r="0.5" style="stroke:#000000"/> +<circle cx="240" cy="388" r="0.5" style="stroke:#000000"/> +<circle cx="263" cy="225" r="0.5" style="stroke:#000000"/> +<circle cx="252" cy="207" r="0.5" style="stroke:#000000"/> +<circle cx="233" cy="287" r="0.5" style="stroke:#000000"/> +<circle cx="234" cy="245" r="0.5" style="stroke:#000000"/> +<circle cx="285" cy="264" r="0.5" style="stroke:#000000"/> +<circle cx="176" cy="259" r="0.5" style="stroke:#000000"/> +<circle cx="284" cy="256" r="0.5" style="stroke:#000000"/> +<circle cx="233" cy="258" r="0.5" style="stroke:#000000"/> +<circle cx="108" cy="336" r="0.5" style="stroke:#000000"/> +<circle cx="379" cy="402" r="0.5" style="stroke:#000000"/> +<circle cx="260" cy="256" r="0.5" style="stroke:#000000"/> +<circle cx="232" cy="265" r="0.5" style="stroke:#000000"/> +<circle cx="432" cy="286" r="0.5" style="stroke:#000000"/> +<circle cx="347" cy="197" r="0.5" style="stroke:#000000"/> +<circle cx="248" cy="249" r="0.5" style="stroke:#000000"/> +<circle cx="176" cy="213" r="0.5" style="stroke:#000000"/> +<circle cx="330" cy="370" r="0.5" style="stroke:#000000"/> +<circle cx="249" cy="253" r="0.5" style="stroke:#000000"/> +<circle cx="249" cy="243" r="0.5" style="stroke:#000000"/> +<circle cx="119" cy="320" r="0.5" style="stroke:#000000"/> +<circle cx="280" cy="263" r="0.5" style="stroke:#000000"/> +<circle cx="317" cy="287" r="0.5" style="stroke:#000000"/> +<circle cx="304" cy="209" r="0.5" style="stroke:#000000"/> +<circle cx="315" cy="193" r="0.5" style="stroke:#000000"/> +<circle cx="304" cy="109" r="0.5" style="stroke:#000000"/> +<circle cx="119" cy="179" r="0.5" style="stroke:#000000"/> +<circle cx="188" cy="215" r="0.5" style="stroke:#000000"/> +<circle cx="263" cy="218" r="0.5" style="stroke:#000000"/> +<circle cx="196" cy="228" r="0.5" style="stroke:#000000"/> +<circle cx="371" cy="307" r="0.5" style="stroke:#000000"/> +<circle cx="285" cy="263" r="0.5" style="stroke:#000000"/> +<circle cx="130" cy="217" r="0.5" style="stroke:#000000"/> +<circle cx="250" cy="250" r="0.5" style="stroke:#000000"/> +<circle cx="335" cy="201" r="0.5" style="stroke:#000000"/> +<circle cx="211" cy="145" r="0.5" style="stroke:#000000"/> +<circle cx="242" cy="182" r="0.5" style="stroke:#000000"/> +<circle cx="221" cy="256" r="0.5" style="stroke:#000000"/> +<circle cx="177" cy="398" r="0.5" style="stroke:#000000"/> +<circle cx="333" cy="158" r="0.5" style="stroke:#000000"/> +<circle cx="199" cy="297" r="0.5" style="stroke:#000000"/> +<circle cx="342" cy="153" r="0.5" style="stroke:#000000"/> +<circle cx="273" cy="419" r="0.5" style="stroke:#000000"/> +<circle cx="227" cy="173" r="0.5" style="stroke:#000000"/> +<circle cx="169" cy="242" r="0.5" style="stroke:#000000"/> +<circle cx="294" cy="292" r="0.5" style="stroke:#000000"/> +<circle cx="303" cy="155" r="0.5" style="stroke:#000000"/> +<circle cx="211" cy="124" r="0.5" style="stroke:#000000"/> +<circle cx="253" cy="116" r="0.5" style="stroke:#000000"/> +<circle cx="254" cy="246" r="0.5" style="stroke:#000000"/> +<circle cx="377" cy="388" r="0.5" style="stroke:#000000"/> +<circle cx="130" cy="285" r="0.5" style="stroke:#000000"/> +<circle cx="273" cy="215" r="0.5" style="stroke:#000000"/> +<circle cx="438" cy="229" r="0.5" style="stroke:#000000"/> +<circle cx="446" cy="216" r="0.5" style="stroke:#000000"/> +<circle cx="242" cy="238" r="0.5" style="stroke:#000000"/> +<circle cx="224" cy="229" r="0.5" style="stroke:#000000"/> +<circle cx="133" cy="181" r="0.5" style="stroke:#000000"/> +<circle cx="270" cy="222" r="0.5" style="stroke:#000000"/> +<circle cx="275" cy="237" r="0.5" style="stroke:#000000"/> +<circle cx="160" cy="202" r="0.5" style="stroke:#000000"/> +<circle cx="416" cy="302" r="0.5" style="stroke:#000000"/> +<circle cx="366" cy="244" r="0.5" style="stroke:#000000"/> +<circle cx="279" cy="186" r="0.5" style="stroke:#000000"/> +<circle cx="134" cy="353" r="0.5" style="stroke:#000000"/> +<circle cx="99" cy="159" r="0.5" style="stroke:#000000"/> +<circle cx="177" cy="198" r="0.5" style="stroke:#000000"/> +<circle cx="239" cy="253" r="0.5" style="stroke:#000000"/> +<circle cx="298" cy="190" r="0.5" style="stroke:#000000"/> +<circle cx="213" cy="70" r="0.5" style="stroke:#000000"/> +<circle cx="122" cy="236" r="0.5" style="stroke:#000000"/> +<circle cx="318" cy="92" r="0.5" style="stroke:#000000"/> +<circle cx="196" cy="362" r="0.5" style="stroke:#000000"/> +<circle cx="234" cy="235" r="0.5" style="stroke:#000000"/> +<circle cx="250" cy="250" r="0.5" style="stroke:#000000"/> +<circle cx="321" cy="367" r="0.5" style="stroke:#000000"/> +<circle cx="251" cy="249" r="0.5" style="stroke:#000000"/> +<circle cx="141" cy="154" r="0.5" style="stroke:#000000"/> +<circle cx="152" cy="308" r="0.5" style="stroke:#000000"/> +<circle cx="110" cy="178" r="0.5" style="stroke:#000000"/> +<circle cx="229" cy="216" r="0.5" style="stroke:#000000"/> +<circle cx="421" cy="250" r="0.5" style="stroke:#000000"/> +<circle cx="215" cy="269" r="0.5" style="stroke:#000000"/> +<circle cx="131" cy="157" r="0.5" style="stroke:#000000"/> +<circle cx="238" cy="245" r="0.5" style="stroke:#000000"/> +<circle cx="264" cy="224" r="0.5" style="stroke:#000000"/> +<circle cx="79" cy="327" r="0.5" style="stroke:#000000"/> +<circle cx="424" cy="266" r="0.5" style="stroke:#000000"/> +<circle cx="237" cy="232" r="0.5" style="stroke:#000000"/> +<circle cx="142" cy="253" r="0.5" style="stroke:#000000"/> +<circle cx="156" cy="355" r="0.5" style="stroke:#000000"/> +<circle cx="239" cy="239" r="0.5" style="stroke:#000000"/> +<circle cx="238" cy="322" r="0.5" style="stroke:#000000"/> +<circle cx="177" cy="396" r="0.5" style="stroke:#000000"/> +<circle cx="310" cy="152" r="0.5" style="stroke:#000000"/> +<circle cx="83" cy="354" r="0.5" style="stroke:#000000"/> +<circle cx="236" cy="434" r="0.5" style="stroke:#000000"/> +<circle cx="439" cy="287" r="0.5" style="stroke:#000000"/> +<circle cx="173" cy="232" r="0.5" style="stroke:#000000"/> +<circle cx="181" cy="143" r="0.5" style="stroke:#000000"/> +<circle cx="404" cy="232" r="0.5" style="stroke:#000000"/> +<circle cx="173" cy="177" r="0.5" style="stroke:#000000"/> +<circle cx="362" cy="161" r="0.5" style="stroke:#000000"/> +<circle cx="87" cy="81" r="0.5" style="stroke:#000000"/> +<circle cx="124" cy="106" r="0.5" style="stroke:#000000"/> +<circle cx="76" cy="141" r="0.5" style="stroke:#000000"/> +<circle cx="65" cy="166" r="0.5" style="stroke:#000000"/> +<circle cx="93" cy="103" r="0.5" style="stroke:#000000"/> +<circle cx="107" cy="159" r="0.5" style="stroke:#000000"/> +<circle cx="140" cy="80" r="0.5" style="stroke:#000000"/> +<circle cx="134" cy="81" r="0.5" style="stroke:#000000"/> +<circle cx="76" cy="60" r="0.5" style="stroke:#000000"/> +<circle cx="123" cy="123" r="0.5" style="stroke:#000000"/> +<circle cx="139" cy="64" r="0.5" style="stroke:#000000"/> +<circle cx="100" cy="100" r="0.5" style="stroke:#000000"/> +<circle cx="110" cy="96" r="0.5" style="stroke:#000000"/> +<circle cx="110" cy="159" r="0.5" style="stroke:#000000"/> +<circle cx="67" cy="117" r="0.5" style="stroke:#000000"/> +<circle cx="140" cy="159" r="0.5" style="stroke:#000000"/> +<circle cx="103" cy="101" r="0.5" style="stroke:#000000"/> +<circle cx="99" cy="88" r="0.5" style="stroke:#000000"/> +<circle cx="100" cy="101" r="0.5" style="stroke:#000000"/> +<circle cx="76" cy="89" r="0.5" style="stroke:#000000"/> +<circle cx="37" cy="80" r="0.5" style="stroke:#000000"/> +<circle cx="62" cy="78" r="0.5" style="stroke:#000000"/> +<circle cx="115" cy="34" r="0.5" style="stroke:#000000"/> +<circle cx="36" cy="79" r="0.5" style="stroke:#000000"/> +<circle cx="60" cy="70" r="0.5" style="stroke:#000000"/> +<circle cx="137" cy="124" r="0.5" style="stroke:#000000"/> +<circle cx="156" cy="144" r="0.5" style="stroke:#000000"/> +<circle cx="111" cy="124" r="0.5" style="stroke:#000000"/> +<circle cx="137" cy="168" r="0.5" style="stroke:#000000"/> +<circle cx="110" cy="55" r="0.5" style="stroke:#000000"/> +<circle cx="75" cy="111" r="0.5" style="stroke:#000000"/> +<circle cx="137" cy="171" r="0.5" style="stroke:#000000"/> +<circle cx="102" cy="68" r="0.5" style="stroke:#000000"/> +<circle cx="63" cy="131" r="0.5" style="stroke:#000000"/> +<circle cx="122" cy="78" r="0.5" style="stroke:#000000"/> +<circle cx="126" cy="104" r="0.5" style="stroke:#000000"/> +<circle cx="86" cy="144" r="0.5" style="stroke:#000000"/> +<circle cx="123" cy="122" r="0.5" style="stroke:#000000"/> +<circle cx="92" cy="88" r="0.5" style="stroke:#000000"/> +<circle cx="91" cy="140" r="0.5" style="stroke:#000000"/> +<circle cx="91" cy="78" r="0.5" style="stroke:#000000"/> +<circle cx="126" cy="112" r="0.5" style="stroke:#000000"/> +<circle cx="84" cy="78" r="0.5" style="stroke:#000000"/> +<circle cx="147" cy="87" r="0.5" style="stroke:#000000"/> +<circle cx="70" cy="85" r="0.5" style="stroke:#000000"/> +<circle cx="47" cy="77" r="0.5" style="stroke:#000000"/> +<circle cx="127" cy="46" r="0.5" style="stroke:#000000"/> +<circle cx="100" cy="100" r="0.5" style="stroke:#000000"/> +<circle cx="142" cy="163" r="0.5" style="stroke:#000000"/> +<circle cx="101" cy="99" r="0.5" style="stroke:#000000"/> +<circle cx="88" cy="119" r="0.5" style="stroke:#000000"/> +<circle cx="87" cy="93" r="0.5" style="stroke:#000000"/> +<circle cx="113" cy="88" r="0.5" style="stroke:#000000"/> +<circle cx="96" cy="83" r="0.5" style="stroke:#000000"/> +<circle cx="106" cy="102" r="0.5" style="stroke:#000000"/> +<circle cx="124" cy="130" r="0.5" style="stroke:#000000"/> +<circle cx="80" cy="99" r="0.5" style="stroke:#000000"/> +<circle cx="155" cy="144" r="0.5" style="stroke:#000000"/> +<circle cx="59" cy="74" r="0.5" style="stroke:#000000"/> +<circle cx="50" cy="94" r="0.5" style="stroke:#000000"/> +<circle cx="103" cy="120" r="0.5" style="stroke:#000000"/> +<circle cx="102" cy="100" r="0.5" style="stroke:#000000"/> +<circle cx="20" cy="98" r="0.5" style="stroke:#000000"/> +<circle cx="92" cy="136" r="0.5" style="stroke:#000000"/> +<circle cx="75" cy="115" r="0.5" style="stroke:#000000"/> +<circle cx="75" cy="74" r="0.5" style="stroke:#000000"/> +<circle cx="146" cy="165" r="0.5" style="stroke:#000000"/> +<circle cx="73" cy="56" r="0.5" style="stroke:#000000"/> +<circle cx="122" cy="45" r="0.5" style="stroke:#000000"/> +<circle cx="115" cy="59" r="0.5" style="stroke:#000000"/> +<circle cx="160" cy="97" r="0.5" style="stroke:#000000"/> +<circle cx="116" cy="161" r="0.5" style="stroke:#000000"/> +<circle cx="139" cy="63" r="0.5" style="stroke:#000000"/> +<circle cx="115" cy="57" r="0.5" style="stroke:#000000"/> +<circle cx="89" cy="94" r="0.5" style="stroke:#000000"/> +<circle cx="72" cy="64" r="0.5" style="stroke:#000000"/> +<circle cx="53" cy="99" r="0.5" style="stroke:#000000"/> +<circle cx="95" cy="110" r="0.5" style="stroke:#000000"/> +<circle cx="99" cy="100" r="0.5" style="stroke:#000000"/> +<circle cx="81" cy="158" r="0.5" style="stroke:#000000"/> +<circle cx="77" cy="46" r="0.5" style="stroke:#000000"/> +<circle cx="104" cy="118" r="0.5" style="stroke:#000000"/> +<circle cx="98" cy="160" r="0.5" style="stroke:#000000"/> +<circle cx="102" cy="121" r="0.5" style="stroke:#000000"/> +<circle cx="81" cy="88" r="0.5" style="stroke:#000000"/> +<circle cx="145" cy="163" r="0.5" style="stroke:#000000"/> +<circle cx="110" cy="94" r="0.5" style="stroke:#000000"/> +<circle cx="72" cy="122" r="0.5" style="stroke:#000000"/> +<circle cx="103" cy="96" r="0.5" style="stroke:#000000"/> +<circle cx="101" cy="95" r="0.5" style="stroke:#000000"/> +<circle cx="95" cy="163" r="0.5" style="stroke:#000000"/> +<circle cx="99" cy="101" r="0.5" style="stroke:#000000"/> +<circle cx="89" cy="106" r="0.5" style="stroke:#000000"/> +<circle cx="98" cy="101" r="0.5" style="stroke:#000000"/> +<circle cx="70" cy="138" r="0.5" style="stroke:#000000"/> +<circle cx="149" cy="134" r="0.5" style="stroke:#000000"/> +<circle cx="117" cy="33" r="0.5" style="stroke:#000000"/> +<circle cx="96" cy="155" r="0.5" style="stroke:#000000"/> +<circle cx="105" cy="90" r="0.5" style="stroke:#000000"/> +<circle cx="101" cy="83" r="0.5" style="stroke:#000000"/> +<circle cx="93" cy="115" r="0.5" style="stroke:#000000"/> +<circle cx="94" cy="98" r="0.5" style="stroke:#000000"/> +<circle cx="114" cy="105" r="0.5" style="stroke:#000000"/> +<circle cx="70" cy="103" r="0.5" style="stroke:#000000"/> +<circle cx="114" cy="103" r="0.5" style="stroke:#000000"/> +<circle cx="93" cy="103" r="0.5" style="stroke:#000000"/> +<circle cx="43" cy="135" r="0.5" style="stroke:#000000"/> +<circle cx="152" cy="161" r="0.5" style="stroke:#000000"/> +<circle cx="104" cy="102" r="0.5" style="stroke:#000000"/> +<circle cx="93" cy="106" r="0.5" style="stroke:#000000"/> +<circle cx="173" cy="115" r="0.5" style="stroke:#000000"/> +<circle cx="139" cy="79" r="0.5" style="stroke:#000000"/> +<circle cx="99" cy="99" r="0.5" style="stroke:#000000"/> +<circle cx="70" cy="85" r="0.5" style="stroke:#000000"/> +<circle cx="132" cy="148" r="0.5" style="stroke:#000000"/> +<circle cx="99" cy="101" r="0.5" style="stroke:#000000"/> +<circle cx="100" cy="97" r="0.5" style="stroke:#000000"/> +<circle cx="47" cy="128" r="0.5" style="stroke:#000000"/> +<circle cx="112" cy="105" r="0.5" style="stroke:#000000"/> +<circle cx="127" cy="115" r="0.5" style="stroke:#000000"/> +<circle cx="122" cy="84" r="0.5" style="stroke:#000000"/> +<circle cx="126" cy="77" r="0.5" style="stroke:#000000"/> +<circle cx="121" cy="44" r="0.5" style="stroke:#000000"/> +<circle cx="48" cy="72" r="0.5" style="stroke:#000000"/> +<circle cx="75" cy="86" r="0.5" style="stroke:#000000"/> +<circle cx="105" cy="87" r="0.5" style="stroke:#000000"/> +<circle cx="79" cy="91" r="0.5" style="stroke:#000000"/> +<circle cx="148" cy="123" r="0.5" style="stroke:#000000"/> +<circle cx="114" cy="105" r="0.5" style="stroke:#000000"/> +<circle cx="52" cy="87" r="0.5" style="stroke:#000000"/> +<circle cx="100" cy="100" r="0.5" style="stroke:#000000"/> +<circle cx="134" cy="80" r="0.5" style="stroke:#000000"/> +<circle cx="84" cy="58" r="0.5" style="stroke:#000000"/> +<circle cx="97" cy="73" r="0.5" style="stroke:#000000"/> +<circle cx="88" cy="102" r="0.5" style="stroke:#000000"/> +<circle cx="71" cy="159" r="0.5" style="stroke:#000000"/> +<circle cx="133" cy="63" r="0.5" style="stroke:#000000"/> +<circle cx="80" cy="119" r="0.5" style="stroke:#000000"/> +<circle cx="137" cy="61" r="0.5" style="stroke:#000000"/> +<circle cx="109" cy="168" r="0.5" style="stroke:#000000"/> +<circle cx="91" cy="69" r="0.5" style="stroke:#000000"/> +<circle cx="68" cy="97" r="0.5" style="stroke:#000000"/> +<circle cx="117" cy="117" r="0.5" style="stroke:#000000"/> +<circle cx="121" cy="62" r="0.5" style="stroke:#000000"/> +<circle cx="84" cy="50" r="0.5" style="stroke:#000000"/> +<circle cx="101" cy="46" r="0.5" style="stroke:#000000"/> +<circle cx="102" cy="98" r="0.5" style="stroke:#000000"/> +<circle cx="151" cy="155" r="0.5" style="stroke:#000000"/> +<circle cx="52" cy="114" r="0.5" style="stroke:#000000"/> +<circle cx="109" cy="86" r="0.5" style="stroke:#000000"/> +<circle cx="175" cy="91" r="0.5" style="stroke:#000000"/> +<circle cx="178" cy="87" r="0.5" style="stroke:#000000"/> +<circle cx="97" cy="95" r="0.5" style="stroke:#000000"/> +<circle cx="90" cy="92" r="0.5" style="stroke:#000000"/> +<circle cx="53" cy="72" r="0.5" style="stroke:#000000"/> +<circle cx="108" cy="89" r="0.5" style="stroke:#000000"/> +<circle cx="110" cy="95" r="0.5" style="stroke:#000000"/> +<circle cx="64" cy="81" r="0.5" style="stroke:#000000"/> +<circle cx="166" cy="121" r="0.5" style="stroke:#000000"/> +<circle cx="146" cy="97" r="0.5" style="stroke:#000000"/> +<circle cx="112" cy="74" r="0.5" style="stroke:#000000"/> +<circle cx="54" cy="141" r="0.5" style="stroke:#000000"/> +<circle cx="40" cy="64" r="0.5" style="stroke:#000000"/> +<circle cx="71" cy="79" r="0.5" style="stroke:#000000"/> +<circle cx="96" cy="101" r="0.5" style="stroke:#000000"/> +<circle cx="119" cy="76" r="0.5" style="stroke:#000000"/> +<circle cx="85" cy="28" r="0.5" style="stroke:#000000"/> +<circle cx="49" cy="94" r="0.5" style="stroke:#000000"/> +<circle cx="127" cy="37" r="0.5" style="stroke:#000000"/> +<circle cx="78" cy="145" r="0.5" style="stroke:#000000"/> +<circle cx="94" cy="94" r="0.5" style="stroke:#000000"/> +<circle cx="100" cy="100" r="0.5" style="stroke:#000000"/> +<circle cx="128" cy="147" r="0.5" style="stroke:#000000"/> +<circle cx="101" cy="100" r="0.5" style="stroke:#000000"/> +<circle cx="56" cy="62" r="0.5" style="stroke:#000000"/> +<circle cx="61" cy="123" r="0.5" style="stroke:#000000"/> +<circle cx="44" cy="71" r="0.5" style="stroke:#000000"/> +<circle cx="92" cy="86" r="0.5" style="stroke:#000000"/> +<circle cx="169" cy="100" r="0.5" style="stroke:#000000"/> +<circle cx="86" cy="107" r="0.5" style="stroke:#000000"/> +<circle cx="52" cy="63" r="0.5" style="stroke:#000000"/> +<circle cx="95" cy="98" r="0.5" style="stroke:#000000"/> +<circle cx="106" cy="89" r="0.5" style="stroke:#000000"/> +<circle cx="32" cy="131" r="0.5" style="stroke:#000000"/> +<circle cx="170" cy="106" r="0.5" style="stroke:#000000"/> +<circle cx="95" cy="93" r="0.5" style="stroke:#000000"/> +<circle cx="57" cy="101" r="0.5" style="stroke:#000000"/> +<circle cx="62" cy="142" r="0.5" style="stroke:#000000"/> +<circle cx="95" cy="95" r="0.5" style="stroke:#000000"/> +<circle cx="95" cy="129" r="0.5" style="stroke:#000000"/> +<circle cx="71" cy="158" r="0.5" style="stroke:#000000"/> +<circle cx="124" cy="61" r="0.5" style="stroke:#000000"/> +<circle cx="33" cy="142" r="0.5" style="stroke:#000000"/> +<circle cx="94" cy="174" r="0.5" style="stroke:#000000"/> +<circle cx="176" cy="115" r="0.5" style="stroke:#000000"/> +<circle cx="69" cy="93" r="0.5" style="stroke:#000000"/> +<circle cx="73" cy="57" r="0.5" style="stroke:#000000"/> +<circle cx="162" cy="93" r="0.5" style="stroke:#000000"/> +<circle cx="69" cy="71" r="0.5" style="stroke:#000000"/> +<circle cx="145" cy="64" r="0.5" style="stroke:#000000"/> +<circle cx="145" cy="293" r="0.5" style="stroke:#000000"/> +<circle cx="159" cy="302" r="0.5" style="stroke:#000000"/> +<circle cx="141" cy="315" r="0.5" style="stroke:#000000"/> +<circle cx="137" cy="325" r="0.5" style="stroke:#000000"/> +<circle cx="147" cy="301" r="0.5" style="stroke:#000000"/> +<circle cx="152" cy="322" r="0.5" style="stroke:#000000"/> +<circle cx="165" cy="293" r="0.5" style="stroke:#000000"/> +<circle cx="163" cy="293" r="0.5" style="stroke:#000000"/> +<circle cx="141" cy="285" r="0.5" style="stroke:#000000"/> +<circle cx="159" cy="309" r="0.5" style="stroke:#000000"/> +<circle cx="164" cy="287" r="0.5" style="stroke:#000000"/> +<circle cx="150" cy="300" r="0.5" style="stroke:#000000"/> +<circle cx="154" cy="299" r="0.5" style="stroke:#000000"/> +<circle cx="154" cy="322" r="0.5" style="stroke:#000000"/> +<circle cx="138" cy="306" r="0.5" style="stroke:#000000"/> +<circle cx="165" cy="322" r="0.5" style="stroke:#000000"/> +<circle cx="151" cy="301" r="0.5" style="stroke:#000000"/> +<circle cx="150" cy="295" r="0.5" style="stroke:#000000"/> +<circle cx="150" cy="300" r="0.5" style="stroke:#000000"/> +<circle cx="141" cy="296" r="0.5" style="stroke:#000000"/> +<circle cx="126" cy="292" r="0.5" style="stroke:#000000"/> +<circle cx="136" cy="292" r="0.5" style="stroke:#000000"/> +<circle cx="156" cy="275" r="0.5" style="stroke:#000000"/> +<circle cx="126" cy="292" r="0.5" style="stroke:#000000"/> +<circle cx="135" cy="289" r="0.5" style="stroke:#000000"/> +<circle cx="164" cy="309" r="0.5" style="stroke:#000000"/> +<circle cx="171" cy="316" r="0.5" style="stroke:#000000"/> +<circle cx="154" cy="309" r="0.5" style="stroke:#000000"/> +<circle cx="164" cy="326" r="0.5" style="stroke:#000000"/> +<circle cx="154" cy="283" r="0.5" style="stroke:#000000"/> +<circle cx="141" cy="304" r="0.5" style="stroke:#000000"/> +<circle cx="164" cy="326" r="0.5" style="stroke:#000000"/> +<circle cx="151" cy="288" r="0.5" style="stroke:#000000"/> +<circle cx="136" cy="312" r="0.5" style="stroke:#000000"/> +<circle cx="158" cy="292" r="0.5" style="stroke:#000000"/> +<circle cx="160" cy="302" r="0.5" style="stroke:#000000"/> +<circle cx="145" cy="317" r="0.5" style="stroke:#000000"/> +<circle cx="158" cy="308" r="0.5" style="stroke:#000000"/> +<circle cx="147" cy="295" r="0.5" style="stroke:#000000"/> +<circle cx="147" cy="315" r="0.5" style="stroke:#000000"/> +<circle cx="147" cy="292" r="0.5" style="stroke:#000000"/> +<circle cx="160" cy="304" r="0.5" style="stroke:#000000"/> +<circle cx="144" cy="292" r="0.5" style="stroke:#000000"/> +<circle cx="168" cy="295" r="0.5" style="stroke:#000000"/> +<circle cx="139" cy="294" r="0.5" style="stroke:#000000"/> +<circle cx="130" cy="292" r="0.5" style="stroke:#000000"/> +<circle cx="160" cy="280" r="0.5" style="stroke:#000000"/> +<circle cx="150" cy="300" r="0.5" style="stroke:#000000"/> +<circle cx="166" cy="323" r="0.5" style="stroke:#000000"/> +<circle cx="150" cy="299" r="0.5" style="stroke:#000000"/> +<circle cx="145" cy="307" r="0.5" style="stroke:#000000"/> +<circle cx="145" cy="297" r="0.5" style="stroke:#000000"/> +<circle cx="155" cy="296" r="0.5" style="stroke:#000000"/> +<circle cx="148" cy="294" r="0.5" style="stroke:#000000"/> +<circle cx="152" cy="301" r="0.5" style="stroke:#000000"/> +<circle cx="159" cy="311" r="0.5" style="stroke:#000000"/> +<circle cx="142" cy="300" r="0.5" style="stroke:#000000"/> +<circle cx="171" cy="317" r="0.5" style="stroke:#000000"/> +<circle cx="135" cy="290" r="0.5" style="stroke:#000000"/> +<circle cx="131" cy="298" r="0.5" style="stroke:#000000"/> +<circle cx="151" cy="307" r="0.5" style="stroke:#000000"/> +<circle cx="151" cy="300" r="0.5" style="stroke:#000000"/> +<circle cx="120" cy="299" r="0.5" style="stroke:#000000"/> +<circle cx="147" cy="314" r="0.5" style="stroke:#000000"/> +<circle cx="141" cy="305" r="0.5" style="stroke:#000000"/> +<circle cx="141" cy="290" r="0.5" style="stroke:#000000"/> +<circle cx="167" cy="324" r="0.5" style="stroke:#000000"/> +<circle cx="140" cy="283" r="0.5" style="stroke:#000000"/> +<circle cx="158" cy="279" r="0.5" style="stroke:#000000"/> +<circle cx="155" cy="284" r="0.5" style="stroke:#000000"/> +<circle cx="172" cy="299" r="0.5" style="stroke:#000000"/> +<circle cx="156" cy="323" r="0.5" style="stroke:#000000"/> +<circle cx="164" cy="286" r="0.5" style="stroke:#000000"/> +<circle cx="156" cy="284" r="0.5" style="stroke:#000000"/> +<circle cx="146" cy="298" r="0.5" style="stroke:#000000"/> +<circle cx="140" cy="286" r="0.5" style="stroke:#000000"/> +<circle cx="133" cy="300" r="0.5" style="stroke:#000000"/> +<circle cx="148" cy="304" r="0.5" style="stroke:#000000"/> +<circle cx="149" cy="300" r="0.5" style="stroke:#000000"/> +<circle cx="143" cy="322" r="0.5" style="stroke:#000000"/> +<circle cx="141" cy="280" r="0.5" style="stroke:#000000"/> +<circle cx="152" cy="307" r="0.5" style="stroke:#000000"/> +<circle cx="149" cy="322" r="0.5" style="stroke:#000000"/> +<circle cx="151" cy="308" r="0.5" style="stroke:#000000"/> +<circle cx="143" cy="296" r="0.5" style="stroke:#000000"/> +<circle cx="167" cy="323" r="0.5" style="stroke:#000000"/> +<circle cx="154" cy="298" r="0.5" style="stroke:#000000"/> +<circle cx="139" cy="308" r="0.5" style="stroke:#000000"/> +<circle cx="151" cy="299" r="0.5" style="stroke:#000000"/> +<circle cx="150" cy="298" r="0.5" style="stroke:#000000"/> +<circle cx="148" cy="324" r="0.5" style="stroke:#000000"/> +<circle cx="150" cy="301" r="0.5" style="stroke:#000000"/> +<circle cx="146" cy="302" r="0.5" style="stroke:#000000"/> +<circle cx="149" cy="300" r="0.5" style="stroke:#000000"/> +<circle cx="139" cy="314" r="0.5" style="stroke:#000000"/> +<circle cx="168" cy="313" r="0.5" style="stroke:#000000"/> +<circle cx="156" cy="275" r="0.5" style="stroke:#000000"/> +<circle cx="148" cy="321" r="0.5" style="stroke:#000000"/> +<circle cx="152" cy="296" r="0.5" style="stroke:#000000"/> +<circle cx="150" cy="294" r="0.5" style="stroke:#000000"/> +<circle cx="147" cy="305" r="0.5" style="stroke:#000000"/> +<circle cx="148" cy="299" r="0.5" style="stroke:#000000"/> +<circle cx="155" cy="302" r="0.5" style="stroke:#000000"/> +<circle cx="139" cy="301" r="0.5" style="stroke:#000000"/> +<circle cx="155" cy="301" r="0.5" style="stroke:#000000"/> +<circle cx="147" cy="301" r="0.5" style="stroke:#000000"/> +<circle cx="129" cy="313" r="0.5" style="stroke:#000000"/> +<circle cx="169" cy="323" r="0.5" style="stroke:#000000"/> +<circle cx="151" cy="301" r="0.5" style="stroke:#000000"/> +<circle cx="147" cy="302" r="0.5" style="stroke:#000000"/> +<circle cx="177" cy="305" r="0.5" style="stroke:#000000"/> +<circle cx="165" cy="292" r="0.5" style="stroke:#000000"/> +<circle cx="150" cy="300" r="0.5" style="stroke:#000000"/> +<circle cx="139" cy="294" r="0.5" style="stroke:#000000"/> +<circle cx="162" cy="318" r="0.5" style="stroke:#000000"/> +<circle cx="150" cy="300" r="0.5" style="stroke:#000000"/> +<circle cx="150" cy="299" r="0.5" style="stroke:#000000"/> +<circle cx="130" cy="310" r="0.5" style="stroke:#000000"/> +<circle cx="155" cy="302" r="0.5" style="stroke:#000000"/> +<circle cx="160" cy="306" r="0.5" style="stroke:#000000"/> +<circle cx="158" cy="294" r="0.5" style="stroke:#000000"/> +<circle cx="160" cy="291" r="0.5" style="stroke:#000000"/> +<circle cx="158" cy="279" r="0.5" style="stroke:#000000"/> +<circle cx="130" cy="289" r="0.5" style="stroke:#000000"/> +<circle cx="141" cy="295" r="0.5" style="stroke:#000000"/> +<circle cx="152" cy="295" r="0.5" style="stroke:#000000"/> +<circle cx="142" cy="297" r="0.5" style="stroke:#000000"/> +<circle cx="168" cy="309" r="0.5" style="stroke:#000000"/> +<circle cx="155" cy="302" r="0.5" style="stroke:#000000"/> +<circle cx="132" cy="295" r="0.5" style="stroke:#000000"/> +<circle cx="150" cy="300" r="0.5" style="stroke:#000000"/> +<circle cx="163" cy="293" r="0.5" style="stroke:#000000"/> +<circle cx="144" cy="284" r="0.5" style="stroke:#000000"/> +<circle cx="149" cy="290" r="0.5" style="stroke:#000000"/> +<circle cx="146" cy="301" r="0.5" style="stroke:#000000"/> +<circle cx="139" cy="322" r="0.5" style="stroke:#000000"/> +<circle cx="163" cy="286" r="0.5" style="stroke:#000000"/> +<circle cx="142" cy="307" r="0.5" style="stroke:#000000"/> +<circle cx="164" cy="286" r="0.5" style="stroke:#000000"/> +<circle cx="153" cy="325" r="0.5" style="stroke:#000000"/> +<circle cx="147" cy="289" r="0.5" style="stroke:#000000"/> +<circle cx="138" cy="299" r="0.5" style="stroke:#000000"/> +<circle cx="157" cy="306" r="0.5" style="stroke:#000000"/> +<circle cx="158" cy="286" r="0.5" style="stroke:#000000"/> +<circle cx="144" cy="281" r="0.5" style="stroke:#000000"/> +<circle cx="150" cy="280" r="0.5" style="stroke:#000000"/> +<circle cx="151" cy="299" r="0.5" style="stroke:#000000"/> +<circle cx="169" cy="321" r="0.5" style="stroke:#000000"/> +<circle cx="132" cy="305" r="0.5" style="stroke:#000000"/> +<circle cx="153" cy="295" r="0.5" style="stroke:#000000"/> +<circle cx="178" cy="297" r="0.5" style="stroke:#000000"/> +<circle cx="179" cy="295" r="0.5" style="stroke:#000000"/> +<circle cx="149" cy="298" r="0.5" style="stroke:#000000"/> +<circle cx="146" cy="297" r="0.5" style="stroke:#000000"/> +<circle cx="132" cy="290" r="0.5" style="stroke:#000000"/> +<circle cx="153" cy="296" r="0.5" style="stroke:#000000"/> +<circle cx="154" cy="298" r="0.5" style="stroke:#000000"/> +<circle cx="136" cy="293" r="0.5" style="stroke:#000000"/> +<circle cx="175" cy="308" r="0.5" style="stroke:#000000"/> +<circle cx="167" cy="299" r="0.5" style="stroke:#000000"/> +<circle cx="154" cy="290" r="0.5" style="stroke:#000000"/> +<circle cx="133" cy="316" r="0.5" style="stroke:#000000"/> +<circle cx="127" cy="286" r="0.5" style="stroke:#000000"/> +<circle cx="139" cy="292" r="0.5" style="stroke:#000000"/> +<circle cx="148" cy="300" r="0.5" style="stroke:#000000"/> +<circle cx="157" cy="291" r="0.5" style="stroke:#000000"/> +<circle cx="144" cy="273" r="0.5" style="stroke:#000000"/> +<circle cx="131" cy="298" r="0.5" style="stroke:#000000"/> +<circle cx="160" cy="276" r="0.5" style="stroke:#000000"/> +<circle cx="142" cy="317" r="0.5" style="stroke:#000000"/> +<circle cx="148" cy="298" r="0.5" style="stroke:#000000"/> +<circle cx="150" cy="300" r="0.5" style="stroke:#000000"/> +<circle cx="161" cy="318" r="0.5" style="stroke:#000000"/> +<circle cx="150" cy="300" r="0.5" style="stroke:#000000"/> +<circle cx="134" cy="286" r="0.5" style="stroke:#000000"/> +<circle cx="135" cy="309" r="0.5" style="stroke:#000000"/> +<circle cx="129" cy="289" r="0.5" style="stroke:#000000"/> +<circle cx="147" cy="295" r="0.5" style="stroke:#000000"/> +<circle cx="176" cy="300" r="0.5" style="stroke:#000000"/> +<circle cx="145" cy="303" r="0.5" style="stroke:#000000"/> +<circle cx="132" cy="286" r="0.5" style="stroke:#000000"/> +<circle cx="148" cy="299" r="0.5" style="stroke:#000000"/> +<circle cx="152" cy="296" r="0.5" style="stroke:#000000"/> +<circle cx="124" cy="311" r="0.5" style="stroke:#000000"/> +<circle cx="176" cy="302" r="0.5" style="stroke:#000000"/> +<circle cx="148" cy="297" r="0.5" style="stroke:#000000"/> +<circle cx="134" cy="301" r="0.5" style="stroke:#000000"/> +<circle cx="136" cy="316" r="0.5" style="stroke:#000000"/> +<circle cx="148" cy="298" r="0.5" style="stroke:#000000"/> +<circle cx="148" cy="311" r="0.5" style="stroke:#000000"/> +<circle cx="139" cy="322" r="0.5" style="stroke:#000000"/> +<circle cx="159" cy="285" r="0.5" style="stroke:#000000"/> +<circle cx="125" cy="316" r="0.5" style="stroke:#000000"/> +<circle cx="148" cy="328" r="0.5" style="stroke:#000000"/> +<circle cx="178" cy="306" r="0.5" style="stroke:#000000"/> +<circle cx="138" cy="297" r="0.5" style="stroke:#000000"/> +<circle cx="140" cy="284" r="0.5" style="stroke:#000000"/> +<circle cx="173" cy="297" r="0.5" style="stroke:#000000"/> +<circle cx="138" cy="289" r="0.5" style="stroke:#000000"/> +<circle cx="167" cy="287" r="0.5" style="stroke:#000000"/> +<circle cx="495" cy="113" r="0.5" style="stroke:#000000"/> +<circle cx="509" cy="122" r="0.5" style="stroke:#000000"/> +<circle cx="491" cy="135" r="0.5" style="stroke:#000000"/> +<circle cx="487" cy="145" r="0.5" style="stroke:#000000"/> +<circle cx="497" cy="121" r="0.5" style="stroke:#000000"/> +<circle cx="502" cy="142" r="0.5" style="stroke:#000000"/> +<circle cx="515" cy="113" r="0.5" style="stroke:#000000"/> +<circle cx="513" cy="113" r="0.5" style="stroke:#000000"/> +<circle cx="491" cy="105" r="0.5" style="stroke:#000000"/> +<circle cx="509" cy="129" r="0.5" style="stroke:#000000"/> +<circle cx="514" cy="107" r="0.5" style="stroke:#000000"/> +<circle cx="500" cy="120" r="0.5" style="stroke:#000000"/> +<circle cx="504" cy="119" r="0.5" style="stroke:#000000"/> +<circle cx="504" cy="142" r="0.5" style="stroke:#000000"/> +<circle cx="488" cy="126" r="0.5" style="stroke:#000000"/> +<circle cx="515" cy="142" r="0.5" style="stroke:#000000"/> +<circle cx="501" cy="121" r="0.5" style="stroke:#000000"/> +<circle cx="500" cy="115" r="0.5" style="stroke:#000000"/> +<circle cx="500" cy="120" r="0.5" style="stroke:#000000"/> +<circle cx="491" cy="116" r="0.5" style="stroke:#000000"/> +<circle cx="476" cy="112" r="0.5" style="stroke:#000000"/> +<circle cx="486" cy="112" r="0.5" style="stroke:#000000"/> +<circle cx="506" cy="95" r="0.5" style="stroke:#000000"/> +<circle cx="476" cy="112" r="0.5" style="stroke:#000000"/> +<circle cx="485" cy="109" r="0.5" style="stroke:#000000"/> +<circle cx="514" cy="129" r="0.5" style="stroke:#000000"/> +<circle cx="521" cy="136" r="0.5" style="stroke:#000000"/> +<circle cx="504" cy="129" r="0.5" style="stroke:#000000"/> +<circle cx="514" cy="146" r="0.5" style="stroke:#000000"/> +<circle cx="504" cy="103" r="0.5" style="stroke:#000000"/> +<circle cx="491" cy="124" r="0.5" style="stroke:#000000"/> +<circle cx="514" cy="146" r="0.5" style="stroke:#000000"/> +<circle cx="501" cy="108" r="0.5" style="stroke:#000000"/> +<circle cx="486" cy="132" r="0.5" style="stroke:#000000"/> +<circle cx="508" cy="112" r="0.5" style="stroke:#000000"/> +<circle cx="510" cy="122" r="0.5" style="stroke:#000000"/> +<circle cx="495" cy="137" r="0.5" style="stroke:#000000"/> +<circle cx="508" cy="128" r="0.5" style="stroke:#000000"/> +<circle cx="497" cy="115" r="0.5" style="stroke:#000000"/> +<circle cx="497" cy="135" r="0.5" style="stroke:#000000"/> +<circle cx="497" cy="112" r="0.5" style="stroke:#000000"/> +<circle cx="510" cy="124" r="0.5" style="stroke:#000000"/> +<circle cx="494" cy="112" r="0.5" style="stroke:#000000"/> +<circle cx="518" cy="115" r="0.5" style="stroke:#000000"/> +<circle cx="489" cy="114" r="0.5" style="stroke:#000000"/> +<circle cx="480" cy="112" r="0.5" style="stroke:#000000"/> +<circle cx="510" cy="100" r="0.5" style="stroke:#000000"/> +<circle cx="500" cy="120" r="0.5" style="stroke:#000000"/> +<circle cx="516" cy="143" r="0.5" style="stroke:#000000"/> +<circle cx="500" cy="119" r="0.5" style="stroke:#000000"/> +<circle cx="495" cy="127" r="0.5" style="stroke:#000000"/> +<circle cx="495" cy="117" r="0.5" style="stroke:#000000"/> +<circle cx="505" cy="116" r="0.5" style="stroke:#000000"/> +<circle cx="498" cy="114" r="0.5" style="stroke:#000000"/> +<circle cx="502" cy="121" r="0.5" style="stroke:#000000"/> +<circle cx="509" cy="131" r="0.5" style="stroke:#000000"/> +<circle cx="492" cy="120" r="0.5" style="stroke:#000000"/> +<circle cx="521" cy="137" r="0.5" style="stroke:#000000"/> +<circle cx="485" cy="110" r="0.5" style="stroke:#000000"/> +<circle cx="481" cy="118" r="0.5" style="stroke:#000000"/> +<circle cx="501" cy="127" r="0.5" style="stroke:#000000"/> +<circle cx="501" cy="120" r="0.5" style="stroke:#000000"/> +<circle cx="470" cy="119" r="0.5" style="stroke:#000000"/> +<circle cx="497" cy="134" r="0.5" style="stroke:#000000"/> +<circle cx="491" cy="125" r="0.5" style="stroke:#000000"/> +<circle cx="491" cy="110" r="0.5" style="stroke:#000000"/> +<circle cx="517" cy="144" r="0.5" style="stroke:#000000"/> +<circle cx="490" cy="103" r="0.5" style="stroke:#000000"/> +<circle cx="508" cy="99" r="0.5" style="stroke:#000000"/> +<circle cx="505" cy="104" r="0.5" style="stroke:#000000"/> +<circle cx="522" cy="119" r="0.5" style="stroke:#000000"/> +<circle cx="506" cy="143" r="0.5" style="stroke:#000000"/> +<circle cx="514" cy="106" r="0.5" style="stroke:#000000"/> +<circle cx="506" cy="104" r="0.5" style="stroke:#000000"/> +<circle cx="496" cy="118" r="0.5" style="stroke:#000000"/> +<circle cx="490" cy="106" r="0.5" style="stroke:#000000"/> +<circle cx="483" cy="120" r="0.5" style="stroke:#000000"/> +<circle cx="498" cy="124" r="0.5" style="stroke:#000000"/> +<circle cx="499" cy="120" r="0.5" style="stroke:#000000"/> +<circle cx="493" cy="142" r="0.5" style="stroke:#000000"/> +<circle cx="491" cy="100" r="0.5" style="stroke:#000000"/> +<circle cx="502" cy="127" r="0.5" style="stroke:#000000"/> +<circle cx="499" cy="142" r="0.5" style="stroke:#000000"/> +<circle cx="501" cy="128" r="0.5" style="stroke:#000000"/> +<circle cx="493" cy="116" r="0.5" style="stroke:#000000"/> +<circle cx="517" cy="143" r="0.5" style="stroke:#000000"/> +<circle cx="504" cy="118" r="0.5" style="stroke:#000000"/> +<circle cx="489" cy="128" r="0.5" style="stroke:#000000"/> +<circle cx="501" cy="119" r="0.5" style="stroke:#000000"/> +<circle cx="500" cy="118" r="0.5" style="stroke:#000000"/> +<circle cx="498" cy="144" r="0.5" style="stroke:#000000"/> +<circle cx="500" cy="121" r="0.5" style="stroke:#000000"/> +<circle cx="496" cy="122" r="0.5" style="stroke:#000000"/> +<circle cx="499" cy="120" r="0.5" style="stroke:#000000"/> +<circle cx="489" cy="134" r="0.5" style="stroke:#000000"/> +<circle cx="518" cy="133" r="0.5" style="stroke:#000000"/> +<circle cx="506" cy="95" r="0.5" style="stroke:#000000"/> +<circle cx="498" cy="141" r="0.5" style="stroke:#000000"/> +<circle cx="502" cy="116" r="0.5" style="stroke:#000000"/> +<circle cx="500" cy="114" r="0.5" style="stroke:#000000"/> +<circle cx="497" cy="125" r="0.5" style="stroke:#000000"/> +<circle cx="498" cy="119" r="0.5" style="stroke:#000000"/> +<circle cx="505" cy="122" r="0.5" style="stroke:#000000"/> +<circle cx="489" cy="121" r="0.5" style="stroke:#000000"/> +<circle cx="505" cy="121" r="0.5" style="stroke:#000000"/> +<circle cx="497" cy="121" r="0.5" style="stroke:#000000"/> +<circle cx="479" cy="133" r="0.5" style="stroke:#000000"/> +<circle cx="519" cy="143" r="0.5" style="stroke:#000000"/> +<circle cx="501" cy="121" r="0.5" style="stroke:#000000"/> +<circle cx="497" cy="122" r="0.5" style="stroke:#000000"/> +<circle cx="527" cy="125" r="0.5" style="stroke:#000000"/> +<circle cx="515" cy="112" r="0.5" style="stroke:#000000"/> +<circle cx="500" cy="120" r="0.5" style="stroke:#000000"/> +<circle cx="489" cy="114" r="0.5" style="stroke:#000000"/> +<circle cx="512" cy="138" r="0.5" style="stroke:#000000"/> +<circle cx="500" cy="120" r="0.5" style="stroke:#000000"/> +<circle cx="500" cy="119" r="0.5" style="stroke:#000000"/> +<circle cx="480" cy="130" r="0.5" style="stroke:#000000"/> +<circle cx="505" cy="122" r="0.5" style="stroke:#000000"/> +<circle cx="510" cy="126" r="0.5" style="stroke:#000000"/> +<circle cx="508" cy="114" r="0.5" style="stroke:#000000"/> +<circle cx="510" cy="111" r="0.5" style="stroke:#000000"/> +<circle cx="508" cy="99" r="0.5" style="stroke:#000000"/> +<circle cx="480" cy="109" r="0.5" style="stroke:#000000"/> +<circle cx="491" cy="115" r="0.5" style="stroke:#000000"/> +<circle cx="502" cy="115" r="0.5" style="stroke:#000000"/> +<circle cx="492" cy="117" r="0.5" style="stroke:#000000"/> +<circle cx="518" cy="129" r="0.5" style="stroke:#000000"/> +<circle cx="505" cy="122" r="0.5" style="stroke:#000000"/> +<circle cx="482" cy="115" r="0.5" style="stroke:#000000"/> +<circle cx="500" cy="120" r="0.5" style="stroke:#000000"/> +<circle cx="513" cy="113" r="0.5" style="stroke:#000000"/> +<circle cx="494" cy="104" r="0.5" style="stroke:#000000"/> +<circle cx="499" cy="110" r="0.5" style="stroke:#000000"/> +<circle cx="496" cy="121" r="0.5" style="stroke:#000000"/> +<circle cx="489" cy="142" r="0.5" style="stroke:#000000"/> +<circle cx="513" cy="106" r="0.5" style="stroke:#000000"/> +<circle cx="492" cy="127" r="0.5" style="stroke:#000000"/> +<circle cx="514" cy="106" r="0.5" style="stroke:#000000"/> +<circle cx="503" cy="145" r="0.5" style="stroke:#000000"/> +<circle cx="497" cy="109" r="0.5" style="stroke:#000000"/> +<circle cx="488" cy="119" r="0.5" style="stroke:#000000"/> +<circle cx="507" cy="126" r="0.5" style="stroke:#000000"/> +<circle cx="508" cy="106" r="0.5" style="stroke:#000000"/> +<circle cx="494" cy="101" r="0.5" style="stroke:#000000"/> +<circle cx="500" cy="100" r="0.5" style="stroke:#000000"/> +<circle cx="501" cy="119" r="0.5" style="stroke:#000000"/> +<circle cx="519" cy="141" r="0.5" style="stroke:#000000"/> +<circle cx="482" cy="125" r="0.5" style="stroke:#000000"/> +<circle cx="503" cy="115" r="0.5" style="stroke:#000000"/> +<circle cx="528" cy="117" r="0.5" style="stroke:#000000"/> +<circle cx="529" cy="115" r="0.5" style="stroke:#000000"/> +<circle cx="499" cy="118" r="0.5" style="stroke:#000000"/> +<circle cx="496" cy="117" r="0.5" style="stroke:#000000"/> +<circle cx="482" cy="110" r="0.5" style="stroke:#000000"/> +<circle cx="503" cy="116" r="0.5" style="stroke:#000000"/> +<circle cx="504" cy="118" r="0.5" style="stroke:#000000"/> +<circle cx="486" cy="113" r="0.5" style="stroke:#000000"/> +<circle cx="525" cy="128" r="0.5" style="stroke:#000000"/> +<circle cx="517" cy="119" r="0.5" style="stroke:#000000"/> +<circle cx="504" cy="110" r="0.5" style="stroke:#000000"/> +<circle cx="483" cy="136" r="0.5" style="stroke:#000000"/> +<circle cx="477" cy="106" r="0.5" style="stroke:#000000"/> +<circle cx="489" cy="112" r="0.5" style="stroke:#000000"/> +<circle cx="498" cy="120" r="0.5" style="stroke:#000000"/> +<circle cx="507" cy="111" r="0.5" style="stroke:#000000"/> +<circle cx="494" cy="93" r="0.5" style="stroke:#000000"/> +<circle cx="481" cy="118" r="0.5" style="stroke:#000000"/> +<circle cx="510" cy="96" r="0.5" style="stroke:#000000"/> +<circle cx="492" cy="137" r="0.5" style="stroke:#000000"/> +<circle cx="498" cy="118" r="0.5" style="stroke:#000000"/> +<circle cx="500" cy="120" r="0.5" style="stroke:#000000"/> +<circle cx="511" cy="138" r="0.5" style="stroke:#000000"/> +<circle cx="500" cy="120" r="0.5" style="stroke:#000000"/> +<circle cx="484" cy="106" r="0.5" style="stroke:#000000"/> +<circle cx="485" cy="129" r="0.5" style="stroke:#000000"/> +<circle cx="479" cy="109" r="0.5" style="stroke:#000000"/> +<circle cx="497" cy="115" r="0.5" style="stroke:#000000"/> +<circle cx="526" cy="120" r="0.5" style="stroke:#000000"/> +<circle cx="495" cy="123" r="0.5" style="stroke:#000000"/> +<circle cx="482" cy="106" r="0.5" style="stroke:#000000"/> +<circle cx="498" cy="119" r="0.5" style="stroke:#000000"/> +<circle cx="502" cy="116" r="0.5" style="stroke:#000000"/> +<circle cx="474" cy="131" r="0.5" style="stroke:#000000"/> +<circle cx="526" cy="122" r="0.5" style="stroke:#000000"/> +<circle cx="498" cy="117" r="0.5" style="stroke:#000000"/> +<circle cx="484" cy="121" r="0.5" style="stroke:#000000"/> +<circle cx="486" cy="136" r="0.5" style="stroke:#000000"/> +<circle cx="498" cy="118" r="0.5" style="stroke:#000000"/> +<circle cx="498" cy="131" r="0.5" style="stroke:#000000"/> +<circle cx="489" cy="142" r="0.5" style="stroke:#000000"/> +<circle cx="509" cy="105" r="0.5" style="stroke:#000000"/> +<circle cx="475" cy="136" r="0.5" style="stroke:#000000"/> +<circle cx="498" cy="148" r="0.5" style="stroke:#000000"/> +<circle cx="528" cy="126" r="0.5" style="stroke:#000000"/> +<circle cx="488" cy="117" r="0.5" style="stroke:#000000"/> +<circle cx="490" cy="104" r="0.5" style="stroke:#000000"/> +<circle cx="523" cy="117" r="0.5" style="stroke:#000000"/> +<circle cx="488" cy="109" r="0.5" style="stroke:#000000"/> +<circle cx="517" cy="107" r="0.5" style="stroke:#000000"/> +<circle cx="275" cy="163" r="0.5" style="stroke:#000000"/> +<circle cx="345" cy="212" r="0.5" style="stroke:#000000"/> +<circle cx="256" cy="277" r="0.5" style="stroke:#000000"/> +<circle cx="235" cy="324" r="0.5" style="stroke:#000000"/> +<circle cx="286" cy="206" r="0.5" style="stroke:#000000"/> +<circle cx="312" cy="311" r="0.5" style="stroke:#000000"/> +<circle cx="375" cy="163" r="0.5" style="stroke:#000000"/> +<circle cx="363" cy="164" r="0.5" style="stroke:#000000"/> +<circle cx="254" cy="126" r="0.5" style="stroke:#000000"/> +<circle cx="343" cy="243" r="0.5" style="stroke:#000000"/> +<circle cx="372" cy="133" r="0.5" style="stroke:#000000"/> +<circle cx="301" cy="201" r="0.5" style="stroke:#000000"/> +<circle cx="319" cy="193" r="0.5" style="stroke:#000000"/> +<circle cx="319" cy="311" r="0.5" style="stroke:#000000"/> +<circle cx="238" cy="232" r="0.5" style="stroke:#000000"/> +<circle cx="376" cy="310" r="0.5" style="stroke:#000000"/> +<circle cx="305" cy="203" r="0.5" style="stroke:#000000"/> +<circle cx="299" cy="177" r="0.5" style="stroke:#000000"/> +<circle cx="300" cy="201" r="0.5" style="stroke:#000000"/> +<circle cx="256" cy="179" r="0.5" style="stroke:#000000"/> +<circle cx="182" cy="162" r="0.5" style="stroke:#000000"/> +<circle cx="229" cy="158" r="0.5" style="stroke:#000000"/> +<circle cx="328" cy="75" r="0.5" style="stroke:#000000"/> +<circle cx="180" cy="161" r="0.5" style="stroke:#000000"/> +<circle cx="225" cy="144" r="0.5" style="stroke:#000000"/> +<circle cx="369" cy="245" r="0.5" style="stroke:#000000"/> +<circle cx="406" cy="282" r="0.5" style="stroke:#000000"/> +<circle cx="320" cy="245" r="0.5" style="stroke:#000000"/> +<circle cx="369" cy="328" r="0.5" style="stroke:#000000"/> +<circle cx="318" cy="115" r="0.5" style="stroke:#000000"/> +<circle cx="253" cy="221" r="0.5" style="stroke:#000000"/> +<circle cx="369" cy="332" r="0.5" style="stroke:#000000"/> +<circle cx="303" cy="140" r="0.5" style="stroke:#000000"/> +<circle cx="231" cy="259" r="0.5" style="stroke:#000000"/> +<circle cx="342" cy="159" r="0.5" style="stroke:#000000"/> +<circle cx="348" cy="208" r="0.5" style="stroke:#000000"/> +<circle cx="273" cy="283" r="0.5" style="stroke:#000000"/> +<circle cx="342" cy="241" r="0.5" style="stroke:#000000"/> +<circle cx="284" cy="177" r="0.5" style="stroke:#000000"/> +<circle cx="283" cy="276" r="0.5" style="stroke:#000000"/> +<circle cx="284" cy="159" r="0.5" style="stroke:#000000"/> +<circle cx="348" cy="222" r="0.5" style="stroke:#000000"/> +<circle cx="269" cy="159" r="0.5" style="stroke:#000000"/> +<circle cx="388" cy="175" r="0.5" style="stroke:#000000"/> +<circle cx="245" cy="172" r="0.5" style="stroke:#000000"/> +<circle cx="200" cy="158" r="0.5" style="stroke:#000000"/> +<circle cx="351" cy="99" r="0.5" style="stroke:#000000"/> +<circle cx="300" cy="201" r="0.5" style="stroke:#000000"/> +<circle cx="379" cy="317" r="0.5" style="stroke:#000000"/> +<circle cx="301" cy="197" r="0.5" style="stroke:#000000"/> +<circle cx="277" cy="236" r="0.5" style="stroke:#000000"/> +<circle cx="275" cy="187" r="0.5" style="stroke:#000000"/> +<circle cx="324" cy="178" r="0.5" style="stroke:#000000"/> +<circle cx="292" cy="168" r="0.5" style="stroke:#000000"/> +<circle cx="312" cy="204" r="0.5" style="stroke:#000000"/> +<circle cx="345" cy="255" r="0.5" style="stroke:#000000"/> +<circle cx="262" cy="198" r="0.5" style="stroke:#000000"/> +<circle cx="403" cy="283" r="0.5" style="stroke:#000000"/> +<circle cx="223" cy="152" r="0.5" style="stroke:#000000"/> +<circle cx="207" cy="189" r="0.5" style="stroke:#000000"/> +<circle cx="305" cy="237" r="0.5" style="stroke:#000000"/> +<circle cx="303" cy="200" r="0.5" style="stroke:#000000"/> +<circle cx="150" cy="197" r="0.5" style="stroke:#000000"/> +<circle cx="286" cy="268" r="0.5" style="stroke:#000000"/> +<circle cx="254" cy="227" r="0.5" style="stroke:#000000"/> +<circle cx="254" cy="152" r="0.5" style="stroke:#000000"/> +<circle cx="387" cy="322" r="0.5" style="stroke:#000000"/> +<circle cx="250" cy="117" r="0.5" style="stroke:#000000"/> +<circle cx="341" cy="97" r="0.5" style="stroke:#000000"/> +<circle cx="327" cy="122" r="0.5" style="stroke:#000000"/> +<circle cx="412" cy="193" r="0.5" style="stroke:#000000"/> +<circle cx="329" cy="315" r="0.5" style="stroke:#000000"/> +<circle cx="372" cy="130" r="0.5" style="stroke:#000000"/> +<circle cx="328" cy="120" r="0.5" style="stroke:#000000"/> +<circle cx="279" cy="190" r="0.5" style="stroke:#000000"/> +<circle cx="248" cy="132" r="0.5" style="stroke:#000000"/> +<circle cx="213" cy="199" r="0.5" style="stroke:#000000"/> +<circle cx="291" cy="218" r="0.5" style="stroke:#000000"/> +<circle cx="297" cy="200" r="0.5" style="stroke:#000000"/> +<circle cx="264" cy="309" r="0.5" style="stroke:#000000"/> +<circle cx="257" cy="100" r="0.5" style="stroke:#000000"/> +<circle cx="308" cy="235" r="0.5" style="stroke:#000000"/> +<circle cx="296" cy="312" r="0.5" style="stroke:#000000"/> +<circle cx="305" cy="240" r="0.5" style="stroke:#000000"/> +<circle cx="264" cy="178" r="0.5" style="stroke:#000000"/> +<circle cx="383" cy="317" r="0.5" style="stroke:#000000"/> +<circle cx="319" cy="189" r="0.5" style="stroke:#000000"/> +<circle cx="247" cy="241" r="0.5" style="stroke:#000000"/> +<circle cx="306" cy="193" r="0.5" style="stroke:#000000"/> +<circle cx="302" cy="190" r="0.5" style="stroke:#000000"/> +<circle cx="292" cy="319" r="0.5" style="stroke:#000000"/> +<circle cx="298" cy="203" r="0.5" style="stroke:#000000"/> +<circle cx="280" cy="211" r="0.5" style="stroke:#000000"/> +<circle cx="296" cy="202" r="0.5" style="stroke:#000000"/> +<circle cx="243" cy="272" r="0.5" style="stroke:#000000"/> +<circle cx="392" cy="263" r="0.5" style="stroke:#000000"/> +<circle cx="331" cy="74" r="0.5" style="stroke:#000000"/> +<circle cx="292" cy="303" r="0.5" style="stroke:#000000"/> +<circle cx="310" cy="181" r="0.5" style="stroke:#000000"/> +<circle cx="302" cy="168" r="0.5" style="stroke:#000000"/> +<circle cx="287" cy="227" r="0.5" style="stroke:#000000"/> +<circle cx="288" cy="196" r="0.5" style="stroke:#000000"/> +<circle cx="326" cy="210" r="0.5" style="stroke:#000000"/> +<circle cx="244" cy="206" r="0.5" style="stroke:#000000"/> +<circle cx="325" cy="205" r="0.5" style="stroke:#000000"/> +<circle cx="287" cy="206" r="0.5" style="stroke:#000000"/> +<circle cx="194" cy="265" r="0.5" style="stroke:#000000"/> +<circle cx="397" cy="314" r="0.5" style="stroke:#000000"/> +<circle cx="307" cy="204" r="0.5" style="stroke:#000000"/> +<circle cx="286" cy="212" r="0.5" style="stroke:#000000"/> +<circle cx="436" cy="227" r="0.5" style="stroke:#000000"/> +<circle cx="373" cy="161" r="0.5" style="stroke:#000000"/> +<circle cx="298" cy="199" r="0.5" style="stroke:#000000"/> +<circle cx="244" cy="172" r="0.5" style="stroke:#000000"/> +<circle cx="360" cy="290" r="0.5" style="stroke:#000000"/> +<circle cx="299" cy="202" r="0.5" style="stroke:#000000"/> +<circle cx="300" cy="195" r="0.5" style="stroke:#000000"/> +<circle cx="201" cy="252" r="0.5" style="stroke:#000000"/> +<circle cx="323" cy="210" r="0.5" style="stroke:#000000"/> +<circle cx="350" cy="228" r="0.5" style="stroke:#000000"/> +<circle cx="341" cy="170" r="0.5" style="stroke:#000000"/> +<circle cx="349" cy="157" r="0.5" style="stroke:#000000"/> +<circle cx="340" cy="94" r="0.5" style="stroke:#000000"/> +<circle cx="202" cy="147" r="0.5" style="stroke:#000000"/> +<circle cx="254" cy="174" r="0.5" style="stroke:#000000"/> +<circle cx="309" cy="176" r="0.5" style="stroke:#000000"/> +<circle cx="260" cy="183" r="0.5" style="stroke:#000000"/> +<circle cx="391" cy="243" r="0.5" style="stroke:#000000"/> +<circle cx="326" cy="210" r="0.5" style="stroke:#000000"/> +<circle cx="210" cy="175" r="0.5" style="stroke:#000000"/> +<circle cx="300" cy="200" r="0.5" style="stroke:#000000"/> +<circle cx="364" cy="163" r="0.5" style="stroke:#000000"/> +<circle cx="271" cy="121" r="0.5" style="stroke:#000000"/> +<circle cx="294" cy="149" r="0.5" style="stroke:#000000"/> +<circle cx="278" cy="205" r="0.5" style="stroke:#000000"/> +<circle cx="245" cy="311" r="0.5" style="stroke:#000000"/> +<circle cx="363" cy="131" r="0.5" style="stroke:#000000"/> +<circle cx="262" cy="236" r="0.5" style="stroke:#000000"/> +<circle cx="369" cy="128" r="0.5" style="stroke:#000000"/> +<circle cx="317" cy="327" r="0.5" style="stroke:#000000"/> +<circle cx="283" cy="143" r="0.5" style="stroke:#000000"/> +<circle cx="239" cy="194" r="0.5" style="stroke:#000000"/> +<circle cx="333" cy="231" r="0.5" style="stroke:#000000"/> +<circle cx="340" cy="129" r="0.5" style="stroke:#000000"/> +<circle cx="271" cy="105" r="0.5" style="stroke:#000000"/> +<circle cx="302" cy="100" r="0.5" style="stroke:#000000"/> +<circle cx="303" cy="197" r="0.5" style="stroke:#000000"/> +<circle cx="395" cy="303" r="0.5" style="stroke:#000000"/> +<circle cx="210" cy="227" r="0.5" style="stroke:#000000"/> +<circle cx="317" cy="174" r="0.5" style="stroke:#000000"/> +<circle cx="441" cy="184" r="0.5" style="stroke:#000000"/> +<circle cx="447" cy="175" r="0.5" style="stroke:#000000"/> +<circle cx="294" cy="191" r="0.5" style="stroke:#000000"/> +<circle cx="281" cy="184" r="0.5" style="stroke:#000000"/> +<circle cx="212" cy="148" r="0.5" style="stroke:#000000"/> +<circle cx="315" cy="179" r="0.5" style="stroke:#000000"/> +<circle cx="318" cy="190" r="0.5" style="stroke:#000000"/> +<circle cx="232" cy="164" r="0.5" style="stroke:#000000"/> +<circle cx="425" cy="239" r="0.5" style="stroke:#000000"/> +<circle cx="387" cy="195" r="0.5" style="stroke:#000000"/> +<circle cx="322" cy="152" r="0.5" style="stroke:#000000"/> +<circle cx="213" cy="278" r="0.5" style="stroke:#000000"/> +<circle cx="187" cy="132" r="0.5" style="stroke:#000000"/> +<circle cx="245" cy="161" r="0.5" style="stroke:#000000"/> +<circle cx="292" cy="202" r="0.5" style="stroke:#000000"/> +<circle cx="336" cy="155" r="0.5" style="stroke:#000000"/> +<circle cx="272" cy="65" r="0.5" style="stroke:#000000"/> +<circle cx="204" cy="190" r="0.5" style="stroke:#000000"/> +<circle cx="351" cy="82" r="0.5" style="stroke:#000000"/> +<circle cx="259" cy="284" r="0.5" style="stroke:#000000"/> +<circle cx="288" cy="189" r="0.5" style="stroke:#000000"/> +<circle cx="300" cy="200" r="0.5" style="stroke:#000000"/> +<circle cx="353" cy="288" r="0.5" style="stroke:#000000"/> +<circle cx="301" cy="199" r="0.5" style="stroke:#000000"/> +<circle cx="218" cy="128" r="0.5" style="stroke:#000000"/> +<circle cx="226" cy="243" r="0.5" style="stroke:#000000"/> +<circle cx="195" cy="146" r="0.5" style="stroke:#000000"/> +<circle cx="284" cy="174" r="0.5" style="stroke:#000000"/> +<circle cx="428" cy="200" r="0.5" style="stroke:#000000"/> +<circle cx="274" cy="214" r="0.5" style="stroke:#000000"/> +<circle cx="211" cy="131" r="0.5" style="stroke:#000000"/> +<circle cx="291" cy="196" r="0.5" style="stroke:#000000"/> +<circle cx="310" cy="180" r="0.5" style="stroke:#000000"/> +<circle cx="172" cy="257" r="0.5" style="stroke:#000000"/> +<circle cx="431" cy="212" r="0.5" style="stroke:#000000"/> +<circle cx="290" cy="187" r="0.5" style="stroke:#000000"/> +<circle cx="219" cy="203" r="0.5" style="stroke:#000000"/> +<circle cx="230" cy="279" r="0.5" style="stroke:#000000"/> +<circle cx="291" cy="192" r="0.5" style="stroke:#000000"/> +<circle cx="291" cy="254" r="0.5" style="stroke:#000000"/> +<circle cx="245" cy="309" r="0.5" style="stroke:#000000"/> +<circle cx="345" cy="126" r="0.5" style="stroke:#000000"/> +<circle cx="175" cy="278" r="0.5" style="stroke:#000000"/> +<circle cx="289" cy="338" r="0.5" style="stroke:#000000"/> +<circle cx="442" cy="228" r="0.5" style="stroke:#000000"/> +<circle cx="242" cy="186" r="0.5" style="stroke:#000000"/> +<circle cx="249" cy="120" r="0.5" style="stroke:#000000"/> +<circle cx="415" cy="186" r="0.5" style="stroke:#000000"/> +<circle cx="242" cy="145" r="0.5" style="stroke:#000000"/> +<circle cx="384" cy="133" r="0.5" style="stroke:#000000"/> +<circle cx="20" cy="98" r="1" style="stroke:#ff0000"/> +<circle cx="50" cy="246" r="1" style="stroke:#ff0000"/> +<circle cx="83" cy="354" r="1" style="stroke:#ff0000"/> +<circle cx="164" cy="416" r="1" style="stroke:#ff0000"/> +<circle cx="236" cy="434" r="1" style="stroke:#ff0000"/> +<circle cx="343" cy="427" r="1" style="stroke:#ff0000"/> +<circle cx="366" cy="412" r="1" style="stroke:#ff0000"/> +<circle cx="379" cy="402" r="1" style="stroke:#ff0000"/> +<circle cx="519" cy="143" r="1" style="stroke:#ff0000"/> +<circle cx="528" cy="126" r="1" style="stroke:#ff0000"/> +<circle cx="529" cy="115" r="1" style="stroke:#ff0000"/> +<circle cx="510" cy="96" r="1" style="stroke:#ff0000"/> +<circle cx="506" cy="95" r="1" style="stroke:#ff0000"/> +<circle cx="117" cy="33" r="1" style="stroke:#ff0000"/> +<circle cx="85" cy="28" r="1" style="stroke:#ff0000"/> +<circle cx="40" cy="64" r="1" style="stroke:#ff0000"/> +</svg> diff --git a/testsuite/tests/dph/quickhull/dph-quickhull.T b/testsuite/tests/dph/quickhull/dph-quickhull.T new file mode 100644 index 0000000000..f1a1debe3f --- /dev/null +++ b/testsuite/tests/dph/quickhull/dph-quickhull.T @@ -0,0 +1,20 @@ + +test ('dph-quickhull-opt' + , [ alone + , skip_if_fast + , reqlib('dph-par') + , reqlib('dph-prim-par') + , only_ways(['normal', 'threaded1', 'threaded2']) ] + , multimod_compile_and_run + , [ 'Main' + , '-Odph -funfolding-use-threshold30 -fdph-par']) + +test ('dph-quickhull-fast' + , [ reqlib('dph-par') + , reqlib('dph-prim-par') + , only_ways(['normal', 'threaded1', 'threaded2']) ] + , multimod_compile_and_run + , [ 'Main' + , '-O -fno-enable-rewrite-rules -fdph-par']) + + diff --git a/testsuite/tests/dph/smvm/Main.hs b/testsuite/tests/dph/smvm/Main.hs new file mode 100644 index 0000000000..e30938bc21 --- /dev/null +++ b/testsuite/tests/dph/smvm/Main.hs @@ -0,0 +1,65 @@ +{-# LANGUAGE TypeOperators #-} + +import SMVMVect (smvm) + +import Control.Exception (evaluate) +import System.IO +import System.Environment + +import qualified Data.Array.Parallel.Unlifted as U +import Data.Array.Parallel.Prelude +import Data.Array.Parallel.PArray as P + + +-- Load sparse matrix from a file +loadSM :: String + -> IO (PArray (PArray (Int, Double)), PArray Double) + +loadSM s + = do + (segd, m, v) <- loadSM' s + return $ (nestUSegdPA' segd (fromUArrPA_2' m), fromUArrPA' v) + + +loadSM' :: String + -> IO ( U.Segd + , U.Array (Int, Double) + , U.Array Double) +loadSM' fname = + do + h <- openBinaryFile fname ReadMode + lengths <- U.hGet h + indices <- U.hGet h + values <- U.hGet h + dv <- U.hGet h + let segd = U.lengthsToSegd lengths + m = U.zip indices values + evaluate lengths + evaluate indices + evaluate values + evaluate dv + return (segd, m, dv) + +main + = do [inFile, outFile] <- getArgs + (m, v) <- loadSM inFile + let result = smvm m v + + -- ignore wibbles in low-order bits + let output + = (unlines + $ map (take 12) + $ map show + $ P.toList result) + ++ ("SUM = " + ++ (take 12 $ show $ sum $ P.toList result) + ++ "\n") + + -- check our result against the provided outFile + outputCheck <- readFile outFile + print $ output == outputCheck + + + + + diff --git a/testsuite/tests/dph/smvm/Makefile b/testsuite/tests/dph/smvm/Makefile new file mode 100644 index 0000000000..9101fbd40a --- /dev/null +++ b/testsuite/tests/dph/smvm/Makefile @@ -0,0 +1,3 @@ +TOP=../../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk diff --git a/testsuite/tests/dph/smvm/SMVMVect.hs b/testsuite/tests/dph/smvm/SMVMVect.hs new file mode 100644 index 0000000000..93f3775741 --- /dev/null +++ b/testsuite/tests/dph/smvm/SMVMVect.hs @@ -0,0 +1,17 @@ +{-# LANGUAGE ParallelArrays #-} +{-# OPTIONS -fvectorise #-} +module SMVMVect (smvm) where + +import Data.Array.Parallel +import Data.Array.Parallel.Prelude.Double as D +import Data.Array.Parallel.Prelude.Int as I + +import qualified Prelude as P + +smvm :: PArray (PArray (Int, Double)) -> PArray Double -> PArray Double +{-# NOINLINE smvm #-} +smvm m v = toPArrayP (smvm' (fromNestedPArrayP m) (fromPArrayP v)) + +smvm' :: [:[: (Int, Double) :]:] -> [:Double:] -> [:Double:] +smvm' m v = [: D.sumP [: x D.* (v !: i) | (i,x) <- row :] | row <- m :] + diff --git a/testsuite/tests/dph/smvm/dph-smvm.T b/testsuite/tests/dph/smvm/dph-smvm.T new file mode 100644 index 0000000000..d0a940a7c1 --- /dev/null +++ b/testsuite/tests/dph/smvm/dph-smvm.T @@ -0,0 +1,30 @@ + + +testFile = 'nothing' +if config.platform.startswith('i386-'): + testFile = 'test-i386.dat' + outFile = 'result-i386.txt' + +elif config.platform.startswith('x86_64-'): + testFile = 'test-x86_64.dat' + outFile = 'result-x86_64.txt' + +elif config.platform.startswith('sparc-'): + testFile = 'test-sparc.dat' + outFile = 'result-sparc.txt' + + +if testFile != 'nothing': + test ('dph-smvm' + , [ alone + , skip_if_fast + , reqlib('dph-par') + , reqlib('dph-prim-par') + , only_ways(['normal', 'threaded1', 'threaded2']) + , extra_run_opts(testFile + " " + outFile) + ] + , multimod_compile_and_run + , [ 'Main' + , '-Odph -fdph-par']) + + diff --git a/testsuite/tests/dph/smvm/dph-smvm.stdout b/testsuite/tests/dph/smvm/dph-smvm.stdout new file mode 100644 index 0000000000..0ca95142bb --- /dev/null +++ b/testsuite/tests/dph/smvm/dph-smvm.stdout @@ -0,0 +1 @@ +True diff --git a/testsuite/tests/dph/smvm/result-i386.txt b/testsuite/tests/dph/smvm/result-i386.txt new file mode 100644 index 0000000000..bf279482ef --- /dev/null +++ b/testsuite/tests/dph/smvm/result-i386.txt @@ -0,0 +1,101 @@ +70.911036010 +6.2813390683 +22.790766463 +138.15513262 +52.633427554 +23.459671609 +39.794269586 +37.387466366 +16.666309389 +86.252836326 +2.0045195528 +89.578046705 +15.195705417 +14.397637033 +9.9571970137 +12.966919776 +314.12848526 +106.92515769 +53.308659874 +187.71842503 +19.814258245 +3.5465802997 +26.462654791 +39.989634289 +27.636953710 +14.238025227 +43.040256543 +2.1571625382 +67.541648911 +24.912387408 +7.6904324146 +2.9650091269 +48.668083695 +56.313556473 +285.31615184 +25.595785904 +49.488178849 +25.310153120 +10.706428715 +80.585871589 +225.85945599 +27.813502732 +36.745192736 +157.41617010 +51.501091484 +30.457678049 +254.13030691 +17.469473192 +60.702335620 +52.376229564 +26.517446882 +46.939308590 +19.961999016 +226.11502829 +69.361878263 +206.34127990 +59.002071706 +23.815778535 +101.90955813 +0.3802732664 +41.728371059 +12.021386376 +20.282213202 +17.500045961 +19.148201048 +73.983800195 +7.6944408324 +20.993610043 +58.350721826 +67.038534218 +31.260033960 +14.283638817 +140.68179300 +31.766861701 +46.639106640 +5.2416016510 +175.49192085 +6.1624941117 +3.0550277985 +51.818892673 +7.8677940322 +22.311195092 +258.22325771 +47.475395836 +104.78223912 +38.825154663 +1.6611687222 +63.278567845 +139.86840253 +72.273773546 +71.487712807 +46.823777361 +125.50127870 +3.7203037750 +48.211248191 +79.659040149 +59.672472372 +73.220258924 +63.910310588 +23.405170831 +SUM = 6054.6294998 diff --git a/testsuite/tests/dph/smvm/result-sparc.txt b/testsuite/tests/dph/smvm/result-sparc.txt new file mode 100644 index 0000000000..8c85795cbc --- /dev/null +++ b/testsuite/tests/dph/smvm/result-sparc.txt @@ -0,0 +1,101 @@ +31.171134675 +136.96399669 +99.558688941 +2.3944559306 +132.07457337 +64.316928783 +17.141482371 +363.11345177 +12.350699032 +62.403552077 +25.836846192 +488.62415222 +90.786181827 +2650.5823673 +28.153073045 +29.698154931 +280.42051630 +264.68315963 +0.0 +17.241401450 +103.44167214 +120.25222269 +0.6481556022 +3.8143291874 +57.942419415 +0.9485226158 +11.722857133 +80.685346313 +497.97232376 +7.3021493591 +0.0 +4.9013220836 +61.582851534 +104.83102162 +12.196177619 +16.799924219 +8.8828491057 +20.672947720 +0.0 +8.9693097972 +66.272730332 +145.39838263 +2.6011327691 +80.289657428 +17.075494290 +0.5897431148 +26.250003553 +114.75531349 +57.010466242 +38.222004332 +5.6130133753 +120.90679901 +106.19820538 +0.0 +22.471060597 +50.616335208 +0.7352665245 +13.632854738 +72.201368578 +54.552907983 +3.2165935380 +31.048444965 +3.3117670262 +224.93467543 +110.02973746 +2.0467456318 +0.0 +7.2930317411 +8.6809940997 +41.756667327 +118.07161086 +358.47370477 +8.1013874742 +9.1189573118 +35.367265915 +10.245691446 +25.785856741 +55.679020534 +83.594437531 +34.102347192 +0.2950061972 +16.641363479 +0.0 +29.534024840 +0.0 +26.338163918 +149.17642877 +0.1698288578 +24.176530881 +57.626923103 +33.976034955 +15.977447399 +0.0 +893.79869661 +117.52170252 +60.450794548 +0.5763239875 +4.9690229931 +14.014097678 +275.53547442 +SUM = 9808.1107603 diff --git a/testsuite/tests/dph/smvm/result-x86_64.txt b/testsuite/tests/dph/smvm/result-x86_64.txt new file mode 100644 index 0000000000..ebad60a2b0 --- /dev/null +++ b/testsuite/tests/dph/smvm/result-x86_64.txt @@ -0,0 +1,101 @@ +2.3160849869 +26.283679649 +76.729994661 +405.68040155 +55.723673494 +33.938026665 +26.505926115 +52.261424813 +33.397325696 +1.1328178441 +5.3697979892 +9.4419428065 +28.678826876 +61.019008268 +4.5301894841 +43.464645691 +0.0 +34.335714653 +20.798359422 +16.561984995 +17.581964787 +23.948149350 +19.120544306 +30.215710069 +0.7009196726 +51.297030554 +4.4591823094 +209.96809687 +47.289681980 +32.498492600 +13.196267290 +0.9989265108 +1.0341069617 +38.917182375 +7.9955088012 +10.355804741 +20.095073245 +36.647037472 +18.786308469 +14.370553796 +6.3265152208 +28.117268967 +65.265404040 +898.53639610 +2.1015959321 +188.65890412 +31.810545943 +14.182075117 +16.239269064 +27.309800346 +126.26472539 +32.948733352 +20.290181336 +0.0 +40.083403468 +81.626718007 +141.59574874 +8.5797914307 +37.726704414 +0.5807127190 +6.3771256902 +6.3486182511 +5.8655193980 +8.1395223932 +32.695645766 +16.964781766 +5.2863815777 +31.967858939 +21.161490986 +61.257464383 +4.1240057418 +18.099623432 +2.1851562467 +3.7220913984 +55.452918211 +10.289474473 +46.276301220 +23.201718136 +7.6338488432 +45.868472148 +12.976885901 +18.483762115 +143.50458515 +24.999794955 +12.121764180 +6.7194800847 +1.8693415211 +23.848562170 +1092.0362340 +67.588787350 +248.07913042 +0.0 +38.838570262 +13.800391661 +1277.9084108 +53.491216504 +14.325720303 +10.152650478 +17.439312837 +40.696348267 +SUM = 6837.6898296 diff --git a/testsuite/tests/dph/smvm/test-i386.dat b/testsuite/tests/dph/smvm/test-i386.dat Binary files differnew file mode 100644 index 0000000000..4db8d62620 --- /dev/null +++ b/testsuite/tests/dph/smvm/test-i386.dat diff --git a/testsuite/tests/dph/smvm/test-sparc.dat b/testsuite/tests/dph/smvm/test-sparc.dat Binary files differnew file mode 100644 index 0000000000..73d2c201cd --- /dev/null +++ b/testsuite/tests/dph/smvm/test-sparc.dat diff --git a/testsuite/tests/dph/smvm/test-x86_64.dat b/testsuite/tests/dph/smvm/test-x86_64.dat Binary files differnew file mode 100644 index 0000000000..08a91f5ab1 --- /dev/null +++ b/testsuite/tests/dph/smvm/test-x86_64.dat diff --git a/testsuite/tests/dph/sumnats/Main.hs b/testsuite/tests/dph/sumnats/Main.hs new file mode 100644 index 0000000000..9e18e335a9 --- /dev/null +++ b/testsuite/tests/dph/sumnats/Main.hs @@ -0,0 +1,21 @@ + +import SumNatsVect (sumNats) + +-- Solution for 1st Euler problem +-- Add all the natural numbers below 1000 that are multiples of 3 or 5. + +solutionLists maxN + = let sumOnetoN n = n * (n+1) `div` 2 + sumStep s n = s * sumOnetoN (n `div` s) + in sumStep 3 (maxN - 1) + sumStep 5 (maxN - 1) - sumStep 15 (maxN - 1) + +solutionLists2 maxN + = sum [ x | x <- [0.. maxN - 1] + , (x `mod` 3 == 0) || (x `mod` 5 == 0) ] + +main + = do let n = 1000 + print $ solutionLists n + print $ solutionLists2 n + print $ sumNats n +
\ No newline at end of file diff --git a/testsuite/tests/dph/sumnats/Makefile b/testsuite/tests/dph/sumnats/Makefile new file mode 100644 index 0000000000..9101fbd40a --- /dev/null +++ b/testsuite/tests/dph/sumnats/Makefile @@ -0,0 +1,3 @@ +TOP=../../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk diff --git a/testsuite/tests/dph/sumnats/SumNatsVect.hs b/testsuite/tests/dph/sumnats/SumNatsVect.hs new file mode 100644 index 0000000000..f51f207d0c --- /dev/null +++ b/testsuite/tests/dph/sumnats/SumNatsVect.hs @@ -0,0 +1,14 @@ +{-# LANGUAGE ParallelArrays #-} +{-# OPTIONS -fvectorise #-} +module SumNatsVect (sumNats) where + +import Data.Array.Parallel.Prelude +import Data.Array.Parallel.Prelude.Int + +import qualified Prelude as P + +sumNats :: Int -> Int +sumNats maxN + = sumP [: x | x <- enumFromToP 0 (maxN - 1) + , (x `mod` 3 == 0) || (x `mod` 5 == 0) :] + diff --git a/testsuite/tests/dph/sumnats/dph-sumnats.T b/testsuite/tests/dph/sumnats/dph-sumnats.T new file mode 100644 index 0000000000..f84757c5d7 --- /dev/null +++ b/testsuite/tests/dph/sumnats/dph-sumnats.T @@ -0,0 +1,10 @@ + +test ('dph-sumnats' + , [ reqlib('dph-par') + , reqlib('dph-prim-par') + , only_ways(['normal', 'threaded1', 'threaded2']) ] + , multimod_compile_and_run + , [ 'Main' + , '-Odph -fdph-par']) + + diff --git a/testsuite/tests/dph/sumnats/dph-sumnats.stdout b/testsuite/tests/dph/sumnats/dph-sumnats.stdout new file mode 100644 index 0000000000..8858be2164 --- /dev/null +++ b/testsuite/tests/dph/sumnats/dph-sumnats.stdout @@ -0,0 +1,3 @@ +233168 +233168 +233168 diff --git a/testsuite/tests/dph/words/Main.hs b/testsuite/tests/dph/words/Main.hs new file mode 100644 index 0000000000..bc706fb751 --- /dev/null +++ b/testsuite/tests/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/dph/words/Makefile b/testsuite/tests/dph/words/Makefile new file mode 100644 index 0000000000..9101fbd40a --- /dev/null +++ b/testsuite/tests/dph/words/Makefile @@ -0,0 +1,3 @@ +TOP=../../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk diff --git a/testsuite/tests/dph/words/WordsVect.hs b/testsuite/tests/dph/words/WordsVect.hs new file mode 100644 index 0000000000..abf416e763 --- /dev/null +++ b/testsuite/tests/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 ParallelArrays, 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 + +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-half) 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/dph/words/dph-words-fast.stdout b/testsuite/tests/dph/words/dph-words-fast.stdout new file mode 100644 index 0000000000..a7ad9be6b6 --- /dev/null +++ b/testsuite/tests/dph/words/dph-words-fast.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 diff --git a/testsuite/tests/dph/words/dph-words-opt.stdout b/testsuite/tests/dph/words/dph-words-opt.stdout new file mode 100644 index 0000000000..a7ad9be6b6 --- /dev/null +++ b/testsuite/tests/dph/words/dph-words-opt.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 diff --git a/testsuite/tests/dph/words/dph-words.T b/testsuite/tests/dph/words/dph-words.T new file mode 100644 index 0000000000..c89d01b08e --- /dev/null +++ b/testsuite/tests/dph/words/dph-words.T @@ -0,0 +1,21 @@ + +test ('dph-words-opt' + , [ alone + , skip_if_fast + , reqlib('dph-par') + , reqlib('dph-prim-par') + , only_ways(['normal']) ] + , multimod_compile_and_run + , [ 'Main' + , '-Odph -fdph-par -fno-liberate-case']) + + +test ('dph-words-fast' + , [ reqlib('dph-par') + , reqlib('dph-prim-par') + , only_ways(['normal']) ] + , multimod_compile_and_run + , [ 'Main' + , '-O -fno-enable-rewrite-rules -fdph-par']) + + |