diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -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.
diff --git a/Setup.lhs b/Setup.lhs
new file mode 100644
--- /dev/null
+++ b/Setup.lhs
@@ -0,0 +1,3 @@
+#! /usr/bin/env runhaskell
+> import Distribution.Simple
+> main = defaultMain
diff --git a/accelerate-fourier-benchmark.cabal b/accelerate-fourier-benchmark.cabal
new file mode 100644
--- /dev/null
+++ b/accelerate-fourier-benchmark.cabal
@@ -0,0 +1,44 @@
+Name:             accelerate-fourier-benchmark
+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-fourier-benchmark/
+Category:         Math
+Synopsis:         Compare different implementations of the Fast Fourier Transform
+Description:
+  Compare
+  .
+  * @accelerate-fourier@
+  .
+  * @accelerate-cufft@
+  .
+  * @accelerate-fftw@
+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-fourier-benchmark/
+
+Source-Repository head
+  Type:        darcs
+  Location:    http://code.haskell.org/~thielema/accelerate-fourier-benchmark/
+
+Executable accelerate-fourier-benchmark
+  Main-Is:          Main.hs
+  GHC-Options:      -Wall -fwarn-missing-import-lists -threaded
+  GHC-Prof-Options: -fprof-auto -rtsopts
+  Hs-Source-Dirs:   src
+  Default-Language: Haskell98
+  Build-Depends:
+    criterion >=1.0 && <1.1,
+    accelerate-cufft >=0.0 && <0.1,
+    accelerate-fftw >=0.0 && <0.1,
+    accelerate-fourier >=0.0 && <0.1,
+    accelerate-cuda >=0.15 && <0.16,
+    accelerate >=0.15 && <0.16,
+    base >=4.5 && <4.8
diff --git a/src/Main.hs b/src/Main.hs
new file mode 100644
--- /dev/null
+++ b/src/Main.hs
@@ -0,0 +1,96 @@
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE ConstraintKinds #-}
+module Main where
+
+import Criterion.Main (Benchmark, defaultMain, bgroup, bench, whnf, )
+
+import qualified Data.Array.Accelerate.CUFFT.Batched as CUFFT
+import qualified Data.Array.Accelerate.FFTW.Manifest as FFTW
+
+import qualified Data.Array.Accelerate.Fourier.Planned as Planned
+import qualified Data.Array.Accelerate.Fourier.Preprocessed as Prep
+
+import qualified Data.Array.Accelerate.CUDA as CUDA
+import qualified Data.Array.Accelerate as A
+import Data.Array.Accelerate (Array, DIM2, Z(Z), (:.)((:.)), )
+import Data.Complex (Complex, )
+
+import System.IO.Unsafe (unsafePerformIO)
+
+
+data Elem a = Elem
+
+
+width :: DIM2 -> Int
+width (Z:._:.n) = n
+
+powersOfTwo ::
+   (A.Elt a, RealFloat a) =>
+   Elem a ->
+   (DIM2 ->
+    Array DIM2 (Complex a) ->
+    Array DIM2 (Complex a)) ->
+   [Benchmark]
+powersOfTwo Elem f =
+   flip map (take 6 $ iterate (2*) 1024) $ \len ->
+      let sh = Z:.16:.len
+      in  bench (show len) $ whnf (f sh) $
+          A.fromList sh $ repeat 0
+
+powersOfTwos ::
+   (CUFFT.Real a, A.IsFloating a, FFTW.Element a, RealFloat a) =>
+   Elem a -> [Benchmark]
+powersOfTwos e =
+   bgroup "CUDA split-radix"
+      (powersOfTwo e (CUDA.run1 . Prep.ditSplitRadix Prep.forward . width)) :
+   bgroup "CUFFT"
+      (powersOfTwo e $ \sh ->
+         CUDA.run1 $ CUFFT.transform $
+         unsafePerformIO $ CUFFT.plan1D CUFFT.forwardComplex sh) :
+   bgroup "FFTW"
+      (powersOfTwo e (const FFTW.dft)) :
+   []
+
+
+arbitrary ::
+   (A.Elt a, RealFloat a) =>
+   Elem a ->
+   (DIM2 ->
+    Array DIM2 (Complex a) ->
+    Array DIM2 (Complex a)) ->
+   [Benchmark]
+arbitrary Elem f =
+   flip map (takeWhile (<=128) $ iterate (1+) 64) $ \len ->
+      let sh = Z:.2048:.len
+      in  bench (show len) $ whnf (f sh) $
+          A.fromList sh $ repeat 0
+
+arbitraryLengths ::
+   (CUFFT.Real a, A.IsFloating a, FFTW.Element a, RealFloat a) =>
+   Elem a -> [Benchmark]
+arbitraryLengths e =
+   bgroup "CUDA generic"
+      (arbitrary e (CUDA.run1 . Planned.transform Planned.forward . width)) :
+   bgroup "CUFFT"
+      (arbitrary e $ \sh ->
+         CUDA.run1 $ CUFFT.transform $
+         unsafePerformIO $ CUFFT.plan1D CUFFT.forwardComplex sh) :
+   bgroup "FFTW"
+      (arbitrary e (const FFTW.dft)) :
+   []
+
+
+allBenchs ::
+   (CUFFT.Real a, A.IsFloating a, FFTW.Element a, RealFloat a) =>
+   Elem a -> [Benchmark]
+allBenchs e =
+   bgroup "2^n" (powersOfTwos e) :
+   bgroup "any" (arbitraryLengths e) :
+   []
+
+
+main :: IO ()
+main = defaultMain $
+   bgroup "float" (allBenchs (Elem :: Elem Float)) :
+   bgroup "double" (allBenchs (Elem :: Elem Double)) :
+   []
