diff --git a/accelerate-examples.cabal b/accelerate-examples.cabal
--- a/accelerate-examples.cabal
+++ b/accelerate-examples.cabal
@@ -1,7 +1,7 @@
 Name:                   accelerate-examples
-Version:                0.14.0.0
+Version:                0.15.0.0
 Cabal-version:          >=1.6
-Tested-with:            GHC == 7.6.*
+Tested-with:            GHC == 7.8.*
 Build-type:             Simple
 
 Synopsis:               Examples using the Accelerate library
@@ -44,21 +44,74 @@
   Description:          Enable the OpenCL parallel backend
   Default:              False
 
+Flag llvm-cpu
+  Description:          Enable the LLVM backend for multicore CPUs
+  Default:              True
 
--- Flags to specify which programs to build (all true by default)
+Flag llvm-gpu
+  Description:          Enable the LLVM backend for NVIDIA CPUs
+  Default:              True
+
+Flag llvm-multi
+  Description:          Enable the multi-device LLVM backend
+  Default:              True
+
+
+-- Flags to specify which programs to build
 --
 Flag nofib
+  Description:          Regression test suite
+  Default:              True
+
 Flag smvm
+  Description:          Sparse-matrix vector multiplication benchmark
+  Default:              True
+
 Flag crystal
+  Description:          A visualisation of a sum of waves in a plane
+  Default:              True
+
 Flag canny
+  Description:          Canny edge detection benchmark
+  Default:              True
+
 Flag mandelbrot
+  Description:          A Mandelbrot fractal benchmark
+  Default:              True
+
 Flag fluid
+  Description:          An interactive particle-based fluid simulation
+  Default:              True
+
 Flag nbody
+  Description:          Simulation of gravitational attraction between solid particles
+  Default:              True
+
 Flag smoothlife
+  Description:          A cellular automata simulation
+  Default:              True
+
 Flag hashcat
+  Description:          A "password recovery" application for MD5 cracking
+  Default:              True
+
 Flag fft
+  Description:          Simple FFT-based high/low-pass image filtering
+  Default:              True
 
+Flag pagerank
+  Description:          Implementation of the PageRank algorithm
+  Default:              True
 
+Flag ray
+  Description:          A simple real-time ray tracer
+  Default:              True
+
+Flag kmeans
+  Description:          An implementation of k-means clustering in a plane
+  Default:              True
+
+
 -- The main test program. This includes randomised quickcheck testing for array
 -- primitives, unit tests, imaginary/spectral/real programs, and benchmarks.
 --
@@ -74,6 +127,7 @@
                         QuickCheck.Arbitrary.Array
                         QuickCheck.Arbitrary.Shape
                         Test.Base
+                        Test.FFT
                         Test.IO
                         Test.IO.Ptr
                         Test.IO.Vector
@@ -81,6 +135,17 @@
                         Test.Imaginary.DotP
                         Test.Imaginary.SASUM
                         Test.Imaginary.SAXPY
+                        Test.Issues
+                        Test.Issues.Issue93
+                        Test.Issues.Issue102
+                        Test.Issues.Issue114
+                        Test.Issues.Issue119
+                        Test.Issues.Issue123
+                        Test.Issues.Issue137
+                        Test.Issues.Issue168
+                        Test.Issues.Issue184
+                        Test.Issues.Issue185
+                        Test.Issues.Issue187
                         Test.Prelude
                         Test.Prelude.Filter
                         Test.Prelude.IndexSpace
@@ -100,6 +165,8 @@
                         -fpedantic-bottoms
                         -fno-full-laziness
                         -fno-excess-precision
+                        -eventlog
+                        -rtsopts
 
   ghc-prof-options:     -auto-all
 
@@ -107,38 +174,40 @@
   c-sources:            examples/nofib/Test/IO/fill_with_values.cpp
                         examples/nofib/Test/Spectral/BlackScholes.cpp
 
-  if impl(ghc >= 7.0)
-    ghc-options:        -rtsopts
-
   if flag(cuda)
     CPP-options:        -DACCELERATE_CUDA_BACKEND
-    build-depends:      accelerate-cuda                 == 0.14.*
+    build-depends:      accelerate-cuda                 == 0.15.*
     other-modules:      Test.Foreign
 
-  if flag(opencl)
-    CPP-options:        -DACCELERATE_OPENCL_BACKEND
-    build-depends:      accelerate-opencl               == 0.1.*
+  if flag(llvm-cpu)
+    CPP-options:        -DACCELERATE_LLVM_NATIVE_BACKEND
+    build-depends:      accelerate-llvm-native          == 0.15.*
 
+  if flag(llvm-gpu)
+    CPP-options:        -DACCELERATE_LLVM_PTX_BACKEND
+    build-depends:      accelerate-llvm-ptx             == 0.15.*
+
   if flag(ekg)
     CPP-options:        -DACCELERATE_ENABLE_EKG
-    build-depends:      ekg                             >= 0.3          && < 0.4
+    build-depends:      ekg                             >= 0.3
     ghc-options:        -with-rtsopts=-T
 
   if !flag(nofib)
     buildable:          False
   else
-    build-depends:      accelerate                      == 0.14.*,
-                        accelerate-io                   == 0.14.*,
-                        base                            == 4.6.*,
+    build-depends:      accelerate                      == 0.15.*,
+                        accelerate-fft                  == 0.15.*,
+                        accelerate-io                   == 0.15.*,
+                        base                            == 4.7.*,
                         array                           >= 0.3,
                         containers                      >= 0.5,
-                        criterion                       >= 0.5          && < 0.9,
-                        fclabels                        >= 2.0          && < 2.1,
-                        HUnit                           >= 1.2          && < 1.3,
-                        QuickCheck                      >= 2.0          && < 2.7,
-                        test-framework                  >= 0.5          && < 0.9,
-                        test-framework-hunit            >= 0.3          && < 0.4,
-                        test-framework-quickcheck2      >= 0.2          && < 0.4,
+                        criterion                       >= 0.5 && < 1.0,
+                        fclabels                        >= 2.0,
+                        HUnit                           >= 1.2,
+                        QuickCheck                      >= 2.7,
+                        test-framework                  >= 0.5,
+                        test-framework-hunit            >= 0.3,
+                        test-framework-quickcheck2      >= 0.2,
                         random
 
 
@@ -154,42 +223,43 @@
                         MatrixMarket
                         SMVM
 
-  ghc-options:          -O2 -Wall -threaded
+  ghc-options:          -O2 -Wall -threaded -rtsopts -eventlog
   ghc-prof-options:     -auto-all
 
-  if impl(ghc >= 7.0)
-    ghc-options:        -rtsopts
-
   if impl(ghc >= 7.6)
     ghc-options:        -fsimpl-tick-factor=130
 
   if flag(cuda)
     CPP-options:        -DACCELERATE_CUDA_BACKEND
-    build-depends:      accelerate-cuda         == 0.14.*
+    build-depends:      accelerate-cuda         == 0.15.*
 
-  if flag(opencl)
-    CPP-options:        -DACCELERATE_OPENCL_BACKEND
-    build-depends:      accelerate-opencl       == 0.1.*
+  if flag(llvm-cpu)
+    CPP-options:        -DACCELERATE_LLVM_NATIVE_BACKEND
+    build-depends:      accelerate-llvm-native  == 0.15.*
 
+  if flag(llvm-gpu)
+    CPP-options:        -DACCELERATE_LLVM_PTX_BACKEND
+    build-depends:      accelerate-llvm-ptx     == 0.15.*
+
   if flag(ekg)
     CPP-options:        -DACCELERATE_ENABLE_EKG
-    build-depends:      ekg                     >= 0.3          && < 0.4
+    build-depends:      ekg                     >= 0.3
     ghc-options:        -with-rtsopts=-T
 
   if !flag(smvm)
     buildable:          False
   else
-    build-depends:      accelerate              == 0.14.*,
-                        base                    == 4.6.*,
-                        attoparsec              >= 0.10         && < 0.11,
-                        bytestring              >= 0.9          && < 0.11,
-                        bytestring-lexing       >= 0.2          && < 0.5,
-                        criterion               >= 0.5          && < 0.9,
-                        fclabels                >= 2.0          && < 2.1,
-                        primitive               >= 0.5          && < 0.6,
-                        mwc-random              >= 0.8          && < 0.14,
-                        vector                  >= 0.7          && < 0.11,
-                        vector-algorithms       >= 0.4          && < 0.6
+    build-depends:      accelerate              == 0.15.*,
+                        base                    == 4.7.*,
+                        attoparsec              >= 0.10,
+                        bytestring              >= 0.9,
+                        bytestring-lexing       >= 0.2,
+                        criterion               >= 0.5 && < 1.0,
+                        fclabels                >= 2.0,
+                        primitive               >= 0.5,
+                        mwc-random              >= 0.8,
+                        vector                  >= 0.7,
+                        vector-algorithms       >= 0.4
 
 
 -- A quasicrystal demo as the sum of waves in a plane
@@ -200,36 +270,37 @@
   Main-is:              Main.hs
   other-modules:        Config ParseArgs Monitoring
 
-  ghc-options:          -O2 -Wall -threaded
+  ghc-options:          -O2 -Wall -threaded -rtsopts -eventlog
   ghc-prof-options:     -auto-all
 
-  if impl(ghc >= 7.0)
-    ghc-options:        -rtsopts
-
   if flag(gui)
     CPP-options:        -DACCELERATE_ENABLE_GUI
 
   if flag(cuda)
     CPP-options:        -DACCELERATE_CUDA_BACKEND
-    build-depends:      accelerate-cuda         == 0.14.*
+    build-depends:      accelerate-cuda         == 0.15.*
 
-  if flag(opencl)
-    CPP-options:        -DACCELERATE_OPENCL_BACKEND
-    build-depends:      accelerate-opencl       == 0.1.*
+  if flag(llvm-cpu)
+    CPP-options:        -DACCELERATE_LLVM_NATIVE_BACKEND
+    build-depends:      accelerate-llvm-native  == 0.15.*
 
+  if flag(llvm-gpu)
+    CPP-options:        -DACCELERATE_LLVM_PTX_BACKEND
+    build-depends:      accelerate-llvm-ptx     == 0.15.*
+
   if flag(ekg)
     CPP-options:        -DACCELERATE_ENABLE_EKG
-    build-depends:      ekg                     >= 0.3          && < 0.4
+    build-depends:      ekg                     >= 0.3
     ghc-options:        -with-rtsopts=-T
 
   if !flag(crystal)
     buildable:          False
   else
-    build-depends:      accelerate              == 0.14.*,
-                        base                    == 4.6.*,
-                        criterion               >= 0.5          && < 0.9,
-                        fclabels                >= 2.0          && < 2.1,
-                        gloss-raster-accelerate >= 1.8          && < 1.9
+    build-depends:      accelerate              == 0.15.*,
+                        base                    == 4.7.*,
+                        criterion               >= 0.5 && < 1.0,
+                        fclabels                >= 2.0,
+                        gloss-raster-accelerate >= 1.7
 
 
 -- Image edge detection
@@ -240,36 +311,44 @@
   Main-is:              Main.hs
   other-modules:        Config ParseArgs Canny Wildfire Monitoring
 
-  ghc-options:          -Wall -threaded -Odph -fllvm -optlo-O3
-  ghc-prof-options:     -auto-all
+  ghc-options:          -Wall
+                        -threaded
+                        -Odph
+                        -fllvm
+                        -optlo-O3
+                        -eventlog
+                        -rtsopts
 
-  if impl(ghc >= 7.0)
-    ghc-options:        -rtsopts
+  ghc-prof-options:     -auto-all
 
   if flag(cuda)
     CPP-options:        -DACCELERATE_CUDA_BACKEND
-    build-depends:      accelerate-cuda         == 0.14.*
+    build-depends:      accelerate-cuda         == 0.15.*
 
-  if flag(opencl)
-    CPP-options:        -DACCELERATE_OPENCL_BACKEND
-    build-depends:      accelerate-opencl       == 0.1.*
+  if flag(llvm-cpu)
+    CPP-options:        -DACCELERATE_LLVM_NATIVE_BACKEND
+    build-depends:      accelerate-llvm-native  == 0.15.*
 
+  if flag(llvm-gpu)
+    CPP-options:        -DACCELERATE_LLVM_PTX_BACKEND
+    build-depends:      accelerate-llvm-ptx     == 0.15.*
+
   if flag(ekg)
     CPP-options:        -DACCELERATE_ENABLE_EKG
-    build-depends:      ekg                     >= 0.3          && < 0.4
+    build-depends:      ekg                     >= 0.3
     ghc-options:        -with-rtsopts=-T
 
   if !flag(canny)
     buildable:          False
   else
-    build-depends:      accelerate              == 0.14.*,
-                        accelerate-io           == 0.14.*,
-                        base                    == 4.6.*,
-                        criterion               >= 0.5          && < 0.9,
-                        fclabels                >= 2.0          && < 2.1,
-                        repa                    >= 3.1          && < 3.3,
-                        repa-io                 >= 3.1          && < 3.3,
-                        vector                  >= 0.7          && < 0.11
+    build-depends:      accelerate              == 0.15.*,
+                        accelerate-io           == 0.15.*,
+                        base                    == 4.7.*,
+                        criterion               >= 0.5 && < 1.0,
+                        fclabels                >= 2.0,
+                        repa                    >= 3.1,
+                        repa-io                 >= 3.1,
+                        vector                  >= 0.7
 
 
 -- A simple mandelbrot generator
@@ -280,39 +359,44 @@
   Main-is:              Main.hs
   other-modules:        Config World Mandel ParseArgs Monitoring
 
-  ghc-options:          -O2 -Wall -threaded
+  ghc-options:          -O2 -Wall -threaded -eventlog -rtsopts
   ghc-prof-options:     -auto-all
 
-  if impl(ghc >= 7.0)
-    ghc-options:        -rtsopts
-
   if flag(gui)
     CPP-options:        -DACCELERATE_ENABLE_GUI
 
   if flag(cuda)
     CPP-options:        -DACCELERATE_CUDA_BACKEND
-    build-depends:      accelerate-cuda         == 0.14.*
+    build-depends:      accelerate-cuda         == 0.15.*
 
-  if flag(opencl)
-    CPP-options:        -DACCELERATE_OPENCL_BACKEND
-    build-depends:      accelerate-opencl       == 0.1.*
+  if flag(llvm-cpu)
+    CPP-options:        -DACCELERATE_LLVM_NATIVE_BACKEND
+    build-depends:      accelerate-llvm-native  == 0.15.*,
+                        accelerate-llvm
 
+  if flag(llvm-gpu)
+    CPP-options:        -DACCELERATE_LLVM_PTX_BACKEND
+    build-depends:      accelerate-llvm-ptx     == 0.15.*
+
+  if flag(llvm-cpu) && flag(llvm-gpu) && flag(llvm-multi)
+    CPP-options:        -DACCELERATE_LLVM_MULTIDEV_BACKEND
+    build-depends:      accelerate-llvm-multidev== 0.15.*
+
   if flag(ekg)
     CPP-options:        -DACCELERATE_ENABLE_EKG
-    build-depends:      ekg                     >= 0.3          && < 0.4
+    build-depends:      ekg                     >= 0.3
     ghc-options:        -with-rtsopts=-T
 
   if !flag(mandelbrot)
     buildable:          False
   else
-    build-depends:      accelerate              == 0.14.*,
-                        accelerate-fft          == 0.14.*,
-                        accelerate-io           == 0.14.*,
-                        base                    == 4.6.*,
-                        criterion               >= 0.5          && < 0.9,
-                        fclabels                >= 2.0          && < 2.1,
-                        gloss                   >= 1.7          && < 1.9,
-                        gloss-accelerate        >= 1.7          && < 1.9
+    build-depends:      accelerate              == 0.15.*,
+                        accelerate-io           == 0.15.*,
+                        base                    == 4.7.*,
+                        criterion               >= 0.5 && < 1.0,
+                        fclabels                >= 2.0,
+                        gloss                   >= 1.7,
+                        gloss-accelerate        >= 1.7
 
 
 -- A stable fluid simulation
@@ -327,34 +411,39 @@
                         Type
                         World
 
-  ghc-options:          -O2 -Wall -threaded
+  ghc-options:          -O2 -Wall -threaded -eventlog -rtsopts
   ghc-prof-options:     -auto-all
 
-  if impl(ghc >= 7.0)
-    ghc-options:        -rtsopts
-
   if flag(gui)
     CPP-options:        -DACCELERATE_ENABLE_GUI
 
   if flag(cuda)
     cpp-options:        -DACCELERATE_CUDA_BACKEND
-    build-depends:      accelerate-cuda         == 0.14.*
+    build-depends:      accelerate-cuda         == 0.15.*
 
+  if flag(llvm-cpu)
+    CPP-options:        -DACCELERATE_LLVM_NATIVE_BACKEND
+    build-depends:      accelerate-llvm-native  == 0.15.*
+
+  if flag(llvm-gpu)
+    CPP-options:        -DACCELERATE_LLVM_PTX_BACKEND
+    build-depends:      accelerate-llvm-ptx     == 0.15.*
+
   if flag(ekg)
     CPP-options:        -DACCELERATE_ENABLE_EKG
-    build-depends:      ekg                     >= 0.3          && < 0.4
+    build-depends:      ekg                     >= 0.3
     ghc-options:        -with-rtsopts=-T
 
   if !flag(fluid)
     buildable:          False
   else
-    build-depends:      accelerate              == 0.14.*,
-                        accelerate-io           == 0.14.*,
-                        base                    == 4.6.*,
+    build-depends:      accelerate              == 0.15.*,
+                        accelerate-io           == 0.15.*,
+                        base                    == 4.7.*,
                         bmp                     >= 1.2,
-                        criterion               >= 0.5          && < 0.9,
-                        fclabels                >= 2.0          && < 2.1,
-                        gloss                   >= 1.7          && < 1.9
+                        criterion               >= 0.5 && < 1.0,
+                        fclabels                >= 2.0,
+                        gloss                   >= 1.7
 
 
 -- Simulation of gravitational attraction between solid particles
@@ -379,33 +468,38 @@
                         Solver.Naive1
                         Solver.Naive2
 
-  ghc-options:          -O2 -Wall -threaded
+  ghc-options:          -O2 -Wall -threaded -eventlog -rtsopts
   ghc-prof-options:     -auto-all
 
-  if impl(ghc >= 7.0)
-    ghc-options:        -rtsopts
-
   if flag(gui)
     cpp-options:        -DACCELERATE_ENABLE_GUI
 
   if flag(cuda)
     cpp-options:        -DACCELERATE_CUDA_BACKEND
-    build-depends:      accelerate-cuda         == 0.14.*
+    build-depends:      accelerate-cuda         == 0.15.*
 
+  if flag(llvm-cpu)
+    CPP-options:        -DACCELERATE_LLVM_NATIVE_BACKEND
+    build-depends:      accelerate-llvm-native  == 0.15.*
+
+  if flag(llvm-gpu)
+    CPP-options:        -DACCELERATE_LLVM_PTX_BACKEND
+    build-depends:      accelerate-llvm-ptx     == 0.15.*
+
   if flag(ekg)
     CPP-options:        -DACCELERATE_ENABLE_EKG
-    build-depends:      ekg                     >= 0.3          && < 0.4
+    build-depends:      ekg                     >= 0.3
     ghc-options:        -with-rtsopts=-T
 
   if !flag(nbody)
     buildable:          False
   else
-    build-depends:      accelerate              == 0.14.*,
-                        base                    == 4.6.*,
-                        criterion               >= 0.5          && < 0.9,
-                        fclabels                >= 2.0          && < 2.1,
-                        gloss                   >= 1.7          && < 1.9,
-                        mwc-random              >= 0.8          && < 0.14
+    build-depends:      accelerate              == 0.15.*,
+                        base                    == 4.7.*,
+                        criterion               >= 0.5 && < 1.0,
+                        fclabels                >= 2.0,
+                        gloss                   >= 1.7,
+                        mwc-random              >= 0.8
 
 
 -- A celular automata
@@ -422,36 +516,41 @@
                         Random.Array
                         Random.Splat
 
-  ghc-options:          -O2 -Wall -threaded
+  ghc-options:          -O2 -Wall -threaded -threaded -rtsopts
   ghc-prof-options:     -auto-all
 
-  if impl(ghc >= 7.0)
-    ghc-options:        -rtsopts
-
   if flag(gui)
     cpp-options:        -DACCELERATE_ENABLE_GUI
 
   if flag(cuda)
     cpp-options:        -DACCELERATE_CUDA_BACKEND
-    build-depends:      accelerate-cuda         == 0.14.*
+    build-depends:      accelerate-cuda         == 0.15.*
 
+  if flag(llvm-cpu)
+    CPP-options:        -DACCELERATE_LLVM_NATIVE_BACKEND
+    build-depends:      accelerate-llvm-native  == 0.15.*
+
+  if flag(llvm-gpu)
+    CPP-options:        -DACCELERATE_LLVM_PTX_BACKEND
+    build-depends:      accelerate-llvm-ptx     == 0.15.*
+
   if flag(ekg)
     CPP-options:        -DACCELERATE_ENABLE_EKG
-    build-depends:      ekg                     >= 0.3          && < 0.4
+    build-depends:      ekg                     >= 0.3
     ghc-options:        -with-rtsopts=-T
 
   if !flag(smoothlife)
     buildable:          False
   else
-    build-depends:      accelerate              == 0.14.*,
-                        accelerate-fft          == 0.14.*,
-                        accelerate-io           == 0.14.*,
-                        base                    == 4.6.*,
-                        criterion               >= 0.5          && < 0.9,
-                        fclabels                >= 2.0          && < 2.1,
-                        gloss                   >= 1.7          && < 1.9,
-                        gloss-accelerate        >= 1.7          && < 1.9,
-                        mwc-random              >= 0.8          && < 0.14
+    build-depends:      accelerate              == 0.15.*,
+                        accelerate-fft          == 0.15.*,
+                        accelerate-io           == 0.15.*,
+                        base                    == 4.7.*,
+                        criterion               >= 0.5 && < 1.0,
+                        fclabels                >= 2.0,
+                        gloss                   >= 1.7,
+                        gloss-accelerate        >= 1.7,
+                        mwc-random              >= 0.8
 
 
 -- A password recovery tool
@@ -465,32 +564,37 @@
                         MD5
                         Util
 
-  ghc-options:          -O2 -Wall -threaded
+  ghc-options:          -O2 -Wall -threaded -threaded -rtsopts
   ghc-prof-options:     -auto-all
 
-  if impl(ghc >= 7.0)
-    ghc-options:        -rtsopts
-
   if flag(cuda)
     cpp-options:        -DACCELERATE_CUDA_BACKEND
-    build-depends:      accelerate-cuda         == 0.14.*
+    build-depends:      accelerate-cuda         == 0.15.*
 
+  if flag(llvm-cpu)
+    CPP-options:        -DACCELERATE_LLVM_NATIVE_BACKEND
+    build-depends:      accelerate-llvm-native  == 0.15.*
+
+  if flag(llvm-gpu)
+    CPP-options:        -DACCELERATE_LLVM_PTX_BACKEND
+    build-depends:      accelerate-llvm-ptx     == 0.15.*
+
   if flag(ekg)
     CPP-options:        -DACCELERATE_ENABLE_EKG
-    build-depends:      ekg                     >= 0.3          && < 0.4
+    build-depends:      ekg                     >= 0.3
     ghc-options:        -with-rtsopts=-T
 
   if !flag(hashcat)
     buildable:          False
   else
-    build-depends:      accelerate              == 0.14.*,
-                        base                    == 4.6.*,
-                        bytestring              >= 0.9          && < 0.11,
-                        bytestring-lexing       >= 0.2          && < 0.5,
-                        cereal                  >= 0.3          && < 0.5,
-                        criterion               >= 0.5          && < 0.9,
-                        fclabels                >= 2.0          && < 2.1,
-                        mwc-random              >= 0.8          && < 0.14
+    build-depends:      accelerate              == 0.15.*,
+                        base                    == 4.7.*,
+                        bytestring              >= 0.9,
+                        bytestring-lexing       >= 0.2,
+                        cereal                  >= 0.3,
+                        criterion               >= 0.5 && < 1.0,
+                        fclabels                >= 2.0,
+                        mwc-random              >= 0.8
 
 -- FFT examples
 -- ------------
@@ -503,24 +607,174 @@
                         HighPass
                         FFT
 
-  ghc-options:          -O2 -Wall -threaded
-  if impl(ghc >= 7.0)
-    ghc-options:        -rtsopts
+  ghc-options:          -O2 -Wall -threaded -threaded -rtsopts
+  ghc-prof-options:     -auto-all
 
   if flag(cuda)
     cpp-options:        -DACCELERATE_CUDA_BACKEND
-    build-depends:      accelerate-cuda         == 0.14.*
+    build-depends:      accelerate-cuda         == 0.15.*
 
+  if flag(llvm-cpu)
+    CPP-options:        -DACCELERATE_LLVM_NATIVE_BACKEND
+    build-depends:      accelerate-llvm-native  == 0.15.*
+
+  if flag(llvm-gpu)
+    CPP-options:        -DACCELERATE_LLVM_PTX_BACKEND
+    build-depends:      accelerate-llvm-ptx     == 0.15.*
+
   if !flag(fft)
     buildable:          False
   else
-    build-depends:      accelerate              == 0.14.*,
-                        accelerate-io           == 0.14.*,
-                        accelerate-fft          == 0.14.*,
-                        base                    == 4.6.*,
-                        criterion               >= 0.5          && < 0.9,
-                        fclabels                >= 2.0          && < 2.1,
+    build-depends:      accelerate              == 0.15.*,
+                        accelerate-io           == 0.15.*,
+                        accelerate-fft          == 0.15.*,
+                        base                    == 4.7.*,
+                        criterion               >= 0.5 && < 1.0,
+                        fclabels                >= 2.0,
                         filepath                >= 1.0
+
+-- PageRank
+-- --------
+
+Executable accelerate-pagerank
+  Main-is:              Main.hs
+  hs-source-dirs:       examples/pagerank lib
+  other-modules:        Config
+                        Page
+                        Progress
+                        Rank
+                        Step
+                        Count
+                        Rank
+                        Step
+                        Load
+  ghc-options:          -rtsopts -threaded -O2
+
+  if flag(cuda)
+    cpp-options:        -DACCELERATE_CUDA_BACKEND
+    build-depends:      accelerate-cuda         == 0.15.*
+
+  if flag(llvm-cpu)
+    CPP-options:        -DACCELERATE_LLVM_NATIVE_BACKEND
+    build-depends:      accelerate-llvm-native  == 0.15.*
+
+  if flag(llvm-gpu)
+    CPP-options:        -DACCELERATE_LLVM_PTX_BACKEND
+    build-depends:      accelerate-llvm-ptx     == 0.15.*
+
+  if !flag(pagerank)
+    buildable:          False
+  else
+    build-depends:      accelerate              == 0.15.*,
+                        accelerate-io           == 0.15.*,
+                        base                    == 4.7.*,
+                        bytestring              >= 0.9.2,
+                        containers              >= 0.4.2,
+                        criterion               >= 0.5 && < 1.0,
+                        directory               >= 1.1,
+                        fclabels                >= 1.0,
+                        vector                  >= 0.9,
+                        vector-algorithms       >= 0.5.4
+
+
+-- Ray tracer
+-- ----------
+
+Executable accelerate-ray
+  Main-is:              Main.hs
+  hs-source-dirs:       examples/ray lib
+  other-modules:        ParseArgs Monitoring
+                        Config
+                        Vec3
+                        Gloss.Draw
+                        Gloss.Event
+                        Ray.Intersect
+                        Ray.Trace
+                        Scene.Light
+                        Scene.Object
+                        Scene.State
+                        Scene.World
+
+  if !flag(ray)
+    buildable:          False
+  else
+    build-depends:      accelerate              == 0.15.*,
+                        accelerate-io           == 0.15.*,
+                        base                    == 4.7.*,
+                        criterion               >= 0.5 && < 1.0,
+                        fclabels                >= 1.0,
+                        gloss                   == 1.8.*,
+                        gloss-accelerate        == 1.8.*,
+                        gloss-raster-accelerate == 1.8.*
+
+  if flag(cuda)
+    cpp-options:        -DACCELERATE_CUDA_BACKEND
+    build-depends:      accelerate-cuda         >= 0.15
+
+  if flag(llvm-cpu)
+    CPP-options:        -DACCELERATE_LLVM_NATIVE_BACKEND
+    build-depends:      accelerate-llvm-native  == 0.15.*
+
+  if flag(llvm-gpu)
+    CPP-options:        -DACCELERATE_LLVM_PTX_BACKEND
+    build-depends:      accelerate-llvm-ptx     == 0.15.*
+
+  if flag(llvm-cpu) && flag(llvm-gpu) && flag(llvm-multi)
+    CPP-options:        -DACCELERATE_LLVM_MULTIDEV_BACKEND
+    build-depends:      accelerate-llvm-multidev== 0.15.*
+
+  if flag(ekg)
+    cpp-options:        -DACCELERATE_ENABLE_EKG
+    build-depends:      ekg                     >= 0.3
+    ghc-options:        -with-rtsopts=-T
+
+  if flag(gui)
+    CPP-options:        -DACCELERATE_ENABLE_GUI
+
+  ghc-options:          -Wall -O2 -threaded -threaded -rtsopts
+  ghc-prof-options:     -auto-all
+
+
+-- K-means
+-- -------
+
+Executable accelerate-kmeans
+  Main-is:              Main.hs
+  hs-source-dirs:       examples/kmeans lib
+  other-modules:        ParseArgs Monitoring
+                        Config
+                        Main
+                        Kmeans
+
+  if !flag(kmeans)
+    buildable:          False
+  else
+    build-depends:      accelerate              == 0.15.*,
+                        base                    == 4.7.*,
+                        binary                  >= 0.7,
+                        criterion               >= 0.5 && < 1.0,
+                        normaldistribution,
+                        random
+
+  if flag(cuda)
+    cpp-options:        -DACCELERATE_CUDA_BACKEND
+    build-depends:      accelerate-cuda         >= 0.15
+
+  if flag(llvm-cpu)
+    CPP-options:        -DACCELERATE_LLVM_NATIVE_BACKEND
+    build-depends:      accelerate-llvm-native  == 0.15.*
+
+  if flag(llvm-gpu)
+    CPP-options:        -DACCELERATE_LLVM_PTX_BACKEND
+    build-depends:      accelerate-llvm-ptx     == 0.15.*
+
+  if flag(ekg)
+    cpp-options:        -DACCELERATE_ENABLE_EKG
+    build-depends:      ekg                     >= 0.3
+    ghc-options:        -with-rtsopts=-T
+
+  ghc-options:          -Wall -O2 -threaded -threaded -rtsopts
+  ghc-prof-options:     -auto-all
 
 
 source-repository head
diff --git a/examples/canny/src-acc/Canny.hs b/examples/canny/src-acc/Canny.hs
--- a/examples/canny/src-acc/Canny.hs
+++ b/examples/canny/src-acc/Canny.hs
@@ -82,12 +82,12 @@
 gaussianX :: Acc (Image Float) -> Acc (Image Float)
 gaussianX = stencil (convolve5x1 gaussian) Clamp
   where
-    gaussian = [ 1, 4, 6, 4, 1 ]
+    gaussian = P.map (/16) [ 1, 4, 6, 4, 1 ]
 
 gaussianY :: Acc (Image Float) -> Acc (Image Float)
 gaussianY = stencil (convolve1x5 gaussian) Clamp
   where
-    gaussian = P.map (/256) [ 1, 4, 6, 4, 1 ]
+    gaussian = P.map (/16) [ 1, 4, 6, 4, 1 ]
 
 
 -- Gradients in the x- and y- directions
diff --git a/examples/fft/src-acc/FFT.hs b/examples/fft/src-acc/FFT.hs
--- a/examples/fft/src-acc/FFT.hs
+++ b/examples/fft/src-acc/FFT.hs
@@ -5,8 +5,8 @@
 import Prelude                                          as P
 import Data.Array.Accelerate                            as A
 import Data.Array.Accelerate.IO                         as A
+import Data.Array.Accelerate.Data.Complex               as A
 import Data.Array.Accelerate.Math.FFT                   as A
-import Data.Array.Accelerate.Math.Complex               as A
 import Data.Array.Accelerate.Math.DFT.Centre            as A
 
 
diff --git a/examples/fft/src-acc/HighPass.hs b/examples/fft/src-acc/HighPass.hs
--- a/examples/fft/src-acc/HighPass.hs
+++ b/examples/fft/src-acc/HighPass.hs
@@ -6,8 +6,8 @@
 import Data.Array.Accelerate                            as A
 import Data.Array.Accelerate.IO                         as A
 import Data.Array.Accelerate.Math.FFT                   as A
-import Data.Array.Accelerate.Math.Complex               as A
 import Data.Array.Accelerate.Math.DFT.Centre            as A
+import Data.Array.Accelerate.Data.Complex               as A
 
 
 highpassFFT :: Int -> Int -> Int -> Acc (Array DIM2 RGBA32) -> Acc (Array DIM2 RGBA32)
diff --git a/examples/fluid/src-acc/Fluid.hs b/examples/fluid/src-acc/Fluid.hs
--- a/examples/fluid/src-acc/Fluid.hs
+++ b/examples/fluid/src-acc/Fluid.hs
@@ -105,6 +105,11 @@
        ?| ( field, A.permute (.+.) field (is A.!) ps )
 
 
+-- The core of the fluid flow algorithm is a finite time step simulation on the
+-- grid, implemented as a matrix relaxation involving the discrete Laplace
+-- operator \nabla^2. This step, know as the linear solver, is used to diffuse
+-- the density and velocity fields throughout the grid.
+--
 diffuse
     :: FieldElt e
     => Int
diff --git a/examples/fluid/src-acc/Main.hs b/examples/fluid/src-acc/Main.hs
--- a/examples/fluid/src-acc/Main.hs
+++ b/examples/fluid/src-acc/Main.hs
@@ -44,7 +44,7 @@
       -- Prepare user-input density and velocity sources
       --
       sources s = let (ix, ss)  = P.unzip s
-                      sh        = Z :. length ix
+                      sh        = Z :. P.length ix
                   in  ( A.fromList sh ix, A.fromList sh ss )
 
       -- for benchmarking
diff --git a/examples/hashcat/MD5.hs b/examples/hashcat/MD5.hs
--- a/examples/hashcat/MD5.hs
+++ b/examples/hashcat/MD5.hs
@@ -141,7 +141,7 @@
 showMD5 (a,b,c,d) =
   let bs                = S.runPutLazy $ S.putWord32be d >> S.putWord32be c >> S.putWord32be b >> S.putWord32be a
       showsHex str w    = let x = showHex w str
-                          in if length x < length str + 2
+                          in if P.length x < P.length str + 2
                                 then '0':x
                                 else x
   in
diff --git a/examples/kmeans/Config.hs b/examples/kmeans/Config.hs
new file mode 100644
--- /dev/null
+++ b/examples/kmeans/Config.hs
@@ -0,0 +1,54 @@
+{-# LANGUAGE TemplateHaskell #-}
+
+module Config where
+
+import ParseArgs
+import Data.Label
+
+
+-- Configuration options
+--
+data Config
+  = Config
+  {
+    _configBackend      :: Backend
+  , _configHelp         :: Bool
+  }
+  deriving Show
+
+$(mkLabels [''Config])
+
+defaults :: Config
+defaults = Config
+  {
+    _configBackend      = maxBound
+  , _configHelp         = False
+  }
+
+
+-- The set of available command line options
+--
+options :: [OptDescr (Config -> Config)]
+options =
+  [ Option  ['h', '?'] ["help"]
+            (NoArg (set configHelp True))
+            "show this help message"
+  ]
+
+
+-- Command line decoration
+--
+header :: [String]
+header =
+  [ "accelerate-kmeans (c) [2014] The Accelerate Team"
+  , ""
+  , "Usage: accelerate-kmeans [OPTIONS]"
+  , ""
+  , "Be sure to first build and run the GenSamples program, in order to"
+  , "generate some random data points."
+  , ""
+  ]
+
+footer :: [String]
+footer = []
+
diff --git a/examples/kmeans/Kmeans.hs b/examples/kmeans/Kmeans.hs
new file mode 100644
--- /dev/null
+++ b/examples/kmeans/Kmeans.hs
@@ -0,0 +1,226 @@
+{-# LANGUAGE TypeOperators       #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+-- |
+-- Module      : Data.Array.Accelerate.Math.Kmeans
+-- Copyright   : [2014] Trevor L. McDonell
+-- License     : BSD3
+--
+-- Maintainer  : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+--
+-- An implementation of K-means clustering in Accelerate using Lloyd's
+-- algorithm. This heuristic technique finds a solution by iteratively improving
+-- an initial guess. The algorithm takes as input the number of clusters to find
+-- and makes an initial guess at the center of each cluster. Then proceeds as
+-- follows:
+--
+--   1. Assign each point to the cluster to which it is closest. This forms the
+--   new set of clusters.
+--
+--   2. Compute the centroid of the cluster (the average of all points in the
+--   cluster.
+--
+--   3. Repeat until the centroid locations stabilise (or some maximum iteration
+--   limit is reached).
+--
+-- Adapted from K-Means sample from "Parallel and Concurrent Programming in
+-- Haskell", (c) Simon Marlow, 2013.
+--
+
+module Kmeans ( Point, Cluster, Id, kmeans )
+  where
+
+import Prelude                                          as P
+import Data.Array.Accelerate                            as A
+
+
+-- This implementation works on 2D points. In future, generalise this to some
+-- arbitrary "feature vector".
+--
+type Point a = (a, a)
+
+-- Clusters consist of the centroid location as well as its identifier
+--
+type Id = Word32
+type Cluster a = (Id, (a, a))
+
+idOfCluster :: Elt a => Exp (Cluster a) -> Exp Id
+idOfCluster = A.fst
+
+centroidOfCluster :: Elt a => Exp (Cluster a) -> Exp (Point a)
+centroidOfCluster = A.snd
+
+-- We'll use this as an intermediate structure; it contains the number of points
+-- in the set as well as the sum of the x and y coordinates respectively.
+--
+type PointSum a = (Word32, (a, a))
+
+
+-- Get the distance (squared) between two points. Since we only compare this
+-- value, we elide the square root.
+--
+distance :: (Elt a, IsNum a) => Exp (Point a) -> Exp (Point a) -> Exp a
+distance u v =
+  let (x1,y1) = unlift u
+      (x2,y2) = unlift v
+  in
+  (x1-x2)^(2::Int) + (y1-y2)^(2::Int)
+
+
+-- For each of the given points, return the cluster Id that that that point is
+-- closest to.
+--
+findClosestCluster
+    :: forall a. (Elt a, IsFloating a, RealFloat a)
+    => Acc (Vector (Cluster a))
+    -> Acc (Vector (Point a))
+    -> Acc (Vector Id)
+findClosestCluster clusters points =
+  A.map (\p -> A.fst $ A.sfoldl (nearest p) z (constant Z) clusters) points
+  where
+    z = constant (-1, inf)
+
+    nearest :: Exp (Point a) -> Exp (Id, a) -> Exp (Cluster a) -> Exp (Id, a)
+    nearest p st c =
+      let d  = A.snd st
+          d' = distance p (centroidOfCluster c)
+      in
+      d' <* d ? ( lift (idOfCluster c, d') , st )
+
+
+-- Given a vector of points and a vector of clusters we, we first locate the
+-- closest cluster to each point, assign that point to their closest cluster,
+-- and compute the centroid of the cluster. This yields the new centroid
+-- locations.
+--
+makeNewClusters
+    :: forall a. (Elt a, IsFloating a, RealFloat a)
+    => Acc (Vector (Point a))
+    -> Acc (Vector (Cluster a))
+    -> Acc (Vector (Cluster a))
+makeNewClusters points clusters
+  = pointSumToCluster
+  . makePointSum
+  . findClosestCluster clusters
+  $ points
+
+-- TLM: This setup might be quicker, because it forces the result of
+--      findClosestCluster to be evaluated, which overall reduces memory
+--      traffic. However, this is hitting a sharing recovery bug in Accelerate
+--      so can't be used right now ):
+--
+--      As per tip in issue #148, we can get around the bug by making the first
+--      argument to pipe closed. It turns out that the first version is quicker!
+--
+--  = A.uncurry findClosestCluster >-> pointSumToCluster . makePointSum $ A.lift (clusters, points)
+  where
+    npts        = size points
+    nclusters   = size clusters
+
+    -- Turn the PointSum intermediate structure into the clusters, by averaging
+    -- the cumulative (x,y) positions.
+    --
+    pointSumToCluster :: Acc (Vector (PointSum a)) -> Acc (Vector (Cluster a))
+    pointSumToCluster ps =
+      A.generate (A.shape ps)
+                 (\ix -> lift (A.fromIntegral (unindex1 ix), average (ps ! ix)))
+
+    average :: Exp (PointSum a) -> Exp (Point a)
+    average ps =
+      let (n, xy) = unlift ps   :: (Exp Word32, Exp (Point a))
+          (x, y)  = unlift xy
+      in
+      lift (x / A.fromIntegral n, y / A.fromIntegral n) -- TLM: what if there are no points in the cluster??
+
+    -- Reduce along the rows of 'pointSum' to get the cumulative (x,y) position
+    -- and number of points assigned to each centroid.
+    --
+    makePointSum :: Acc (Vector Id) -> Acc (Vector (PointSum a))
+    makePointSum = A.fold1 addPointSum . pointSum
+
+    -- The point sum is an intermediate 2D array (it gets fused away, so does
+    -- not exist in memory). The points are laid out along the innermost
+    -- dimension (rows), and down the column is each of the clusters.
+    --
+    -- For each point, we put its (x,y) coordinates into the row corresponding
+    -- to whichever cluster it is closest to, and zeros in each of the other
+    -- rows.
+    --
+    pointSum :: Acc (Vector Id) -> Acc (Array DIM2 (PointSum a))
+    pointSum nearest =
+      A.generate (lift (Z:.nclusters:.npts))
+                 (\ix -> let Z:.i:.j = unlift ix    :: Z :. Exp Int :. Exp Int
+                             near    = nearest ! index1 j
+
+                             yes     = lift (constant 1, points ! index1 j)
+                             no      = constant (0, (0,0))
+                         in
+                         near ==* A.fromIntegral i ? ( yes, no ))
+
+    addPointSum :: Exp (PointSum a) -> Exp (PointSum a) -> Exp (PointSum a)
+    addPointSum x y =
+      let (c1, u) = unlift x    :: (Exp Word32, Exp (Point a))
+          (c2, v) = unlift y    :: (Exp Word32, Exp (Point a))
+          (x1,y1) = unlift u    :: (Exp a, Exp a)
+          (x2,y2) = unlift v    :: (Exp a, Exp a)
+      in
+      lift (c1+c2, lift (x1+x2, y1+y2) :: Exp (Point a))
+
+{--
+    -- Alternative to computing the PointSum structure.
+    --
+    -- This method uses a forward permutation with atomic instructions to create
+    -- the array directly (this method is closer to what one might write
+    -- sequentially). This avoids a parallel reduction, but has very high
+    -- contention. Overall performance much lower, as:
+    --
+    --   number of clusters << number of points
+    --
+    makePointSum :: Acc (Vector (PointSum a))
+    makePointSum = A.permute addPointSum zeros near input
+      where
+        zeros   = A.fill (constant (Z:.nclusters)) (constant (0,(0,0)))
+        input   = A.zip (A.fill (A.shape points) (constant 1)) points
+        near ix = index1 (A.fromIntegral (nearest ! ix))
+--}
+
+
+-- To complete the k-means algorithm, we loop repeatedly generating new clusters
+-- positions, until the positions converge (or some maximum iteration limit is
+-- reached?)
+--
+kmeans :: forall a. (Elt a, IsFloating a, RealFloat a)
+       => Acc (Vector (Point a))        -- the points to cluster
+       -> Acc (Vector (Cluster a))      -- initial cluster positions (guess)
+       -> Acc (Vector (Cluster a))
+kmeans points clusters
+  = A.asnd
+  $ A.awhile (A.uncurry keepGoing)
+             (\cs -> let (_, old) = unlift cs   :: (Acc (Vector (Cluster a)), Acc (Vector (Cluster a)))
+                         new      = makeNewClusters points old
+                     in
+                     lift (old,new))
+             (lift (clusters, makeNewClusters points clusters))
+  where
+    keepGoing :: Acc (Vector (Cluster a)) -> Acc (Vector (Cluster a)) -> Acc (Scalar Bool)
+    keepGoing xs ys
+      = A.or
+      $ A.zipWith (\c1 c2 -> let (x1,y1) = unlift (centroidOfCluster c1)
+                                 (x2,y2) = unlift (centroidOfCluster c2)
+                             in
+                             abs (x1-x2) >* 0.01 ||* abs (y1-y2) >* 0.01) xs ys
+
+
+-- The largest non-infinite floating point number
+--
+inf :: forall a. RealFloat a => a
+inf = encodeFloat m n
+  where
+    a           = undefined :: a
+    b           = floatRadix a
+    e           = floatDigits a
+    (_, e')     = floatRange a
+    m           = b ^ e - 1
+    n           = e' - e
+
diff --git a/examples/kmeans/Main.hs b/examples/kmeans/Main.hs
new file mode 100644
--- /dev/null
+++ b/examples/kmeans/Main.hs
@@ -0,0 +1,61 @@
+--
+-- A k-means clustering implementation.
+-- Run the generate-samples program first to create some random data.
+--
+
+module Main where
+
+import Kmeans
+import Config
+import Monitoring
+import ParseArgs
+
+import Prelude                                          as P
+import Data.Array.Accelerate                            as A
+
+import Control.Applicative                              ( (<$>), (<*>) )
+import Control.Monad                                    ( unless )
+import Criterion.Main                                   ( defaultMainWith, bench, whnf )
+import Data.Binary                                      ( decodeFile )
+import Data.Label                                       ( get )
+import System.Directory
+import System.Environment
+
+
+main :: IO ()
+main
+  = do  beginMonitoring
+        argv                    <- getArgs
+        (conf, cconf, nops)     <- parseArgs configHelp configBackend options defaults header footer argv
+
+        inputs                  <- (&&) <$> doesFileExist "points.bin"
+                                        <*> doesFileExist "clusters"
+        unless inputs $ do
+          error "Run the GenSamples program first to generate random data"
+
+        points'                 <- decodeFile "points.bin"
+        initial'                <- read `fmap` readFile "clusters"
+
+        let nclusters   = P.length initial'
+            npoints     = P.length points'
+
+            solve       = run1 backend (kmeans (use points))
+            backend     = get configBackend conf
+
+            initial :: Vector (Cluster Float)
+            initial = A.fromList (Z:.nclusters) initial'
+
+            points :: Vector (Point Float)
+            points = A.fromList (Z:.npoints)   points'
+
+        -- Warm up first by printing the expected results
+        --
+        putStrLn $ "number of points: " P.++ show npoints
+        putStrLn $ "final clusters:\n"  P.++
+          unlines (P.map show . A.toList $ solve initial)
+
+        -- Now benchmark
+        --
+        withArgs nops $ defaultMainWith cconf (return ())
+          [ bench "k-means" $ whnf solve initial ]
+
diff --git a/examples/mandelbrot/Main.hs b/examples/mandelbrot/Main.hs
--- a/examples/mandelbrot/Main.hs
+++ b/examples/mandelbrot/Main.hs
@@ -39,7 +39,7 @@
             height      = get optHeight conf
 
             -- Centre coordinates: Re(c) = -0.7; Im(c) = 0
-            -- View width: 3.0769
+            -- View width: 3.067
             --
             view        = (-2.23, -1.15, 0.83, 1.15)
 
diff --git a/examples/mandelbrot/Mandel.hs b/examples/mandelbrot/Mandel.hs
--- a/examples/mandelbrot/Mandel.hs
+++ b/examples/mandelbrot/Mandel.hs
@@ -16,7 +16,7 @@
 import Prelude                                  as P
 import Data.Array.Accelerate                    as A
 import Data.Array.Accelerate.IO                 as A
-import Data.Array.Accelerate.Math.Complex
+import Data.Array.Accelerate.Data.Complex
 
 -- Types -----------------------------------------------------------------------
 
@@ -63,7 +63,7 @@
     -- initial conditions for a given pixel in the window, translated to the
     -- corresponding point in the complex plane
     initial :: Exp DIM2 -> Exp (Complex a)
-    initial ix                = lift ( (xmin + (x * sizex) / viewx) :+ (ymin + (y * sizey) / viewy) )
+    initial ix = lift ( (xmin + (x * sizex) / viewx) :+ (ymin + (y * sizey) / viewy) )
       where
         pr = unindex2 ix
         x  = A.fromIntegral (A.snd pr :: Exp Int)
@@ -76,7 +76,7 @@
     dot c = let r :+ i = unlift c
             in  r*r + i*i
 
-    lIMIT = constant (P.fromIntegral depth)
+    lIMIT = P.fromIntegral depth
 
 
 -- Rendering -------------------------------------------------------------------
diff --git a/examples/mandelbrot/World.hs b/examples/mandelbrot/World.hs
--- a/examples/mandelbrot/World.hs
+++ b/examples/mandelbrot/World.hs
@@ -1,5 +1,6 @@
-{-# LANGUAGE GADTs         #-}
-{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE GADTs               #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeOperators       #-}
 
 module World (
 
@@ -143,6 +144,7 @@
     char 'x'            = toggle zooming Out
     char 'd'            = precision Double
     char 'f'            = precision Float
+    char n | isDigit n  = preset n
     char _              = const id
 
     special KeyUp       = toggle vertical Fwd
@@ -157,7 +159,10 @@
     precision f Down    = setPrecisionOfWorld f opt
     precision _ _       = id
 
+    preset n Down       = loadPreset (read [n])
+    preset _ Up         = id
 
+
 -- Miscellaneous
 -- -------------
 
@@ -172,4 +177,28 @@
 
 convertView :: (Real a, Fractional b) => View a -> View b
 convertView (x,y,x',y') = (realToFrac x, realToFrac y, realToFrac x', realToFrac y')
+
+-- Presets
+-- -------
+
+loadPreset :: Int -> World -> World
+loadPreset n (World _ r z h v) = load (table P.!! n)
+  where
+    load (posX, posY, zoom, _iters :: Double, _radius :: Double)        -- type signature only to suppress a warning
+      = let x' = zoom / 2
+            y' = x' * 0.75
+        in  World (posX-x', posY-y', posX+x', posY+y') r z h v
+
+    table =
+      [ (-0.7,                   0,                               3.067,                  100.0,               2.0)
+      , (0.20508818500545423,    0.9014915666351141   * 900/1440, 6.375321937544527e-6,   629.3354966759534,   16.0)
+      , (0.4510757067879078,     0.6144133202705898   * 900/1440, 7.632248223018773e-5,   253.61352386150395,  2.0)
+      , (0.3469337523117071,     0.6866350870407725   * 900/1440, 3.508380713647269e-5,   168.61054759193718,  1024.0)
+      , (-0.7902001921590814,    0.24910667566731381  * 900/1440, 5.071115028132377e-4,   1176.757810813391,   3.4359738368e10)
+      , (2.3127178455019423e-2, -1.301205470975472    * 900/1440, 3.6349313304610088e-9,  343.0390372557315,   2.0)
+      , (2.3127176148480418e-2, -1.3012054707668765   * 900/1440, 2.71444790387451e-10,   604.1620768089155,   2.0)
+      , (2.3127176156746785e-2, -1.301205470242045    * 900/1440, 4.49615119202067e-12,   1731.8575629678642,  2.0)
+      , (0.2550376327692795,     8.962363618058007e-4 * 900/1440, 7.351698819132829e-5,   1412.1093729760698,  16.0)
+      , (0.25498593633806477,    8.726424280526077e-4 * 900/1440, 1.6858526052251987e-10, 10492.090844482025,  2.0)
+      ]
 
diff --git a/examples/n-body/Random/Position.hs b/examples/n-body/Random/Position.hs
--- a/examples/n-body/Random/Position.hs
+++ b/examples/n-body/Random/Position.hs
@@ -1,4 +1,5 @@
-{-# LANGUAGE ViewPatterns #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE ViewPatterns  #-}
 
 --
 -- Generators for various distributions of particle positions
@@ -8,14 +9,14 @@
 
 import Common.Type
 
-import Control.Monad.ST                         ( ST )
-import System.Random.MWC                        ( GenST, uniformR )
+import Random.Array                             ( (:~>) )
+import System.Random.MWC                        ( uniformR )
 import Data.Array.Accelerate.Array.Sugar        as A
 
 
 -- | Points distributed as a disc
 --
-disc :: Position -> R -> sh -> GenST s -> ST s Position
+disc :: Position -> R -> sh :~> Position
 disc (originX, originY, originZ) radiusMax _ix gen
   = do  radius          <- uniformR (0,radiusMax) gen
         theta           <- uniformR (0, pi)       gen
@@ -28,7 +29,7 @@
 
 -- | A point cloud with areas of high and low density
 --
-cloud :: Shape sh => (Int,Int) -> R -> sh -> GenST s -> ST s Position
+cloud :: Shape sh => (Int,Int) -> R -> sh :~> Position
 cloud (fromIntegral -> sizeX, fromIntegral -> sizeY) radiusMax ix gen
   = let
         blob (sx,sy,sz) r
diff --git a/examples/nofib/Main.hs b/examples/nofib/Main.hs
--- a/examples/nofib/Main.hs
+++ b/examples/nofib/Main.hs
@@ -8,11 +8,13 @@
 
 import Config
 import Monitoring
+import Test.FFT
 import Test.IO
 import Test.Prelude
 import Test.Sharing
 import Test.Imaginary
 import Test.Spectral
+import Test.Issues
 #ifdef ACCELERATE_CUDA_BACKEND
 import Test.Foreign
 #endif
@@ -38,12 +40,14 @@
   defaultMainWithOpts
     [ test_prelude conf
     , test_sharing conf
+    , test_fft conf
     , test_io conf
     , test_imaginary conf
     , test_spectral conf
 #ifdef ACCELERATE_CUDA_BACKEND
     , test_foreign conf
 #endif
+    , test_issues conf
     ]
     tfconf
     -- test-framework wants to have a nap on success; don't let it.
diff --git a/examples/nofib/Test/Base.hs b/examples/nofib/Test/Base.hs
--- a/examples/nofib/Test/Base.hs
+++ b/examples/nofib/Test/Base.hs
@@ -6,6 +6,9 @@
 module Test.Base where
 
 import Prelude                                          as P
+import Data.Complex
+import Control.Monad                                    ( unless )
+import Test.HUnit                                       ( Assertion, assertFailure )
 import Test.QuickCheck
 import Data.Array.Accelerate
 import Data.Array.Accelerate.Array.Sugar                as Sugar
@@ -28,9 +31,25 @@
   _      ~= _           = False
 
 instance (Similar a, Similar b) => Similar (a, b) where
-  (x1, y1) ~= (x2, y2)  = x1 ~= x2 && y1 ~= y2
+  (x1, x2) ~= (y1, y2) = x1 ~= y1 && x2 ~= y2
 
+instance (Similar a, Similar b, Similar c) => Similar (a, b, c) where
+  (x1, x2, x3) ~= (y1, y2, y3) = x1 ~= y1 && x2 ~= y2 && x3 ~= y3
 
+instance (Similar a, Similar b, Similar c, Similar d) => Similar (a, b, c, d) where
+  (x1, x2, x3, x4) ~= (y1, y2, y3, y4) = x1 ~= y1 && x2 ~= y2 && x3 ~= y3 && x4 ~= y4
+
+instance (Similar a, Similar b, Similar c, Similar d, Similar e)
+    => Similar (a, b, c, d, e) where
+  (x1, x2, x3, x4, x5) ~= (y1, y2, y3, y4, y5) =
+    x1 ~= y1 && x2 ~= y2 && x3 ~= y3 && x4 ~= y4 && x5 ~= y5
+
+instance (Similar a, Similar b, Similar c, Similar d, Similar e, Similar f)
+    => Similar (a, b, c, d, e, f) where
+  (x1, x2, x3, x4, x5, x6) ~= (y1, y2, y3, y4, y5, y6) =
+    x1 ~= y1 && x2 ~= y2 && x3 ~= y3 && x4 ~= y4 && x5 ~= y5 && x6 ~= y6
+
+
 instance Similar Int
 instance Similar Int8
 instance Similar Int16
@@ -41,17 +60,29 @@
 instance Similar Word16
 instance Similar Word32
 instance Similar Word64
+instance Similar Char
+instance Similar Bool
 
-instance Similar Float  where (~=) = absRelTol
-instance Similar Double where (~=) = absRelTol
+instance Similar DIM1
+instance Similar DIM2
+instance Similar DIM3
 
+instance Similar Float  where (~=) = absRelTol 0.00005 0.005
+instance Similar Double where (~=) = absRelTol 0.00005 0.005
+
+instance (Similar e, RealFloat e) => Similar (Complex e) where
+  -- CUFFT can actually give quite large errors, so we have to
+  -- increase the epsilon for the absolute relative value difference.
+  (r1 :+ i1) ~= (r2 :+ i2) = r1 ~= r2 && i1 ~= i2
+
+
 {-# INLINE relTol #-}
 relTol :: (Fractional a, Ord a) => a -> a -> a -> Bool
 relTol epsilon x y = abs ((x-y) / (x+y+epsilon)) < epsilon
 
 {-# INLINE absRelTol #-}
-absRelTol :: (RealFloat a, Ord a) => a -> a -> Bool
-absRelTol u v
+absRelTol :: (RealFloat a, Ord a) => a -> a -> a -> a -> Bool
+absRelTol epsilonAbs epsilonRel u v
   |  isInfinite u
   && isInfinite v          = True
   |  isNaN u
@@ -59,9 +90,6 @@
   | abs (u-v) < epsilonAbs = True
   | abs u > abs v          = abs ((u-v) / u) < epsilonRel
   | otherwise              = abs ((v-u) / v) < epsilonRel
-  where
-    epsilonRel = 0.001
-    epsilonAbs = 0.00001
 
 instance (Eq e, Eq sh, Shape sh) => Eq (Array sh e) where
   a1 == a2      =  arrayShape a1 == arrayShape a2
@@ -81,32 +109,31 @@
 --
 assertEqual
     :: (Similar a, Show a)
-    => Bool     -- ^ Print the test case as well?
-    -> a        -- ^ The expected value
+    => a        -- ^ The expected value
     -> a        -- ^ The actual value
-    -> Property
-assertEqual v expected actual =
-  printTestCase message (expected ~= actual)
-  where
-    message
-      | P.not v         = []
-      | otherwise       = unlines [ "*** Expected:", show expected
-                                  , "*** Received:", show actual ]
+    -> Assertion
+assertEqual expected actual =
+  unless (expected ~= actual)
+         (assertFailure (failure expected actual))
 
+failure :: Show a => a -> a -> String
+failure expected actual =
+  unlines [ "*** Expected:", show expected
+          , "*** Received:", show actual ]
+
 infix 1 ~=?, ~?=
 
 -- Short hand for a test case that asserts similarity, with the actual value on
 -- the right hand side and the expected value on the left.
 --
 (~=?) :: (Similar a, Show a) => a -> a -> Property
-(~=?) = assertEqual True
+expected ~=? actual = counterexample (failure expected actual) (expected ~= actual)
 
 -- Short hand for a test case that asserts similarity, with the actual value on
 -- the left hand side and the expected value on the right.
 --
 (~?=) :: (Similar a, Show a) => a -> a -> Property
 (~?=) = flip (~=?)
-
 
 
 -- Miscellaneous
diff --git a/examples/nofib/Test/FFT.hs b/examples/nofib/Test/FFT.hs
new file mode 100644
--- /dev/null
+++ b/examples/nofib/Test/FFT.hs
@@ -0,0 +1,78 @@
+{-# LANGUAGE RankNTypes          #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeOperators       #-}
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+module Test.FFT (
+
+  test_fft
+
+)  where
+
+import Config
+import ParseArgs
+
+import Control.Applicative
+import Data.Label
+import Data.Maybe
+import Data.Typeable
+
+import Prelude as P
+
+import Test.Base
+import Test.QuickCheck                        hiding ( (.&.) )
+import Test.Framework
+import Test.Framework.Providers.QuickCheck2
+import QuickCheck.Arbitrary.Array
+
+import Data.Array.Accelerate.Math.FFT         as FFT
+import Data.Array.Accelerate                  as A hiding ( (!) )
+import Data.Array.Accelerate.Array.Sugar      ( (!) )
+import Data.Array.Accelerate.Data.Complex
+
+newtype PowerOf2Array a = PowerOf2Array (Array DIM2 a) deriving Show
+
+instance (Arbitrary a, Elt a) => Arbitrary (PowerOf2Array a) where
+  arbitrary =
+    do
+      Z:.y:.x <- arbitrary
+      PowerOf2Array <$> arbitraryArray (Z:.ceil2n y:.ceil2n x)
+    where
+      ceil2n :: Int -> Int
+      ceil2n = (2^) . (P.floor :: Float -> Int) . P.logBase 2 . (+1) . (P.fromIntegral :: Int -> Float)
+  shrink (PowerOf2Array a)
+    = let Z:.h:.w = arrayShape a
+      in if h > 0 && w >0
+         then [ PowerOf2Array . fromList (Z:.(h `div` 2):.w) $ [a ! (Z:.y:.x) | y <- [0..h `div` 2], x <- [0..w - 1]]
+              , PowerOf2Array . fromList (Z:.h:.(w `div` 2)) $ [a ! (Z:.y:.x) | y <- [0..h - 1], x <- [0..w `div` 2]] ]
+         else []
+
+test_fft :: Config -> Test
+test_fft opt =  testGroup "fft" $ catMaybes
+  [ testElt configFloat  (undefined::Float)
+  , testElt configDouble (undefined::Double)
+  ]
+  where
+    backend = get configBackend opt
+
+    testElt :: forall a. (Elt a, Similar a, Arbitrary a, IsFloating a, RealFloat a)
+            => (Config :-> Bool)
+            -> a
+            -> Maybe Test
+    testElt ok _
+      | P.not (get ok opt)      = Nothing
+      | otherwise             = Just $ testGroup (show (typeOf (undefined :: a)))
+          [ testProperty "size"  (test_size  :: PowerOf2Array (Complex a) -> Property)
+          , testProperty "trans" (test_trans :: PowerOf2Array (Complex a) -> Property) ]
+
+    test_trans :: (Elt a, RealFloat a, IsFloating a, Similar a) => PowerOf2Array (Complex a) -> Property
+    test_trans (PowerOf2Array xs)
+      = let Z:.h:.w = arrayShape xs
+        in     run1 backend (transpose . fft2D' Forward w h) xs
+           ~?= run1 backend (fft2D' Forward h w . transpose) xs
+
+    test_size :: (Elt a, IsFloating a, RealFloat a, Similar a) => PowerOf2Array (Complex a) -> Property
+    test_size (PowerOf2Array xs)
+      = let Z:.h:.w = arrayShape xs
+        in     arrayShape xs
+           ~?= arrayShape (run1 backend (fft2D' Forward w h) xs)
+
diff --git a/examples/nofib/Test/Issues.hs b/examples/nofib/Test/Issues.hs
new file mode 100644
--- /dev/null
+++ b/examples/nofib/Test/Issues.hs
@@ -0,0 +1,38 @@
+
+module Test.Issues (
+
+  test_issues
+
+) where
+
+import Config
+
+import Test.Framework
+import Test.Issues.Issue93
+import Test.Issues.Issue102
+import Test.Issues.Issue114
+import Test.Issues.Issue119
+import Test.Issues.Issue123
+import Test.Issues.Issue137
+import Test.Issues.Issue168
+import Test.Issues.Issue184
+import Test.Issues.Issue185
+import Test.Issues.Issue187
+
+
+test_issues :: Config -> Test
+test_issues conf =
+  testGroup "issues"
+    [
+      test_issue93  conf
+    , test_issue102 conf
+    , test_issue114 conf
+    , test_issue119 conf
+    , test_issue123 conf
+    , test_issue137 conf
+    , test_issue168 conf
+    , test_issue184 conf
+    , test_issue185 conf
+    , test_issue187 conf
+    ]
+
diff --git a/examples/nofib/Test/Issues/Issue102.hs b/examples/nofib/Test/Issues/Issue102.hs
new file mode 100644
--- /dev/null
+++ b/examples/nofib/Test/Issues/Issue102.hs
@@ -0,0 +1,62 @@
+{-# LANGUAGE TypeOperators  #-}
+
+module Test.Issues.Issue102 (test_issue102)
+  where
+
+import Config
+import ParseArgs
+import Test.Base
+import Test.Framework
+import Test.Framework.Providers.HUnit
+
+import Prelude                                  as P
+import Data.Array.Accelerate                    as A
+import Data.Label
+
+
+test_issue102 :: Config -> Test
+test_issue102 conf =
+  testCase "102" (assertEqual ref1 $ run backend test1)
+  where
+    backend = get configBackend conf
+
+
+ref1 :: Array DIM3 Int
+ref1 = fromList (Z :. 1 :. 3 :. 1) [4,4,4]
+
+test1 :: Acc (Array DIM3 Int)
+test1 =
+  let p         = 3
+      lts       = 1
+      rts       = 1
+      rustride  = 1
+
+      v         = fill (constant (Z:.(p-1))) (constant 2)
+      ru'       = fill (constant (Z:.(p-1))) (constant 1)
+
+      -- generate a vector with phi(p)=p-1 elements
+      x'        = reshape (constant (Z :. lts :. (p-1) :. rts)) v
+
+      --embed into a vector of length p
+      y         = generate (constant (Z :. lts :. p :. rts))
+                           (\ix -> let (Z :. l :. i :. r) = unlift ix :: Z :. Exp Int :. Exp Int :. Exp Int
+                                   in  i ==* 0 ? (0, x' ! (lift $ Z :. l :. i-1 :. r)))
+
+      -- do a DFT_p
+      y'        = reshape (constant (Z :. lts :. p :. rts)) (flatten y)
+      dftrus    = generate (constant (Z :. p :. p))
+                           (\ix -> let (Z :. i :. j) = unlift ix :: Z :. Exp Int :. Exp Int
+                                   in ru' ! (lift (Z :. (i*j*rustride `mod` (constant p)))))
+
+      tensorDFTCoeffs   = A.replicate (lift (Z:.lts:.All:.rts:.All)) dftrus
+      tensorInputCoeffs = generate (shape tensorDFTCoeffs)
+                                   (\ix -> let (Z:.l:._:.r:.col) = unlift ix :: Z :. Exp Int :. Exp Int :. Exp Int :. Exp Int
+                                           in  y' ! (lift $ Z:.l:.col:.r))
+
+      dftans    = flatten $ fold (+) (constant 0) $ A.zipWith (*) tensorDFTCoeffs tensorInputCoeffs
+
+      --continue the alternate transform, but this line breaks
+      dfty      = reshape (shape y) $ dftans
+  in
+  dfty
+
diff --git a/examples/nofib/Test/Issues/Issue114.hs b/examples/nofib/Test/Issues/Issue114.hs
new file mode 100644
--- /dev/null
+++ b/examples/nofib/Test/Issues/Issue114.hs
@@ -0,0 +1,65 @@
+
+module Test.Issues.Issue114 (test_issue114)
+  where
+
+import Config
+import ParseArgs
+import Test.Base
+import Test.Framework
+import Test.Framework.Providers.HUnit
+
+import Prelude                                  as P
+import Data.Array.Accelerate                    as A
+import Data.Label
+
+
+test_issue114 :: Config -> Test
+test_issue114 conf = testGroup "114"
+  [ testCase "A" (assertEqual ref1 $ run backend test1)
+  , testCase "B" (assertEqual ref2 $ run backend test2)
+  ]
+  where
+    backend     = get configBackend conf
+
+
+type EFloat = (Float, Float) -- Represents a real number with a value and error
+
+fromFloat :: Float -> EFloat
+fromFloat x = (x, 0)
+
+-- toFloat :: EFloat -> Float
+-- toFloat (val, err) = val + err
+
+add :: Exp EFloat -> Exp EFloat -> Exp EFloat
+add = lift2 f
+    where
+        f :: (Exp Float, Exp Float) -> (Exp Float, Exp Float) -> (Exp Float, Exp Float)
+        f (aval, aerr) (bval, berr) = (val, err)
+            where
+                val = aval + bval
+                err = aval - (val - det) + (bval - det) + aerr + berr
+                det = val - aval
+
+esum :: Acc (Vector EFloat) -> Acc (Scalar EFloat)
+esum  x = A.fold1  add x
+
+epsum :: Acc (Vector EFloat) -> Acc (Vector EFloat)
+epsum x = A.scanl1 add x
+
+xs :: Acc (Vector EFloat)
+xs = use $ fromFunction (Z :. 100) (\_ -> fromFloat 1.01)
+
+
+ref1 :: Scalar EFloat
+ref1 = fromList Z [(101,0)]
+
+test1 :: Acc (Scalar EFloat)
+test1 = esum xs
+
+
+ref2 :: Vector EFloat
+ref2 = fromList (Z :. 100) [ (1.01 * i, 0) | i <- [1..]]
+
+test2 :: Acc (Vector EFloat)
+test2 = epsum xs
+
diff --git a/examples/nofib/Test/Issues/Issue119.hs b/examples/nofib/Test/Issues/Issue119.hs
new file mode 100644
--- /dev/null
+++ b/examples/nofib/Test/Issues/Issue119.hs
@@ -0,0 +1,173 @@
+
+module Test.Issues.Issue119 (test_issue119)
+  where
+
+import Config
+import ParseArgs
+import Test.Base
+import Test.Framework
+import Test.Framework.Providers.HUnit
+
+import Prelude                                          as P
+import Data.Array.Accelerate                            as A
+import Data.Label
+
+
+test_issue119 :: Config -> Test
+test_issue119 conf = testGroup "119"
+  [ testCase "A" (assertEqual ref1 (run backend test1))
+  , testCase "B" (assertEqual ref2 (run backend test2))
+  , testCase "C" (assertEqual ref3 (run backend test3))
+  , testCase "D" (assertEqual ref4 (run backend test4))
+  , testCase "E" (assertEqual ref5 (run backend test5))
+  , testCase "F" (assertEqual ref6 (run backend test6))
+  , testCase "G" (assertEqual ref7 (run backend test7))
+  , testCase "H" (assertEqual ref8 (run backend test8))
+  , testCase "I" (assertEqual ref9 (run backend test9))
+  , testCase "J" (assertEqual ref10 (run backend test10))
+  , testCase "K" (assertEqual ref11 (run backend test11))
+  ]
+  where
+    backend = get configBackend conf
+
+
+-- Fold tests
+-- ----------
+
+ref1 :: Scalar Int32
+ref1 = fromList Z [734889155]
+
+test1 :: Acc (Scalar Int32)
+test1 = A.foldAll (+) 0 xs
+  where
+    xs :: Acc (Array DIM2 Int32)
+    xs = use $ fromList (Z :. 5 :. 28) [14769239,-43969807,34096869,26467320,-21446403,-19566997,-20757196,-66879020,19321522,16802755,51423005,-30832656,12956743,-12318583,-48025228,61945796,-2250529,18157252,-44635606,-57062680,54654752,-45950438,-45550976,-62875929,66292458,64296866,34105235,20487639,30133337,-34016948,46574440,-21782247,7668293,8257005,-52134520,65769526,-53807259,56265864,44995988,2419563,50453876,57043978,32058611,41795482,1356242,28417251,5365744,-50462079,-4690548,-63375747,-46568125,17130936,-9136428,53870799,65779607,65381795,-32284364,1085336,41766147,-48032615,-8611290,-31457130,52882781,-11785315,31039408,14338797,11749455,4037928,-28111863,50044760,-63234128,17276128,8579326,57409776,64794871,-43959064,17740348,33371212,-18433618,303726,8599511,14055754,38794127,-49407153,-20949080,-66174156,-43639360,13828228,-36941738,-2879784,-32949921,5454298,46134687,58015243,-2497378,-35813131,-66438706,-28087800,-22569678,21234344,51086800,-17488916,62884654,55526000,31676635,7777220,38149962,66027320,-23764609,41016045,18232856,6488342,20118159,28851925,-6610856,23434278,-57333215,57974240,-66022236,55082111,61254643,-52552004,-62140522,-13018201,17313534,6955448,52914957,8368369,-25845462,50594480,-32920224,-26202745,-25861093,55035780,-60835478,6582276,55668636,26991003,228691,62551594]
+
+
+ref2 :: Scalar Int32
+ref2 = fromList Z [638248245]
+
+test2 :: Acc (Scalar Int32)
+test2 = A.foldAll (+) z xs
+  where
+    z  = constant 0
+    xs :: Acc (Array DIM2 Int32)
+    xs = use $ fromList (Z :. 28 :. 5) [30332431,6796098,-15522385,-32163376,-22219878,10020835,22638601,20673036,-30769405,-23271551,16790184,-17975968,29134928,29540030,15695897,-9531463,12041364,15327083,-7856190,28479946,24497912,-13994046,5037581,-25167431,11992516,-25544745,26910784,-29607037,21237332,30371276,1858744,20239265,1576853,5549626,1732708,21169707,-8592014,-17303153,-4691351,29659929,-17704246,-13035309,-21373638,14713362,21130870,-6403753,13321799,22126635,30318513,-25651322,-10668441,-24247707,24353923,-5541473,15335372,-7118652,-28357515,30896735,19938864,21360170,16766774,29976096,10055680,9181294,10294712,-23189559,28234139,19443020,20018378,18990662,12790940,-31136432,7945796,-11687674,4320146,-1353679,21896288,2731169,24625097,12506224,27189679,-10270450,3097174,-11012112,29232397,3162933,-11403300,30059570,-9243914,13047945,16513682,-8138375,-17921376,30769432,23685828,21912950,9206743,25339626,11122590,-13094182,-20380905,-8019817,3199026,21598845,4761221,9104850,-30744683,29597011,-26264428,-17658633,831337,-8352528,-27450307,-29451038,9006711,-21943478,25866183,21329008,-7148827,14493559,-14888430,-26543546,25318288,-14096306,-9132505,2388950,9740892,-12973005,10141734,28363840,-1974095,12753649,26765381,23979765,15399126,20204488,19148086,14457571,-18842735,31509219]
+
+
+ref3 :: Scalar Int64
+ref3 = fromList Z [-2304750112110]
+
+test3 :: Acc (Scalar Int64)
+test3 = A.foldAll (+) 0 xs
+  where
+    xs :: Acc (Array DIM2 Int64)
+    xs = use $ fromList (Z :. 4 :. 34) [-119582066848,211418632971,-273814068829,-441336869225,49277660114,545904743034,-107108516086,272730345990,-227553979182,-205217278623,-334933374202,51481780401,-243087611110,499367622597,-281520298752,183942102289,-352104016609,-411607044687,-462706494917,-405072342281,-443472456667,57859494326,340657028984,268146891294,319572181437,-328099124733,-499762864333,435940295598,310279498548,-450247211372,101309611345,508483612496,170564579262,-18976287892,-455590358368,171197058025,-370071394217,238505304901,201668743044,498589419201,297393267447,303651235875,504136702140,240153057419,227119976864,-54751959043,-389119831605,35618580405,-155315665549,539301360661,461515245841,-420790558552,-407621743214,512382547226,64401598442,75455583959,-422914101157,-444213359875,-464670739203,-151444593289,12666639431,366304035864,33213351756,-337126953996,469279395971,-318783703943,524684201810,-360908771731,-365270829375,95123780502,-392655992888,-76730831811,479382581014,-223793301821,-405318001331,-478562160184,-163914780202,-411178397558,-73093917592,322239790820,420249956833,-122752719617,-420777967956,-489170073738,232626269189,398537832770,136477711761,-117743069079,473757016199,461956975541,75333205695,122914427050,-277154707123,-344965932671,18790179442,242296707870,183037500718,380718816714,-433509147619,305765602753,436058308076,-140428136472,-289391463887,-530251700495,-306686789129,224410693891,-484184400934,463805089162,-501756254322,393903748222,-269147001559,-359942689809,-163943277620,74971067748,-202611183518,-308196672762,320023013452,75437650523,475680122061,446935336626,114910599577,-421539248344,-25530906498,-424571606102,-396438535665,354002379792,134141026509,-543141869270,-347289264435,333557662160,33168540124,-167015747466,268026632123,-65645693801,-196414232999,393080421747]
+
+ref4 :: Scalar Int64
+ref4 = fromList Z [-1982037004259]
+
+test4 :: Acc (Scalar Int64)
+test4 = A.foldAll (+) z xs
+  where
+    z = constant 0
+    xs :: Acc (Array DIM2 Int64)
+    xs = use $ fromList (Z :. 27 :. 5) [-516950650221,-198681319472,-62248207215,-368566588052,-221815889746,-404814200669,15045398798,430679777170,163443360209,58097521335,-87590898111,497607465075,-27049301510,149071552167,-119172901827,-108679661992,412502711937,-213838885992,-491807426758,-169121244505,377480661744,-364997600163,452887211838,498386633616,-196697034533,426777341897,-459406805363,-239048240471,250937389006,-453316577416,477182495522,-79624988438,-483304189443,141157669081,355197721240,-328308821798,10400185896,398549525265,-141936649498,218818467494,402542618206,456236393213,-503876199918,52591145304,-149056547666,-336820739966,-101305073619,-472113159559,-321357874802,-95088218225,47976047271,509800579620,-145214377978,258457805786,252700511510,537909713977,247668230739,-259697031014,-230995125913,77530842572,283307049087,-411792373178,324606551065,302376540936,500057254214,36752111995,-55143618182,-42362785469,-68090351859,-345780793879,485419604422,-525756197664,-67428156655,121298292757,-523227354037,542168812603,-63016595487,404709620252,492764196616,173842446373,-251029882829,53802486346,-530196219472,38098754466,-451928062539,-198941999979,-430777494835,356103891588,-478934564072,421540513969,129261909711,267834058695,-449200229070,-153755923804,548585896851,-362848223110,166182675419,272214294990,-530215315236,-342214087116,-474705180756,168367792089,-53404310532,-472623730372,-147327201280,519069543952,-135155501227,159093854025,-268230727831,529927846798,-135583708544,-435621161817,-482622020289,-337169671550,-199594728505,85511984309,389604901651,276696290309,336198922744,-456923645150,186500760911,388034346215,-121368960575,168640682551,-7576869074,69728513684,276429408489,-383852114311,-496978282447,-257731685849,286922686952,332263669356,-371802274827,144134413275,-524312126151]
+
+
+ref5 :: Vector Int32
+ref5 = fromList (Z :. 1) [-564354555]
+
+test5 :: Acc (Vector Int32)
+test5 = A.fold (+) 0 xs
+  where
+    xs :: Acc (Array DIM2 Int32)
+    xs = use $ fromList (Z :. 1 :. 130) [-4457702,-122533607,-128044610,-118567484,-51241069,207290580,-220286030,4228986,27469434,-150317120,-203604157,-825364,-5199079,33434421,-254928269,215941275,-84557225,155733915,171166525,94162372,46201848,74472984,-20540100,203227620,-205035659,139581872,-64200870,-95685833,-248817216,181149788,-51154438,5754365,-39623339,-30285278,-124075023,-116700449,198097791,-79621402,-6975987,-103294438,-193880739,-42554593,-52665481,-6774561,-145101208,217440464,-234644017,-165019600,-141695655,-110020351,179140674,66343428,43188757,192222207,196444242,72638801,260767189,-234015110,238745515,-12235263,114454889,-117207038,-56788533,-166739373,207303540,-52047526,-2280395,31679387,87315138,181256391,-197760275,147977350,-105987066,-126709084,-180021047,-91253871,88115823,-220087038,141701192,-100881541,197803243,-35493996,71878227,123953012,190031396,233047641,-172754808,-87849442,-82869836,-208702873,-91940076,-42225767,124028996,-129061972,7648559,28609363,258568067,-156621004,154765390,-15205853,-189458486,-55442626,133343504,-107377067,-153448167,-83812681,216682270,235806226,-155366374,-29170502,-113839485,-249632147,220516680,159108225,49056288,-14524239,148547005,151302845,53892421,-215278906,-59578587,-36754634,169714732,-4520583,40832244,159375461,236429345,-257962058,-19375172,-98736004]
+
+
+-- Scan tests
+-- ----------
+
+ref6 :: Vector Int64
+ref6 = fromList (Z :. 748) [9125498,-16063035,-50980,-27239361,-28337646,-37708670,-21121249,-11217118,-13848672,-39334849,-46707491,-66531944,-43011362,-52687842,-22827761,-971267,-5223404,-4411473,-18981275,13313900,6542877,11493167,22215941,15573052,-4268436,13222384,11042779,-3043325,-30361025,-12714603,3072363,31204175,3603936,1445050,3106420,-10215901,-35287878,-41312051,-33332828,-8728274,-5932326,15089470,15341055,22710136,33070009,20938516,9183939,13338488,27196906,10726312,-19896886,-5528880,-25763431,-47546113,-21147316,8321444,1963928,-26863855,-250164,32934074,44835086,57843946,26305229,6456986,-26980567,-41996719,-70804933,-84259108,-87879612,-110692672,-142798291,-116098588,-85567404,-116207069,-123821326,12584983,25114364,-7860303,1367004,22680794,6730923,24499547,45160622,66310423,75777515,95908783,82670280,75336288,86887135,72442174,70887722,56336211,86112478,69983042,71665675,72070119,94687414,125141027,117692500,91136141,111363947,94258056,102908356,70818523,80142514,92859070,122763909,93075287,77155392,54968337,29421292,31177870,1920103,6519230,-19551499,-21222657,-570094,-24097292,-21808392,-10348212,-25233388,1173489,-9736680,16762526,28315631,29037674,11984290,21576469,34826173,1642762,32046691,35140081,58642652,77835445,80197959,89973092,115910407,129847184,118117169,95353096,79367357,62093373,28767797,-2146590,-10917398,20424644,4676917,7932556,3312401,-15966908,-7189949,5420963,8175943,4434171,-23666656,-10061080,-6041726,-31631217,-46272817,-61706087,-29314516,-7596012,14721710,37426611,63932827,37620518,28457552,40061842,31619691,27526728,56295666,80222812,105097861,88788604,97864477,79172130,10011195,-11909105,14225322,47137915,41586134,43468287,16346843,33297215,32170527,53289540,54985040,81533030,110490559,94932129,-13972154,-562189,-26994686,-56883836,-38812939,-13124808,-40371526,-52769442,-21433054,-38472715,-27141571,-29136605,-25500474,-3609550,2499409,-5483029,7386627,-24798720,-19594335,-27615046,-27638210,-60052370,-60759465,21354265,35287006,20122081,39265392,30972278,-57680,-32797288,-40752069,-27338717,-42161108,-14223907,-26783347,2619156,-14191849,6138144,7386063,-2032880,-1427633,24663443,12623199,41575592,41247980,57154315,51594681,59172894,71372344,62594824,88295328,58813946,37705204,28408628,16061632,9164297,-20127170,-9336346,-19571825,-52179514,-68566225,-54477198,-47004940,-29937062,-26901831,-4920101,3005622,7980962,8028145,29521179,4597970,28713400,59139068,43239497,14548340,-5703663,19550414,41133083,40431977,71464673,71868771,61227439,41134554,31050857,8517828,36666702,67999523,50219401,20584724,22991750,27378599,54105073,39320349,15820114,40457939,41491964,23091500,7320002,-21415520,9737506,37844167,55041071,80397844,102622122,100100178,86108928,104370032,96478192,129355326,154538582,125989958,143228198,145176468,139822044,153528336,178316046,164246971,175794520,146308152,146195800,176242327,204855629,175565103,7396173,21863242,35694390,20236011,2751512,20138366,15394266,-820941,-4081067,-14269206,6911689,-11814644,-29241281,-49447821,29070717,12178489,4706892,-12315553,-19458729,-21356132,32958033,45401858,53370676,28467559,19593822,-2362034,-22117369,-7304152,-39099651,-22225335,-11600163,-22285664,2291892,-7750742,-7695599,6170980,-15707745,-37482681,-55991916,-82981918,-83046513,-56843137,-84028152,-114039097,-143926441,-152072244,-126187325,-147424750,-167404074,-162720270,-190867797,-167936982,-141061455,-109557195,-97843277,-111686956,-136635385,-104293809,-74950582,25017856,23279847,50087106,44767052,28328844,44871147,17608101,35664270,61602884,52831414,70249540,1819043,3429541,11974074,-13604141,-9364540,-31853055,1318244,-32151004,-31320318,-44830769,-21132509,-13995287,9516139,-22382471,-15989865,-4087485,-14545639,-41647841,-35817861,-30140793,-62661641,-37684047,-10791435,-31361559,-28965957,-35074554,-18300410,5455270,23648211,32414689,50928057,84178047,64930378,93870236,79795842,86863035,105461553,79769102,80114784,54005743,33702322,65727435,62447610,52138169,43806272,31938677,37096050,70218042,77215870,106108777,139027677,114174251,126267131,140175411,160639557,193663077,206137637,220658257,202941018,-12251575,-23552773,-55866025,-23809513,-20926637,-31109913,-39762123,-46364008,-60594496,-42978446,-13334636,-30452598,-50434052,-61031253,-74842844,-93367283,-61532012,-84351158,-84841171,-104231070,-100891101,-126393754,-103372367,-130732559,-19187634,14573150,41644350,15935939,-17222201,13190162,18958067,-14125622,-24081209,3812159,26073207,1502885,27132466,50360103,32308017,43791273,28658841,-3014391,17498899,39691132,55285193,24930027,1313945,8269524,-3616873,-6270603,18469472,36099131,39395283,19467169,35946131,56127923,23068454,-3858447,127864,80862,7732537,-19112498,-51201127,-26195163,-56817262,-25264735,8237471,22946551,43448141,44527962,15371977,41182890,37330623,23803440,25133955,21428283,16975035,3669458,-3948266,-18836608,-46801069,-52964698,-22530552,-43387214,-61356367,-25196164,14528267,42710847,12057272,-28567150,-4999302,-9802327,-40044668,-50932747,-55517409,-42227774,-46720093,-55222219,-78741202,-85956859,-66535020,-46117937,-27770713,-58407711,-78187327,-69135214,1202125,-12657006,-36736334,-5285746,1284850,13974673,6428450,-2859916,11195300,21966510,41773652,75026766,86232546,65434150,56281777,31791084,-27496239,-11755947,-38243335,-15570305,-44944537,-56626147,-35689712,-29230541,-1790980,4913883,30309378,35999451,4247731,19877599,30464878,23724438,22283982,54499416,24386456,49397482,20056046,2245136,10370839,11303423,-17409033,-42771071,-74956837,-48166691,-43816115,-57542384,-70157229,-70862427,30408652,58898077,77293926,73729762,95277184,81563941,57283977,-771117,-456441,-29488849,22679627,5899338,-18076694,-37016795,-11679478,-41387957,-66065963,-88627508,-59231050,-72154351,-87239154,-98183118,-86163605,-100655815,-71105015,-71941883,-79022844,-95476326,-106781948,-122827571,-3991744,-12632889,-27237421,-19346941,-5049031,25932613,27025347,58034895,43432663,12227336,8100095,-24316081,-26074118,1861244,10308239,-14252133,-42882738,-11297680,-4134810,4642524,-2106749,4520659,4934233,-11147022,-19198158,-2631779,-7452327,10453095,2109765,-2103352,-13046685,5993258,-6044315,-8865526,-36469279,-34399945,-33492684,-66014105,-74152720,-100291068,-74237210,-51603820,-42707028,-25514375,-19566946,-28671426,-45101886,-57481104,-39262753,-53578037,-75105802,-8050453,-27079364,-31976388,-59853991,-76305099,-80118582,-75523310,-53358835,-33059777,23735157,-1173436,28637604,45579674,38153401,33484359,6520549,-19987615,-17046612,-49115976,-67297686,-76330959,-92100052,-78367933,-49573941,-47282497,-45204417,-26379619,-54724537,-31225313,-47054807,-31957234,-31249236,-45845237,-22124907,10320350,14739088,-4252207,-7762331,7155734,29164118,9070424,5290023,22450707,17614712,35173605,15421806,21377612,-11164562,-19598904,-6382529,-10075749,-31582043,-24288750,-17233764,-46634709,-51009691,-37586000,-22709095,-15330330,-41238844,-38766663,-55248088,-35014428,-8943742,5195603,18754494,8744144,17178020,48895778,81969511,58113659]
+
+test6 :: Acc (Vector Int64)
+test6 = A.scanl1Seg (+) xs seg
+  where
+    xs :: Acc (Vector Int64)
+    xs = use $ fromList (Z :. 748) [9125498,-25188533,16012055,-27188381,-1098285,-9371024,16587421,9904131,-2631554,-25486177,-7372642,-19824453,23520582,-9676480,-22827761,21856494,-4252137,811931,-14569802,32295175,-6771023,4950290,10722774,-6642889,-19841488,17490820,-2179605,-14086104,-27317700,17646422,15786966,28131812,-27600239,-2158886,1661370,-13322321,-25071977,-6024173,7979223,24604554,2795948,21021796,251585,7369081,10359873,20938516,-11754577,4154549,13858418,-16470594,-30623198,14368006,-20234551,-21782682,26398797,29468760,-6357516,-28827783,26613691,33184238,11901012,13008860,-31538717,-19848243,-33437553,-15016152,-28808214,-13454175,-3620504,-22813060,-32105619,26699703,30531184,-30639665,-7614257,12584983,12529381,-32974667,9227307,21313790,-15949871,17768624,20661075,21149801,9467092,20131268,-13238503,-7333992,11550847,-14444961,-1554452,-14551511,29776267,-16129436,1682633,404444,22617295,30453613,-7448527,-26556359,20227806,-17105891,8650300,-32089833,9323991,12716556,29904839,-29688622,-15919895,-22187055,29421292,1756578,-29257767,4599127,-26070729,-1671158,20652563,-23527198,2288900,11460180,-14885176,26406877,-10910169,26499206,11553105,722043,-17053384,9592179,13249704,-33183411,30403929,3093390,23502571,19192793,2362514,9775133,25937315,13936777,-11730015,-22764073,-15985739,-17273984,-33325576,-30914387,-8770808,31342042,-15747727,7932556,-4620155,-19279309,8776959,12610912,2754980,-3741772,-28100827,13605576,4019354,-25589491,-14641600,-15433270,32391571,-7596012,22317722,22704901,26506216,-26312309,-9162966,11604290,-8442151,-4092963,28768938,23927146,24875049,-16309257,9075873,-18692347,10011195,-21920300,26134427,32912593,-5551781,1882153,-27121444,16950372,-1126688,21119013,1695500,26547990,28957529,-15558430,-13972154,13409965,-26432497,-29889150,18070897,25688131,-27246718,-12397916,31336388,-17039661,11331144,-1995034,3636131,21890924,6108959,-7982438,12869656,-32185347,5204385,-8020711,-23164,-32414160,-707095,21354265,13932741,-15164925,19143311,-8293114,-31029958,-32739608,-7954781,13413352,-14822391,27937201,-12559440,2619156,-16811005,20329993,1247919,-9418943,605247,26091076,-12040244,28952393,-327612,15906335,-5559634,7578213,12199450,-8777520,25700504,-29481382,-21108742,-9296576,-12346996,-6897335,-29291467,10790824,-10235479,-32607689,-16386711,14089027,7472258,17067878,3035231,21981730,7925723,4975340,47183,21493034,4597970,24115430,30425668,-15899571,-28691157,-20252003,25254077,21582669,-701106,31032696,404098,-10641332,-20092885,-10083697,-22533029,28148874,31332821,-17780122,-29634677,2407026,4386849,26726474,-14784724,-23500235,24637825,1034025,-18400464,-15771498,-21415520,31153026,28106661,17196904,25356773,22224278,-2521944,-13991250,18261104,-7891840,32877134,25183256,-28548624,17238240,1948270,-5354424,13706292,24787710,-14069075,11547549,-29486368,-112352,30046527,28613302,-29290526,7396173,14467069,13831148,-15458379,-17484499,17386854,-4744100,-16215207,-3260126,-10188139,21180895,-18726333,-17426637,-20206540,29070717,-16892228,4706892,-17022445,-7143176,-1897403,32958033,12443825,7968818,-24903117,-8873737,-21955856,-19755335,14813217,-31795499,16874316,10625172,-10685501,24577556,-10042634,55143,13866579,-21878725,-21774936,-18509235,-26990002,-64595,26203376,-27185015,-30010945,-29887344,-8145803,25884919,-21237425,-19979324,4683804,-28147527,22930815,26875527,31504260,11713918,-13843679,-24948429,32341576,29343227,25017856,-1738009,26807259,-5320054,-16438208,16542303,-27263046,18056169,25938614,-8771470,17418126,1819043,1610498,8544533,-25578215,4239601,-22488515,33171299,-33469248,830686,-13510451,23698260,7137222,23511426,-31898610,6392606,11902380,-10458154,-27102202,5829980,5677068,-32520848,24977594,26892612,-20570124,2395602,-6108597,-18300410,23755680,18192941,8766478,18513368,33249990,-19247669,28939858,-14074394,7067193,18598518,-25692451,345682,-26109041,-20303421,32025113,-3279825,-10309441,-8331897,-11867595,5157373,33121992,6997828,28892907,32918900,-24853426,12092880,13908280,20464146,33023520,12474560,14520620,-17717239,-12251575,-11301198,-32313252,32056512,2882876,-10183276,-8652210,-6601885,-14230488,17616050,29643810,-17117962,-19981454,-10597201,-13811591,-18524439,31835271,-22819146,-490013,-19389899,3339969,-25502653,23021387,-27360192,-19187634,14573150,27071200,-25708411,-33158140,30412363,5767905,-14125622,-9955587,27893368,22261048,-24570322,25629581,23227637,-18052086,11483256,-15132432,-31673232,20513290,22192233,15594061,-30355166,-23616082,6955579,-11886397,-2653730,24740075,17629659,3296152,-19928114,16478962,20181792,-33059469,-26926901,3986311,-47002,7732537,-26845035,-32088629,25005964,-30622099,31552527,33502206,14709080,20501590,1079821,-29155985,25810913,-3852267,-13527183,1330515,-3705672,-4453248,-13305577,-7617724,-14888342,-27964461,-6163629,30434146,-20856662,-17969153,-25196164,14528267,28182580,-30653575,-28567150,23567848,-4803025,-30242341,-10888079,-4584662,13289635,-4492319,-8502126,-23518983,-7215657,19421839,20417083,18347224,-30636998,-19779616,9052113,1202125,-13859131,-24079328,31450588,6570596,12689823,-7546223,-9288366,14055216,10771210,19807142,33253114,11205780,-20798396,-9152373,-24490693,-27496239,15740292,-26487388,22673030,-29374232,-11681610,20936435,6459171,27439561,6704863,25395495,5690073,-31751720,15629868,10587279,-6740440,-1440456,32215434,-30112960,25011026,-29341436,-17810910,8125703,932584,-28712456,-25362038,-32185766,26790146,4350576,-13726269,-12614845,-705198,30408652,28489425,18395849,-3564164,21547422,-13713243,-24279964,-771117,314676,-29032408,22679627,-16780289,-23976032,-18940101,25337317,-29708479,-24678006,-22561545,29396458,-12923301,-15084803,-10943964,12019513,-14492210,29550800,-836868,-7080961,-16453482,-11305622,-16045623,-3991744,-8641145,-14604532,7890480,14297910,30981644,27025347,31009548,-14602232,-31205327,-4127241,-32416176,-26074118,27935362,8446995,-24560372,-28630605,31585058,7162870,8777334,-6749273,6627408,413574,-16081255,-8051136,16566379,-4820548,17905422,-8343330,-4213117,-10943333,19039943,-12037573,-8865526,-27603753,2069334,907261,-32521421,-8138615,-26138348,26053858,22633390,8896792,17192653,5947429,-9104480,-16430460,-12379218,18218351,-14315284,-21527765,-8050453,-19028911,-4897024,-27877603,-16451108,-3813483,4595272,22164475,20299058,23735157,-24908593,29811040,16942070,-7426273,-4669042,-26963810,-26508164,2941003,-32069364,-18181710,-9033273,-15769093,13732119,28793992,2291444,2078080,18824798,-28344918,23499224,-15829494,15097573,-31249236,-14596001,23720330,32445257,4418738,-18991295,-3510124,14918065,22008384,-20093694,-3780401,17160684,-4835995,17558893,-19751799,5955806,-32542174,-8434342,13216375,-3693220,-21506294,7293293,7054986,-29400945,-4374982,13423691,14876905,7378765,-25908514,2472181,-16481425,20233660,26070686,14139345,13558891,-10010350,8433876,31717758,33073733,-23855852]
+
+    seg :: Acc (Segments Int32)
+    seg = use $ fromList (Z :. 40) [14,31,30,35,37,14,15,14,23,12,35,28,25,14,2,4,39,11,26,33,24,1,6,29,25,1,3,17,16,32,7,3,20,6,6,21,18,9,22,40]
+
+
+ref7 :: Vector Int64
+ref7 = fromList (Z :. 738) [-48782707,-48069783,-76099136,-54652346,-25365627,-15287764,6356466,-12813466,-8407583,19978290,-9072659,-5915918,-36585578,-15711835,15422422,-9019547,-22292746,-32631763,-37371290,-15640610,71266024,76379806,62728369,44496969,47936553,67925416,42543207,28256825,46993513,68696441,62762548,88843983,77734052,65986283,34730508,52119715,67762330,58853279,38574549,13150417,14186593,36907720,65459740,40756535,72731638,74649918,46434954,15908233,-16539565,-31475560,-51915490,-26886587,-15628016,676507,80785577,97966741,122492495,96127350,125381692,121887919,114659417,115475678,82844858,67113463,85021319,117361113,94819908,69936468,84937047,90201353,56988036,23644741,45179661,23562116,38281224,66172480,73193812,82782863,65386382,50390098,43128359,36249064,14980469,108493316,92959780,62909215,43183526,43891523,28202405,38141961,38711587,22173107,33427444,5089227,-19895449,9446767,-9329550,15990062,27937078,10302744,-15427015,-24032122,220227,-244305648,-248544880,-216775110,-202718801,-203420228,-192771970,-167669427,-197813315,-199494672,-197082872,-207854928,-211196422,-193844772,-181103988,-181876034,-165735816,-133474822,-106956023,-82248081,-49842013,-69252000,-65369160,-46610625,-13293665,-86242428,-77700448,-54939430,-49026334,-81348375,-63863233,-81374276,-66370269,-64109103,-82546545,-101149747,-117134127,-97831968,-79075256,-93927664,-106999178,-116193016,-111355657,-142840401,-149392627,-128125153,-121344215,-116284247,-146348780,-122554770,-94499397,-65672590,-75420069,-49490678,-44521996,-49552615,-22516329,-31498419,-59429269,-30793092,-17012933,-19585098,-19894459,-11313269,17242975,26384275,20837140,-39580349,-32039154,-58779061,-31809529,-31860791,-62928294,-45073900,-71749150,-59563687,-46788878,-79384275,-68620575,-48661520,-21830363,-31430266,21524909,35884674,36972475,29674096,20377847,20983226,38258246,20827628,-14124025,-41503458,-57583707,-42613410,-71982937,-49774496,-41193192,-53347165,-62309796,-71478479,-45886895,-78704146,-59158164,-67547671,-44882655,-16244584,-38481867,-30340794,1470458,17149252,36086423,59062879,56262539,35254717,13744500,14429826,20662188,3507389,12225467,22022073,20840496,49430785,30701622,-176961463,-151524797,-172754811,-202787227,-209645388,-208244461,-196470369,-206049987,-190830353,-171109808,-139130211,-111671490,-132637043,-125735699,-106374742,-94463283,-74530374,-102363645,-88879041,-75249338,-86163630,-58293022,-71134360,-74292036,-41027036,-43611173,-45664281,-46838277,-14775189,-21989256,-215581,4895895,26505964,9881215,6006006,21791812,30399863,11059334,-15405962,-40457904,-51506444,-34718154,-12018577,6175960,31133560,-15381417,-24454448,-5290847,-23131138,-90166937,-94603634,-110598990,-102018157,-103077965,-101919562,-112451349,-79323195,-69828212,-41204487,-48476615,-16487710,-19288308,-19650316,-15196570,-14200432,14249659,26415718,-1787516,24530828,-3765711,22589689,20470588,11663379,13847971,-19004777,-8662105,-16191632,-16504147,-18339663,6010780,26824986,-263637509,-233180488,-217662025,-240293973,-229737496,-233942831,-266581338,-240283840,-221970049,-192160233,-186556300,-156510619,-157980671,-159298043,-191254443,-165340852,-181342218,-154490961,-142888991,-125613381,-105764731,-74423852,-43553208,-71733054,-38403655,-65769516,-41776811,-66580138,-58084207,-60606933,-31855509,-30976667,-60210984,-46087807,-45645362,-18703486,-11448733,-18539947,-44401293,-77378414,-104806024,-119161329,-145595331,-128577399,-102240384,-131731412,-153965054,-138203406,-136107911,-169236957,-171380864,-177805907,-154124779,-177987589,-154112100,-137736720,-122295605,-123319691,-152104867,-133462923,-163731604,-137346078,-141974369,-139229959,-115343677,-100246891,-101857581,-79635122,-58498597,-56956671,-27846111,2514723,14539638,-856211,6094147,-143939605,-114556906,-93259166,-62776322,-51886782,-49805668,-49431917,-74588752,-52582864,-69028392,-49573309,-53206133,-29967317,-15913522,-35424192,-42953149,-34525589,-22120615,-22458128,-37201856,-59870268,-63601712,-55156115,-39259547,-20561668,-13924991,-4343294,-3802313,122068251,133014364,106044038,103669137,134430169,148789334,141929442,110101523,78227591,63166498,42545018,37401662,43844352,61892182,38965269,61152447,43991599,42367631,56420014,48147227,16120995,13523168,-12973607,1166745,20340645,-8645743,69400609,62637313,33238840,5342820,17405647,4881263,10407925,-22227407,-9285528,-24279449,-31837105,-12669381,-34047179,-2711090,-26208960,2899657,-97174441,-112298451,-79439394,-84329209,-78384623,-105840777,-126752608,-110394917,-138128377,-134889126,-108654091,-114727725,-98923120,-66683703,-35041593,-51372583,-34976067,-61712406,-48730299,-26309307,-3152004,30193014,162071102,135062608,113614122,97742763,89441064,68362698,89887651,72658190,54790707,28888401,14596198,6934234,-51398793,-36048649,-64586259,-77001171,-108515514,-101660672,-120183736,-103974869,-107572971,-126104081,-97581382,-67174136,-69001306,-76561059,-48904254,-50376102,-47702115,-29837381,-44448701,-52078856,-20635428,-24924851,-35615675,-68278334,-96389847,-97000000,-80417765,-49553418,-27291772,-38508142,-30069928,-59576150,-51106683,-24593113,75962,138863600,158599246,130947464,109890205,82891951,55655298,43959461,18718460,27418095,1490441,-25173893,-41233589,-11411110,-4784998,21180595,-20092951,-19866345,-14625234,-1393509,-30003860,48038753,41278966,56150464,24427936,48510687,46956838,18206865,-14599729,-12438450,-12136742,-20552578,-34069029,-41733751,-22523991,-55669734,-46280266,-31205428,-27829333,-4518109,-37115511,-20546874,3069181,1104372,31215428,35398190,14119871,-8341624,-19741499,-6338114,7013637,-12550393,10571885,17180134,22004968,26290384,15424987,-12196414,-27805732,3893455,3705021,34303755,10858903,44234506,69653623,59799317,41855292,47636949,70210705,49577396,32263101,12862903,-3141227,8704244,-15735990,-42463538,-14281982,-34140899,-29944926,-48194015,-73380186,-53981004,-25683673,3436705,-347326,-13473324,-28337288,-6060609,-36670246,-40321076,-26406623,-25136754,-50993989,-19489063,11995210,-11523983,-31765052,-19746897,13123904,22054274,35973231,46315575,58458518,64785448,37087818,60336567,50407722,60213274,88311583,75588379,50392946,50310126,60156227,28023981,-4599077,-15670813,-480659,66326700,88952449,112560471,80424796,59167705,49073681,69439599,36559892,13608188,-10849505,-27511038,-18002566,-11679162,-14245301,-33196908,-59458637,-88762770,-76931280,-75985853,-73664670,-54646553,-73314781,-98519275,-131515581,-101578410,-70993721,-48717455,-34490455,-9721647,-33346014,-64431160,-74351523,-48527265,-47818443,-39778144,-27056813,3172756,16428504,32078563,27314822,-84911462,-70883891,-67734204,-58203952,-29560484,-7636085,-32316716,-33073244,-31465591,-19382415,-19463832,-51250364,-69332001,-43742902,-15587162,-18707052,-27391604,-8628411,-29019238,-14338164,-32687266,-34755132,-21912223,-40789415,-56697052,-30869305,8245928,22216157,-1300450,-8539733,15367658,-4898165,-23038236,-8233426,20237515,-1488029,-3344902,24899437,13240791,356287,30134185,24453047,-6857567,-11423381,8820097,40066727,55587484,72052998,100594380,76094952,61642627,29001112,9974448,42079530,9172704,-11553890,-34131793,-8675576,-36427927,-22535570,-42072165,-27144828]
+
+test7 :: Acc (Vector Int64)
+test7 = A.scanr1Seg (+) xs seg
+  where
+    xs :: Acc (Vector Int64)
+    xs = use $ fromList (Z :. 738) [-712924,28029353,-21446790,-29286719,-10077863,-21644230,19169932,-4405883,-28385873,29050949,-3156741,30669660,-20873743,-31134257,24441969,13273199,10339017,4739527,-21730680,-15640610,-5113782,13651437,18231400,-3439584,-19988863,25382209,14286382,-18736688,-21702928,5933893,-26081435,11109931,11747769,31255775,-17389207,-15642615,8909051,20278730,25424132,-1036176,-22721127,-28552020,24703205,-31975103,-1918280,28214964,30526721,32447798,14935995,20439930,-25028903,-11258571,-16304523,676507,-17181164,-24525754,26365145,-29254342,3493773,7228502,-816261,32630820,15731395,-17907856,-32339794,22541205,24883440,-15000579,-5264306,33213317,33343295,-21534920,21617545,-14719108,-27891256,-7021332,-9589051,17396481,14996284,7261739,6879295,21268595,14980469,15533536,30050565,19725689,-707997,15689118,-9939556,-569626,16538480,-11254337,28338217,24984676,-29342216,18776317,-25319612,-11947016,17634334,25729759,8605107,-24252349,220227,4239232,-31769770,-14056309,701427,-10648258,-25102543,30143888,1681357,-2411800,10772056,3341494,-17351650,-12740784,772046,-16140218,-32260994,-26518799,-24707942,-32406068,19409987,-3882840,-18758535,-33316960,-13293665,-8541980,-22761018,-5913096,32322041,-17485142,17511043,-15004007,-2261166,18437442,18603202,15984380,-19302159,-18756712,14852408,13071514,9193838,-4837359,31484744,6552226,-21267474,-6780938,-5059968,30064533,-23794010,-28055373,-28826807,9747479,-25929391,-4968682,5030619,-27036286,8982090,-31498419,-28636177,-13780159,2572165,309361,-8581190,-28556244,-9141300,5547135,20837140,-7541195,26739907,-26969532,51262,31067503,-17854394,26675250,-12185463,-12774809,32595397,-10763700,-19959055,-26831157,9599903,-31430266,-14359765,-1087801,7298379,9296249,-605379,-17275020,17430618,20827628,27379433,16080249,-14970297,29369527,-22208441,-8581304,12153973,8962631,9168683,-25591584,32817251,-19545982,8389507,-22665016,-28638071,22237283,-8141073,-31811252,-15678794,-18937171,-22976456,2800340,21007822,21510217,-685326,-6232362,17154799,-8718078,-9796606,1181577,-28590289,18729163,30701622,-25436666,21230014,30032416,6858161,-1400927,-11774092,9579618,-15219634,-19720545,-31979597,-27458721,20965553,-6901344,-19360957,-11911459,-19932909,27833271,-13484604,-13629703,10914292,-27870608,12841338,3157676,-33265000,2584137,2053108,1173996,-32063088,7214067,-21773675,-5111476,-21610069,16624749,3875209,-15785806,21791812,19340529,26465296,25051942,11048540,-16788290,-22699577,-18194537,-24957600,31133560,9073031,-19163601,17840291,-23131138,4436697,15995356,-8580833,1059808,-1158403,10531787,-33128154,-9494983,-28623725,7272128,-31988905,2800598,362008,-4453746,-996138,-28450091,-12166059,28203234,-1787516,28296539,-26355400,2119101,8807209,-2184592,32852748,-10342672,7529527,312515,1835516,-24350443,-20814206,26824986,-30457021,-15518463,22631948,-10556477,4205335,32638507,-26297498,-18313791,-29809816,-5603933,-30045681,1470052,1317372,31956400,-25913591,16001366,-26851257,-11601970,-17275610,-19848650,-31340879,-30870644,28179846,-33329399,27365861,-23992705,24803327,-8495931,2522726,-28751424,-878842,29234317,-14123177,-442445,-26941876,-7254753,-11448733,25861346,32977121,27427610,14355305,26434002,-17017932,-26337015,29491028,22233642,-15761648,-2095495,33129046,2143907,6425043,-23681128,23862810,-23875489,-16375380,-15441115,1024086,28785176,-18641944,30268681,-26385526,4628291,-2744410,-23886282,-15096786,1610690,-22222459,-21136525,-1541926,-29110560,-30360834,-12024915,15395849,-6950358,6094147,-29382699,-21297740,-30482844,-10889540,-2081114,-373751,25156835,-22005888,16445528,-19455083,3632824,-23238816,-14053795,19510670,7528957,-8427560,-12404974,337513,14743728,22668412,3731444,-8445597,-15896568,-18697879,-20561668,-9581697,-540981,-3802313,-10946113,26970326,2374901,-30761032,-14359165,6859892,31827919,31873932,15061093,20621480,5143356,-6442690,-18047830,22926913,-22187178,17160848,1623968,-14052383,8272787,32026232,2597827,26496775,-14140352,-19173900,28986388,-8645743,6763296,29398473,27896020,-12062827,12524384,-5526662,32635332,-12941879,14993921,7557656,-19167724,21377798,-31336089,23497870,-29108617,2899657,15124010,-32859057,4889815,-5944586,27456154,20911831,-16357691,27733460,-3239251,-26235035,6073634,-15804605,-32239417,-31642110,16330990,-16396516,26736339,-12982107,-22420992,-23157303,-33345018,30193014,27008494,21448486,15871359,8301699,21078366,-21524953,17229461,17867483,25902306,14292203,7661964,6934234,-15350144,28537610,12414912,31514343,-6854842,18523064,-16208867,3598102,18531110,-28522699,-30407246,1827170,7559753,-27656805,1471848,-2673987,-17864734,14611320,7630155,-31443428,4289423,10690824,32662659,28111513,610153,-16582235,-30864347,-22261646,11216370,-8438214,29506222,-8469467,-26513570,-24669075,75962,-19735646,27651782,21057259,26998254,27236653,11695837,25241001,-8699635,25927654,26664334,16059696,-29822479,-6626112,-25965593,21180595,-226606,-5241111,-13231725,28610351,-30003860,6759787,-14871498,31722528,-24082751,1553849,28749973,32806594,-2161279,-301708,8415836,13516451,7664722,-19209760,33145743,-9389468,-15074838,-3376095,-23311224,32597402,-16568637,-23616055,1964809,-30111056,-4182762,21278319,22461495,11399875,-13403385,-13351751,19564030,-23122278,-6608249,-4824834,22004968,10865397,27621401,15609318,-31699187,188434,-30598734,23444852,-33375603,-25419117,9854306,17944025,-5781657,-22573756,20633309,17314295,19400198,16004130,-11845471,24440234,26727548,-28181556,19858917,-4195973,18249089,25186171,-19399182,-28297331,-29120378,3436705,13125998,14863964,-22276679,30609637,3650830,-13914453,-1269869,25857235,-31504926,-31484273,23519193,20241069,-12018155,-32870801,-8930370,-13918957,-10342344,-12142943,-6326930,27697630,-23248749,9928845,-9805552,-28098309,12723204,25195433,82820,-9846101,32132246,32623058,11071736,-15190154,-480659,-22625749,-23608022,32135675,21257091,10094024,-20365918,32879707,22951704,24457693,16661533,-9508472,-6323404,2566139,18951607,26261729,29304133,-11831490,-945427,-2321183,-19018117,18668228,25204494,32996306,-29937171,-30584689,-22276266,-14227000,-24768808,23624367,31085146,9920363,-25824258,-708822,-8040299,-12721331,-30229569,-13255748,-15650059,4763741,27314822,-14027571,-3149687,-9530252,-28643468,-21924399,24680631,756528,-1607653,-12083176,81417,31786532,18081637,-25589099,-28155740,3119890,8684552,-18763193,20390827,-14681074,18349102,2067866,-12842909,18877192,15907637,-25827747,-30869305,-13970229,23516607,7239283,-23907391,20265823,18140071,-23038236,-28470941,21725544,1856873,-28244339,11658646,12884504,-29777898,5681138,31310614,4565814,-20243478,-31246630,-15520757,-16465514,-28541382,24499428,14452325,32641515,19026664,-32105082,32906826,20726594,22577903,-25456217,27752351,-13892357,19536595,-14927337,-27144828]
+
+    seg :: Acc (Segments Int32)
+    seg = use $ fromList (Z :. 33) [20,34,29,20,24,33,9,15,8,33,36,9,4,19,13,37,38,25,3,26,16,22,12,35,15,5,34,29,33,40,26,7,29]
+
+
+ref8 :: Vector Int64
+ref8 = fromList (Z :. 645) [0,-3770243,-5579205,-7046208,-10121610,-11747201,-13282326,-17283687,-18231759,-20046491,-21926492,-22713980,-26318076,-28006910,-31889802,-34194230,-38096679,-39693040,-35966076,-38959249,-41938765,-41994560,-41013600,-41922485,-39410829,-38960516,-35942875,-33376608,-29844503,-29318389,-28736296,-25580458,-29739876,-32401640,-36553276,-40171099,0,345952,-2993267,-5717922,-9907694,-10027890,-13870687,-11867126,-9328942,-6192885,-8184575,-11674536,-10400036,-11388719,-10353407,-8145138,-6678399,-2486811,-6487953,-8733058,-10561951,-6480166,-7972853,0,1139992,-104326,1079373,3348511,0,3395695,6337287,4100926,1022638,1452658,0,3593867,3814687,6806052,3747065,2713485,3570566,5270237,6848581,6155011,1966243,5365176,3983882,286985,2324988,721490,466546,-700995,-338083,2411347,3365002,3154319,3507792,4576100,0,-2285386,-4288389,-7082102,-4660000,-857446,721455,660475,273568,-2789646,-6674913,-9130960,-11826040,-9536699,-6104295,-9673441,-11613956,-10411885,-12286738,-8645110,-8436095,-7590486,-4452638,-1581976,0,-934927,1608397,304641,-2958108,-942792,-1396361,-3542834,0,2350876,227658,-3779069,-1035644,-972794,-3797476,-4505766,-4865910,-7425388,-7182479,-9067132,-10043764,-8627455,-4953615,-3166350,0,1298211,4883021,8143644,9991079,13383006,11704147,11985221,8647018,8086113,7664604,8718062,11039021,7936960,4598083,5635829,1450422,159881,3657858,4103183,3527017,883273,-1321504,-2478748,-1006972,455760,4266983,7194819,11232555,9833490,12524076,16207697,20249758,19286134,17160940,18352071,0,-1562519,-3710355,-2848884,0,741078,2195352,1715399,4902918,2472295,-1673954,951060,-205765,-410930,2925408,0,2661266,6376248,6698089,7240432,9214046,10362817,13102857,16942419,20040610,19554929,18142416,20333122,24002080,25936153,26861250,28286514,25107483,27772679,25952139,0,124429,3721751,0,4171155,4260049,3631576,713779,-1444554,1964929,2806146,4319313,995223,3554404,-282429,96550,1888015,3379400,3874424,5448190,8604326,7429367,4814852,0,-3835274,170581,-3872285,-4136902,-6586985,-8127633,-9740679,-10940596,-11302147,-14863360,-16636561,-15426039,-18342257,-16067741,-12830665,-14394729,-17308091,-13537763,-10075189,-6255542,-4427649,-8416077,-10456703,-8195749,-5827305,-4993142,-3673480,0,869492,1594197,4025097,2848783,0,2126507,3949710,4447981,1253204,3235070,7367011,5351006,6654097,2818742,5393616,4706372,3331207,1161359,0,1885699,1289175,-763581,2481999,2068732,6240239,9030236,6369832,3409522,1150603,-1677392,-773316,-3184156,404696,-683547,910053,-2491074,-94029,-2827691,-5512379,-7783991,-8736510,-6524861,-2725098,-5093277,-6514413,0,742604,-606571,-725780,1744947,3431452,-405237,-457263,709944,4319401,624627,-2608016,0,3642681,2908707,5512358,5530669,0,-3215609,-7345078,-8196654,-11105059,-12591552,-15198735,-11340348,-10281817,-12147811,-10530601,-11500997,-7477780,-10439606,-9986548,0,3533811,4486946,5531887,1511249,-557775,435067,1631130,1815263,-1867113,2273415,1514738,-1206877,555832,741913,-3166709,-287429,-4411008,-4700935,-3946601,-4617892,-7550664,-6112017,0,-667061,-1239970,1156892,-722075,-4186731,-7404810,-11407733,-13636105,-12949852,-11213787,-11386775,-15541235,-18076969,-21589829,-19336525,-21546880,-20418698,-24006743,-23003415,-19580602,-16414098,-17729103,-17560035,-21218247,0,-781526,1156089,-2142153,-419575,-3055657,-716334,-2312034,118635,711944,4112840,7878285,7762706,8255775,8380414,11299416,12714032,15289946,14300365,15027849,19200256,22844171,0,-1224713,1837521,62083,-2435081,-280845,3789736,4259660,7108468,3611361,1501427,4453169,6217988,9274431,13178646,16388059,15410829,13060952,14279789,17319316,14533179,13976967,9836157,7001049,5716786,5459256,5101104,7249617,8962409,9911065,7505371,7218925,8578944,5307366,0,859492,-3077001,-4576770,-8344542,-8263692,-9244057,-8761336,-10520101,-11364186,-10078629,-11263983,-11008053,-14512411,-14775947,-16672625,-14513613,0,694423,-1173637,-2704935,1260688,4786656,1709582,-249261,-2458089,-4733195,-3473620,-3843053,-150511,-4048267,-6698308,-2513431,-6005597,-4249435,-4821144,-8932215,-8692409,-4892474,-3015738,-914415,773709,4562402,8689641,8298796,12102005,13700416,12590982,9153649,7960537,6137906,4292150,2600272,-1457822,0,-1806374,1041907,-2078323,-842307,-3701664,0,-2626906,-2068475,1803835,-316068,-1526877,-3914878,-1840677,-2474665,-4520977,-6059889,0,-161266,2625449,4235821,4877373,1374740,118771,2880196,4463038,3245456,6984711,3642280,2229177,3494184,3387547,5293512,1401776,4539065,6886384,11057250,14889641,15259441,13231998,10138107,7266168,8228888,5129351,1841256,1082772,724230,-2146010,-859151,1049573,2686216,-1006176,1740846,0,-2567334,487038,-3421145,-4411824,-6418173,-4404660,0,2828945,6815455,7060886,6549094,9292080,13211354,12694643,14924363,12485234,14542169,14311383,16026086,17059251,18866314,15263353,18915246,20747408,20628390,21408706,20042728,24104321,21412324,24779975,23077325,20881558,22407427,20391992,21407566,19978783,0,1589469,-794608,-1541980,-1274750,-1931789,-3719881,-175562,1353495,3729793,4102597,330109,-90750,2740945,4316009,2734066,4093765,656207,-844822,-3930596,-1093202,-2998732,564186,3880070,5179086,6959784,10449214,14577355,13359512,0,1964984,3384303,1505373,3694802,6588743,0,1412262,5040779,5239461,9430965,6115620,10111491,10560650,8218897,4044049,4210501,1038630,1711549,0,-3317531,-4953062,-1809142,-1092410,-3951290,-7965161]
+
+test8 :: Acc (Vector Int64)
+test8 = A.scanlSeg (+) 0 xs seg
+  where
+    xs :: Acc (Vector Int64)
+    xs = use $ fromList (Z :. 609) [-3770243,-1808962,-1467003,-3075402,-1625591,-1535125,-4001361,-948072,-1814732,-1880001,-787488,-3604096,-1688834,-3882892,-2304428,-3902449,-1596361,3726964,-2993173,-2979516,-55795,980960,-908885,2511656,450313,3017641,2566267,3532105,526114,582093,3155838,-4159418,-2661764,-4151636,-3617823,345952,-3339219,-2724655,-4189772,-120196,-3842797,2003561,2538184,3136057,-1991690,-3489961,1274500,-988683,1035312,2208269,1466739,4191588,-4001142,-2245105,-1828893,4081785,-1492687,1139992,-1244318,1183699,2269138,3395695,2941592,-2236361,-3078288,430020,3593867,220820,2991365,-3058987,-1033580,857081,1699671,1578344,-693570,-4188768,3398933,-1381294,-3696897,2038003,-1603498,-254944,-1167541,362912,2749430,953655,-210683,353473,1068308,-2285386,-2003003,-2793713,2422102,3802554,1578901,-60980,-386907,-3063214,-3885267,-2456047,-2695080,2289341,3432404,-3569146,-1940515,1202071,-1874853,3641628,209015,845609,3137848,2870662,-934927,2543324,-1303756,-3262749,2015316,-453569,-2146473,2350876,-2123218,-4006727,2743425,62850,-2824682,-708290,-360144,-2559478,242909,-1884653,-976632,1416309,3673840,1787265,1298211,3584810,3260623,1847435,3391927,-1678859,281074,-3338203,-560905,-421509,1053458,2320959,-3102061,-3338877,1037746,-4185407,-1290541,3497977,445325,-576166,-2643744,-2204777,-1157244,1471776,1462732,3811223,2927836,4037736,-1399065,2690586,3683621,4042061,-963624,-2125194,1191131,-1562519,-2147836,861471,741078,1454274,-479953,3187519,-2430623,-4146249,2625014,-1156825,-205165,3336338,2661266,3714982,321841,542343,1973614,1148771,2740040,3839562,3098191,-485681,-1412513,2190706,3668958,1934073,925097,1425264,-3179031,2665196,-1820540,124429,3597322,4171155,88894,-628473,-2917797,-2158333,3409483,841217,1513167,-3324090,2559181,-3836833,378979,1791465,1491385,495024,1573766,3156136,-1174959,-2614515,-3835274,4005855,-4042866,-264617,-2450083,-1540648,-1613046,-1199917,-361551,-3561213,-1773201,1210522,-2916218,2274516,3237076,-1564064,-2913362,3770328,3462574,3819647,1827893,-3988428,-2040626,2260954,2368444,834163,1319662,869492,724705,2430900,-1176314,2126507,1823203,498271,-3194777,1981866,4131941,-2016005,1303091,-3835355,2574874,-687244,-1375165,-2169848,1885699,-596524,-2052756,3245580,-413267,4171507,2789997,-2660404,-2960310,-2258919,-2827995,904076,-2410840,3588852,-1088243,1593600,-3401127,2397045,-2733662,-2684688,-2271612,-952519,2211649,3799763,-2368179,-1421136,742604,-1349175,-119209,2470727,1686505,-3836689,-52026,1167207,3609457,-3694774,-3232643,3642681,-733974,2603651,18311,-3215609,-4129469,-851576,-2908405,-1486493,-2607183,3858387,1058531,-1865994,1617210,-970396,4023217,-2961826,453058,3533811,953135,1044941,-4020638,-2069024,992842,1196063,184133,-3682376,4140528,-758677,-2721615,1762709,186081,-3908622,2879280,-4123579,-289927,754334,-671291,-2932772,1438647,-667061,-572909,2396862,-1878967,-3464656,-3218079,-4002923,-2228372,686253,1736065,-172988,-4154460,-2535734,-3512860,2253304,-2210355,1128182,-3588045,1003328,3422813,3166504,-1315005,169068,-3658212,-781526,1937615,-3298242,1722578,-2636082,2339323,-1595700,2430669,593309,3400896,3765445,-115579,493069,124639,2919002,1414616,2575914,-989581,727484,4172407,3643915,-1224713,3062234,-1775438,-2497164,2154236,4070581,469924,2848808,-3497107,-2109934,2951742,1764819,3056443,3904215,3209413,-977230,-2349877,1218837,3039527,-2786137,-556212,-4140810,-2835108,-1284263,-257530,-358152,2148513,1712792,948656,-2405694,-286446,1360019,-3271578,859492,-3936493,-1499769,-3767772,80850,-980365,482721,-1758765,-844085,1285557,-1185354,255930,-3504358,-263536,-1896678,2159012,694423,-1868060,-1531298,3965623,3525968,-3077074,-1958843,-2208828,-2275106,1259575,-369433,3692542,-3897756,-2650041,4184877,-3492166,1756162,-571709,-4111071,239806,3799935,1876736,2101323,1688124,3788693,4127239,-390845,3803209,1598411,-1109434,-3437333,-1193112,-1822631,-1845756,-1691878,-4058094,-1806374,2848281,-3120230,1236016,-2859357,-2626906,558431,3872310,-2119903,-1210809,-2388001,2074201,-633988,-2046312,-1538912,-161266,2786715,1610372,641552,-3502633,-1255969,2761425,1582842,-1217582,3739255,-3342431,-1413103,1265007,-106637,1905965,-3891736,3137289,2347319,4170866,3832391,369800,-2027443,-3093891,-2871939,962720,-3099537,-3288095,-758484,-358542,-2870240,1286859,1908724,1636643,-3692392,2747022,-2567334,3054372,-3908183,-990679,-2006349,2013513,2828945,3986510,245431,-511792,2742986,3919274,-516711,2229720,-2439129,2056935,-230786,1714703,1033165,1807063,-3602961,3651893,1832162,-119018,780316,-1365978,4061593,-2691997,3367651,-1702650,-2195767,1525869,-2015435,1015574,-1428783,1589469,-2384077,-747372,267230,-657039,-1788092,3544319,1529057,2376298,372804,-3772488,-420859,2831695,1575064,-1581943,1359699,-3437558,-1501029,-3085774,2837394,-1905530,3562918,3315884,1299016,1780698,3489430,4128141,-1217843,1964984,1419319,-1878930,2189429,2893941,1412262,3628517,198682,4191504,-3315345,3995871,449159,-2341753,-4174848,166452,-3171871,672919,-3317531,-1635531,3143920,716732,-2858880,-4013871]
+
+    seg :: Acc (Segments Int32)
+    seg = use $ fromList (Z :. 36) [35,22,4,5,23,23,7,15,35,3,10,19,2,19,27,4,13,26,11,4,14,22,24,21,33,16,36,5,10,35,6,29,28,5,12,6]
+
+
+ref9 :: Vector Int64
+ref9 = fromList (Z :. 661) [-23545410,-19092190,-15199726,-12351144,-19787110,-24907783,-28924702,-22582323,-15004292,-7986712,-15814964,-12796809,-20874665,-23199295,-21814743,-14474247,-11428070,-11326540,-11987400,-14049880,-15904429,-16813716,-20127269,-27880670,-27115572,-22970078,-19161294,-20116738,-25696300,-20399870,-12598014,-4441841,-5339204,0,5258152,-3047807,-4983198,-152087,-6694074,-2774154,3094062,8979166,16074241,10127078,17254868,10052255,14618407,7297758,13556880,7757925,4862968,0,7035358,13265906,15886283,9773585,17111824,11482952,10360509,16178260,11573685,8057435,8957179,1861100,-4510903,2522742,-1952534,343602,-931257,1182026,8572670,9866510,5314905,0,9915533,6504277,14881592,17126294,9902843,9461226,11857883,12119033,7534110,13764697,17029680,12738298,10093900,9378149,1497597,4121921,6980765,5509560,13297927,19208174,13439826,9261637,3697126,1029090,5742435,7165092,9870407,4667463,9603255,3143595,0,19520337,24293005,18170289,16949209,24484583,25098797,16940571,17168669,20017902,18512677,17276624,20668621,23764749,18559293,19179431,13603545,6821021,4128258,5178140,1807923,625766,-5793038,557951,8468013,16821699,9014973,10154282,13712629,15418321,17772979,13187310,9341891,9346469,3562777,-4236026,3943064,1821268,0,-17597987,-14338111,-13160839,-21095607,-13659930,-5524189,-447843,3198401,-3906944,2444625,4930508,0,-1780995,4941517,3428221,6945832,5471438,-2089694,-1840520,-748417,-622281,-4266815,-3578951,4175923,1214444,-6157294,-11771424,-4253316,122413,-5115729,-2403737,-2280632,-7692875,-7176319,165603,-4608911,2275343,4121415,3691356,8960495,8220951,6560764,3361772,122451,2068485,2266879,0,-23261891,-21773982,-18640394,-16250482,-8288981,-14366391,-12019056,-4951591,0,10327511,16096523,11513457,3775062,1456323,950660,0,39500473,42134191,49326132,44908043,44189915,40545597,42583889,36771665,37976838,42637161,43042497,41877155,36320177,36033649,30456233,23955666,24578825,25647024,25212428,22072107,15320240,7407492,5131363,10409387,17711966,18345108,25613171,20134088,18672784,20466069,19103089,11665491,5005634,2753606,2758578,0,-23237696,-29354162,-28222112,-22820572,-18856465,-11451199,-6544145,-13678867,-15169991,-16665935,-8801766,-16956831,-22118443,-14855674,-19710134,-18333052,-12310671,-12903337,-8724596,-6190610,-12330615,-6733634,-2371106,277264,-6820245,0,9171599,16241475,9734750,11053683,4530017,-3696390,3735716,11641789,12422324,8541343,10317301,6602275,6515789,1853520,2351453,6520804,8199852,16513029,15956233,17535751,12479352,11996485,11488976,15956849,19335984,20273115,14309339,8502747,5054202,4792421,-1998961,6344690,0,8641635,14614220,22621519,24778420,22934500,30033834,31388539,31358268,35741081,35363404,28488749,35704092,39869443,33641031,41683686,43114143,37049122,42162389,38581957,30630741,33093671,29883603,26722722,28918564,23162080,17010863,15643511,8259148,0,67812641,73385203,68588801,71302771,70440392,68339659,72121169,71757257,71620440,66640453,59362044,56439252,50169030,50545377,46897589,42431129,34191912,25809204,22184527,16142939,18006336,15320689,8056937,4727494,4455178,4714354,-2929312,3315582,-712782,0,-10533559,-7453596,-7355822,-11184899,-5346034,-5517666,-5655507,-13233681,-11036355,-15169542,-11673998,-13330134,-12975730,-15731486,-23927365,-15672527,-7651033,-41473,5213372,8569093,5202320,-1932697,4629347,7838047,-310810,-1472760,-1483648,-7832330,-10302351,-7461765,0,56489872,57285707,49989598,56584906,62675766,58030500,53272676,57170277,51364588,45405741,41313157,33038217,27969264,30537052,29338965,24226308,21920794,18781965,16276111,17831599,19945279,12010786,11775519,15528815,8084160,6735740,1256501,0,-4316639,-649184,-2875249,-1265836,-8062475,-1039628,-4165745,2818361,3338123,3984362,-2416008,1539566,1949311,7282131,1416000,2812559,4846439,-1681841,0,17517431,20918622,15129697,12644787,9788494,4980177,4751268,5168036,12807316,6885561,0,-12911606,-7044558,-4259336,-1778572,3942903,-99590,-1755397,1187146,-5227554,-2697658,-5743694,-9164574,-17324325,-9573146,-9518972,-7544657,-3459738,4724166,-2766402,0,-28888665,-23766795,-17908909,-23193011,-18768818,-18321941,-12120774,-4097683,3882582,11680259,16891026,8958627,9777882,4023025,0,-28142843,-31706317,-23725731,-17057441,-23215793,-22411703,-21651678,-16896450,-9881916,-14102625,-16892825,-11726368,-6761066,-8913778,-8706274,-16789108,-15505593,-17559207,-10278334,-2276389,2567755,8618151,12914239,11325856,6127225,622598,8390786,12165621,9912453,4123344,214225,-3540061,-3451397,0,22049876,24841111,19336800,18657023,17237080,16187600,12259897,11391983,6247808,12737198,14285951,16115720,7891953,5229659,12852009,14056688,10927973,15415445,15884318,9189272,15118784,14926893,16328727,24176496,21498476,13130655,9949458,7428893,4075586,2266204,2732845,0,-5712816,-5352191,521344,-2229408,265697,7718151,0,10535066,8408094,12259060,5061913,7346875,12522051,9215406,7737787,3313157,9824900,8315680,14840204,13742226,6034361,12850753,5702446,-584149,-132181,5582800,12810567,7762879,5801224,3571657,2874166,0,-24212535,-26325437,-21693913,-14975748,-19464741,-17568114,-22144287,-26451701,-24659593,-27491447,-34368798,-33273519,-31645836,-27659172,-19824103,-17292768,-17232842,-21445918,-17409995,-11585791,-18676054,-13722054,-6234778,0,-26835027,-26837945,-31679362,-27828204,-24983789,-27977465,-22748208,-18058978,-9787299,-2368565,4785532,-149793,-1166138,-1765051,6274501,-215131,2298449,-4372183,-5668260,-4416255,570850,-3446772,2138867,-3249857,3212736,5020102,6795919,0,-22301653,-17085039,-17386088,-12674648,-7197062,-4438712,2099952,6419507,10331533,18614405,16136985,16786718,17272339,12394596,15925356,21566888,14364344,8727743,12639637,16706011,14337230,9800607,6454097,8805762,2901622,2003370,0]
+
+test9 :: Acc (Vector Int64)
+test9 = A.scanrSeg (+) 0 xs seg
+  where
+    xs :: Acc (Vector Int64)
+    xs = use $ fromList (Z :. 634) [-4453220,-3892464,-2848582,7435966,5120673,4016919,-6342379,-7578031,-7017580,7828252,-3018155,8077856,2324630,-1384552,-7340496,-3046177,-101530,660860,2062480,1854549,909287,3313553,7753401,-765098,-4145494,-3808784,955444,5579562,-5296430,-7801856,-8156173,897363,-5339204,8305959,1935391,-4831111,6541987,-3919920,-5868216,-5885104,-7095075,5947163,-7127790,7202613,-4566152,7320649,-6259122,5798955,2894957,4862968,-6230548,-2620377,6112698,-7338239,5628872,1122443,-5817751,4604575,3516250,-899744,7096079,6372003,-7033645,4475276,-2296136,1274859,-2113283,-7390644,-1293840,4551605,5314905,3411256,-8377315,-2244702,7223451,441617,-2396657,-261150,4584923,-6230587,-3264983,4291382,2644398,715751,7880552,-2624324,-2858844,1471205,-7788367,-5910247,5768348,4178189,5564511,2668036,-4713345,-1422657,-2705315,5202944,-4935792,6459660,3143595,-4772668,6122716,1221080,-7535374,-614214,8158226,-228098,-2849233,1505225,1236053,-3391997,-3096128,5205456,-620138,5575886,6782524,2692763,-1049882,3370217,1182157,6418804,-6350989,-7910062,-8353686,7806726,-1139309,-3558347,-1705692,-2354658,4585669,3845419,-4578,5783692,7798803,-8179090,2121796,1821268,-3259876,-1177272,7934768,-7435677,-8135741,-5076346,-3646244,7105345,-6351569,-2485883,4930508,-6722512,1513296,-3517611,1474394,7561132,-249174,-1092103,-126136,3644534,-687864,-7754874,2961479,7371738,5614130,-7518108,-4375729,5238142,-2711992,-123105,5412243,-516556,-7341922,4774514,-6884254,-1846072,430059,-5269139,739544,1660187,3198992,3239321,-1946034,-198394,2266879,-1487909,-3133588,-2389912,-7961501,6077410,-2347335,-7067465,-4951591,-5769012,4583066,7738395,2318739,505663,950660,-2633718,-7191941,4418089,718128,3644318,-2038292,5812224,-1205173,-4660323,-405336,1165342,5556978,286528,5577416,6500567,-623159,-1068199,434596,3140321,6751867,7912748,2276129,-5278024,-7302579,-633142,-7268063,5479083,1461304,-1793285,1362980,7437598,6659857,2252028,-4972,2758578,6116466,-1132050,-5401540,-3964107,-7405266,-4907054,7134722,1491124,1495944,-7864169,8155065,5161612,-7262769,4854460,-1377082,-6022381,592666,-4178741,-2533986,6140005,-5596981,-4362528,-2648370,7097509,-6820245,-7069876,6506725,-1318933,6523666,8226407,-7432106,-7906073,-780535,3880981,-1775958,3715026,86486,4662269,-497933,-4169351,-1679048,-8313177,556796,-1579518,5056399,482867,507509,-4467873,-3379135,-937131,5963776,5806592,3448545,261781,6791382,-8343651,6344690,-5972585,-8007299,-2156901,1843920,-7099334,-1354705,30271,-4382813,377677,6874655,-7215343,-4165351,6228412,-8042655,-1430457,6065021,-5113267,3580432,7951216,-2462930,3210068,3160881,-2195842,5756484,6151217,1367352,7384363,8259148,-5572562,4796402,-2713970,862379,2100733,-3781510,363912,136817,4979987,7278409,2922792,6270222,-376347,3647788,4466460,8239217,8382708,3624677,6041588,-1863397,2685647,7263752,3329443,272316,-259176,7643666,-6244894,4028364,-712782,-3079963,-97774,3829077,-5838865,171632,137841,7578174,-2197326,4133187,-3495544,1656136,-354404,2755756,8195879,-8254838,-8021494,-7609560,-5254845,-3355721,3366773,7135017,-6562044,-3208700,8148857,1161950,10888,6348682,2470021,-2840586,-7461765,-795835,7296109,-6595308,-6090860,4645266,4757824,-3897601,5805689,5958847,4092584,8274940,5068953,-2567788,1198087,5112657,2305514,3138829,2505854,-1555488,-2113680,7934493,235267,-3753296,7444655,1348420,5479239,1256501,-3667455,2226065,-1609413,6796639,-7022847,3126117,-6984106,-519762,-646239,6400370,-3955574,-409745,-5332820,5866131,-1396559,-2033880,6528280,-1681841,-3401191,5788925,2484910,2856293,4808317,228909,-416768,-7639280,5921755,6885561,-5867048,-2785222,-2480764,-5721475,4042493,1655807,-2942543,6414700,-2529896,3046036,3420880,8159751,-7751179,-54174,-1974315,-4084919,-8183904,7490568,-2766402,-5121870,-5857886,5284102,-4424193,-446877,-6201167,-8023091,-7980265,-7797677,-5210767,7932399,-819255,5754857,4023025,3563474,-7980586,-6668290,6158352,-804090,-760025,-4755228,-7014534,4220709,2790200,-5166457,-4965302,2152712,-207504,8082834,-1283515,2053614,-7280873,-8001945,-4844144,-6050396,-4296088,1588383,5198631,5504627,-7768188,-3774835,2253168,5789109,3909119,3754286,-88664,-3451397,-2791235,5504311,679777,1419943,1049480,3927703,867914,5144175,-6489390,-1548753,-1829769,8223767,2662294,-7622350,-1204679,3128715,-4487472,-468873,6695046,-5929512,191891,-1401834,-7847769,2678020,8367821,3181197,2520565,3353307,1809382,-466641,2732845,-360625,-5873535,2750752,-2495105,-7452454,7718151,2126972,-3850966,7197147,-2284962,-5175176,3306645,1477619,4424630,-6511743,1509220,-6524524,1097978,7707865,-6816392,7148307,6286595,-451968,-5714981,-7227767,5047688,1961655,2229567,697491,2874166,2112902,-4631524,-6718165,4488993,-1896627,4576173,4307414,-1792108,2831854,6877351,-1095279,-1627683,-3986664,-7835069,-2531335,-59926,4213076,-4035923,-5824204,7090263,-4954000,-7487276,-6234778,2918,4841417,-3851158,-2844415,2993676,-5229257,-4689230,-8271679,-7418734,-7154097,4935325,1016345,598913,-8039552,6489632,-2513580,6670632,1296077,-1252005,-4987105,4017622,-5585639,5388724,-6462593,-1807366,-1775817,6795919,-5216614,301049,-4711440,-5477586,-2758350,-6538664,-4319555,-3912026,-8282872,2477420,-649733,-485621,4877743,-3530760,-5641532,7202544,5636601,-3911894,-4066374,2368781,4536623,3346510,-2351665,5904140,898252,2003370]
+
+    seg :: Acc (Segments Int32)
+    seg = use $ fromList (Z :. 27) [33,17,21,30,37,11,34,8,6,35,25,32,28,29,30,27,18,10,19,14,33,31,6,24,23,27,26]
+
+
+ref10 :: (Vector Int64, Vector Int64)
+ref10 = (ps, rs)
+  where
+    ps = fromList (Z :. 569) [0,-66818,0,251795,699710,802697,480274,853290,752860,1138919,862260,939763,894697,1099711,1557688,1971825,2058686,2243003,2277978,1888289,1704690,1494021,1883285,2376628,2742325,2967694,0,-332732,-837801,-1190081,-1155758,-864618,-1011546,-1506561,-1455653,-1461081,-1468925,0,-17398,-499085,-748440,-252548,-711966,-497932,-195879,220930,-206548,-255380,-568898,-757326,-427050,-393296,-111710,-602208,-649037,-444294,-18070,-10846,275102,386815,-81884,-314019,-787111,-444473,-623219,-786284,-1224148,-948653,0,83288,141789,-376897,-801010,-1229392,-1437542,-1343774,-1252581,-1407581,-1230786,-1080778,-887420,-1407282,-1684415,-1586879,-1817380,-1644980,-2018396,-1578302,-2078661,-2403312,0,-348073,-61579,-410265,-889716,-590911,-305754,14324,90455,238709,0,-514467,-18980,-246615,-269435,47130,486843,133713,-235497,231266,18100,49540,309653,128285,358799,71567,-82550,-153304,220347,510910,469921,274902,621062,1078829,872577,737543,784276,1024881,903770,582412,557177,0,-79157,156274,608119,229318,288224,717375,977407,469445,324953,457611,641493,880116,360122,700100,821083,939413,1353849,1301020,1159702,1066315,1313991,1759726,0,64229,71186,-445530,-895389,-788935,-1273825,-1752166,-1318004,-925613,-1174396,-723669,-699056,-956311,-472962,-854802,-631555,-568744,-121748,262164,315678,286142,516418,774854,802149,0,242513,-78471,-447748,-208334,80367,353728,395938,349793,843076,665615,217631,152661,369532,391974,528953,54121,-213080,0,-379824,-596797,-930399,-1233561,0,49961,470555,-8966,-421041,-358131,-522150,-438106,-257326,-388186,-349745,-150297,-321019,196862,-303784,-753841,-673582,0,-214043,-451282,-817091,-960814,-680287,-213731,-513040,-214838,188079,567961,716777,411753,456206,168684,5973,275529,253742,173181,179486,571390,660839,1011720,1004275,736990,0,486399,121062,152334,-63078,263827,149145,660440,499071,805451,578235,959506,1402219,1313257,873908,1270627,845536,422653,125870,-131875,40533,-20688,217854,732938,722699,1196205,735699,266278,419403,821116,925710,0,370129,684573,735026,1258789,911909,583991,400539,247903,534707,541244,391465,0,-59023,-409311,-21312,-433939,-148438,-668644,-386892,-631301,-1038008,-574634,-1058043,0,265219,578285,758977,1231768,805524,487154,300489,389030,-120499,311989,-44810,-112116,-251032,-86539,-435986,-866365,-443801,-14900,309866,444678,-26681,324055,68761,544046,622794,0,74157,-317149,23825,481577,562395,875574,840706,1160287,1619936,1498032,1475610,1164467,949769,1280500,1015376,1063969,905518,615928,0,-87002,-594303,-548189,-192022,-133977,74580,549869,205817,162377,410494,90138,597008,664846,830524,377126,735741,778767,353906,382320,613333,979868,770860,604628,887587,1280914,956452,1320009,1428155,1055994,0,168619,-88538,-351560,109200,531151,46281,-461996,-305458,-431157,-351578,-445572,-193773,222034,454655,416443,229141,16838,482113,458503,-36529,37212,336796,-124876,-247953,-568505,-351627,0,174429,326398,0,479713,860680,1036211,514896,729323,669741,578086,375592,810904,1314492,0,516330,592423,921726,929593,1045808,747506,626620,597816,458291,216687,699340,216117,-132060,-312354,-2136,-520935,-569805,-970137,-1267749,-880767,-1038096,0,118085,-218891,-76411,-133008,70809,-229674,61482,463032,157647,74287,65534,406373,241452,697069,1054306,708766,949749,1455240,1211918,1300078,1171212,1214004,1127868,1159521,0,183087,153680,15177,-116973,21188,233956,-64713,-354746,-877965,-1342227,-1529732,-1008952,-1394152,-1765713,-1975211,0,-481619,-382778,78075,191489,507177,333103,613687,506194,597264,96635,-69800,-337325,-620875,-885881,-521276,-776467,-401089,-240095,-174539,-655262,-662689,-309418,-543461,-287504,-502363,-425626,-135632,-634977,-125686,0,-406528,-758206,-879047,-365289,-104346,-472971,-535915,-48760,328278,251722,321627,-127699,-192224,248204,-32639,-104266,-265995,207560,-284650,-231682,0,-61639,-279193,-294943,-445218,-331468,-365358,141884,-55123,-528518,-56843,-482234,-590206,-389883,-77870,42781,466913,753792,0,154707,337717,186947,-17501,-222052,-205272,247871,705,307861,459828,791604,945119,1286260,934495,425248,514350,276711,257592,748516,730039,673631]
+    rs = fromList (Z :. 30)  [215752,2738275,-1800525,-1372798,-2118027,296082,207526,2063381,312429,-190965,-907082,-914710,442481,1282782,716990,-1224980,1060351,109154,849522,130337,247166,1435364,-1200037,1292937,-2157594,-649389,-498810,970579,243783,0]
+
+test10 :: Acc (Vector Int64, Vector Int64)
+test10 = A.scanl'Seg (+) 0 xs seg
+  where
+    xs :: Acc (Vector Int64)
+    xs = use $ fromList (Z :. 569) [-66818,282570,251795,447915,102987,-322423,373016,-100430,386059,-276659,77503,-45066,205014,457977,414137,86861,184317,34975,-389689,-183599,-210669,389264,493343,365697,225369,-229419,-332732,-505069,-352280,34323,291140,-146928,-495015,50908,-5428,-7844,-331600,-17398,-481687,-249355,495892,-459418,214034,302053,416809,-427478,-48832,-313518,-188428,330276,33754,281586,-490498,-46829,204743,426224,7224,285948,111713,-468699,-232135,-473092,342638,-178746,-163065,-437864,275495,-424145,83288,58501,-518686,-424113,-428382,-208150,93768,91193,-155000,176795,150008,193358,-519862,-277133,97536,-230501,172400,-373416,440094,-500359,-324651,285285,-348073,286494,-348686,-479451,298805,285157,320078,76131,148254,57373,-514467,495487,-227635,-22820,316565,439713,-353130,-369210,466763,-213166,31440,260113,-181368,230514,-287232,-154117,-70754,373651,290563,-40989,-195019,346160,457767,-206252,-135034,46733,240605,-121111,-321358,-25235,-349651,-79157,235431,451845,-378801,58906,429151,260032,-507962,-144492,132658,183882,238623,-519994,339978,120983,118330,414436,-52829,-141318,-93387,247676,445735,303655,64229,6957,-516716,-449859,106454,-484890,-478341,434162,392391,-248783,450727,24613,-257255,483349,-381840,223247,62811,446996,383912,53514,-29536,230276,258436,27295,-489720,242513,-320984,-369277,239414,288701,273361,42210,-46145,493283,-177461,-447984,-64970,216871,22442,136979,-474832,-267201,22115,-379824,-216973,-333602,-303162,326479,49961,420594,-479521,-412075,62910,-164019,84044,180780,-130860,38441,199448,-170722,517881,-500646,-450057,80259,-241128,-214043,-237239,-365809,-143723,280527,466556,-299309,298202,402917,379882,148816,-305024,44453,-287522,-162711,269556,-21787,-80561,6305,391904,89449,350881,-7445,-267285,-294509,486399,-365337,31272,-215412,326905,-114682,511295,-161369,306380,-227216,381271,442713,-88962,-439349,396719,-425091,-422883,-296783,-257745,172408,-61221,238542,515084,-10239,473506,-460506,-469421,153125,401713,104594,357072,370129,314444,50453,523763,-346880,-327918,-183452,-152636,286804,6537,-149779,325525,-59023,-350288,387999,-412627,285501,-520206,281752,-244409,-406707,463374,-483409,-166937,265219,313066,180692,472791,-426244,-318370,-186665,88541,-509529,432488,-356799,-67306,-138916,164493,-349447,-430379,422564,428901,324766,134812,-471359,350736,-255294,475285,78748,437557,74157,-391306,340974,457752,80818,313179,-34868,319581,459649,-121904,-22422,-311143,-214698,330731,-265124,48593,-158451,-289590,-506774,-87002,-507301,46114,356167,58045,208557,475289,-344052,-43440,248117,-320356,506870,67838,165678,-453398,358615,43026,-424861,28414,231013,366535,-209008,-166232,282959,393327,-324462,363557,108146,-372161,-206472,168619,-257157,-263022,460760,421951,-484870,-508277,156538,-125699,79579,-93994,251799,415807,232621,-38212,-187302,-212303,465275,-23610,-495032,73741,299584,-461672,-123077,-320552,216878,481964,174429,151969,-79232,479713,380967,175531,-521315,214427,-59582,-91655,-202494,435312,503588,120872,516330,76093,329303,7867,116215,-298302,-120886,-28804,-139525,-241604,482653,-483223,-348177,-180294,310218,-518799,-48870,-400332,-297612,386982,-157329,-161941,118085,-336976,142480,-56597,203817,-300483,291156,401550,-305385,-83360,-8753,340839,-164921,455617,357237,-345540,240983,505491,-243322,88160,-128866,42792,-86136,31653,133416,183087,-29407,-138503,-132150,138161,212768,-298669,-290033,-523219,-464262,-187505,520780,-385200,-371561,-209498,-182383,-481619,98841,460853,113414,315688,-174074,280584,-107493,91070,-500629,-166435,-267525,-283550,-265006,364605,-255191,375378,160994,65556,-480723,-7427,353271,-234043,255957,-214859,76737,289994,-499345,509291,-523703,-406528,-351678,-120841,513758,260943,-368625,-62944,487155,377038,-76556,69905,-449326,-64525,440428,-280843,-71627,-161729,473555,-492210,52968,-267128,-61639,-217554,-15750,-150275,113750,-33890,507242,-197007,-473395,471675,-425391,-107972,200323,312013,120651,424132,286879,216787,154707,183010,-150770,-204448,-204551,16780,453143,-247166,307156,151967,331776,153515,341141,-351765,-509247,89102,-237639,-19119,490924,-18477,-56408,-429848]
+
+    seg :: Acc (Segments Int32)
+    seg = use $ fromList (Z :. 30) [2,24,11,31,22,10,31,23,25,18,5,17,25,31,12,12,26,19,30,27,3,11,22,25,16,30,21,18,22,0]
+
+
+ref11 :: (Vector Int64, Vector Int64)
+ref11 = (ps, rs)
+  where
+    ps = fromList (Z :. 750) [300202,-3934108,-7293301,118329,0,-9620841,-6707242,194332,33523,-2362285,4356093,8130701,7381954,6320569,13020915,19242062,20405079,12162531,9328566,2344030,6249515,1195987,714789,-3387204,-1156156,-4385845,-1505374,3054547,10517703,14551257,7158564,5521908,4076566,9423606,9791035,15883498,13341839,5338906,7755970,0,8449937,14272421,7658262,4242448,106786,-1538494,6329826,-1969224,-3562793,-5238381,-11479790,-19204769,-23383409,-15529258,-9197176,-3153045,2044602,7324780,0,-4389691,3327745,6304656,5225571,10231407,12003136,8669740,11482531,16463383,14927577,18131497,21726278,19113902,24183865,18037487,12252168,20461643,15647208,19992282,16169909,8901867,3534110,5568184,6826591,1884406,-4706766,-6388012,94426,-8160379,-4083019,-10378695,-15486623,-7206171,-695686,4860798,0,10857061,3955448,-1061568,6951301,-1071594,0,-13446920,-12173160,-8243921,-11230304,-8734571,-16936920,-16750142,-9949134,-10991997,-3350146,-8268859,0,-14302173,-16276308,-11142092,-13546302,-15960168,-15744133,-20140592,-27616401,-23636225,-24849690,-18571631,-14996447,-8469842,-2690306,-1586836,1141087,-1808235,-5396094,-6508579,0,33601076,40110614,40470091,39158954,31965378,23662135,26792692,22837593,15375475,7595486,5806140,0,5557752,6250667,3210301,4771732,10208018,9244194,1488326,-6840876,-5503541,-6377388,1921887,8701362,436706,5155610,4702952,9854658,12359455,11367064,17274738,12815997,16178778,13979944,14676004,11309648,10910551,8856116,1692110,6290491,9917167,13883564,6354535,2315726,2456500,-3357012,-2245597,5286714,0,27838965,23929687,16271002,14334800,12447318,8856790,5550657,2872825,5216149,1984481,6519741,-380267,-2676926,5698169,-2416327,5822052,12780665,13247384,20633185,15313341,14149220,12991370,11193529,10073298,4257177,8166119,6158966,7167487,8065374,4626067,5253098,221789,0,-22666015,-19830708,-26450648,-22323702,-14812315,-12769333,-8380998,-124066,-3429801,1735354,8675238,5922004,3773612,4863814,8973510,8243987,8052797,-131886,-1218987,944425,-5693971,-10284458,-3771161,-6911370,1215128,6417910,7616391,10888675,12684613,15718607,12760177,4418538,0,-19124759,-16690729,-14466748,-7312246,-8934031,-14128478,-6391701,-5586522,-3281158,-6126513,-12086460,-11947805,-8977838,-4679499,-7044384,-3585849,2517797,4187257,1143610,5599470,12556,468724,0,-38086726,-38209271,-34895951,-29641991,-33756478,-34159294,-29272266,-24192985,-18907102,-10553406,-8755717,-5576171,1187225,5646949,0,-26021214,-24968854,-16606604,-23345266,-26556968,-27031671,-32169558,-29741461,-22232488,-21561792,-17815214,-9755318,-5676615,-1531928,0,-7082738,-2096546,69095,1247646,-2028294,278676,1852334,4571352,-3233037,-3429729,-6398514,-9422414,-2191733,2284645,-864442,-254370,1472191,0,3756457,650062,-4943727,-6384744,-850321,-5359348,-645558,-2506083,-3114762,-366178,-6339582,-4052845,0,65534,-7573163,-12029806,-18419840,-13680249,-6009158,-7346388,0,-39890208,-43517086,-35311112,-37123834,-36260718,-33030305,-34707046,-39911126,-35939603,-30275083,-36082502,-32249760,-27147583,-23233819,-25620860,-25554234,-22141128,-25506989,-22929605,-15879316,-24134083,-16570735,-9997301,-4200711,-2668164,1487850,3578750,-1305145,1080697,-6119380,-6192140,-4780925,-6340276,0,-26181571,-18058810,-10653064,-6588755,-9696374,-5833999,-9675119,-10632518,-11082908,-10756776,-10864096,-13002610,-7721565,-9182352,-6394042,-2752356,-9605533,-4366062,-8172748,0,-16273637,-12506792,-8904008,-8280500,-10173545,-6329127,-3926250,-8763799,-8461557,-5251290,1921403,9241406,2219290,2078592,1370230,2365533,0,-36174378,-34747120,-36960421,-38916018,-33713341,-27862565,-19493548,-13614863,-18329350,-13726747,-18636836,-21433533,-22047575,-17828457,-18477083,-18912228,-16845393,-14834848,-10961203,-4503372,2709924,-5670489,0,8244107,7371898,1062426,-5349784,-1530037,-4243202,1657954,0,58761276,64777759,62710415,55540126,63734805,67828569,66998117,65406433,58629880,51628041,49304089,52468514,44515601,37206921,40107031,36553913,32964413,28315600,22177065,24792502,21656741,20411694,28296854,21119658,16847130,10142928,6275059,10233804,7892690,6605617,812948,-4276554,421536,-282529,0,10264903,3489193,0,47453090,48772541,54603425,48519299,46216432,50441440,48516811,45678872,39908077,32646114,28833886,23180980,15877983,14237392,6679178,13066338,6271764,8380814,1833690,-4162730,-1918105,5114142,0,-25911951,-28491981,-26929631,-23869603,-20710623,-28958111,-23436032,-16629161,-16368397,-15117344,-13086145,-7862262,-3970195,-1325162,69199,2584855,-390927,-753348,-7662405,0,44746008,36954219,37811396,37926769,38442648,38288713,29989290,27015712,25484790,22372796,17537520,16774727,8552613,13943585,17093179,10142287,5721997,10994509,9787684,9382836,9256805,16015565,8545047,10254145,12213051,12551830,8902381,12267197,4492349,3729047,8190040,1659416,-5162630,0,-39096550,-32628259,-39002248,-31910093,-31760558,-26048323,-23199546,-18154141,-15577194,-20921838,-13620329,-5287668,-10372255,-7345019,-13225631,-8543390,-10782084,-10995673,-6251002,1830175,-5731084,-3491981,-9221778,-10184068,-15385965,-16015517,-7715802,-1442733,6174121,2371134,-1808823,5881932,0,-10833715,-9130099,-7149409,-89049,-6363174,-3030367,884814,0,4329246,-712705,-2477029,-4838047,-6361858,-758166,6976202,50092,-5046096,2007750,-5232448,-1895517,-5590470,-4630085,-5205817,-5003092,1356974,0,-30933008,-25815115,-26412272,-27208148,-28291145,-30761072,-24801972,-20136889,-20802009,-17119600,-9796191,-5951994,-3024348,-6817180,-10261727,-12018141,-6423630,-7809004,-12362519,-15505819,-17738534,-12482571,-16777356,-8514106,-10646693,-13579392,-17091140,-10886710,-8783584,-3787667,0,-10399417,-9783351,-11140112,-10286438,-18016415,-24699666,-29534073,-30173237,-22982316,-16232479,-20550054,-17508444,-20456501,-15338123,-16089893,-19682049,-17509739,-17545850,-20482200,-16092902,-10112370,-9857530,-7086012,-5758886,-13713007,-18431943,-12663085,-10395688,-9242682,-3627676,-4124458,324696,0,-1239916,-1099231,0,-52728448,-49740852,-53462736,-48128709,-51184308,-50512793,-51205907,-44973519,-45435372,-48750664,-42361329,-35515045,-32329339,-31125840,-23377216,-15586974,-16058124,-22592883,-17078262,-10577077,-10527747,-13404618,-8157252,-2726103,-4759099,-9619550,-11889364,-13992613,-14997209,-7958218,0,11463857,11389338,6395972,4491458,0,9908832,4627071,2514558,5454929,3049640,-3347579,-4585603,-8139773,-4727321,-5405095,-5516549,-1072707,2091727,10164364,8109479,13221076,11835227,5915534,7266805,10176116,7976055,487672,-1039582,4809829,-3150159,0,-5576241,2649236,-4909388,2973172,0]
+    rs = fromList (Z :. 37)  [1828591,-5649957,12711572,-882080,8724897,-5592479,-16715596,30682536,8434130,20924927,-21828584,-20372532,-33000591,-25847170,-2348236,7144729,-7521765,-37600334,-21413350,-17584160,-30265145,2716955,54962523,15814454,52796336,-29414196,44937491,-41772916,-13871531,5751378,-32142219,-11167891,-5978481,-54925970,6000925,17510325,-13863452]
+
+test11 :: Acc (Vector Int64, Vector Int64)
+test11 = A.scanr'Seg (+) 0 xs seg
+  where
+    xs :: Acc (Vector Int64)
+    xs = use $ fromList (Z :. 750) [1528389,4234310,3359193,-7411630,118329,3970884,-2913599,-6901574,160809,2395808,-6718378,-3774608,748747,1061385,-6700346,-6221147,-1163017,8242548,2833965,6984536,-3905485,5053528,481198,4101993,-2231048,3229689,-2880471,-4559921,-7463156,-4033554,7392693,1636656,1445342,-5347040,-367429,-6092463,2541659,8002933,-2417064,7755970,4261635,-5822484,6614159,3415814,4135662,1645280,-7868320,8299050,1593569,1675588,6241409,7724979,4178640,-7854151,-6332082,-6044131,-5197647,-5280178,7324780,3507611,-7717436,-2976911,1079085,-5005836,-1771729,3333396,-2812791,-4980852,1535806,-3203920,-3594781,2612376,-5069963,6146378,5785319,-8209475,4814435,-4345074,3822373,7268042,5367757,-2034074,-1258407,4942185,6591172,1681246,-6482438,8254805,-4077360,6295676,5107928,-8280452,-6510485,-5556484,4860798,-2132164,6901613,5017016,-8012869,8022895,-1071594,7854441,-1273760,-3929239,2986383,-2495733,8202349,-186778,-6801008,1042863,-7641851,4918713,-8268859,-2413423,1974135,-5134216,2404210,2413866,-216035,4396459,7475809,-3980176,1213465,-6278059,-3575184,-6526605,-5779536,-1103470,-2727923,2949322,3587859,1112485,-6508579,-2918540,-6509538,-359477,1311137,7193576,8303243,-3130557,3955099,7462118,7779989,1789346,5806140,2876378,-692915,3040366,-1561431,-5436286,963824,7755868,8329202,-1337335,873847,-8299275,-6779475,8264656,-4718904,452658,-5151706,-2504797,992391,-5907674,4458741,-3362781,2198834,-696060,3366356,399097,2054435,7164006,-4598381,-3626676,-3966397,7529029,4038809,-140774,5813512,-1111415,-7532311,5286714,-6914038,3909278,7658685,1936202,1887482,3590528,3306133,2677832,-2343324,3231668,-4535260,6900008,2296659,-8375095,8114496,-8238379,-6958613,-466719,-7385801,5319844,1164121,1157850,1797841,1120231,5816121,-3908942,2007153,-1008521,-897887,3439307,-627031,5031309,221789,837431,-2835307,6619940,-4126946,-7511387,-2042982,-4388335,-8256932,3305735,-5165155,-6939884,2753234,2148392,-1090202,-4109696,729523,191190,8184683,1087101,-2163412,6638396,4590487,-6513297,3140209,-8126498,-5202782,-1198481,-3272284,-1795938,-3033994,2958430,8341639,4418538,-1247773,-2434030,-2223981,-7154502,1621785,5194447,-7736777,-805179,-2305364,2845355,5959947,-138655,-2969967,-4298339,2364885,-3458535,-6103646,-1669460,3043647,-4455860,5586914,-456168,468724,5086135,122545,-3313320,-5253960,4114487,402816,-4887028,-5079281,-5285883,-8353696,-1797689,-3179546,-6763396,-4459724,5646949,174044,-1052360,-8362250,6738662,3211702,474703,5137887,-2428097,-7508973,-670696,-3746578,-8059896,-4078703,-4144687,-1531928,4734502,-4986192,-2165641,-1178551,3275940,-2306970,-1573658,-2719018,7804389,196692,2968785,3023900,-7230681,-4476378,3149087,-610072,-1726561,1472191,3388272,3106395,5593789,1441017,-5534423,4509027,-4713790,1860525,608679,-2748584,5973404,-2286737,-4052845,-7587299,7638697,4456643,6390034,-4739591,-7671091,1337230,-7346388,2289874,3626878,-8205974,1812722,-863116,-3230413,1676741,5204080,-3971523,-5664520,5807419,-3832742,-5102177,-3913764,2387041,-66626,-3413106,3365861,-2577384,-7050289,8254767,-7563348,-6573434,-5796590,-1532547,-4156014,-2090900,4883895,-2385842,7200077,72760,-1411215,1559351,-6340276,4768221,-8122761,-7405746,-4064309,3107619,-3862375,3841120,957399,450390,-326132,107320,2138514,-5281045,1460787,-2788310,-3641686,6853177,-5239471,3806686,-8172748,-1310523,-3766845,-3602784,-623508,1893045,-3844418,-2402877,4837549,-302242,-3210267,-7172693,-7320003,7022116,140698,708362,-995303,2365533,5909233,-1427258,2213301,1955597,-5202677,-5850776,-8369017,-5878685,4714487,-4602603,4910089,2796697,614042,-4219118,648626,435145,-2066835,-2010545,-3873645,-6457831,-7213296,8380413,-5670489,-5527152,872209,6309472,6412210,-3819747,2713165,-5901156,1657954,-3798753,-6016483,2067344,7170289,-8194679,-4093764,830452,1591684,6776553,7001839,2323952,-3164425,7952913,7308680,-2900110,3553118,3589500,4648813,6138535,-2615437,3135761,1245047,-7885160,7177196,4272528,6704202,3867869,-3958745,2341114,1287073,5792669,5089502,-4698090,704065,-282529,5549551,6775710,3489193,5343246,-1319451,-5830884,6084126,2302867,-4225008,1924629,2837939,5770795,7261963,3812228,5652906,7302997,1640591,7558214,-6387160,6794574,-2109050,6547124,5996420,-2244625,-7032247,5114142,-3502245,2580030,-1562350,-3060028,-3158980,8247488,-5522079,-6806871,-260764,-1251053,-2031199,-5223883,-3892067,-2645033,-1394361,-2515656,2975782,362421,6909057,-7662405,191483,7791789,-857177,-115373,-515879,153935,8299423,2973578,1530922,3111994,4835276,762793,8222114,-5390972,-3149594,6950892,4420290,-5272512,1206825,404848,126031,-6758760,7470518,-1709098,-1958906,-338779,3649449,-3364816,7774848,763302,-4460993,6530624,6822046,-5162630,-2676366,-6468291,6373989,-7092155,-149535,-5712235,-2848777,-5045405,-2576947,5344644,-7301509,-8332661,5084587,-3027236,5880612,-4682241,2238694,213589,-4744671,-8081177,7561259,-2239103,5729797,962290,5201897,629552,-8299715,-6273069,-7616854,3802987,4179957,-7690755,5881932,-3037816,-1703616,-1980690,-7060360,6274125,-3332807,-3915181,884814,1422132,5041951,1764324,2361018,1523811,-5603692,-7734368,6926110,5096188,-7053846,7240198,-3336931,3694953,-960385,575732,-202725,-6360066,1356974,-1209211,-5117893,597157,795876,1082997,2469927,-5959100,-4665083,665120,-3682409,-7323409,-3844197,-2927646,3792832,3444547,1756414,-5594511,1385374,4553515,3143300,2232715,-5255963,4294785,-8263250,2132587,2932699,3511748,-6204430,-2103126,-4995917,-3787667,-768474,-616066,1356761,-853674,7729977,6683251,4834407,639164,-7190921,-6749837,4317575,-3041610,2948057,-5118378,751770,3592156,-2172310,36111,2936350,-4389298,-5980532,-254840,-2771518,-1327126,7954121,4718936,-5768858,-2267397,-1153006,-5615006,496782,-4449154,324696,-4738565,-140685,-1099231,-2197522,-2987596,3721884,-5334027,3055599,-671515,693114,-6232388,461853,3315292,-6389335,-6846284,-3185706,-1203499,-7748624,-7790242,471150,6534759,-5514621,-6501185,-49330,2876871,-5247366,-5431149,2032996,4860451,2269814,2103249,1004596,-7038991,-7958218,-5462932,74519,4993366,1904514,4491458,7601493,5281761,2112513,-2940371,2405289,6397219,1238024,3554170,-3412452,677774,111454,-4443842,-3164434,-8072637,2054885,-5111597,1385849,5919693,-1351271,-2909311,2200061,7488383,1527254,-5849411,7959988,-3150159,-8287211,-8225477,7558624,-7882560,2973172]
+
+    seg :: Acc (Segments Int32)
+    seg = use $ fromList (Z :. 37) [5,35,19,36,6,12,20,12,37,33,33,23,15,15,18,13,8,34,20,17,23,8,35,3,23,20,34,33,8,18,31,33,3,31,5,26,5]
+
diff --git a/examples/nofib/Test/Issues/Issue123.hs b/examples/nofib/Test/Issues/Issue123.hs
new file mode 100644
--- /dev/null
+++ b/examples/nofib/Test/Issues/Issue123.hs
@@ -0,0 +1,29 @@
+
+module Test.Issues.Issue123 (test_issue123)
+  where
+
+import Config
+import ParseArgs
+import Test.Base
+import Test.Framework
+import Test.Framework.Providers.HUnit
+
+import Prelude                                  as P
+import Data.Array.Accelerate                    as A
+import Data.Label
+
+
+test_issue123 :: Config -> Test
+test_issue123 conf =
+  testCase "123" (assertEqual ref1 $ run backend (test1 n))
+  where
+    backend     = get configBackend conf
+    n           = 100
+    ref1        = fromList Z [n]
+
+
+test1 :: Int -> Acc (Scalar Int)
+test1 n
+  = fold (+) 0
+  $ fill (constant (Z:.n)) 1
+
diff --git a/examples/nofib/Test/Issues/Issue137.hs b/examples/nofib/Test/Issues/Issue137.hs
new file mode 100644
--- /dev/null
+++ b/examples/nofib/Test/Issues/Issue137.hs
@@ -0,0 +1,46 @@
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeOperators       #-}
+
+module Test.Issues.Issue137 (test_issue137)
+  where
+
+import Config
+import ParseArgs
+import Test.Base
+import Test.Framework
+import Test.Framework.Providers.HUnit
+
+import Prelude                                  as P
+import Data.Array.Accelerate                    as A
+import Data.Label
+
+
+test_issue137 :: Config -> Test
+test_issue137 conf =
+  testCase "137" (assertEqual ref1 $ run backend test1)
+  where
+    backend = get configBackend conf
+
+ref1 :: Vector (Int,Int)
+ref1 = fromList (Z:.384) [(1,2),(0,1),(2,3),(0,1),(3,4),(0,1),(4,5),(0,1),(5,5),(0,1),(4,5),(0,1),(3,4),(0,1),(2,3),(0,1),(1,2),(1,2),(0,1),(2,3),(0,1),(3,4),(0,1),(4,5),(0,1),(5,5),(0,1),(4,5),(0,1),(3,4),(0,1),(2,3),(0,1),(1,2),(1,2),(0,1),(2,3),(0,1),(3,4),(0,1),(4,5),(0,1),(5,5),(0,1),(4,5),(0,1),(3,4),(0,1),(2,3),(0,1),(1,2),(1,2),(0,1),(2,3),(0,1),(3,4),(0,1),(4,5),(0,1),(5,5),(0,1),(4,5),(0,1),(3,4),(0,1),(2,3),(0,1),(1,2),(1,2),(0,1),(2,3),(0,1),(3,4),(0,1),(4,5),(0,1),(5,5),(0,1),(4,5),(0,1),(3,4),(0,1),(2,3),(0,1),(1,2),(1,2),(0,1),(2,3),(0,1),(3,4),(0,1),(4,5),(0,1),(5,5),(0,1),(4,5),(0,1),(3,4),(0,1),(2,3),(0,1),(1,2),(1,2),(0,1),(2,3),(0,1),(3,4),(0,1),(4,5),(0,1),(5,5),(0,1),(4,5),(0,1),(3,4),(0,1),(2,3),(0,1),(1,2),(1,2),(0,1),(2,3),(0,1),(3,4),(0,1),(4,5),(0,1),(5,5),(0,1),(4,5),(0,1),(3,4),(0,1),(2,3),(0,1),(1,2),(1,2),(0,1),(2,3),(0,1),(3,4),(0,1),(4,5),(0,1),(5,5),(0,1),(4,5),(0,1),(3,4),(0,1),(2,3),(0,1),(1,2),(1,2),(0,1),(2,3),(0,1),(3,4),(0,1),(4,5),(0,1),(5,5),(0,1),(4,5),(0,1),(3,4),(0,1),(2,3),(0,1),(1,2),(1,2),(0,1),(2,3),(0,1),(3,4),(0,1),(4,5),(0,1),(5,5),(0,1),(4,5),(0,1),(3,4),(0,1),(2,3),(0,1),(1,2),(1,2),(0,1),(2,3),(0,1),(3,4),(0,1),(4,5),(0,1),(5,5),(0,1),(4,5),(0,1),(3,4),(0,1),(2,3),(0,1),(1,2),(1,2),(0,1),(2,3),(0,1),(3,4),(0,1),(4,5),(0,1),(5,5),(0,1),(4,5),(0,1),(3,4),(0,1),(2,3),(0,1),(1,2),(1,2),(0,1),(2,3),(0,1),(3,4),(0,1),(4,5),(0,1),(5,5),(0,1),(4,5),(0,1),(3,4),(0,1),(2,3),(0,1),(1,2),(1,2),(0,1),(2,3),(0,1),(3,4),(0,1),(4,5),(0,1),(5,5),(0,1),(4,5),(0,1),(3,4),(0,1),(2,3),(0,1),(1,2),(1,2),(0,1),(2,3),(0,1),(3,4),(0,1),(4,5),(0,1),(5,5),(0,1),(4,5),(0,1),(3,4),(0,1),(2,3),(0,1),(1,2),(1,2),(0,1),(2,3),(0,1),(3,4),(0,1),(4,5),(0,1),(5,5),(0,1),(4,5),(0,1),(3,4),(0,1),(2,3),(0,1),(1,2),(1,2),(0,1),(2,3),(0,1),(3,4),(0,1),(4,5),(0,1),(5,5),(0,1),(4,5),(0,1),(3,4),(0,1),(2,3),(0,1),(1,2),(1,2),(0,1),(2,3),(0,1),(3,4),(0,1),(4,5),(0,1),(5,5),(0,1),(4,5),(0,1),(3,4),(0,1),(2,3),(0,1),(1,2),(1,2),(0,1),(2,3),(0,1),(3,4),(0,1),(4,5),(0,1),(5,5),(0,1),(4,5),(0,1),(3,4),(0,1),(2,3),(0,1),(1,2),(1,2),(0,1),(2,3),(0,1),(3,4),(0,1),(4,5),(0,1),(5,5),(0,1),(4,5),(0,1),(3,4),(0,1),(2,3),(0,1),(1,2),(1,2),(0,1),(2,3),(0,1),(3,4),(0,1),(4,5),(0,1),(5,5),(0,1),(4,5),(0,1),(3,4),(0,1),(2,3),(0,1),(1,2),(1,2),(0,10000),(10000,10000),(10000,10000),(10000,10000),(10000,10000),(10000,10000),(10000,10000),(10000,10000),(10000,10000)]
+
+test1 :: Acc (Vector (Int,Int))
+test1 =
+  let
+      sz          = 3000 :: Int
+      interm_arrA = use $ A.fromList (Z :. sz) [ P.fromIntegral $ 8 - (a `mod` 17) | a <- [1..sz]]
+      msA         = use $ A.fromList (Z :. sz) [ P.fromIntegral $ (a `div` 8) | a <- [1..sz]]
+      inf         = 10000 :: Exp Int
+      infsA       = A.generate (index1 (384 :: Exp Int)) (\_ -> lift (inf,inf))
+      inpA        = A.map (\v -> lift (abs v,inf) :: Exp (Int,Int)) interm_arrA
+  in
+  A.permute (\a12 b12 -> let (a1,a2) = unlift a12
+                             (b1,b2) = unlift b12
+                         in (a1 <=* b1)
+                          ? ( lift (a1, min a2 b1)
+                            , lift (b1, min b2 a1)
+                            ))
+            infsA
+            (\ix -> index1 (msA A.! ix))
+            inpA
+
diff --git a/examples/nofib/Test/Issues/Issue168.hs b/examples/nofib/Test/Issues/Issue168.hs
new file mode 100644
--- /dev/null
+++ b/examples/nofib/Test/Issues/Issue168.hs
@@ -0,0 +1,57 @@
+
+module Test.Issues.Issue168 (test_issue168)
+  where
+
+import Config
+import ParseArgs
+import Test.Base
+import Test.Framework
+import Test.Framework.Providers.HUnit
+
+import Prelude                                  as P
+import Data.Array.Accelerate                    as A
+import Data.Label
+
+
+test_issue168 :: Config -> Test
+test_issue168 conf = testGroup "168"
+  [ testCase "A" (assertEqual ref1 $ run backend (A.fill sh test1))
+  , testCase "B" (assertEqual ref2 $ run backend (A.fill sh test2))
+  , testCase "C" (assertEqual ref3 $ run backend (A.fill sh test3))
+  ]
+  where
+    backend     = get configBackend conf
+    sh          = index1 (constant 1) :: Exp DIM1
+
+    -- Test 1
+    -- ------
+    dqc1 :: (Exp Float, Exp Float)
+    dqc1 = (2,1)
+
+    qMult1 :: (Exp Float, Exp Float) -> (Exp Float, Exp Float)
+    qMult1 (a1,_) = (3, a1)
+
+    ref1 = fromList (Z:.1) [(3.0,2.0)]
+
+    test1 :: Exp (Float, Float)
+    test1 = P.iterate (lift1 qMult1) (lift dqc1) P.!! 1
+
+    ref2 = ref1
+
+    test2 :: Exp (Float, Float)
+    test2 = A.iterate (constant 1) (lift1 qMult1) (lift dqc1)
+
+    -- Test 2
+    -- ------
+    ref3 = fromList (Z:.1) [(1.0,2.0,3.0,4.0,5.0,6.0)]
+
+    dqc3 :: (Exp Float, Exp Float, Exp Float, Exp Float, Exp Float, Exp Float)
+    dqc3 = (6,5,4,3,2,1)
+
+    qMult3 :: (Exp Float, Exp Float, Exp Float, Exp Float, Exp Float, Exp Float)
+           -> (Exp Float, Exp Float, Exp Float, Exp Float, Exp Float, Exp Float)
+    qMult3 (a1,b1,c1,d1,e1,f1) = (f1,e1,d1,c1,b1,a1)
+
+    test3 :: Exp (Float,Float,Float,Float,Float,Float)
+    test3 = A.iterate (constant 1) (lift1 qMult3) (lift dqc3)
+
diff --git a/examples/nofib/Test/Issues/Issue184.hs b/examples/nofib/Test/Issues/Issue184.hs
new file mode 100644
--- /dev/null
+++ b/examples/nofib/Test/Issues/Issue184.hs
@@ -0,0 +1,56 @@
+
+module Test.Issues.Issue184 (test_issue184)
+  where
+
+import Config
+import ParseArgs
+import Test.Base
+import Test.Framework
+import Test.Framework.Providers.HUnit
+
+import Prelude                                  as P
+import Data.Array.Accelerate                    as A
+import Data.Label
+
+
+test_issue184 :: Config -> Test
+test_issue184 conf = testGroup "184"
+  [ testCase "A" (assertEqual ref1 $ run backend test1)
+  , testCase "B" (assertEqual ref2 $ run backend test2)
+  , testCase "C" (assertEqual ref3 $ run backend test3)
+  ]
+  where
+    backend     = get configBackend conf
+
+
+ref1 :: Vector Int
+ref1 = fromList (Z :. 1000) [1,4,9,16,25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
+
+test1 :: Acc (Vector Int)
+test1 =
+  let v   = use (fromList (Z :. 5) [1,2,3,4,5] :: Vector Int)
+      f x = x A.<* 5 ? (let y = v A.!! x in y*y, 0)
+  in generate (index1 1000) (f . unindex1)
+
+
+ref2 :: Scalar Bool
+ref2 = fromList Z [True]
+
+test2 :: Acc (Scalar Bool)
+test2 =
+  let x = constant 1 :: Exp Int
+      v = use (fromList (Z :. 5) [1,2,3,4,5] :: Vector Int)
+      y = (x ==* 1 ||* v A.!! (-1) ==* 1)
+  in unit y
+
+
+ref3 :: Scalar Bool
+ref3 = fromList Z [False]
+
+test3 :: Acc (Scalar Bool)
+test3 =
+  let x = constant 1 :: Exp Int
+      v = use (fromList (Z :. 5) [1,2,3,4,5] :: Vector Int)
+      y = (x /=* 1 &&* v A.!! (-1) ==* 1)
+  in unit y
+
diff --git a/examples/nofib/Test/Issues/Issue185.hs b/examples/nofib/Test/Issues/Issue185.hs
new file mode 100644
--- /dev/null
+++ b/examples/nofib/Test/Issues/Issue185.hs
@@ -0,0 +1,107 @@
+{-# LANGUAGE OverloadedLists     #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeOperators       #-}
+
+module Test.Issues.Issue185 (test_issue185)
+  where
+
+import Config
+import ParseArgs
+import Test.Base
+import Test.Framework
+import Test.Framework.Providers.HUnit
+
+import Prelude                                          as P
+import Data.Array.Accelerate                            as A
+import Data.Label
+
+
+test_issue185 :: Config -> Test
+test_issue185 conf = testGroup "185"
+  [ testCase "A" (assertEqual ref1 (run backend acc1 :: Vector Int))
+  , testCase "B" (assertEqual ref2 (run backend acc2 :: Vector Int))
+  , testCase "C" (assertEqual ref3 (run backend acc3 :: Vector Int))
+  , testCase "D" (assertEqual ref4 (run backend acc4 :: Vector Int))
+  , testCase "E" (assertEqual ref5 (run backend acc5 :: Vector Int))
+  , testCase "F" (assertEqual ref6 (run backend acc6 :: Vector Int))
+  ]
+  where
+    backend = get configBackend conf
+
+
+ref1 :: (Elt a, Num a) => Vector a
+ref1 = fromList (Z :. 9) [0,1,4,9,0,4,0,6,2]
+
+acc1 :: (Elt a, IsNum a) => Acc (Vector a)
+acc1 = A.scatter to over xs
+  where
+    over        = use [0, 0, 0, 0, 0, 0, 0, 0, 0]
+    xs          = use [1, 9, 6, 4, 4, 2, 5]
+    to          = use [1, 3, 7, 2, 5, 8]
+
+
+ref2 :: (Elt a, Num a) => Vector a
+ref2 = fromList (Z :. 9) [0,1,0,9,0,0,0,6,0]
+
+acc2 :: (Elt a, IsNum a) => Acc (Vector a)
+acc2 = A.scatter to over xs
+  where
+    over        = use [0, 0, 0, 0, 0, 0, 0, 0, 0]
+    xs          = use [1, 9, 6]
+    to          = use [1, 3, 7, 2, 5, 8]
+
+
+ref3 :: (Elt a, Num a) => Vector a
+ref3 = fromList (Z :. 9) [0,0,0,0,0,4,0,6,2]
+
+acc3 :: (Elt a, IsNum a) => Acc (Vector a)
+acc3 = A.scatterIf to mask p over xs
+  where
+    over        = use [0, 0, 0, 0, 0, 0, 0, 0, 0]
+    to          = use [1, 3, 7, 2, 5, 8]
+    xs          = use [1, 9, 6, 4, 4, 2, 5]
+
+    mask :: Acc (Vector Int32)
+    mask        = use [3, 4, 9, 2, 7, 5]
+    p           = (>* 4)
+
+
+ref4 :: (Elt a, Num a) => Vector a
+ref4 = fromList (Z :. 9) [0,0,0,0,0,0,0,6,0]
+
+acc4 :: (Elt a, IsNum a) => Acc (Vector a)
+acc4 = A.scatterIf to mask p over xs
+  where
+    over        = use [0, 0, 0, 0, 0, 0, 0, 0, 0]
+    to          = use [1, 3, 7, 2, 5, 8]
+    xs          = use [1, 9, 6]
+
+    mask :: Acc (Vector Int32)
+    mask        = use [3, 4, 9, 2, 7, 5]
+    p           = (>* 4)
+
+
+ref5 :: (Elt a, Num a) => Vector a
+ref5 = fromList (Z :. 6) [9,4,1,6,2,4]
+
+acc5 :: (Elt a, IsNum a) => Acc (Vector a)
+acc5 = A.gather from xs
+  where
+    from        = use [1, 3, 7, 2, 5, 3]
+    xs          = use [1, 9, 6, 4, 4, 2, 0, 1, 2]
+
+
+ref6 :: (Elt a, Num a) => Vector a
+ref6 = fromList (Z :. 6) [6,6,1,6,2,4]
+
+acc6 :: (Elt a, IsNum a) => Acc (Vector a)
+acc6 = A.gatherIf from mask p over xs
+  where
+    over        = use [6, 6, 6, 6, 6, 6]
+    from        = use [1, 3, 7, 2, 5, 3]
+    xs          = use [1, 9, 6, 4, 4, 2, 0, 1, 2]
+
+    mask :: Acc (Vector Int32)
+    mask        = use [3, 4, 9, 2, 7, 5]
+    p           = (>* 4)
+
diff --git a/examples/nofib/Test/Issues/Issue187.hs b/examples/nofib/Test/Issues/Issue187.hs
new file mode 100644
--- /dev/null
+++ b/examples/nofib/Test/Issues/Issue187.hs
@@ -0,0 +1,46 @@
+
+module Test.Issues.Issue187 (test_issue187)
+  where
+
+import Config
+import ParseArgs
+import Test.Base
+import Test.Framework
+import Test.Framework.Providers.HUnit
+
+import Prelude                                  as P
+import Data.Array.Accelerate                    as A
+import Data.Label
+
+
+test_issue187 :: Config -> Test
+test_issue187 conf = testGroup "187"
+  [ testCase "A" (assertEqual ref1 $ run backend test1)
+  , testCase "B" (assertEqual ref2 $ run backend test2)
+  ]
+  where
+    backend     = get configBackend conf
+
+
+ref1 :: Scalar Bool
+ref1 = fromList Z [True]
+
+test1 :: Acc (Scalar Bool)
+test1 =
+  let x = constant 1 :: Exp Int
+      v = use (fromList (Z :. 5) [1,2,3,4,5] :: Vector Int)
+      y = (x ==* 1 ||* v A.!! (-1) ==* 1)
+  in generate (constant Z) (const y)
+
+
+ref2 :: Scalar Bool
+ref2 = fromList Z [True]
+
+test2 :: Acc (Scalar Bool)
+test2 =
+  let x  = constant 1 :: Exp Int
+      x' = unit x
+      v  = use (fromList (Z :. 5) [1,2,3,4,5] :: Vector Int)
+      y  = (x ==* the x' ||* let y' = v A.!! (-1) in y'*y' ==* 1)
+  in generate (constant Z) (const y)
+
diff --git a/examples/nofib/Test/Issues/Issue93.hs b/examples/nofib/Test/Issues/Issue93.hs
new file mode 100644
--- /dev/null
+++ b/examples/nofib/Test/Issues/Issue93.hs
@@ -0,0 +1,30 @@
+
+module Test.Issues.Issue93 (test_issue93)
+  where
+
+import Config
+import ParseArgs
+import Test.Base
+import Test.Framework
+import Test.Framework.Providers.HUnit
+
+import Prelude                                  as P
+import Data.Array.Accelerate                    as A
+import Data.Label
+
+
+test_issue93 :: Config -> Test
+test_issue93 conf =
+  testCase "93" (assertEqual xs $ run backend test1)
+  where
+    backend     = get configBackend conf
+
+
+xs :: Array DIM2 Int
+xs = fromList (Z :. 1 :. 1) [5]
+
+test1 :: Acc (Array DIM2 Int)
+test1 = permute (\c _ -> c) (fill (shape xs') (constant 0)) id xs'
+  where
+    xs' = use xs
+
diff --git a/examples/nofib/Test/Prelude/IndexSpace.hs b/examples/nofib/Test/Prelude/IndexSpace.hs
--- a/examples/nofib/Test/Prelude/IndexSpace.hs
+++ b/examples/nofib/Test/Prelude/IndexSpace.hs
@@ -97,13 +97,14 @@
     -- building a histogram. Often tricky for parallel backends.
     --
     test_histogram f g xs =
-      sized $ \n -> run backend (histogramAcc n f xs) ~?= histogramRef n g xs
+      forAll (sized return) $
+        \n -> run backend (histogramAcc n f xs) ~?= histogramRef n g xs
 
     histogramAcc n f xs =
       let n'        = unit (constant n)
           xs'       = use xs
-          zeros     = generate (constant (Z :. n)) (const 0)
-          ones      = generate (shape xs')         (const 1)
+          zeros     = A.generate (constant (Z :. n)) (const 0)
+          ones      = A.generate (shape xs')         (const 1)
       in
       permute (+) zeros (\ix -> index1 $ f (xs' A.! ix) `mod` the n') ones
 
diff --git a/examples/nofib/Test/Prelude/PrefixSum.hs b/examples/nofib/Test/Prelude/PrefixSum.hs
--- a/examples/nofib/Test/Prelude/PrefixSum.hs
+++ b/examples/nofib/Test/Prelude/PrefixSum.hs
@@ -65,30 +65,36 @@
     -- left scan
     --
     test_scanl  xs = run backend (A.scanl (+) 0 (use xs))           ~?= scanlRef (+) 0 xs
-    test_scanl1 xs = run backend (A.scanl1 min (use xs))            ~?= scanl1Ref min xs
     test_scanl' xs = run backend (A.lift $ A.scanl' (+) 0 (use xs)) ~?= scanl'Ref (+) 0 xs
+    test_scanl1 xs =
+      arraySize (arrayShape xs) > 0 ==>
+        run backend (A.scanl1 min (use xs)) ~?= scanl1Ref min xs
 
     -- right scan
     --
     test_scanr  xs = run backend (A.scanr (+) 0 (use xs))           ~?= scanrRef (+) 0 xs
-    test_scanr1 xs = run backend (A.scanr1 max (use xs))            ~?= scanr1Ref max xs
     test_scanr' xs = run backend (A.lift $ A.scanr' (+) 0 (use xs)) ~?= scanr'Ref (+) 0 xs
+    test_scanr1 xs =
+      arraySize (arrayShape xs) > 0 ==>
+      run backend (A.scanr1 max (use xs)) ~?= scanr1Ref max xs
 
     -- segmented left/right scan
     --
     test_scanl1seg elt =
       forAll arbitrarySegments1            $ \(seg :: Vector Int32) ->
       forAll (arbitrarySegmentedArray seg) $ \xs  ->
-        run backend (A.scanl1Seg (+) (use xs) (use seg))
-        ~?=
-        scanl1SegRef (+) (xs `asTypeOf` elt) seg
+        arraySize (arrayShape xs) > 0 ==>
+          run backend (A.scanl1Seg (+) (use xs) (use seg))
+          ~?=
+          scanl1SegRef (+) (xs `asTypeOf` elt) seg
 
     test_scanr1seg elt =
       forAll arbitrarySegments1            $ \(seg :: Vector Int32) ->
       forAll (arbitrarySegmentedArray seg) $ \xs  ->
-        run backend (A.scanr1Seg (+) (use xs) (use seg))
-        ~?=
-        scanr1SegRef (+) (xs `asTypeOf` elt) seg
+        arraySize (arrayShape xs) > 0 ==>
+          run backend (A.scanr1Seg (+) (use xs) (use seg))
+          ~?=
+          scanr1SegRef (+) (xs `asTypeOf` elt) seg
 
     test_scanlseg elt =
       forAll arbitrarySegments             $ \(seg :: Vector Int32) ->
diff --git a/examples/nofib/Test/Prelude/Stencil.hs b/examples/nofib/Test/Prelude/Stencil.hs
--- a/examples/nofib/Test/Prelude/Stencil.hs
+++ b/examples/nofib/Test/Prelude/Stencil.hs
@@ -14,8 +14,10 @@
 import Data.Maybe
 import Data.Typeable
 import Test.QuickCheck
+import Test.HUnit                                       ((@?=))
 import Test.Framework
 import Test.Framework.Providers.QuickCheck2
+import Test.Framework.Providers.HUnit
 
 import Config
 import ParseArgs
@@ -49,6 +51,7 @@
   , testElt configWord64 (undefined :: Word64)
   , testElt configFloat  (undefined :: Float)
   , testElt configDouble (undefined :: Double)
+  , testBoundary
   ]
   where
     backend = get configBackend opt
@@ -160,6 +163,15 @@
           in
           stencil2DRef pattern' constant xs
 
+    -- If the constant boundary is not properly implemented,
+    -- then this will lead to a segmentation fault.
+    testBoundary :: Maybe Test
+    testBoundary = Just . testCase "boundary segfault" $ do
+      let f ((x,_,_,_,_),_,_,_,_) = x
+          b = Constant 0
+          s = stencil (f::Stencil5x5 Int -> Exp Int) b (A.fill (lift (Z:.1:.1000000 :: DIM2)) (0::Exp Int))
+          a = run backend s
+      indexArray a (Z:.0:.0) @?= 0
 
 --
 -- Reference implementation
diff --git a/examples/nofib/Test/Sharing.hs b/examples/nofib/Test/Sharing.hs
--- a/examples/nofib/Test/Sharing.hs
+++ b/examples/nofib/Test/Sharing.hs
@@ -36,7 +36,7 @@
     where
       sharing :: Show a => TestName -> a -> Test
       sharing name acc =
-        testCase name (length (show acc) `seq` return ())
+        testCase name (P.length (show acc) `seq` return ())
 
 
 
@@ -229,7 +229,7 @@
   ]
   where
     iter :: Show a => TestName -> a -> Test
-    iter name acc = testCase name (length (show acc) `seq` return ())
+    iter name acc = testCase name (P.length (show acc) `seq` return ())
 
     vec :: Acc (Vector Float)
     vec = use $ fromList (Z:.10) [0..]
diff --git a/examples/nofib/Test/Spectral/BlackScholes.hs b/examples/nofib/Test/Spectral/BlackScholes.hs
--- a/examples/nofib/Test/Spectral/BlackScholes.hs
+++ b/examples/nofib/Test/Spectral/BlackScholes.hs
@@ -15,7 +15,6 @@
 import Data.Maybe
 import Data.Typeable
 import Test.QuickCheck
-import Test.QuickCheck.Property                                 ( morallyDubiousIOProperty )
 import Test.Framework
 import Test.Framework.Providers.QuickCheck2
 import Foreign.Ptr
@@ -55,10 +54,12 @@
 
     run_blackscholes :: forall a. ( Elt a, IsFloating a, Similar a, Storable a, Random a, Arbitrary a
                                   , BlockPtrs (EltRepr a) ~ ((), Ptr a), BlockPtrs (EltRepr' a) ~ Ptr a)
-                     => BlackScholes a -> Property
-    run_blackscholes cfun = sized $ \nmax ->
+                     => BlackScholes a
+                     -> Property
+    run_blackscholes cfun =
+      forAll (sized return)                     $ \nmax ->
       forAll (choose (0,nmax))                  $ \n ->
-      forAll (arbitraryArrayOf (Z:.n) opts)     $ \psy -> morallyDubiousIOProperty $ do
+      forAll (arbitraryArrayOf (Z:.n) opts)     $ \psy -> ioProperty $ do
         let actual = run1 backend blackscholes psy
         expected  <- blackScholesRef cfun psy
         return     $ expected ~?= actual
diff --git a/examples/nofib/Test/Spectral/RadixSort.hs b/examples/nofib/Test/Spectral/RadixSort.hs
--- a/examples/nofib/Test/Spectral/RadixSort.hs
+++ b/examples/nofib/Test/Spectral/RadixSort.hs
@@ -78,12 +78,12 @@
 
 #define signed(ty)                                                             \
 instance Radix ty where ;                                                      \
-  passes = bitSize ;                                                           \
+  passes = finiteBitSize ;                                                     \
   radix  = radixOfSigned ;
 
 #define unsigned(ty)                                                           \
 instance Radix ty where ;                                                      \
-  passes = bitSize ;                                                           \
+  passes = finiteBitSize ;                                                     \
   radix  = radixOfUnsigned ;
 
 signed(Int)
diff --git a/examples/pagerank/Config.hs b/examples/pagerank/Config.hs
new file mode 100644
--- /dev/null
+++ b/examples/pagerank/Config.hs
@@ -0,0 +1,56 @@
+{-# LANGUAGE CPP             #-}
+{-# LANGUAGE TemplateHaskell #-}
+
+module Config where
+
+import ParseArgs
+import Data.Label
+
+data Options = Options
+  {
+    _optBackend         :: Backend
+  , _optSteps           :: Int
+  , _optChunkSize       :: Int
+  , _optCount           :: Bool
+  , _optHelp            :: Bool
+  }
+  deriving Show
+
+$(mkLabels [''Options])
+
+defaults :: Options
+defaults = Options
+  { _optBackend         = maxBound
+  , _optSteps           = 10
+  , _optChunkSize       = 12000000
+  , _optCount           = False
+  , _optHelp            = False
+  }
+
+
+options :: [OptDescr (Options -> Options)]
+options =
+  [ Option []   ["steps"]       (ReqArg (set optSteps . read) "INT")     "number of steps to perform"
+  , Option []   ["chunk-size"]  (ReqArg (set optChunkSize . read) "INT") "size of chunks to be processed"
+  , Option []   ["count"]       (NoArg  (set optCount True))             "count number of pages in the links file"
+  , Option "h?" ["help"]        (NoArg  (set optHelp True))              "show help message"
+  ]
+
+
+header :: [String]
+header =
+  [ "accelerate-pagerank (c) [2011..2013] The Accelerate Team"
+  , ""
+  , "Usage: accelerate-pagerank [OPTIONS] <LINKS_FILE> <TITLES_FILE> [+RTS -M<HEAP_SIZE>]"
+  , ""
+  , "  NOTE: The -M flag sets the Haskell heap size. If high performance is"
+  , "        desired, then this value, as well as the chunk size, will need to"
+  , "        be adjusted. The idea being to maximise the chunk size without"
+  , "        running out of device memory. With experimentation, you can arrive"
+  , "        at a heap size that will force garbage collection before device"
+  , "        memory runs out."
+  ]
+
+footer :: [String]
+footer = []
+
diff --git a/examples/pagerank/Count.hs b/examples/pagerank/Count.hs
new file mode 100644
--- /dev/null
+++ b/examples/pagerank/Count.hs
@@ -0,0 +1,30 @@
+{-# LANGUAGE BangPatterns #-}
+module Count where
+import Progress
+import qualified Data.ByteString.Lazy.Char8     as BL
+
+
+-- | Get the maximum page number in the file,
+--   and count the total number of lines.
+countPages :: FilePath -> IO (Int, Int)
+countPages !filePath
+ = do   putStrLn $ "* Counting pages in file."
+        bs                     <- BL.readFile filePath
+        (lineCount, maxPageId) <- eat 0 0 (BL.lines bs)
+        printPosition True "  lines read : " 10000 lineCount
+        putStrLn $ "  max page id: " ++ padR 10 (show maxPageId)
+        return (lineCount, maxPageId)
+
+ where  eat !lineCount !maxPageId []
+         = return (lineCount, maxPageId)
+
+        eat !lineCount !maxPageId (l:ls)
+         = case BL.readInt l of
+            Nothing
+             -> error $ "countPages: parse error on line " ++ show lineCount
+
+            Just (pid', _)
+             -> do let !maxPageId' = max pid' maxPageId
+                   printPosition False "  lines read : " 10000 lineCount
+                   eat (lineCount + 1) maxPageId' ls
+
diff --git a/examples/pagerank/Load.hs b/examples/pagerank/Load.hs
new file mode 100644
--- /dev/null
+++ b/examples/pagerank/Load.hs
@@ -0,0 +1,57 @@
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE BangPatterns    #-}
+{-# LANGUAGE PatternGuards   #-}
+module Load where
+
+import Page
+import Progress
+
+import qualified Data.ByteString.Lazy.Char8      as BL
+import qualified Data.Vector.Storable.Mutable    as VM
+import qualified Data.Vector.Storable            as V
+
+
+-- | Load the whole page graph into memory.
+loadPages
+        :: FilePath             -- ^ Pages file.
+        -> PageId               -- ^ Maximum page number
+        -> IO ( V.Vector PageId -- ^ From vector
+              , V.Vector PageId -- ^ To vector
+              , V.Vector Int    -- ^ Degrees (number of outgoing links) for each page
+              )
+
+loadPages filePath maxPageId
+ = do
+        -- Lazilly read the pages files.
+        bs              <- BL.readFile filePath
+
+        -- Create an initial vector to hold the pages.
+        -- We'll grow this as we read more pages.
+        let bufSize     = 100000
+        from            <- VM.new bufSize
+        to              <- VM.new bufSize
+        sizes           <- VM.new (fromIntegral maxPageId +1)
+        go (MLinks 0 bufSize from to sizes) 0 (BL.lines bs)
+
+ where  go links@(MLinks{..}) !ixLine ls
+         -- We've read all the lines.
+         -- Slice out the pages we read from the buffer.
+         | []       <- ls
+         = do   printPosition True "  lines read : " 10000 ixLine
+                from'  <- V.freeze (VM.slice 0 ix from)
+                to'    <- V.freeze (VM.slice 0 ix to)
+                sizes' <- V.freeze sizes
+
+                return (from', to', sizes')
+
+         -- Handle a new line from the file.
+         | l : rest <- ls
+         = do   -- Print how far along we are.
+                printPosition False "  lines read : " 10000 ixLine
+
+                -- Parse the page and add it to the buffer.
+                Just links' <- parsePage l links
+                go links' (ixLine+1) rest
+
+
+
diff --git a/examples/pagerank/Main.hs b/examples/pagerank/Main.hs
new file mode 100644
--- /dev/null
+++ b/examples/pagerank/Main.hs
@@ -0,0 +1,25 @@
+{-# LANGUAGE PatternGuards #-}
+
+-- An implementation of PageRank based off of Ben Lippmeier's Repa implementation (http://repa.ouroborus.net/).
+--
+
+import Config
+import ParseArgs
+import Count
+import Rank
+import Data.Label                 ( get )
+import System.Environment
+import System.Exit
+import Data.Char
+import Control.Monad
+
+
+main :: IO ()
+main
+ = do   argv    <- getArgs
+        (config, _, linksPath : titlesPath : _)  <- parseArgs optHelp optBackend options defaults header footer argv
+
+        if get optCount config
+          then void (countPages linksPath)
+          else rank (get optBackend config) (get optSteps config) (get optChunkSize config) linksPath titlesPath
+
diff --git a/examples/pagerank/Page.hs b/examples/pagerank/Page.hs
new file mode 100644
--- /dev/null
+++ b/examples/pagerank/Page.hs
@@ -0,0 +1,101 @@
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE PatternGuards   #-}
+module Page
+        ( PageId
+        , Rank
+        , Link
+        , MLinks(..)
+        , parsePage
+        , parsePageId)
+where
+import Prelude                                   as P
+import qualified Data.ByteString.Lazy.Char8      as BL
+import qualified Data.Vector.Storable            as U
+import qualified Data.Vector.Storable.Mutable    as UM
+import Control.Monad.ST
+import Data.Word
+
+
+-- | Unique identifier for a page.
+type PageId
+        = Word32
+
+
+-- | Represents a link in the page raph.
+type Link
+        = (PageId, PageId)
+
+
+-- | A single PageRank value.
+type Rank
+        = Float
+
+-- | A mutable set of links
+data MLinks = MLinks { ix    :: Int
+                     , size  :: Int
+                     , from  :: (UM.IOVector PageId)
+                     , to    :: (UM.IOVector PageId)
+                     , sizes :: UM.IOVector Int }
+
+
+-- | Parse just the PageId from a line in the links file.
+parsePageId :: BL.ByteString -> Maybe PageId
+parsePageId bs
+        | Just (pid, _)         <- BL.readInt bs
+        = Just $ fromIntegral pid
+
+        | otherwise
+        = Nothing
+
+
+-- | Parse a whole line of the links file.
+parsePage :: BL.ByteString -> MLinks -> IO (Maybe MLinks)
+parsePage bs links
+        | Just (pid, bs2)       <- BL.readInt bs
+        , Just bs3              <- char ':' bs2
+        = do
+             links'             <- pageIds (fromIntegral pid) bs3 links
+             return (Just links')
+
+        | otherwise
+        = return Nothing
+
+
+-- | Parse a single character.
+char   :: Char -> BL.ByteString -> Maybe BL.ByteString
+char c bs
+ | BL.null bs           = Nothing
+ | BL.head bs == c      = Just (BL.tail bs)
+ | otherwise            = Nothing
+{-# INLINE char #-}
+
+
+-- | Parse a vector of PageIds.
+pageIds    :: PageId -> BL.ByteString -> MLinks -> IO (MLinks)
+pageIds pid bs0 links
+ = go links 0 bs0
+
+ where  go links@(MLinks{..}) count bs
+         | ix >= size
+         = do   from'  <- UM.grow from size
+                to'    <- UM.grow to   size
+                go (MLinks ix (2*size) from' to' sizes) count bs
+
+         | BL.null bs
+         = final
+
+         | Just bs2     <- char ' ' bs
+         = go links count bs2
+
+         | Just (i, bs2) <- BL.readInt bs
+         = do   UM.write from ix pid
+                UM.write to ix (fromIntegral i)
+                go (MLinks (ix+1) size from to sizes) (count+1) bs2
+
+         | otherwise
+         = final
+         where
+            final =
+                do
+                    UM.write sizes (fromIntegral pid) count
+                    return links
diff --git a/examples/pagerank/Progress.hs b/examples/pagerank/Progress.hs
new file mode 100644
--- /dev/null
+++ b/examples/pagerank/Progress.hs
@@ -0,0 +1,58 @@
+
+module Progress 
+        ( printPosition
+        , printProgress
+        , padR
+        , padL)
+where
+import System.IO
+import Control.Monad
+
+
+-- | Print position in a stream, without a maximum value.
+printPosition :: Bool -> String -> Int -> Int -> IO ()
+printPosition isLast header block pos
+ | pos == 0
+ = do   putStr $ header ++ padR 10 (show pos)
+        hFlush stdout
+
+ | pos `mod` block == 0 || isLast
+ = do   putStr $ replicate (length header + 10) '\b'
+        putStr $ header ++ padR 10 (show pos)
+        when isLast
+         $ putStr "\n"
+        hFlush stdout
+
+ | otherwise
+ =      return ()
+
+
+-- | Print progress in a stream towards a maximum value.
+printProgress :: String -> Int -> Int -> Int -> IO ()
+printProgress header block pos len
+ | pos == 0
+ = do   putStr $ header ++ padR 10 (show $ pos) ++ "/" ++ padR 10 (show len)
+        hFlush stdout
+
+ |   pos `mod` block == 0 || pos == len
+ = do   let n   = length header + 21
+        putStr  $ replicate n '\b'
+        putStr $ header ++ padR 10 (show $ pos) ++ "/" ++ padR 10 (show len)
+        when (pos == len)
+         $ putStr "\n"
+        hFlush stdout
+
+ | otherwise
+ =      return ()
+
+
+-- | Pretty print in a right-justified column.
+padR :: Int -> String -> String
+padR n str
+ = replicate (n - length str) ' ' ++ str
+
+
+-- | Pretty print in a left-justified column.
+padL :: Int -> String -> String
+padL n str
+ = str ++ replicate (n - length str) ' '
diff --git a/examples/pagerank/Rank.hs b/examples/pagerank/Rank.hs
new file mode 100644
--- /dev/null
+++ b/examples/pagerank/Rank.hs
@@ -0,0 +1,125 @@
+{-# LANGUAGE BangPatterns #-}
+module Rank
+        (rank)
+where
+import Load
+import Step
+import Count
+import Page
+import ParseArgs
+import System.Directory
+import Control.Monad
+import Prelude                                  as P
+import Data.Array.Accelerate                    as A
+import Data.Array.Accelerate.IO                 as A
+import qualified Data.Vector                    as V
+import qualified Data.Vector.Storable           as S
+import System.CPUTime
+
+
+-- | Perform some iterations of the PageRank algorithm by loading the whole
+--   links graph into memory and passes it off in chunks to Accelerate to
+--   avoid running out of device memory.
+rank
+    :: Backend
+    -> Int                  -- ^ Number of iterations to run.
+    -> Int                  -- ^ Size of chunk.
+    -> FilePath             -- ^ Path to links file.
+    -> FilePath             -- ^ Path to titles file.
+    -> IO ()
+
+rank backend steps chunkSize pagesPath titlesPath
+ = do   (_, maxPageId) <- countPages pagesPath
+        putStrLn "* Loading pages."
+        (!from, !to, !sizes) <- loadPages pagesPath (P.fromIntegral maxPageId)
+        let pageCount   = S.length sizes
+        let !ranks      = initialRanks backend pageCount
+        start <- getCPUTime
+        pageRank backend steps chunkSize pageCount (from, to) (A.fromVectors (Z:.pageCount) ((), sizes)) titlesPath ranks
+        end   <- getCPUTime
+        putStrLn $ "Time taken: " P.++ show (P.fromIntegral (end - start) / (10^12)) P.++ " secs"
+        return ()
+
+
+-- | Construct the initial ranks vector.
+initialRanks :: Backend -> Int -> A.Vector Rank
+initialRanks backend pageCount
+ = let  !startRank   = 1 / P.fromIntegral pageCount
+   in   run backend $ A.fill (index1 (A.lift pageCount)) startRank
+
+
+-- | Run several iterations of the internal PageRank algorithm.
+pageRank
+        :: Backend
+        -> Int                  -- ^ Number of iterations to run.
+        -> Int                  -- ^ Chunk size
+        -> Int                  -- ^ Number of pages
+        -> (S.Vector PageId, S.Vector PageId)            -- ^ Pages graph.
+        -> A.Vector Int         -- ^ The degree of each page
+        -> FilePath             -- ^ Path to titles file.
+        -> A.Vector Rank        -- ^ Initial ranks.
+        -> IO ()
+
+pageRank backend maxIters chunkSize pageCount (from, to) sizes titlesFile ranks0
+ = go maxIters ranks0
+ where  go 0 !ranks
+         = do   -- Show the page with the maximum rank.
+                let !rankMaxIx   = maxIndex ranks
+                let !rankMax     = indexArray ranks (Z:.indexArray rankMaxIx Z)
+                putStrLn $ "  high ix    : "  P.++ show rankMaxIx
+                putStrLn $ "  high rank  : "  P.++ show rankMax
+
+                return ()
+
+        go !i !ranks
+         = do   putStr "\n"
+                putStrLn $ "* Step " P.++ show i
+
+                -- Run a step of the algorithm.
+                let !ranks1 = stepInChunks ranks zeroes 0
+                let !ranks2 = addDangles (ranks, sizes)
+
+                -- Sum up the ranks for all the pages,
+                -- this should be very close to 1, minus some some round-off error.
+                let !rankSum     = sum ranks2
+                putStrLn $ "  rank sum   : "  P.++ show rankSum
+
+                go (i - 1) ranks2
+
+        stepInChunks !ranks !parRanks !start
+          | start >= edgeCount
+          = parRanks
+          | otherwise
+          = let end     = P.min (start + chunkSize) edgeCount
+                from'   = S.slice start (end - start) from
+                to'     = S.slice start (end - start) to
+                !pages  = A.fromVectors (Z:.(end - start)) (((), from'), to')
+                !parRanks1 = step (pages, sizes, ranks, parRanks)
+            in stepInChunks ranks parRanks1 (start + chunkSize)
+
+        -- Add to the rank the score due to dangling vectors.
+        addDangles :: (Vector Rank, Vector Int) -> Vector Rank
+        addDangles = run1 backend $ A.uncurry $ \ranks sizes -> let
+
+            dangleScore = A.fold (+) 0 (A.zipWith d ranks sizes)
+
+            dangleContrib :: Acc (Scalar Rank)
+            dangleContrib = A.unit (the dangleScore / (A.lift (P.fromIntegral pageCount :: Float)))
+
+            d r s = s ==* 0 ? (r, 0)
+
+          in A.map (+ A.the dangleContrib) ranks
+
+        edgeCount = S.length from
+
+        zeroes :: Vector Rank
+        zeroes = run backend $ A.fill (A.lift $ Z :. pageCount) 0
+
+        step :: (PageGraph, Vector Int, Vector Rank, Vector Rank) -> Vector Rank
+        step = run1 backend $ (\t -> let (p,s,r,pr) = unlift t in stepRank p s r pr)
+
+        sum = run1 backend A.sum
+
+        -- Computer the index of the maximum rank.
+        maxIndex :: A.Vector Rank -> A.Scalar Int
+        maxIndex = run1 backend $ (\ranks -> A.fold (\x y -> ranks ! index1 x >* ranks ! index1 y ? (x,y)) 0 (A.enumFromN (A.shape ranks) 0))
diff --git a/examples/pagerank/Step.hs b/examples/pagerank/Step.hs
new file mode 100644
--- /dev/null
+++ b/examples/pagerank/Step.hs
@@ -0,0 +1,37 @@
+
+module Step
+        (stepRank, PageGraph)
+where
+import Page
+import Progress
+import Control.Monad
+import Data.IORef
+import Data.Array.Accelerate as A
+
+
+type PageGraph = Vector Link
+
+
+-- | Perform one iteration step for the internal Page Rank algorithm.
+stepRank
+        :: Acc PageGraph       -- ^ Part of the pages graph.
+        -> Acc (Vector Int)    -- ^ Number of outgoing links for each page.
+        -> Acc (Vector Rank)   -- ^ Old ranks vector.
+        -> Acc (Vector Rank)   -- ^ Partial ranks vector
+        -> Acc (Vector Rank)   -- ^ New ranks vector.
+
+stepRank links sizes ranks parRanks
+ = let
+        pageCount  = A.size sizes
+
+        -- For every link supplied, calculate it's contribution to the page it points to.
+        contribution :: Acc (Vector Float)
+        contribution = A.generate (A.shape links)
+                                  (\ix -> let (from, _) = unlift $ links ! ix :: (Exp PageId, Exp PageId)
+                                          in ranks ! index1 (A.fromIntegral from) / A.fromIntegral (sizes ! index1 (A.fromIntegral from)))
+
+        -- Add to the partial ranks the contribution of the supplied links.
+        ranks' = A.permute (+) parRanks (\ix -> let (_, to) = unlift $ links ! ix :: (Exp PageId, Exp PageId)
+                                              in index1 (A.fromIntegral to)) contribution
+        in ranks'
+
diff --git a/examples/ray/Config.hs b/examples/ray/Config.hs
new file mode 100644
--- /dev/null
+++ b/examples/ray/Config.hs
@@ -0,0 +1,72 @@
+{-# LANGUAGE CPP             #-}
+{-# LANGUAGE TemplateHaskell #-}
+
+module Config where
+
+import ParseArgs
+import Data.Label
+
+data Options = Options
+  {
+    _optBackend         :: Backend
+  , _optWidth           :: Int
+  , _optHeight          :: Int
+  , _optZoom            :: Int
+  , _optFieldOfView     :: Int
+  , _optBounces         :: Int
+  , _optFramerate       :: Int
+  , _optBench           :: Bool
+  , _optHelp            :: Bool
+  }
+  deriving Show
+
+$(mkLabels [''Options])
+
+defaults :: Options
+defaults = Options
+  { _optBackend         = maxBound
+  , _optWidth           = 800
+  , _optHeight          = 600
+  , _optFieldOfView     = 100
+  , _optZoom            = 1
+  , _optBounces         = 4
+  , _optFramerate       = 30
+#ifdef ACCELERATE_ENABLE_GUI
+  , _optBench           = False
+#else
+  , _optBench           = True
+#endif
+  , _optHelp            = False
+  }
+
+
+options :: [OptDescr (Options -> Options)]
+options =
+  [ Option []   ["width"]       (ReqArg (set optWidth . read) "INT")            (describe optWidth "visualisation width")
+  , Option []   ["height"]      (ReqArg (set optHeight . read) "INT")           (describe optHeight "visualisation height")
+  , Option []   ["zoom"]        (ReqArg (set optZoom . read) "INT")             (describe optZoom "pixel replication factor")
+  , Option []   ["fov"]         (ReqArg (set optFieldOfView . read) "INT")      (describe optFieldOfView "field of view")
+  , Option []   ["bounces"]     (ReqArg (set optBounces . read) "INT")          (describe optBounces "ray bounce limit")
+  , Option []   ["fps"]         (ReqArg (set optFramerate . read) "INT")        (describe optFramerate "frames per second")
+  , Option []   ["benchmark"]   (NoArg  (set optBench True))                    "benchmark instead of displaying animation"
+  , Option "h?" ["help"]        (NoArg  (set optHelp True))                     "show help message"
+  ]
+  where
+    describe f msg      = msg ++ " (" ++ show (get f defaults) ++ ")"
+
+header :: [String]
+header =
+  [ "accelerate-ray (c) [2013] The Accelerate Team"
+  , ""
+  , "Usage: accelerate-ray [OPTIONS]"
+  , ""
+  ]
+
+footer :: [String]
+footer =
+  [ ""
+  , "Runtime usage:"
+  , "     WASD         move the eye position"
+  , "     arrows       move the light source"
+  ]
+
diff --git a/examples/ray/Gloss/Draw.hs b/examples/ray/Gloss/Draw.hs
new file mode 100644
--- /dev/null
+++ b/examples/ray/Gloss/Draw.hs
@@ -0,0 +1,64 @@
+
+module Gloss.Draw
+  where
+
+-- friends
+import Vec3
+import Scene.Light
+import Scene.Object
+import Scene.State
+import Ray.Trace
+
+-- frenemies
+import Data.Array.Accelerate                                    as A
+import Graphics.Gloss.Accelerate.Data.Color.RGB
+import qualified Graphics.Gloss.Accelerate.Raster.Field         as G
+
+--library
+import Prelude                                                  as P
+import Data.Label                                               ( get )
+
+
+-- | Prepare the state for rendering
+--
+prepareState :: State -> (Objects, Lights, Scalar Position)
+prepareState state
+  = let
+        objects         = get stateObjects state
+        lights          = get stateLights  state
+        eyePos          = fromList Z [get stateEyePos state]
+    in
+    (objects, lights, eyePos)
+
+
+-- | Render a single pixel of the image
+--
+tracePixel
+    :: Int
+    -> Int
+    -> Int
+    -> Int
+    -> Exp Color
+    -> Acc (Objects, Lights, Scalar Position)
+    -> Exp G.Point
+    -> Exp G.Color
+tracePixel sizeX sizeY fov bounces ambient state point
+  = let
+        sizeX'          = P.fromIntegral sizeX
+        sizeY'          = P.fromIntegral sizeY
+        aspect          = sizeX' / sizeY'
+        fov'            = P.fromIntegral fov
+        fovX            = fov' * aspect
+        fovY            = fov'
+
+        (x,y)           = G.xyOfPoint point
+
+        eyeDir          = normalise $ makeVec3 (x * fovX) ((-y) * fovY) 0 - eyePos
+        eyePos          = the eyePos'
+        (objects, lights, eyePos')
+                        = unlift state
+
+        (r,g,b)         = rgbOfColor $ traceRay bounces objects lights ambient eyePos eyeDir
+    in
+    G.rawColor r g b 1
+
diff --git a/examples/ray/Gloss/Event.hs b/examples/ray/Gloss/Event.hs
new file mode 100644
--- /dev/null
+++ b/examples/ray/Gloss/Event.hs
@@ -0,0 +1,59 @@
+{-# LANGUAGE PatternGuards #-}
+
+module Gloss.Event
+  where
+
+-- friends
+import Vec3
+import Scene.State
+
+-- library
+import Data.Char
+import Data.Label
+import Graphics.Gloss.Interface.Pure.Game                       as G
+
+
+handleEvent :: Event -> State -> State
+handleEvent event state
+  = case event of
+      EventKey (Char c) s _ _           -> char (toLower c) s state
+      EventKey (SpecialKey c) s _ _     -> special c s state
+      EventKey (MouseButton b) s _ l    -> click b l s state
+      EventMotion p                     -> motion p
+      _                                 -> state
+  where
+    toggle f x Down     = set f (Just x)
+    toggle f _ Up       = set f Nothing
+
+    char 'w'            = toggle stateEyeVert Fwd
+    char ','            = toggle stateEyeVert Fwd
+    char 's'            = toggle stateEyeVert Rev
+    char 'o'            = toggle stateEyeVert Rev
+    char 'a'            = toggle stateEyeHoriz Rev
+    char 'd'            = toggle stateEyeHoriz Fwd
+    char 'e'            = toggle stateEyeHoriz Fwd
+    char _              = const id
+
+    click LeftButton    = toggle stateLeftClick
+    click _             = const (const id)
+
+    special KeyUp       = toggle stateLightVert Fwd
+    special KeyDown     = toggle stateLightVert Rev
+    special KeyRight    = toggle stateLightHoriz Fwd
+    special KeyLeft     = toggle stateLightHoriz Rev
+    special _           = const id
+
+    motion (x,y)
+      | Just (oX, oY)           <- get stateLeftClick state
+      , XYZ eyeX eyeY eyeZ      <- get stateEyeDelta  state
+      = let eyeX'       = eyeX + (x - oX)
+            eyeY'       = eyeY
+            eyeZ'       = eyeZ + (y - oY)
+        in
+        set stateEyeDelta (XYZ eyeX' eyeY' eyeZ')
+          $ set stateLeftClick  (Just (x, y))
+          $ state
+
+    motion _
+      = state
+
diff --git a/examples/ray/Main.hs b/examples/ray/Main.hs
new file mode 100644
--- /dev/null
+++ b/examples/ray/Main.hs
@@ -0,0 +1,70 @@
+{-# LANGUAGE CPP #-}
+
+module Main where
+
+-- friends
+import Config
+import ParseArgs
+import Monitoring
+import Scene.State
+import Gloss.Draw
+import Gloss.Event
+import Ray.Trace
+
+-- frenemies
+import Data.Label
+import Data.Array.Accelerate                                    as A
+import Graphics.Gloss.Accelerate.Data.Color.RGB
+import qualified Graphics.Gloss.Accelerate.Raster.Field         as G
+
+-- library
+import Criterion.Main                                           ( defaultMainWith, bench, whnf )
+import System.Environment                                       ( getArgs, withArgs )
+
+
+main :: IO ()
+main = do
+  beginMonitoring
+  argv                  <- getArgs
+  (conf, cconf, rest)   <- parseArgs optHelp optBackend options defaults header footer argv
+
+  let width     = get optWidth conf
+      height    = get optHeight conf
+      zoom      = get optZoom conf
+      fov       = get optFieldOfView conf
+      bounces   = get optBounces conf
+      backend   = get optBackend conf
+      fps       = get optFramerate conf
+      state     = initState 0
+      ambient   = rawColor 0.3 0.3 0.3
+
+      scene st
+        = let eye               = constant (get stateEyePos state)
+              eyeDir            = castViewRays width height fov eye
+              eyePos            = fill (constant (Z :. height :. width)) eye
+              (objects, lights) = unlift st
+          in
+          A.zipWith (traceRay bounces objects lights ambient) eyePos eyeDir
+
+  if get optBench conf
+     then withArgs rest
+        $ defaultMainWith cconf (return ())
+        [ bench "ray" $ whnf (run1 backend scene)
+                             (get stateObjects state, get stateLights state)
+        ]
+
+#ifndef ACCELERATE_ENABLE_GUI
+     else return ()
+#else
+     else G.playFieldWith
+            (run1 backend)
+            (G.InWindow "Ray" (width, height) (10, 10))
+            (zoom, zoom)
+            fps
+            state
+            prepareState
+            (tracePixel width height fov bounces ambient)
+            handleEvent
+            advanceState
+#endif
+
diff --git a/examples/ray/Ray/Intersect.hs b/examples/ray/Ray/Intersect.hs
new file mode 100644
--- /dev/null
+++ b/examples/ray/Ray/Intersect.hs
@@ -0,0 +1,80 @@
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeOperators       #-}
+
+module Ray.Intersect
+  where
+
+-- friends
+import Vec3
+import Scene.Object
+
+-- frenemies
+import Data.Array.Accelerate                                    as A
+
+-- standard library
+import Prelude                                                  as P
+
+
+-- | Of two intersection tests, take the nearest.
+--
+nearest :: forall a. Elt a
+        => Exp (Bool, Float, a)
+        -> Exp (Bool, Float, a)
+        -> Exp (Bool, Float, a)
+nearest x y
+  = let
+        (h1, d1, _ :: Exp a) = unlift x
+        (h2, d2, _ :: Exp a) = unlift y
+    in
+    h1 &&* h2 ? ( d1 <* d2 ? (x, y)     -- both objects intersect; take the nearest
+                , h1 ?       (x, y) )   -- only one object intersects
+
+
+-- | Find the nearest point of intersection for a ray. If there is a hit, then
+-- return the origin and normal of the new reflected ray, as well as the colour
+-- and shine of the surface that was hit.
+--
+-- This tests all objects for each ray and just takes the minimum. To scale to
+-- larger scenes, this should use a spatial decomposition technique like a
+-- bounding volume hierarchy to reduce the search space.
+--
+-- https://developer.nvidia.com/content/thinking-parallel-part-ii-tree-traversal-gpu
+--
+-- https://developer.nvidia.com/content/thinking-parallel-part-iii-tree-construction-gpu
+--
+castRay
+    :: forall object. Elt object
+    => (Exp object -> Exp Position -> Exp Direction -> Exp (Bool, Float))
+    -> Exp object                       -- dummy object (because we have no Maybe types)
+    -> Acc (Vector object)              -- objects to test
+    -> Exp Position                     -- ray origin
+    -> Exp Direction                    -- ray direction
+    -> Exp (Bool, Float, object)
+castRay distanceTo  dummy objects orig dir
+  = sfoldl (\s o -> let (_,   dist, _)  = unlift s      :: (Exp Bool, Exp Float, Exp object)
+                        (hit, dist')    = unlift $ distanceTo o orig dir
+                    in
+                    hit &&* dist' <* dist ? (lift (hit, dist', o), s))
+           (lift (False, infinity, dummy))
+           (constant Z)
+           objects
+
+
+-- | Check where there is some object closer than a given minimum distance. We
+--   stop as soon as there is an intersection.
+--
+checkRay
+    :: Elt object
+    => (Exp object -> Exp Position -> Exp Direction -> Exp (Bool, Float))
+    -> Acc (Vector object)              -- objects to test
+    -> Exp Position                     -- ray origin
+    -> Exp Direction                    -- ray direction
+    -> Exp Float                        -- minimum distance
+    -> Exp Bool
+checkRay distanceTo objs orig dir dist
+  = A.fst $ A.while (\s -> let (hit, i) = unlift s in A.not hit &&* i <* unindex1 (shape objs))
+                    (\s -> let i            = A.snd s
+                               (hit, dist') = unlift $ distanceTo (objs ! index1 i) orig dir
+                           in  hit &&* dist' <* dist ? (lift (True, i), lift (False, i+1)))
+                    (constant (False, 0))
+
diff --git a/examples/ray/Ray/Trace.hs b/examples/ray/Ray/Trace.hs
new file mode 100644
--- /dev/null
+++ b/examples/ray/Ray/Trace.hs
@@ -0,0 +1,149 @@
+{-# LANGUAGE ScopedTypeVariables #-}
+
+module Ray.Trace
+  where
+
+-- friends
+import Vec3
+import Scene.Object
+import Scene.Light
+import Ray.Intersect
+
+-- frenemies
+import Data.Array.Accelerate                                    as A
+import Graphics.Gloss.Accelerate.Data.Color.RGB
+import Graphics.Gloss.Accelerate.Data.Point
+
+-- standard library
+import Prelude                                                  as P
+
+
+-- | Generate all of the rays that will be cast from the given eye position to
+--   cover the entire field of view.
+--
+castViewRays
+    :: Int                              -- width of the display
+    -> Int                              -- height
+    -> Int                              -- field of view
+    -> Exp Position                     -- eye position
+    -> Acc (Array DIM2 Direction)       -- all rays originating from the eye position
+castViewRays sizeX sizeY fov eyePos
+  = let
+        sizeX'          = P.fromIntegral sizeX
+        sizeY'          = P.fromIntegral sizeY
+        aspect          = sizeX' / sizeY'
+        fov'            = P.fromIntegral fov
+        fovX            = fov' * aspect
+        fovY            = fov'
+    in
+    A.generate (constant (Z :. sizeY :. sizeX))
+               (\ix -> let (x, y) = xyOfPoint $ pointOfIndex sizeX sizeY ix
+                       in  normalise $ makeVec3 (x * fovX) ((-y) * fovY) 0 - eyePos)
+
+
+-- | Cast a single ray into the scene
+--
+traceRay
+    :: Int                              -- ^ Maximum reflection count
+    -> Acc Objects                      -- ^ Objects in the scene
+    -> Acc Lights                       -- ^ Direct lighting in the scene
+    -> Exp Color                        -- ^ Ambient light in the scene
+    -> Exp Position                     -- ^ Origin of the ray
+    -> Exp Direction                    -- ^ Direction of the ray
+    -> Exp Color
+traceRay limit objects lights ambient = go limit
+  where
+    (spheres, planes)   = unlift objects
+
+    dummySphere         = constant (Sphere (XYZ 0 0 0) 0           (RGB 0 0 0) 0)
+    dummyPlane          = constant (Plane  (XYZ 0 0 0) (XYZ 0 0 1) (RGB 0 0 0) 0)
+
+    -- Stop once there are too many reflections, in case we've found two
+    -- parallel mirrors.
+    --
+    go 0 _ _
+      = black
+
+    go bounces orig dir
+      = let
+            -- See which objects the ray intersects. Since we have no sum
+            -- types, we need to do this separately for each object type,
+            -- and determine the closest separately.
+            --
+            (hit_s, dist_s, s)  = unlift $ castRay distanceToSphere dummySphere spheres orig dir
+            (hit_p, dist_p, p)  = unlift $ castRay distanceToPlane  dummyPlane  planes  orig dir
+        in
+        A.not (hit_s ||* hit_p) ?
+          -- ray didn't intersect any objects
+        ( black
+
+          -- ray hit an object
+        , let
+              -- Determine the intersection point, and surface properties that
+              -- will contribute to the colour
+              next_s      = hitSphere     s dist_s orig dir
+              next_p      = hitPlaneCheck p dist_p orig dir
+
+              (point, normal, color, shine)
+                          = unlift (dist_s <* dist_p ? ( next_s, next_p ))
+
+              -- result angle of ray after reflection
+              newdir      = dir - (2.0 * (normal `dot` dir)) .* normal
+
+              -- determine the direct lighting at this point
+              direct      = applyLights objects lights point normal
+
+              -- see if the ray hits anything else
+              refl        = go (bounces - 1) point newdir
+
+              -- total lighting is the direct lighting plus ambient
+              lighting    = direct + ambient
+
+              -- total incoming light is direct lighting plus reflections
+              light_in    = scaleColour shine         refl
+                          + scaleColour (1.0 - shine) lighting
+
+              -- outgoing light is incoming light modified by surface color.
+              -- We also need to clip it in case the sum of all incoming
+              -- lights is too bright to display.
+              light_out   = clampColor (light_in * color)
+          in
+          light_out
+        )
+
+
+scaleColour :: Exp Float -> Exp Color -> Exp Color
+scaleColour s c
+  = let (r,g,b) = rgbOfColor c
+    in  rawColor (r * s) (g * s) (b * s)
+
+hitSphere :: Exp Sphere -> Exp Float -> Exp Position -> Exp Direction -> Exp (Position, Direction, Color, Float)
+hitSphere sph dist orig dir
+  = let
+        point   = orig + dist .* dir
+        normal  = sphereNormal sph point
+        color   = sphereColor sph
+        shine   = sphereShine sph
+    in
+    lift (point, normal, color, shine)
+
+hitPlane :: Exp Plane -> Exp Float -> Exp Position -> Exp Direction -> Exp (Position, Direction, Color, Float)
+hitPlane pln dist orig dir
+  = let
+        point   = orig + dist .* dir
+        normal  = planeNormal pln
+        color   = planeColor pln
+        shine   = planeShine pln
+    in
+    lift (point, normal, color, shine)
+
+hitPlaneCheck :: Exp PlaneCheck -> Exp Float -> Exp Position -> Exp Direction -> Exp (Position, Direction, Color, Float)
+hitPlaneCheck pln dist orig dir
+  = let
+        point   = orig + dist .* dir
+        normal  = planeCheckNormal pln
+        color   = checkers point
+        shine   = planeCheckShine pln
+    in
+    lift (point, normal, color, shine)
+
diff --git a/examples/ray/Scene/Light.hs b/examples/ray/Scene/Light.hs
new file mode 100644
--- /dev/null
+++ b/examples/ray/Scene/Light.hs
@@ -0,0 +1,115 @@
+{-# LANGUAGE DeriveDataTypeable    #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE ScopedTypeVariables   #-}
+{-# LANGUAGE TypeFamilies          #-}
+{-# LANGUAGE UndecidableInstances  #-}
+
+module Scene.Light
+  where
+
+-- friends
+import Vec3
+import Ray.Intersect
+import Scene.Object
+
+-- frenemies
+import Data.Array.Accelerate                                    as A
+import Data.Array.Accelerate.Smart
+import Data.Array.Accelerate.Tuple
+import Data.Array.Accelerate.Array.Sugar                        ( Elt(..), EltRepr, EltRepr' )
+import Graphics.Gloss.Accelerate.Data.Color.RGB
+
+-- standard library
+import Data.Typeable
+
+
+-- | An omnidirectional point light source, whose intensity drops off with
+--   distance from the source.
+--
+data Light = Light Position Color
+  deriving (Eq, Show, Typeable)
+
+type Lights = Array DIM1 Light
+
+lightPos   :: Exp Light -> Exp Position
+lightColor :: Exp Light -> Exp Color
+
+
+-- | Compute the direct lighting contribution of all lights acting on a point on
+-- a surface at a given normal direction.
+--
+--    normal
+--         ^           x light
+--         |        .
+--         |     . objects?
+--         |  .
+--   ______x______ surface
+--       point
+--
+applyLights
+    :: Acc Objects
+    -> Acc Lights
+    -> Exp Position
+    -> Exp Direction
+    -> Exp Color
+applyLights objects lights point normal
+  = sfoldl (\c l -> c + applyLight objects point normal l) black (constant Z) lights
+
+
+-- | Compute the direct lighting at a particular point for a single light
+--
+applyLight
+    :: Acc Objects              -- possible occluding objects, used for shadows
+    -> Exp Position             -- point which is being lit
+    -> Exp Direction            -- surface normal at this point
+    -> Exp Light                -- does this light contribute colour to this point?
+    -> Exp Color
+applyLight objects point normal light
+  = let
+        (spheres, planes)       = unlift objects
+
+        -- What is the direction and distance from the light source to the point
+        -- on the surface?
+        --
+        lp_p                    = lightPos light - point
+        dist                    = magnitude lp_p
+        dir                     = (1.0 / dist) .* lp_p
+
+        -- Calculate the magnitude of the reflected light, if there are no
+        -- occluding objects between the light and the surface point.
+        --
+        mag                     = (normal `dot` dir) / (dist * dist)
+        (r, g, b)               = rgbOfColor (lightColor light)
+        refl                    = rawColor (r * mag) (g * mag) (b * mag)
+    in
+    checkRay distanceToSphere spheres point dir dist ||* checkRay distanceToPlane planes point dir dist
+      ? ( black, refl )
+
+
+
+-- Get Lights into Accelerate --------------------------------------------------
+
+lightPos l   = Exp $ SuccTupIdx ZeroTupIdx `Prj` l
+lightColor l = Exp $ ZeroTupIdx `Prj` l
+
+type instance EltRepr Light  = EltRepr (Position, Color)
+type instance EltRepr' Light = EltRepr' (Position, Color)
+
+instance Elt Light where
+  eltType (_ :: Light)  = eltType (undefined :: (Position, Color))
+  toElt light           = let (p,c) = toElt light in Light p c
+  fromElt (Light p c)   = fromElt (p,c)
+
+  eltType' (_ :: Light) = eltType' (undefined :: (Position, Color))
+  toElt' light          = let (p,c) = toElt' light in Light p c
+  fromElt' (Light p c)  = fromElt' (p,c)
+
+instance IsTuple Light where
+  type TupleRepr Light = TupleRepr (Position, Color)
+  fromTuple (Light p c) = fromTuple (p,c)
+  toTuple t             = let (p,c) = toTuple t in Light p c
+
+instance Lift Exp Light where
+  type Plain Light = Light
+  lift (Light p c) = Exp . Tuple $ NilTup `SnocTup` lift p `SnocTup` lift c
+
diff --git a/examples/ray/Scene/Object.hs b/examples/ray/Scene/Object.hs
new file mode 100644
--- /dev/null
+++ b/examples/ray/Scene/Object.hs
@@ -0,0 +1,239 @@
+{-# LANGUAGE DeriveDataTypeable    #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE ScopedTypeVariables   #-}
+{-# LANGUAGE TypeFamilies          #-}
+{-# LANGUAGE UndecidableInstances  #-}
+
+module Scene.Object
+  where
+
+-- friends
+import Vec3
+
+-- frenemies
+import Data.Array.Accelerate                                    as A
+import Data.Array.Accelerate.Smart
+import Data.Array.Accelerate.Tuple
+import Data.Array.Accelerate.Array.Sugar                        ( Elt(..), EltRepr, EltRepr' )
+import Graphics.Gloss.Accelerate.Data.Color.RGB
+
+-- standard library
+import Prelude                                                  as P
+import Data.Bits                                                ( xor )
+import Data.Typeable
+
+
+-- | All objects in the scene
+--
+type Objects = (Array DIM1 Sphere, Array DIM1 Plane)
+
+
+-- | Objects in the world. Accelerate does not have sum types, so define each
+--   object separately (and hope this works out...)
+--
+data Sphere = Sphere Position Float Color Float
+  deriving (Eq, Show, Typeable)
+
+spherePos    :: Exp Sphere -> Exp Position
+sphereColor  :: Exp Sphere -> Exp Color
+sphereShine  :: Exp Sphere -> Exp Float
+sphereRadius :: Exp Sphere -> Exp Float
+
+
+data Plane = Plane Position Direction Color Float
+  deriving (Eq, Show, Typeable)
+
+planePos    :: Exp Plane -> Exp Position
+planeNormal :: Exp Plane -> Exp Direction
+planeColor  :: Exp Plane -> Exp Color
+planeShine  :: Exp Plane -> Exp Float
+
+
+type PlaneCheck = Plane
+
+planeCheckPos    :: Exp PlaneCheck -> Exp Position
+planeCheckNormal :: Exp PlaneCheck -> Exp Direction
+planeCheckShine  :: Exp PlaneCheck -> Exp Float
+
+
+-- | Compute the distance to the surface of a sphere
+--
+distanceToSphere
+    :: Exp Sphere               -- ^ Object to intersect
+    -> Exp Position             -- ^ Ray cast from this point...
+    -> Exp Direction            -- ^ ...along this direction
+    -> Exp (Bool, Float)        -- ^ Distance to intersection, if there is one
+distanceToSphere sphere origin direction
+  = let
+        pos     = spherePos sphere
+        radius  = sphereRadius sphere
+
+        p       = origin + ((pos - origin) `dot` direction) .* direction
+        d_cp    = magnitude (p - pos)
+        sep     = p - origin
+        miss    = d_cp >=* radius ||* sep `dot` direction <=* 0
+    in
+    miss ? ( lift (False, infinity)
+           , lift (True,  magnitude sep - sqrt (radius * radius - d_cp * d_cp)) )
+
+
+-- | Compute the distance to the surface of a Plane
+--
+distanceToPlane
+    :: Exp Plane                -- ^ Plane to intersect
+    -> Exp Position             -- ^ Ray cast from this point
+    -> Exp Direction            -- ^ ...along this direction
+    -> Exp (Bool, Float)        -- ^ Distance to intersection, if there is one
+distanceToPlane plane origin direction
+  = let
+        pos             = planePos plane
+        normal          = planeNormal plane
+        theta           = direction `dot` normal        -- TLM: name?
+    in
+    theta >=* 0 ? ( lift (False, infinity)
+                  , lift (True,  ((pos - origin) `dot` normal) / theta) )
+
+
+-- | The maximum representable floating point value
+--
+infinity :: Exp Float
+infinity = constant (encodeFloat m n)
+  where
+    a           = undefined :: Float
+    b           = floatRadix a
+    e           = floatDigits a
+    (_, e')     = floatRange a
+    m           = b ^ e - 1
+    n           = e' - e
+
+
+-- | Compute the surface normal of a sphere at a point
+--
+sphereNormal
+    :: Exp Sphere
+    -> Exp Position             -- ^ A point on the surface of the sphere
+    -> Exp Direction            -- ^ Normal at that point
+sphereNormal sphere point
+  = normalise (point - spherePos sphere)
+
+
+-- | A checkerboard pattern along the x/z axis
+--
+checkers :: Exp Position -> Exp Color
+checkers pos
+  = let
+        (x,_,z) = xyzOfVec pos
+
+        v1      = (A.truncate (x / 100) :: Exp Int32) `mod` 2
+        v2      = (A.truncate (z / 100) :: Exp Int32) `mod` 2
+        v3      = A.fromIntegral . boolToInt $ x <* 0.0
+        v4      = A.fromIntegral . boolToInt $ z <* 0.0
+    in
+    v1 `xor` v2 `xor` v3 `xor` v4 ==* 1 {- True -}
+      ? ( rawColor 1.0 1.0 1.0
+        , rawColor 0.4 0.4 0.4 )
+
+
+-- Get Objects into Accelerate -------------------------------------------------
+
+-- Because the Object types aren't parameterised, the type of the individual
+-- fields are fixed. Thus we can't unlift from (Exp Sphere) to a Sphere of Exp
+-- things. Poop.
+--
+spherePos s    = Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)) `Prj` s
+sphereRadius s = Exp $ SuccTupIdx (SuccTupIdx ZeroTupIdx) `Prj` s
+sphereColor s  = Exp $ SuccTupIdx ZeroTupIdx `Prj` s
+sphereShine s  = Exp $ ZeroTupIdx `Prj` s
+
+planePos p    = Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)) `Prj` p
+planeNormal p = Exp $ SuccTupIdx (SuccTupIdx ZeroTupIdx) `Prj` p
+planeColor p  = Exp $ SuccTupIdx ZeroTupIdx `Prj` p
+planeShine p  = Exp $ ZeroTupIdx `Prj` p
+
+planeCheckPos    = planePos
+planeCheckNormal = planeNormal
+planeCheckShine  = planeShine
+
+
+-- Sphere
+-- ------
+
+type instance EltRepr Sphere  = EltRepr (Position, Float, Color, Float)
+type instance EltRepr' Sphere = EltRepr' (Position, Float, Color, Float)
+
+instance Elt Sphere where
+  eltType (_ :: Sphere)         = eltType (undefined :: (Position, Float, Color, Float))
+  toElt sphere                  = let (p,r,c,s) = toElt sphere in Sphere p r c s
+  fromElt (Sphere p r c s)      = fromElt (p, r, c, s)
+
+  eltType' (_ :: Sphere)        = eltType' (undefined :: (Position, Float, Color, Float))
+  toElt' sphere                 = let (p,r,c,s) = toElt' sphere in Sphere p r c s
+  fromElt' (Sphere p r c s)     = fromElt' (p, r, c, s)
+
+instance IsTuple Sphere where
+  type TupleRepr Sphere = TupleRepr (Position, Float, Color, Float)
+  fromTuple (Sphere p r c s)    = fromTuple (p, r, c, s)
+  toTuple t                     = let (p, r, c, s) = toTuple t in Sphere p r c s
+
+instance Lift Exp Sphere where
+  type Plain Sphere = Sphere
+  lift (Sphere p r c s)
+      = Exp . Tuple
+      $ NilTup `SnocTup` lift p `SnocTup` lift r `SnocTup` lift c `SnocTup` lift s
+
+
+-- Plane
+-- -----
+
+type instance EltRepr Plane  = EltRepr (Position, Direction, Color, Float)
+type instance EltRepr' Plane = EltRepr' (Position, Direction, Color, Float)
+
+instance Elt Plane where
+  eltType (_ :: Plane)          = eltType (undefined :: (Position, Direction, Color, Float))
+  toElt plane                   = let (p,n,c,s) = toElt plane in Plane p n c s
+  fromElt (Plane p n c s)       = fromElt (p, n, c, s)
+
+  eltType' (_ :: Plane)         = eltType' (undefined :: (Position, Direction, Color, Float))
+  toElt' plane                  = let (p,n,c,s) = toElt' plane in Plane p n c s
+  fromElt' (Plane p n c s)      = fromElt' (p, n, c, s)
+
+instance IsTuple Plane where
+  type TupleRepr Plane = TupleRepr (Position, Direction, Color, Float)
+  fromTuple (Plane p n c s)     = fromTuple (p, n, c, s)
+  toTuple t                     = let (p, n, c, s) = toTuple t in Plane p n c s
+
+instance Lift Exp Plane where
+  type Plain Plane = Plane
+  lift (Plane p n c s)
+      = Exp . Tuple
+      $ NilTup `SnocTup` lift p `SnocTup` lift n `SnocTup` lift c `SnocTup` lift s
+
+
+{--
+-- Checkered Plane
+-- ---------------
+
+type instance EltRepr PlaneCheck  = EltRepr (Position, Direction, Float)
+type instance EltRepr' PlaneCheck = EltRepr' (Position, Direction, Float)
+
+instance Elt PlaneCheck where
+  eltType (_ :: PlaneCheck)     = eltType (undefined :: (Position, Direction, Float))
+  toElt plane                   = let (p,n,s) = toElt plane in PlaneCheck p n s
+  fromElt (PlaneCheck p n s)    = fromElt (p, n, s)
+
+  eltType' (_ :: PlaneCheck)    = eltType' (undefined :: (Position, Direction, Float))
+  toElt' plane                  = let (p,n,s) = toElt' plane in PlaneCheck p n s
+  fromElt' (PlaneCheck p n s)   = fromElt' (p, n, s)
+
+instance IsTuple PlaneCheck where
+  type TupleRepr PlaneCheck = TupleRepr (Position, Direction, Float)
+  fromTuple (PlaneCheck p n s)  = fromTuple (p, n, s)
+  toTuple t                     = let (p, n, s) = toTuple t in PlaneCheck p n s
+
+instance Lift Exp PlaneCheck where
+  type Plain PlaneCheck = PlaneCheck
+  lift (PlaneCheck p n s)
+      = Exp . Tuple
+      $ NilTup `SnocTup` lift p `SnocTup` lift n `SnocTup` lift s
+--}
+
diff --git a/examples/ray/Scene/State.hs b/examples/ray/Scene/State.hs
new file mode 100644
--- /dev/null
+++ b/examples/ray/Scene/State.hs
@@ -0,0 +1,118 @@
+{-# LANGUAGE TemplateHaskell #-}
+
+module Scene.State
+  where
+
+-- friends
+import Vec3
+import Scene.Light
+import Scene.Object
+import Scene.World
+
+-- frenemies
+import Data.Array.Accelerate                                    as A
+
+-- library
+import Prelude                                                  hiding ( (.), id )
+import Data.Label
+import Control.Category
+import qualified Graphics.Gloss                                 as G
+
+
+data Move  = Fwd | Rev
+  deriving Show
+
+data State = State
+  { _stateTime                  :: !Float
+  , _stateEyePos                :: !Position
+  , _stateEyeDelta              :: !Position
+  , _stateLightDelta            :: !Position
+
+  , _stateLeftClick             :: !(Maybe G.Point)
+
+  , _stateMoveSpeed             :: !Float
+  , _stateEyeHoriz              :: !(Maybe Move)
+  , _stateEyeVert               :: !(Maybe Move)
+  , _stateLightHoriz            :: !(Maybe Move)
+  , _stateLightVert             :: !(Maybe Move)
+
+  , _stateObjects               :: !Objects
+  , _stateLights                :: !Lights
+  }
+  deriving Show
+
+mkLabels [''State]
+
+
+-- | Initialise the world and interface state
+--
+initState :: Float -> State
+initState time
+  = advanceState 0
+  $ State
+      { _stateTime              = time
+      , _stateEyePos            = XYZ 50    (-100) (-700)
+
+      , _stateEyeDelta          = XYZ (-50) 200   1296
+      , _stateLightDelta        = XYZ 0     0     0
+
+      , _stateLeftClick         = Nothing
+
+      , _stateMoveSpeed         = 400
+      , _stateEyeHoriz          = Nothing
+      , _stateEyeVert           = Nothing
+      , _stateLightHoriz        = Nothing
+      , _stateLightVert         = Nothing
+
+      , _stateObjects           = makeObjects time
+      , _stateLights            = makeLights  time
+      }
+
+
+-- | Advance the world forward in time
+--
+advanceState :: Float -> State -> State
+advanceState dt state
+  = setTime (get stateTime state + dt)
+  $ move stateLightDelta stateLightVert  zz
+  $ move stateLightDelta stateLightHoriz xx
+  $ move stateEyeDelta stateEyeVert  zz
+  $ move stateEyeDelta stateEyeHoriz xx
+  $ state
+  where
+    speed        = get stateMoveSpeed state
+    move eye f d = case get f state of
+                    Nothing     -> id
+                    Just Fwd    -> modify eye (+ (set d ( speed * dt) (XYZ 0 0 0)))
+                    Just Rev    -> modify eye (+ (set d (-speed * dt) (XYZ 0 0 0)))
+
+    zz          = lens (\(XYZ _ _ z) -> z) (\f (XYZ x y z) -> XYZ x y (f z))
+    xx          = lens (\(XYZ x _ _) -> x) (\f (XYZ x y z) -> XYZ (f x) y z)
+
+
+-- | Set the time of the world
+--
+setTime :: Float -> State -> State
+setTime time state
+  = let
+        objects         = makeObjects time
+        lights          = makeLights  time
+        deltaEye        = get stateEyeDelta   state
+        deltaLight      = get stateLightDelta state + deltaEye
+    in
+    set stateTime time
+      $ set stateObjects (translateObjects deltaEye   objects)
+      $ set stateLights  (translateLights  deltaLight lights)
+      $ state
+
+
+translateObjects :: Position -> Objects -> Objects
+translateObjects v (spheres, planes)
+  = ( fromList (arrayShape spheres) [ Sphere (p + v) r c s | Sphere p r c s <- toList spheres ]
+    , fromList (arrayShape planes)  [ Plane  (p + v) d c s | Plane  p d c s <- toList planes  ]
+    )
+
+translateLights :: Position -> Lights -> Lights
+translateLights v lights
+  = fromList (arrayShape lights) [ Light (p + v) c | Light p c <- toList lights ]
+
diff --git a/examples/ray/Scene/World.hs b/examples/ray/Scene/World.hs
new file mode 100644
--- /dev/null
+++ b/examples/ray/Scene/World.hs
@@ -0,0 +1,53 @@
+
+module Scene.World where
+
+-- friends
+import Vec3
+import Scene.Light
+import Scene.Object
+
+-- frenemies
+import Data.Array.Accelerate                                    as A
+import Graphics.Gloss.Accelerate.Data.Color.RGB
+
+
+makeLights :: Float -> Lights
+makeLights _time
+  = A.fromList (Z :. 1) [ Light (XYZ 300 (-300) (-100))
+                                (RGB 150000 150000 150000)
+                        ]
+
+makeObjects :: Float -> Objects
+makeObjects time
+  = let
+        spheres = A.fromList (Z :. 4)
+          [ Sphere (XYZ (40 * sin time) 80 0.0)
+                   20
+                   (RGB 1.0 0.3 1.0)
+                   0.4
+
+          , Sphere (XYZ (200 * sin time) (-40 * sin (time + pi/2)) (200 * cos time))
+                   100.0
+                   (RGB 0.4 0.4 1.0)
+                   0.8
+
+          , Sphere (XYZ (-200.0 * sin time) (-40 * sin (time - pi/2)) (-200 * cos time))
+                   100.0
+                   (RGB 0.4 0.4 1.0)
+                   0.5
+
+          , Sphere (XYZ 0.0 (-150.0) (-100.0))
+                   50.0
+                   (RGB 1.0 1.0 1.0)
+                   0.8
+          ]
+
+        planes = A.fromList (Z :. 1)
+          [ Plane (XYZ 0.0 100.0 0.0)
+                  (XYZ 0.0 (-0.9805807) (-0.19611613))
+                  (RGB 1.0 1.0 1.0)
+                  0.2
+          ]
+    in
+    (spheres, planes)
+
diff --git a/examples/ray/Vec3.hs b/examples/ray/Vec3.hs
new file mode 100644
--- /dev/null
+++ b/examples/ray/Vec3.hs
@@ -0,0 +1,148 @@
+{-# LANGUAGE DeriveDataTypeable    #-}
+{-# LANGUAGE FlexibleInstances     #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE ScopedTypeVariables   #-}
+{-# LANGUAGE TypeFamilies          #-}
+{-# LANGUAGE UndecidableInstances  #-}
+{-# OPTIONS -fno-warn-missing-methods #-}
+
+module Vec3
+  where
+
+import Prelude
+import Data.Typeable
+import Data.Array.Accelerate
+import Data.Array.Accelerate.Smart
+import Data.Array.Accelerate.Tuple
+import Data.Array.Accelerate.Array.Sugar
+
+
+-- | Points and vectors in 3D Space
+--
+type Position   = Vec3
+type Direction  = Vec3
+type Normal     = (Position, Direction)
+
+-- | A parameterised point in XYZ space.
+--
+type Vec3       = XYZ Float
+
+-- | Make a Vec3
+--
+makeVec3 :: Exp Float -> Exp Float -> Exp Float -> Exp Vec3
+makeVec3 x y z = lift (XYZ x y z)
+
+
+-- | Extract the components of the Vec3
+--
+xyzOfVec :: Exp Vec3 -> (Exp Float, Exp Float, Exp Float)
+xyzOfVec v
+  = let XYZ x y z       = unlift v
+    in  (x, y, z)
+
+
+-- | Yield the magnitude of a vector.
+--
+magnitude :: Exp Vec3 -> Exp Float
+magnitude v
+  = let XYZ x y z       = unlift v
+    in
+    sqrt (x * x + y * y + z * z)
+
+
+-- | Normalise a vector to have unit length.
+--
+normalise :: Exp Vec3 -> Exp Vec3
+normalise v = (1.0 / magnitude v) .* v
+
+
+-- | Component-wise multiply a vector by a scalar.
+--
+infixl 7 .*
+(.*) :: Exp Float -> Exp Vec3 -> Exp Vec3
+(.*) s v
+  = let XYZ x y z       = unlift v
+    in
+    makeVec3 (s * x) (s * y) (s * z)
+
+
+-- | Compute the dot product of two vectors.
+--
+dot :: Exp Vec3 -> Exp Vec3 -> Exp Float
+dot v1 v2
+  = let XYZ x1 y1 z1    = unlift v1
+        XYZ x2 y2 z2    = unlift v2
+    in
+    x1 * x2 + y1 * y2 + z1 * z2
+
+
+-- | Clamp a vectors components to some minimum and maximum values.
+--
+clamp :: Exp Vec3 -> Exp Float -> Exp Float -> Exp Vec3
+clamp v minVal maxVal =
+  makeVec3 (go x) (go y) (go z)
+  where
+    XYZ x y z   = unlift v
+    go u        = minVal `max` u `min` maxVal
+
+
+-- | Clip a vector's components to some maximum value.
+--
+clip :: Exp Vec3 -> Exp Float -> Exp Vec3
+clip v maxVal =
+  makeVec3 (go x) (go y) (go z)
+  where
+    XYZ x y z   = unlift v
+    go u        = u `min` maxVal
+
+
+-- Get a Vec3 into Accelerate --------------------------------------------------
+
+data XYZ a = XYZ a a a
+  deriving (Eq, Show, Typeable)
+
+type instance EltRepr  (XYZ a)  = EltRepr  (a, a, a)
+type instance EltRepr' (XYZ a)  = EltRepr' (a, a, a)
+
+instance Elt a => Elt (XYZ a) where
+  eltType (_ :: XYZ a)  = eltType (undefined :: (a, a, a))
+  toElt p               = let (x,y,z) = toElt p in XYZ x y z
+  fromElt (XYZ x y z)   = fromElt (x, y, z)
+
+  eltType' (_ :: XYZ a) = eltType (undefined :: (a, a, a))
+  toElt' p              = let (x,y,z) = toElt p in XYZ x y z
+  fromElt' (XYZ x y z)  = fromElt (x, y, z)
+
+instance IsTuple (XYZ a) where
+  type TupleRepr (XYZ a) = TupleRepr (a, a, a)
+  fromTuple (XYZ x y z) = fromTuple (x, y, z)
+  toTuple t             = let (x,y,z) = toTuple t in XYZ x y z
+
+instance (Lift Exp a, Elt (Plain a)) => Lift Exp (XYZ a) where
+  type Plain (XYZ a) = XYZ (Plain a)
+  lift (XYZ x y z)      = Exp . Tuple $ NilTup `SnocTup` lift x `SnocTup` lift y `SnocTup` lift z
+
+instance Elt a => Unlift Exp (XYZ (Exp a)) where
+  unlift t      = let x = Exp $ SuccTupIdx (SuccTupIdx ZeroTupIdx) `Prj` t
+                      y = Exp $ SuccTupIdx ZeroTupIdx `Prj` t
+                      z = Exp $ ZeroTupIdx `Prj` t
+                  in XYZ x y z
+
+-- | Pretend a Vec3 is a number
+--
+instance Num a => Num (XYZ a) where
+ (+) (XYZ x1 x2 x3) (XYZ y1 y2 y3)
+        = XYZ (x1 + y1) (x2 + y2) (x3 + y3)
+
+ (-) (XYZ x1 x2 x3) (XYZ y1 y2 y3)
+        = XYZ (x1 - y1) (x2 - y2) (x3 - y3)
+
+ (*) (XYZ x1 x2 x3) (XYZ y1 y2 y3)
+        = XYZ (x1 * y1) (x2 * y2) (x3 * y3)
+
+
+instance (Elt a, IsNum a) => Num (Exp (XYZ a)) where
+  (+)   = lift2 ((+) :: XYZ (Exp a) -> XYZ (Exp a) -> XYZ (Exp a))
+  (-)   = lift2 ((-) :: XYZ (Exp a) -> XYZ (Exp a) -> XYZ (Exp a))
+  (*)   = lift2 ((*) :: XYZ (Exp a) -> XYZ (Exp a) -> XYZ (Exp a))
+
diff --git a/examples/smoothlife/Config.hs b/examples/smoothlife/Config.hs
--- a/examples/smoothlife/Config.hs
+++ b/examples/smoothlife/Config.hs
@@ -11,7 +11,7 @@
 import Control.Category
 
 import Data.Array.Accelerate                            ( Array, DIM2 )
-import Data.Array.Accelerate.Math.Complex               ( Complex )
+import Data.Array.Accelerate.Data.Complex               ( Complex )
 
 
 -- | Types
diff --git a/examples/smoothlife/Random/Splat.hs b/examples/smoothlife/Random/Splat.hs
--- a/examples/smoothlife/Random/Splat.hs
+++ b/examples/smoothlife/Random/Splat.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE TypeOperators #-}
 
 module Random.Splat
   where
@@ -5,15 +6,15 @@
 import Config
 
 import Control.Monad
-import Control.Monad.ST
 import System.Random.MWC
+import Random.Array                             ( (:~>) )
 import Data.Array.Accelerate                    ( DIM2, Z(..), (:.)(..) )
 
 
 
 -- Generate a random point on the grid by checking which circles it overlaps.
 --
-splat :: [(DIM2, R, Bool)] -> DIM2 -> GenST s -> ST s R
+splat :: [(DIM2, R, Bool)] -> DIM2 :~> R
 splat circles ix _ =
   let overlaps          = filter (inside ix) circles
       negative (_,_,s)  = s
diff --git a/examples/smoothlife/SmoothLife.hs b/examples/smoothlife/SmoothLife.hs
--- a/examples/smoothlife/SmoothLife.hs
+++ b/examples/smoothlife/SmoothLife.hs
@@ -19,7 +19,7 @@
 import Data.Array.Accelerate                    as A hiding ( size )
 import Data.Array.Accelerate.Math.FFT
 import Data.Array.Accelerate.Math.DFT.Centre
-import Data.Array.Accelerate.Math.Complex
+import Data.Array.Accelerate.Data.Complex
 
 #ifdef ACCELERATE_CUDA_BACKEND
 import Data.Array.Accelerate.CUDA.Foreign
diff --git a/lib/ParseArgs.hs b/lib/ParseArgs.hs
--- a/lib/ParseArgs.hs
+++ b/lib/ParseArgs.hs
@@ -10,7 +10,6 @@
 
 ) where
 
-import Data.Char
 import Data.List
 import Data.Label
 import System.Exit
@@ -24,6 +23,15 @@
 #ifdef ACCELERATE_CUDA_BACKEND
 import qualified Data.Array.Accelerate.CUDA             as CUDA
 #endif
+#ifdef ACCELERATE_LLVM_NATIVE_BACKEND
+import qualified Data.Array.Accelerate.LLVM.Native      as CPU
+#endif
+#ifdef ACCELERATE_LLVM_PTX_BACKEND
+import qualified Data.Array.Accelerate.LLVM.PTX         as PTX
+#endif
+#ifdef ACCELERATE_LLVM_MULTIDEV_BACKEND
+import qualified Data.Array.Accelerate.LLVM.Multi       as Multi
+#endif
 
 
 -- | Execute Accelerate expressions
@@ -33,6 +41,15 @@
 #ifdef ACCELERATE_CUDA_BACKEND
 run CUDA        = CUDA.run
 #endif
+#ifdef ACCELERATE_LLVM_NATIVE_BACKEND
+run CPU         = CPU.run
+#endif
+#ifdef ACCELERATE_LLVM_PTX_BACKEND
+run PTX         = PTX.run
+#endif
+#ifdef ACCELERATE_LLVM_MULTIDEV_BACKEND
+run Multi       = Multi.run
+#endif
 
 
 run1 :: (Arrays a, Arrays b) => Backend -> (Acc a -> Acc b) -> a -> b
@@ -40,6 +57,15 @@
 #ifdef ACCELERATE_CUDA_BACKEND
 run1 CUDA        f = CUDA.run1 f
 #endif
+#ifdef ACCELERATE_LLVM_NATIVE_BACKEND
+run1 CPU         f = CPU.run1 f
+#endif
+#ifdef ACCELERATE_LLVM_PTX_BACKEND
+run1 PTX         f = PTX.run1 f
+#endif
+#ifdef ACCELERATE_LLVM_MULTIDEV_BACKEND
+run1 Multi       f = Multi.run1 f
+#endif
 
 run2 :: (Arrays a, Arrays b, Arrays c) => Backend -> (Acc a -> Acc b -> Acc c) -> a -> b -> c
 run2 backend f x y = run1 backend (A.uncurry f) (x,y)
@@ -53,19 +79,60 @@
 #ifdef ACCELERATE_CUDA_BACKEND
              | CUDA
 #endif
-  deriving (Eq, Bounded, Show)
+#ifdef ACCELERATE_LLVM_NATIVE_BACKEND
+             | CPU
+#endif
+#ifdef ACCELERATE_LLVM_PTX_BACKEND
+             | PTX
+#endif
+#ifdef ACCELERATE_LLVM_MULTIDEV_BACKEND
+             | Multi
+#endif
+  deriving (Eq, Bounded)
 
+
+instance Show Backend where
+  show Interpreter      = "interpreter"
+#ifdef ACCELERATE_CUDA_BACKEND
+  show CUDA             = "cuda"
+#endif
+#ifdef ACCELERATE_LLVM_NATIVE_BACKEND
+  show CPU              = "llvm-cpu"
+#endif
+#ifdef ACCELERATE_LLVM_PTX_BACKEND
+  show PTX              = "llvm-gpu"
+#endif
+#ifdef ACCELERATE_LLVM_MULTIDEV_BACKEND
+  show Multi            = "llvm-multi"
+#endif
+
+
 availableBackends :: (f :-> Backend) -> [OptDescr (f -> f)]
 availableBackends backend =
-  [ Option  [] ["interpreter"]
+  [ Option  [] [show Interpreter]
             (NoArg (set backend Interpreter))
             "reference implementation (sequential)"
 
 #ifdef ACCELERATE_CUDA_BACKEND
-  , Option  [] ["cuda"]
+  , Option  [] [show CUDA]
             (NoArg (set backend CUDA))
             "implementation for NVIDIA GPUs (parallel)"
 #endif
+#ifdef ACCELERATE_LLVM_NATIVE_BACKEND
+  , Option  [] [show CPU]
+            (NoArg (set backend CPU))
+            "LLVM based implementation for multicore CPUs (parallel)"
+#endif
+#ifdef ACCELERATE_LLVM_PTX_BACKEND
+  , Option  [] [show PTX]
+            (NoArg (set backend PTX))
+            "LLVM based implementation for NVIDIA GPUs (parallel)"
+#endif
+#ifdef ACCELERATE_LLVM_MULTIDEV_BACKEND
+  , Option  [] [show Multi]
+            (NoArg (set backend Multi))
+            "LLVM based multi-device implementation using CPUs and GPUs (parallel)"
+#endif
   ]
 
 
@@ -82,7 +149,7 @@
 fancyHeader :: (config :-> Backend) -> config -> [String] -> [String] -> String
 fancyHeader backend opts header footer = unlines (header ++ body ++ footer)
   where
-    active this         = if this == map toLower (show (get backend opts)) then "*" else ""
+    active this         = if this == show (get backend opts) then "*" else ""
     (ss,bs,ds)          = unzip3 $ map (\(b,d) -> (active b, b, d)) $ concatMap extract (availableBackends backend)
     table               = zipWith3 paste (sameLen ss) (sameLen bs) ds
     paste x y z         = "  " ++ x ++ "  " ++ y ++ "  " ++ z
diff --git a/lib/Random/Array.hs b/lib/Random/Array.hs
--- a/lib/Random/Array.hs
+++ b/lib/Random/Array.hs
@@ -9,7 +9,6 @@
 
 ) where
 
-import Control.Monad.ST
 import System.Random.MWC                        hiding ( uniform, uniformR )
 import qualified System.Random.MWC              as R
 
@@ -20,7 +19,7 @@
 
 -- | A PNRG from indices to variates
 --
-type sh :~> e = forall s. sh -> GenST s -> ST s e
+type sh :~> e = sh -> GenIO -> IO e
 
 
 -- | Uniformly distributed random variates.
@@ -67,7 +66,11 @@
 --
 --   TODO: find a way to do this directly, without going via save/restore.
 --
-randomArrayWithSystemRandom :: forall sh e. (Shape sh, Elt e) => sh :~> e -> sh -> IO (Array sh e)
+randomArrayWithSystemRandom
+    :: forall sh e. (Shape sh, Elt e)
+    => sh :~> e
+    -> sh
+    -> IO (Array sh e)
 randomArrayWithSystemRandom f sh
   = do
        seed   <- withSystemRandom (asGenIO save)
@@ -76,12 +79,15 @@
 
 -- Common function to create a mutable array and fill it with random values
 --
-runRandomArray :: (Shape sh, Elt e) => sh :~> e -> sh -> GenST s -> ST s (MutableArrayData s (EltRepr e))
+runRandomArray
+    :: (Shape sh, Elt e)
+    => sh :~> e
+    -> sh
+    -> GenIO
+    -> IO (MutableArrayData (EltRepr e))
 runRandomArray f sh gen
-  = let
-        n = Sugar.size sh
-    in do
-      arr <- newArrayData n
+  = do
+      arr <- newArrayData $! Sugar.size sh
       let write ix = unsafeWriteArrayData arr (Sugar.toIndex sh ix)
                    . fromElt =<< f ix gen
 
