accelerate-fftw (empty) → 0.0
raw patch · 5 files changed
+293/−0 lines, 5 filesdep +acceleratedep +accelerate-iodep +basesetup-changed
Dependencies added: accelerate, accelerate-io, base, carray, fft, storable-complex
Files
- LICENSE +27/−0
- Setup.lhs +3/−0
- accelerate-fftw.cabal +41/−0
- src/Data/Array/Accelerate/CArray/Conversion.hs +156/−0
- src/Data/Array/Accelerate/FFTW/Manifest.hs +66/−0
+ LICENSE view
@@ -0,0 +1,27 @@+Copyright (c) Henning Thielemann 2014++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions+are met:+1. Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.+2. Redistributions in binary form must reproduce the above copyright+ notice, this list of conditions and the following disclaimer in the+ documentation and/or other materials provided with the distribution.+3. Neither the name of the author nor the names of his contributors+ may be used to endorse or promote products derived from this software+ without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF+SUCH DAMAGE.
+ Setup.lhs view
@@ -0,0 +1,3 @@+#! /usr/bin/env runhaskell+> import Distribution.Simple+> main = defaultMain
+ accelerate-fftw.cabal view
@@ -0,0 +1,41 @@+Name: accelerate-fftw+Version: 0.0+License: BSD3+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/+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+Build-Type: Simple++Source-Repository this+ Tag: 0.0+ Type: darcs+ Location: http://code.haskell.org/~thielema/accelerate-fftw/++Source-Repository head+ Type: darcs+ Location: http://code.haskell.org/~thielema/accelerate-fftw/++Library+ Build-Depends:+ fft >=0.1.7 && <0.2,+ carray >=0.1.5 && <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++ GHC-Options: -Wall -fwarn-missing-import-lists+ Hs-Source-Dirs: src+ Default-Language: Haskell98+ Exposed-Modules:+ Data.Array.Accelerate.FFTW.Manifest+ Other-Modules:+ Data.Array.Accelerate.CArray.Conversion
+ src/Data/Array/Accelerate/CArray/Conversion.hs view
@@ -0,0 +1,156 @@+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+module Data.Array.Accelerate.CArray.Conversion where++import qualified Data.Array.Accelerate.IO as AIO+import qualified Data.Array.Accelerate as A+import Data.Array.Accelerate.Array.Sugar (EltRepr, EltRepr')+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 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.Storable (Storable)++import Control.Monad ((<=<))+import Data.IORef (newIORef, writeIORef, readIORef)+++accFromCArrayReal1D ::+ (A.Elt a, Storable a, AIO.BlockPtrs (EltRepr a) ~ ((), Ptr a)) =>+ CArray Int a -> Array DIM1 a+accFromCArrayReal1D arr =+ let (len, fptr) = CArray.toForeignPtr arr+ in unsafePerformIO $+ withForeignPtr fptr $ \ptr -> AIO.fromPtr (Z :. len) ((), ptr)++accFromCArrayReal2D ::+ (A.Elt a, Storable a, AIO.BlockPtrs (EltRepr a) ~ ((), Ptr a)) =>+ CArray (Int, Int) a -> Array DIM2 a+accFromCArrayReal2D arr =+ unsafePerformIO $+ withCArray arr $ \ptr ->+ AIO.fromPtr (accDimsFromArrayBounds2D $ CArray.bounds arr) ((), ptr)+++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)+accFromCArrayComplex1D arr =+ accFromCArrayComplex (accDimsFromArrayBounds1D $ CArray.bounds 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)+accFromCArrayComplex2D arr =+ accFromCArrayComplex (accDimsFromArrayBounds2D $ CArray.bounds 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)+accFromCArrayComplex sh arr =+ unsafePerformIO $+ withCArray (CArray.amap Complex.realPart arr) $ \ptrReal ->+ withCArray (CArray.amap Complex.imagPart arr) $ \ptrImag ->+ AIO.fromPtr sh (((), ptrReal), ptrImag)+++accDimsFromArrayBounds1D :: (CArray.Ix i) => (i, i) -> DIM1+accDimsFromArrayBounds1D bnds = Z :. rangeSize bnds++accDimsFromArrayBounds2D ::+ (CArray.Ix i, CArray.Ix j) => ((i, j), (i, j)) -> DIM2+accDimsFromArrayBounds2D ((li,lj), (ri,rj)) =+ Z :. rangeSize (li,ri) :. rangeSize (lj,rj)+++cArrayFromAccReal1D ::+ (A.Elt a, Storable a, AIO.BlockPtrs (EltRepr a) ~ ((), Ptr a)) =>+ Array DIM1 a -> CArray Int a+cArrayFromAccReal1D arr =+ let (Z:.len) = A.arrayShape arr+ in unsafePerformIO $+ createCArray (0,len-1) $ \ptr -> AIO.toPtr arr ((), ptr)++cArrayFromAccReal2D ::+ (A.Elt a, Storable a, AIO.BlockPtrs (EltRepr a) ~ ((), Ptr a)) =>+ Array DIM2 a -> CArray (Int, Int) a+cArrayFromAccReal2D arr =+ unsafePerformIO $+ createCArray (arrayBounds2DFromAccDims $ A.arrayShape arr) $ \ptr ->+ AIO.toPtr arr ((), ptr)++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)+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)+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)+++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)+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 -> (Int, Int)+arrayBounds1DFromAccDims (Z :. i) = (0, i-1)++arrayBounds2DFromAccDims :: DIM2 -> ((Int, Int), (Int, Int))+arrayBounds2DFromAccDims (Z :. i :. j) = ((0,0), (i-1,j-1))
+ src/Data/Array/Accelerate/FFTW/Manifest.hs view
@@ -0,0 +1,66 @@+{-# 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 as A+import Data.Array.Accelerate.Array.Sugar (EltRepr, EltRepr')+import Data.Array.Accelerate (Array, (:.)((:.)))++import Foreign.Storable.Complex ()++import Data.Array.Accelerate.Data.Complex (Complex)++import Foreign.Ptr (Ptr)+++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)++dft ::+ (A.Shape sh, Element a) =>+ Transform (sh:.Int) (Complex a)+dft = Conv.withCArrayComplex bnds1 $ FFT.dftN [1]++idft ::+ (A.Shape sh, Element a) =>+ Transform (sh:.Int) (Complex a)+idft = Conv.withCArrayComplex bnds1 $ FFT.dftN [1]++bnds1 :: (A.Shape sh) => sh:.Int -> Bounds (Int,Int)+bnds1 (sh:.n) = ((0,0), (A.arraySize sh-1, n-1))+++dft2d ::+ (A.Shape sh, Element a) =>+ Transform (sh:.Int:.Int) (Complex a)+dft2d =+ Conv.withCArrayComplex bnds2 $ FFT.dftN [1,2]++idft2d ::+ (A.Shape sh, Element 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))