packages feed

accelerate-fftw 0.0 → 1.1

raw patch · 7 files changed

Files

+ Justfile view
@@ -0,0 +1,9 @@+run-test:	update-test+	runhaskell Setup.lhs configure --user --enable-tests+	runhaskell Setup.lhs build+	./dist/build/accelerate-fftw-test/accelerate-fftw-test++update-test:+	doctest-extract-0.1 -i src/ -o test/ \+	  --import-tested --module-prefix Test --executable-main=Test.hs \+	  Data.Array.Accelerate.FFTW.Manifest
accelerate-fftw.cabal view
@@ -1,36 +1,39 @@+Cabal-Version:    2.2 Name:             accelerate-fftw-Version:          0.0-License:          BSD3+Version:          1.1+License:          BSD-3-Clause License-File:     LICENSE Author:           Henning Thielemann <haskell@henning-thielemann.de> Maintainer:       Henning Thielemann <haskell@henning-thielemann.de>-Homepage:         http://code.haskell.org/~thielema/accelerate-fftw/+Homepage:         https://hub.darcs.net/thielema/accelerate-fftw/ Category:         Math Synopsis:         Accelerate frontend to the FFTW library (Fourier transform) Description:   An interface to the Fastest Fourier Transform in the West (FFTW)   for the @accelerate@ framework.-Tested-With:      GHC==7.8.3-Cabal-Version:    >=1.14+Tested-With:      GHC==9.2.8, GHC==9.12.4 Build-Type:       Simple+Extra-Source-Files:+  Justfile  Source-Repository this-  Tag:         0.0+  Tag:         1.1   Type:        darcs-  Location:    http://code.haskell.org/~thielema/accelerate-fftw/+  Location:    https://hub.darcs.net/thielema/accelerate-fftw/  Source-Repository head   Type:        darcs-  Location:    http://code.haskell.org/~thielema/accelerate-fftw/+  Location:    https://hub.darcs.net/thielema/accelerate-fftw/  Library   Build-Depends:-    fft >=0.1.7 && <0.2,-    carray >=0.1.5 && <0.2,+    comfort-fftw >=0.0 && <0.1,+    comfort-array >=0.5.5 && <0.6,+    netlib-ffi >=0.1 && <0.2,     storable-complex >=0.2.1 && <0.3,-    accelerate-io >=0.15 && <0.16,-    accelerate >=0.15 && <0.16,-    base >=4.5 && <4.8+    accelerate-io >=1.3 && <1.5,+    accelerate >=1.3 && <1.5,+    base >=4.5 && <5    GHC-Options:      -Wall -fwarn-missing-import-lists   Hs-Source-Dirs:   src@@ -38,4 +41,22 @@   Exposed-Modules:     Data.Array.Accelerate.FFTW.Manifest   Other-Modules:+    Data.Array.Accelerate.FFTW.Private     Data.Array.Accelerate.CArray.Conversion++Test-Suite accelerate-fftw-test+  Type: exitcode-stdio-1.0+  Build-Depends:+    doctest-exitcode-stdio >=0.0 && <0.1,+    doctest-lib >=0.1.1 && <0.2,+    accelerate-fftw,+    accelerate-utility >=1.1 && <1.2,+    accelerate >=1.3 && <1.5,+    base >=4.5 && <5++  GHC-Options:      -Wall+  Hs-Source-Dirs:   test+  Default-Language: Haskell98+  Main-Is:          Test.hs+  Other-Modules:+    Test.Data.Array.Accelerate.FFTW.Manifest
src/Data/Array/Accelerate/CArray/Conversion.hs view
@@ -1,156 +1,145 @@ {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-}+{-# LANGUAGE ConstraintKinds #-}+-- ToDo: extract to a separate package module Data.Array.Accelerate.CArray.Conversion where -import qualified Data.Array.Accelerate.IO as AIO+import qualified Data.Array.Accelerate.IO.Foreign.ForeignPtr as AIO+import qualified Data.Array.Accelerate.Sugar.Shape as Shape import qualified Data.Array.Accelerate as A-import Data.Array.Accelerate.Array.Sugar (EltRepr, EltRepr')+import Data.Array.Accelerate.Sugar.Elt (EltR) import Data.Array.Accelerate (Array, DIM1, DIM2, Z(Z), (:.)((:.))) -import qualified Data.Array.CArray as CArray-import Data.Array.CArray (CArray, createCArray, withCArray, rangeSize)-import Data.Ix (Ix)+import qualified Data.Array.Comfort.Storable.Private as CArray+import qualified Data.Array.Comfort.Shape as CShape import Foreign.Storable.Complex ()  import Data.Array.Accelerate.Data.Complex (Complex)-import qualified Data.Complex as Complex -import System.IO.Unsafe (unsafePerformIO)-import Foreign.ForeignPtr (withForeignPtr)-import Foreign.Ptr (Ptr)+import Foreign.ForeignPtr (ForeignPtr, castForeignPtr) import Foreign.Storable (Storable) -import Control.Monad ((<=<))-import Data.IORef (newIORef, writeIORef, readIORef) +type CArray = CArray.Array+type ShapeInt = CShape.ZeroBased Int +type RealElement a =+      (A.Elt a, Storable a, AIO.ForeignPtrs (EltR a) ~ ForeignPtr a)++type ComplexElement a ac =+      (Storable a, RealFloat a, Complex a ~ ac, A.Elt ac,+       AIO.ForeignPtrs (EltR ac) ~ ForeignPtr a)++ accFromCArrayReal1D ::-   (A.Elt a, Storable a, AIO.BlockPtrs (EltRepr a) ~ ((), Ptr a)) =>-   CArray Int a -> Array DIM1 a+   (RealElement a) =>+   CArray ShapeInt a -> Array DIM1 a accFromCArrayReal1D arr =-   let (len, fptr) = CArray.toForeignPtr arr-   in  unsafePerformIO $-       withForeignPtr fptr $ \ptr -> AIO.fromPtr (Z :. len) ((), ptr)+   AIO.fromForeignPtrs+      (accDimsFromArrayBounds1D $ CArray.shape arr)+      (CArray.buffer arr)  accFromCArrayReal2D ::-   (A.Elt a, Storable a, AIO.BlockPtrs (EltRepr a) ~ ((), Ptr a)) =>-   CArray (Int, Int) a -> Array DIM2 a+   (RealElement a) =>+   CArray (ShapeInt, ShapeInt) a -> Array DIM2 a accFromCArrayReal2D arr =-   unsafePerformIO $-   withCArray arr $ \ptr ->-      AIO.fromPtr (accDimsFromArrayBounds2D $ CArray.bounds arr) ((), ptr)+   AIO.fromForeignPtrs+      (accDimsFromArrayBounds2D $ CArray.shape arr)+      (CArray.buffer arr)   accFromCArrayComplex1D ::-   (A.Elt a, Storable a, RealFloat a,-    AIO.BlockPtrs (EltRepr a) ~ ((), Ptr a),-    AIO.BlockPtrs (EltRepr' a) ~ Ptr a) =>-   CArray Int (Complex a) -> Array DIM1 (Complex a)+   (ComplexElement a ac) =>+   CArray ShapeInt (Complex a) -> Array DIM1 (Complex a) accFromCArrayComplex1D arr =-   accFromCArrayComplex (accDimsFromArrayBounds1D $ CArray.bounds arr) arr+   accFromCArrayComplex (accDimsFromArrayBounds1D $ CArray.shape arr) arr  accFromCArrayComplex2D ::-   (A.Elt a, Storable a, RealFloat a,-    AIO.BlockPtrs (EltRepr a) ~ ((), Ptr a),-    AIO.BlockPtrs (EltRepr' a) ~ Ptr a) =>-   CArray (Int, Int) (Complex a) -> Array DIM2 (Complex a)+   (ComplexElement a ac) =>+   CArray (ShapeInt, ShapeInt) (Complex a) -> Array DIM2 (Complex a) accFromCArrayComplex2D arr =-   accFromCArrayComplex (accDimsFromArrayBounds2D $ CArray.bounds arr) arr+   accFromCArrayComplex (accDimsFromArrayBounds2D $ CArray.shape arr) arr  accFromCArrayComplex ::-   (Ix i, A.Shape sh,-    A.Elt a, Storable a, RealFloat a,-    AIO.BlockPtrs (EltRepr a) ~ ((), Ptr a),-    AIO.BlockPtrs (EltRepr' a) ~ Ptr a) =>-   sh -> CArray i (Complex a) -> Array sh (Complex a)+   (A.Shape sh, ComplexElement a ac) =>+   sh -> CArray csh ac -> Array sh ac accFromCArrayComplex sh arr =-   unsafePerformIO $-   withCArray (CArray.amap Complex.realPart arr) $ \ptrReal ->-   withCArray (CArray.amap Complex.imagPart arr) $ \ptrImag ->-      AIO.fromPtr sh (((), ptrReal), ptrImag)+   AIO.fromForeignPtrs sh $ castForeignPtrFromComplex $ CArray.buffer arr +castForeignPtrFromComplex :: ForeignPtr (Complex a) -> ForeignPtr a+castForeignPtrFromComplex = castForeignPtr -accDimsFromArrayBounds1D :: (CArray.Ix i) => (i, i) -> DIM1-accDimsFromArrayBounds1D bnds = Z :. rangeSize bnds ++accDimsFromArrayBounds1D :: (CShape.C sh) => sh -> DIM1+accDimsFromArrayBounds1D sh = Z :. CShape.size sh+ accDimsFromArrayBounds2D ::-   (CArray.Ix i, CArray.Ix j) => ((i, j), (i, j)) -> DIM2-accDimsFromArrayBounds2D ((li,lj), (ri,rj)) =-   Z :. rangeSize (li,ri) :. rangeSize (lj,rj)+   (CShape.C sh0, CShape.C sh1) => (sh0, sh1) -> DIM2+accDimsFromArrayBounds2D (sh0, sh1) =+   Z :. CShape.size sh0 :. CShape.size sh1   cArrayFromAccReal1D ::-   (A.Elt a, Storable a, AIO.BlockPtrs (EltRepr a) ~ ((), Ptr a)) =>-   Array DIM1 a -> CArray Int a+   (RealElement a) =>+   Array DIM1 a -> CArray ShapeInt a cArrayFromAccReal1D arr =-   let (Z:.len) = A.arrayShape arr-   in  unsafePerformIO $-       createCArray (0,len-1) $ \ptr -> AIO.toPtr arr ((), ptr)+   CArray.Array+      (arrayBounds1DFromAccDims $ A.arrayShape arr)+      (AIO.toForeignPtrs arr)  cArrayFromAccReal2D ::-   (A.Elt a, Storable a, AIO.BlockPtrs (EltRepr a) ~ ((), Ptr a)) =>-   Array DIM2 a -> CArray (Int, Int) a+   (RealElement a) =>+   Array DIM2 a -> CArray (ShapeInt, ShapeInt) a cArrayFromAccReal2D arr =-   unsafePerformIO $-   createCArray (arrayBounds2DFromAccDims $ A.arrayShape arr) $ \ptr ->-      AIO.toPtr arr ((), ptr)+   CArray.Array+      (arrayBounds2DFromAccDims $ A.arrayShape arr)+      (AIO.toForeignPtrs arr)  cArrayFromAccComplex1D ::-   (A.Elt a, Storable a, RealFloat a,-    AIO.BlockPtrs (EltRepr a) ~ ((), Ptr a),-    AIO.BlockPtrs (EltRepr' a) ~ Ptr a) =>-   Array DIM1 (Complex a) -> CArray Int (Complex a)+   (ComplexElement a ac) =>+   Array DIM1 ac -> CArray ShapeInt ac cArrayFromAccComplex1D arr =    cArrayFromAccComplex       (arrayBounds1DFromAccDims $ A.arrayShape arr) arr  cArrayFromAccComplex2D ::-   (A.Elt a, Storable a, RealFloat a,-    AIO.BlockPtrs (EltRepr a) ~ ((), Ptr a),-    AIO.BlockPtrs (EltRepr' a) ~ Ptr a) =>-   Array DIM2 (Complex a) -> CArray (Int,Int) (Complex a)+   (ComplexElement a ac) =>+   Array DIM2 ac -> CArray (ShapeInt,ShapeInt) ac cArrayFromAccComplex2D arr =    cArrayFromAccComplex       (arrayBounds2DFromAccDims $ A.arrayShape arr) arr  cArrayFromAccComplex ::-   (Ix i, A.Shape sh,-    A.Elt a, Storable a, RealFloat a,-    AIO.BlockPtrs (EltRepr a) ~ ((), Ptr a),-    AIO.BlockPtrs (EltRepr' a) ~ Ptr a) =>-   (i,i) -> Array sh (Complex a) -> CArray i (Complex a)-cArrayFromAccComplex bnds arr = unsafePerformIO $ do-   fmap (uncurry (CArray.liftArray2 (Complex.:+))) $-      createCArrayAdd bnds $ \ptrReal ->-      createCArray bnds $ \ptrImag ->-         AIO.toPtr arr (((), ptrReal), ptrImag)+   (CShape.C csh, A.Shape sh, ComplexElement a ac) =>+   csh -> Array sh ac -> CArray csh ac+cArrayFromAccComplex bnds arr =+   CArray.Array bnds (castForeignPtrToComplex $ AIO.toForeignPtrs arr) +castForeignPtrToComplex :: ForeignPtr a -> ForeignPtr (Complex a)+castForeignPtrToComplex = castForeignPtr + withCArrayComplex ::-   (Ix i, A.Shape sh,-    A.Elt a, Storable a, RealFloat a,-    AIO.BlockPtrs (EltRepr a) ~ ((), Ptr a),-    AIO.BlockPtrs (EltRepr' a) ~ Ptr a) =>-   (sh -> (i,i)) ->-   (CArray i (Complex a) -> CArray i (Complex a)) ->-   Array sh (Complex a) -> Array sh (Complex a)+   (CShape.C csh, A.Shape sh, ComplexElement a ac) =>+   (sh -> csh) ->+   (CArray csh ac -> CArray csh ac) ->+   Array sh ac -> Array sh ac withCArrayComplex bndsFromSh f arr =    let sh = A.arrayShape arr    in  accFromCArrayComplex sh $ f $        cArrayFromAccComplex (bndsFromSh sh) arr  -createCArrayAdd ::-   (Ix i, Storable e) =>-   (i,i) -> (Ptr e -> IO a) -> IO (CArray i e, a)-createCArrayAdd bnds create = do-   ref <- newIORef (error "uninitialized inner value")-   arr <- createCArray bnds $ writeIORef ref <=< create-   fmap ((,) arr) $ readIORef ref+arrayBounds1DFromAccDims :: DIM1 -> ShapeInt+arrayBounds1DFromAccDims (Z :. i) = CShape.ZeroBased i +arrayBounds2DFromAccDims :: DIM2 -> (ShapeInt, ShapeInt)+arrayBounds2DFromAccDims (Z :. i :. j) =+   (CShape.ZeroBased i, CShape.ZeroBased j) -arrayBounds1DFromAccDims :: DIM1 -> (Int, Int)-arrayBounds1DFromAccDims (Z :. i) = (0, i-1) -arrayBounds2DFromAccDims :: DIM2 -> ((Int, Int), (Int, Int))-arrayBounds2DFromAccDims (Z :. i :. j) = ((0,0), (i-1,j-1))+newtype Cube sh = Cube sh++instance (A.Shape sh) => CShape.C (Cube sh) where+   size (Cube sh) = Shape.size sh
src/Data/Array/Accelerate/FFTW/Manifest.hs view
@@ -1,66 +1,99 @@ {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-}-{-# LANGUAGE ConstraintKinds #-} module Data.Array.Accelerate.FFTW.Manifest (    Transform,-   Element,    dft,    idft,    dft2d,    idft2d,    ) where -import qualified Math.FFT as FFT-import Math.FFT.Base (FFTWReal)--import qualified Data.Array.Accelerate.CArray.Conversion as Conv--import qualified Data.Array.Accelerate.IO as AIO+import qualified Data.Array.Accelerate.FFTW.Private as Batch import qualified Data.Array.Accelerate as A-import Data.Array.Accelerate.Array.Sugar (EltRepr, EltRepr')-import Data.Array.Accelerate (Array, (:.)((:.)))+import Data.Array.Accelerate.FFTW.Private (Transform)+import Data.Array.Accelerate ((:.)) +import Data.Array.Accelerate.Data.Complex (Complex) import Foreign.Storable.Complex () -import Data.Array.Accelerate.Data.Complex (Complex)+import qualified Numeric.Netlib.Class as Class -import Foreign.Ptr (Ptr) +{- $setup+>>> import qualified Data.Array.Accelerate.Utility.Lift.Exp as Exp+>>> import qualified Data.Array.Accelerate.Interpreter as AI+>>> import qualified Data.Array.Accelerate as A+>>> import Data.Array.Accelerate.Utility.Lift.Exp (expr)+>>> import Data.Array.Accelerate.Data.Complex (Complex((:+)))+>>> import Data.Array.Accelerate ((:.)((:.)))+>>>+>>> roundComplex :: A.Exp (Complex Float) -> A.Exp (Complex Int)+>>> roundComplex =+>>>    Exp.modify (expr:+expr) $ \(r:+i) -> A.round r :+ (A.round i :: A.Exp Int)+>>>+>>> roundComplexArray ::+>>>    (A.Shape sh) => A.Array sh (Complex Float) -> A.Array sh (Complex Int)+>>> roundComplexArray = AI.run1 (A.map roundComplex)+-} -type Bounds i = (i,i) -type Transform sh a = Array sh a -> Array sh a--type Element a =-      (FFTWReal a, A.Elt a,-       AIO.BlockPtrs (EltRepr a) ~ ((), Ptr a),-       AIO.BlockPtrs (EltRepr' a) ~ Ptr a)-+{- |+>>> roundComplexArray $ dft (A.fromList (A.Z:.3:.3) [1000,0,0, 0,1000,0, 0,0,1000])+Matrix (Z :. 3 :. 3)+  [ 1000 :+ 0,        1000 :+ 0,        1000 :+ 0,+    1000 :+ 0, (-500) :+ (-866),    (-500) :+ 866,+    1000 :+ 0,    (-500) :+ 866, (-500) :+ (-866)]+-} dft ::-   (A.Shape sh, Element a) =>+   (A.Shape sh, Class.Real a) =>    Transform (sh:.Int) (Complex a)-dft = Conv.withCArrayComplex bnds1 $ FFT.dftN [1]+dft = Batch.runComplexTransform $ Class.switchReal Batch.dft Batch.dft +{- |+>>> roundComplexArray $ idft $ dft (A.fromList (A.Z:.3:.3) [1000,0,0, 0,1000,0, 0,0,1000])+Matrix (Z :. 3 :. 3)+  [ 3000 :+ 0,    0 :+ 0,    0 :+ 0,+       0 :+ 0, 3000 :+ 0,    0 :+ 0,+       0 :+ 0,    0 :+ 0, 3000 :+ 0]+-} idft ::-   (A.Shape sh, Element a) =>+   (A.Shape sh, Class.Real a) =>    Transform (sh:.Int) (Complex a)-idft = Conv.withCArrayComplex bnds1 $ FFT.dftN [1]+idft = Batch.runComplexTransform $ Class.switchReal Batch.idft Batch.idft -bnds1 :: (A.Shape sh) => sh:.Int -> Bounds (Int,Int)-bnds1 (sh:.n) = ((0,0), (A.arraySize sh-1, n-1)) +{- |+>>> roundComplexArray $ dft2d (A.fromList (A.Z:.3:.3) [1000,0,0, 0,0,0, 0,0,0])+Matrix (Z :. 3 :. 3)+  [ 1000 :+ 0, 1000 :+ 0, 1000 :+ 0,+    1000 :+ 0, 1000 :+ 0, 1000 :+ 0,+    1000 :+ 0, 1000 :+ 0, 1000 :+ 0] +>>> roundComplexArray $ dft2d (A.fromList (A.Z:.3:.3) [0,1000,0, 0,0,0, 0,0,0])+Matrix (Z :. 3 :. 3)+  [ 1000 :+ 0, (-500) :+ (-866), (-500) :+ 866,+    1000 :+ 0, (-500) :+ (-866), (-500) :+ 866,+    1000 :+ 0, (-500) :+ (-866), (-500) :+ 866]++>>> roundComplexArray $ dft2d (A.fromList (A.Z:.3:.3) [1000,0,0, 0,1000,0, 0,0,1000])+Matrix (Z :. 3 :. 3)+  [ 3000 :+ 0,    0 :+ 0,    0 :+ 0,+       0 :+ 0,    0 :+ 0, 3000 :+ 0,+       0 :+ 0, 3000 :+ 0,    0 :+ 0]+-} dft2d ::-   (A.Shape sh, Element a) =>+   (A.Shape sh, Class.Real a) =>    Transform (sh:.Int:.Int) (Complex a)-dft2d =-   Conv.withCArrayComplex bnds2 $ FFT.dftN [1,2]+dft2d = Batch.runComplexTransform $ Class.switchReal Batch.dft2d Batch.dft2d +{- |+>>> roundComplexArray $ idft2d $ dft2d (A.fromList (A.Z:.3:.3) [1000,0,0, 0,1000,0, 0,0,1000])+Matrix (Z :. 3 :. 3)+  [ 9000 :+ 0,    0 :+ 0,    0 :+ 0,+       0 :+ 0, 9000 :+ 0,    0 :+ 0,+       0 :+ 0,    0 :+ 0, 9000 :+ 0]+-} idft2d ::-   (A.Shape sh, Element a) =>+   (A.Shape sh, Class.Real a) =>    Transform (sh:.Int:.Int) (Complex a)-idft2d =-   Conv.withCArrayComplex bnds2 $ FFT.idftN [1,2]--bnds2 :: (A.Shape sh) => sh:.Int:.Int -> Bounds (Int,Int,Int)-bnds2 (sh:.n:.m) = ((0,0,0), (A.arraySize sh-1, n-1, m-1))+idft2d = Batch.runComplexTransform $ Class.switchReal Batch.idft2d Batch.idft2d
+ src/Data/Array/Accelerate/FFTW/Private.hs view
@@ -0,0 +1,63 @@+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE ConstraintKinds #-}+module Data.Array.Accelerate.FFTW.Private where++import qualified Numeric.FFTW.Batch as Batch+import qualified Numeric.FFTW.Shape as Spectrum+import qualified Numeric.Netlib.Class as Class++import qualified Data.Array.Accelerate.CArray.Conversion as Conv+import qualified Data.Array.Accelerate as A+import Data.Array.Accelerate (Array, (:.)((:.)))++import qualified Data.Array.Comfort.Shape as CShape++import Foreign.Storable.Complex ()++import Data.Array.Accelerate.Data.Complex (Complex)+++type ShapeCyclic = CShape.Cyclic Int++type Transform sh a = Array sh a -> Array sh a++newtype ComplexTransform sh a =+   ComplexTransform {runComplexTransform :: Transform sh (Complex a)}++type Element a ac = (Class.Real a, Conv.ComplexElement a ac)++complexTransform ::+   (A.Shape sh, CShape.C loop, Spectrum.MultiCyclic csh, Element a ac) =>+   (sh -> (loop, csh)) -> Batch.Sign -> ComplexTransform sh a+complexTransform bnds sign =+   ComplexTransform $ Conv.withCArrayComplex bnds $ Batch.fourier sign+++dft ::+   (A.Shape sh, Element a ac) =>+   ComplexTransform (sh:.Int) a+dft = complexTransform bnds1 Batch.Forward++idft ::+   (A.Shape sh, Element a ac) =>+   ComplexTransform (sh:.Int) a+idft = complexTransform bnds1 Batch.Backward++bnds1 :: (A.Shape sh) => sh:.Int -> (Conv.Cube sh, ShapeCyclic)+bnds1 (sh:.n) = (Conv.Cube sh, CShape.Cyclic n)+++dft2d ::+   (A.Shape sh, Element a ac) =>+   ComplexTransform (sh:.Int:.Int) a+dft2d = complexTransform bnds2 Batch.Forward++idft2d ::+   (A.Shape sh, Element a ac) =>+   ComplexTransform (sh:.Int:.Int) a+idft2d = complexTransform bnds2 Batch.Backward++bnds2 ::+   (A.Shape sh) => sh:.Int:.Int -> (Conv.Cube sh, (ShapeCyclic,ShapeCyclic))+bnds2 (sh:.n:.m) = (Conv.Cube sh, (CShape.Cyclic n, CShape.Cyclic m))
+ test/Test.hs view
@@ -0,0 +1,10 @@+-- Do not edit! Automatically created with doctest-extract.+module Main where++import qualified Test.Data.Array.Accelerate.FFTW.Manifest++import qualified Test.DocTest.Driver as DocTest++main :: IO ()+main = DocTest.run $ do+    Test.Data.Array.Accelerate.FFTW.Manifest.test
+ test/Test/Data/Array/Accelerate/FFTW/Manifest.hs view
@@ -0,0 +1,69 @@+-- Do not edit! Automatically created with doctest-extract from src/Data/Array/Accelerate/FFTW/Manifest.hs+{-# LINE 22 "src/Data/Array/Accelerate/FFTW/Manifest.hs" #-}++module Test.Data.Array.Accelerate.FFTW.Manifest where++import Data.Array.Accelerate.FFTW.Manifest+import Test.DocTest.Base+import qualified Test.DocTest.Driver as DocTest++{-# LINE 23 "src/Data/Array/Accelerate/FFTW/Manifest.hs" #-}+import     qualified Data.Array.Accelerate.Utility.Lift.Exp as Exp+import     qualified Data.Array.Accelerate.Interpreter as AI+import     qualified Data.Array.Accelerate as A+import     Data.Array.Accelerate.Utility.Lift.Exp (expr)+import     Data.Array.Accelerate.Data.Complex (Complex((:+)))+import     Data.Array.Accelerate ((:.)((:.)))++roundComplex     :: A.Exp (Complex Float) -> A.Exp (Complex Int)+roundComplex     =+       Exp.modify (expr:+expr) $ \(r:+i) -> A.round r :+ (A.round i :: A.Exp Int)++roundComplexArray     ::+       (A.Shape sh) => A.Array sh (Complex Float) -> A.Array sh (Complex Int)+roundComplexArray     = AI.run1 (A.map roundComplex)++test :: DocTest.T ()+test = do+ DocTest.printPrefix "Data.Array.Accelerate.FFTW.Manifest:41: "+{-# LINE 41 "src/Data/Array/Accelerate/FFTW/Manifest.hs" #-}+ DocTest.example(+{-# LINE 41 "src/Data/Array/Accelerate/FFTW/Manifest.hs" #-}+    roundComplexArray $ dft (A.fromList (A.Z:.3:.3) [1000,0,0, 0,1000,0, 0,0,1000])+  )+  [ExpectedLine [LineChunk "Matrix (Z :. 3 :. 3)"],ExpectedLine [LineChunk "  [ 1000 :+ 0,        1000 :+ 0,        1000 :+ 0,"],ExpectedLine [LineChunk "    1000 :+ 0, (-500) :+ (-866),    (-500) :+ 866,"],ExpectedLine [LineChunk "    1000 :+ 0,    (-500) :+ 866, (-500) :+ (-866)]"]]+ DocTest.printPrefix "Data.Array.Accelerate.FFTW.Manifest:53: "+{-# LINE 53 "src/Data/Array/Accelerate/FFTW/Manifest.hs" #-}+ DocTest.example(+{-# LINE 53 "src/Data/Array/Accelerate/FFTW/Manifest.hs" #-}+    roundComplexArray $ idft $ dft (A.fromList (A.Z:.3:.3) [1000,0,0, 0,1000,0, 0,0,1000])+  )+  [ExpectedLine [LineChunk "Matrix (Z :. 3 :. 3)"],ExpectedLine [LineChunk "  [ 3000 :+ 0,    0 :+ 0,    0 :+ 0,"],ExpectedLine [LineChunk "       0 :+ 0, 3000 :+ 0,    0 :+ 0,"],ExpectedLine [LineChunk "       0 :+ 0,    0 :+ 0, 3000 :+ 0]"]]+ DocTest.printPrefix "Data.Array.Accelerate.FFTW.Manifest:66: "+{-# LINE 66 "src/Data/Array/Accelerate/FFTW/Manifest.hs" #-}+ DocTest.example(+{-# LINE 66 "src/Data/Array/Accelerate/FFTW/Manifest.hs" #-}+    roundComplexArray $ dft2d (A.fromList (A.Z:.3:.3) [1000,0,0, 0,0,0, 0,0,0])+  )+  [ExpectedLine [LineChunk "Matrix (Z :. 3 :. 3)"],ExpectedLine [LineChunk "  [ 1000 :+ 0, 1000 :+ 0, 1000 :+ 0,"],ExpectedLine [LineChunk "    1000 :+ 0, 1000 :+ 0, 1000 :+ 0,"],ExpectedLine [LineChunk "    1000 :+ 0, 1000 :+ 0, 1000 :+ 0]"]]+ DocTest.printPrefix "Data.Array.Accelerate.FFTW.Manifest:72: "+{-# LINE 72 "src/Data/Array/Accelerate/FFTW/Manifest.hs" #-}+ DocTest.example(+{-# LINE 72 "src/Data/Array/Accelerate/FFTW/Manifest.hs" #-}+    roundComplexArray $ dft2d (A.fromList (A.Z:.3:.3) [0,1000,0, 0,0,0, 0,0,0])+  )+  [ExpectedLine [LineChunk "Matrix (Z :. 3 :. 3)"],ExpectedLine [LineChunk "  [ 1000 :+ 0, (-500) :+ (-866), (-500) :+ 866,"],ExpectedLine [LineChunk "    1000 :+ 0, (-500) :+ (-866), (-500) :+ 866,"],ExpectedLine [LineChunk "    1000 :+ 0, (-500) :+ (-866), (-500) :+ 866]"]]+ DocTest.printPrefix "Data.Array.Accelerate.FFTW.Manifest:78: "+{-# LINE 78 "src/Data/Array/Accelerate/FFTW/Manifest.hs" #-}+ DocTest.example(+{-# LINE 78 "src/Data/Array/Accelerate/FFTW/Manifest.hs" #-}+    roundComplexArray $ dft2d (A.fromList (A.Z:.3:.3) [1000,0,0, 0,1000,0, 0,0,1000])+  )+  [ExpectedLine [LineChunk "Matrix (Z :. 3 :. 3)"],ExpectedLine [LineChunk "  [ 3000 :+ 0,    0 :+ 0,    0 :+ 0,"],ExpectedLine [LineChunk "       0 :+ 0,    0 :+ 0, 3000 :+ 0,"],ExpectedLine [LineChunk "       0 :+ 0, 3000 :+ 0,    0 :+ 0]"]]+ DocTest.printPrefix "Data.Array.Accelerate.FFTW.Manifest:90: "+{-# LINE 90 "src/Data/Array/Accelerate/FFTW/Manifest.hs" #-}+ DocTest.example(+{-# LINE 90 "src/Data/Array/Accelerate/FFTW/Manifest.hs" #-}+    roundComplexArray $ idft2d $ dft2d (A.fromList (A.Z:.3:.3) [1000,0,0, 0,1000,0, 0,0,1000])+  )+  [ExpectedLine [LineChunk "Matrix (Z :. 3 :. 3)"],ExpectedLine [LineChunk "  [ 9000 :+ 0,    0 :+ 0,    0 :+ 0,"],ExpectedLine [LineChunk "       0 :+ 0, 9000 :+ 0,    0 :+ 0,"],ExpectedLine [LineChunk "       0 :+ 0,    0 :+ 0, 9000 :+ 0]"]]