accelerate-fftw 0.0 → 1.1
raw patch · 7 files changed
Files
- Justfile +9/−0
- accelerate-fftw.cabal +34/−13
- src/Data/Array/Accelerate/CArray/Conversion.hs +80/−91
- src/Data/Array/Accelerate/FFTW/Manifest.hs +68/−35
- src/Data/Array/Accelerate/FFTW/Private.hs +63/−0
- test/Test.hs +10/−0
- test/Test/Data/Array/Accelerate/FFTW/Manifest.hs +69/−0
+ 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]"]]