{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE PatternGuards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE ViewPatterns #-}
module Data.Array.Accelerate.Math.FFT.LLVM.PTX (
fft,
fft1D,
fft2D,
fft3D,
) where
import Data.Array.Accelerate.Math.FFT.Mode
import Data.Array.Accelerate.Math.FFT.Type
import Data.Array.Accelerate.Math.FFT.LLVM.PTX.Base
import Data.Array.Accelerate.Math.FFT.LLVM.PTX.Plans
import Data.Array.Accelerate.Analysis.Match
import Data.Array.Accelerate.Data.Complex
import Data.Array.Accelerate.Error
import Data.Array.Accelerate.Lifetime
import Data.Array.Accelerate.Representation.Array
import Data.Array.Accelerate.Representation.Shape
import Data.Array.Accelerate.Sugar.Elt
import Data.Primitive.Vec
import Data.Array.Accelerate.LLVM.PTX.Foreign
import Foreign.CUDA.Ptr ( DevicePtr, castDevPtr )
import qualified Foreign.CUDA.FFT as FFT
import Control.Monad.Reader
import Data.Hashable
import System.IO.Unsafe
fft :: forall sh e. HasCallStack
=> Mode
-> ShapeR sh
-> NumericR e
-> ForeignAcc (Array sh (Vec2 e) -> Array sh (Vec2 e))
fft :: Mode
-> ShapeR sh
-> NumericR e
-> ForeignAcc (Array sh (Vec2 e) -> Array sh (Vec2 e))
fft Mode
mode ShapeR sh
shR NumericR e
eR
| Just sh :~: DIM1
Refl <- ShapeR sh -> ShapeR DIM1 -> Maybe (sh :~: DIM1)
forall s t. ShapeR s -> ShapeR t -> Maybe (s :~: t)
matchShapeR ShapeR sh
shR ShapeR DIM1
dim1 = Mode
-> NumericR e
-> ForeignAcc (Array DIM1 (Vec2 e) -> Array DIM1 (Vec2 e))
forall e.
Mode
-> NumericR e
-> ForeignAcc (Array DIM1 (Vec2 e) -> Array DIM1 (Vec2 e))
fft1D Mode
mode NumericR e
eR
| Just sh :~: DIM2
Refl <- ShapeR sh -> ShapeR DIM2 -> Maybe (sh :~: DIM2)
forall s t. ShapeR s -> ShapeR t -> Maybe (s :~: t)
matchShapeR ShapeR sh
shR ShapeR DIM2
dim2 = String
-> (Array DIM2 (Vec2 e) -> Par PTX (Future (Array DIM2 (Vec2 e))))
-> ForeignAcc (Array DIM2 (Vec2 e) -> Array DIM2 (Vec2 e))
forall a b.
String -> (a -> Par PTX (Future b)) -> ForeignAcc (a -> b)
ForeignAcc String
"cuda.fft2.many" ((Array DIM2 (Vec2 e) -> Par PTX (Future (Array DIM2 (Vec2 e))))
-> ForeignAcc (Array DIM2 (Vec2 e) -> Array DIM2 (Vec2 e)))
-> (Array DIM2 (Vec2 e) -> Par PTX (Future (Array DIM2 (Vec2 e))))
-> ForeignAcc (Array DIM2 (Vec2 e) -> Array DIM2 (Vec2 e))
forall a b. (a -> b) -> a -> b
$ Plans (DIM2, Type)
-> Mode
-> ShapeR DIM2
-> NumericR e
-> Array DIM2 (Vec2 e)
-> Par PTX (Future (Array DIM2 (Vec2 e)))
forall sh e.
Plans (sh, Type)
-> Mode
-> ShapeR sh
-> NumericR e
-> Array sh (Vec2 e)
-> Par PTX (Future (Array sh (Vec2 e)))
fft' Plans (DIM2, Type)
fft2DMany_plans Mode
mode ShapeR sh
ShapeR DIM2
shR NumericR e
eR
| Just sh :~: DIM3
Refl <- ShapeR sh -> ShapeR DIM3 -> Maybe (sh :~: DIM3)
forall s t. ShapeR s -> ShapeR t -> Maybe (s :~: t)
matchShapeR ShapeR sh
shR ShapeR DIM3
dim3 = String
-> (Array DIM3 (Vec2 e) -> Par PTX (Future (Array DIM3 (Vec2 e))))
-> ForeignAcc (Array DIM3 (Vec2 e) -> Array DIM3 (Vec2 e))
forall a b.
String -> (a -> Par PTX (Future b)) -> ForeignAcc (a -> b)
ForeignAcc String
"cuda.fft3.many" ((Array DIM3 (Vec2 e) -> Par PTX (Future (Array DIM3 (Vec2 e))))
-> ForeignAcc (Array DIM3 (Vec2 e) -> Array DIM3 (Vec2 e)))
-> (Array DIM3 (Vec2 e) -> Par PTX (Future (Array DIM3 (Vec2 e))))
-> ForeignAcc (Array DIM3 (Vec2 e) -> Array DIM3 (Vec2 e))
forall a b. (a -> b) -> a -> b
$ Plans (DIM3, Type)
-> Mode
-> ShapeR DIM3
-> NumericR e
-> Array DIM3 (Vec2 e)
-> Par PTX (Future (Array DIM3 (Vec2 e)))
forall sh e.
Plans (sh, Type)
-> Mode
-> ShapeR sh
-> NumericR e
-> Array sh (Vec2 e)
-> Par PTX (Future (Array sh (Vec2 e)))
fft' Plans (DIM3, Type)
fft3DMany_plans Mode
mode ShapeR sh
ShapeR DIM3
shR NumericR e
eR
| Bool
otherwise = String -> ForeignAcc (Array sh (Vec2 e) -> Array sh (Vec2 e))
forall a. HasCallStack => String -> a
internalError String
"only for 1D..3D inner-dimension transforms"
fft1D :: Mode -> NumericR e -> ForeignAcc (Array DIM1 (Vec2 e) -> Array DIM1 (Vec2 e))
fft1D :: Mode
-> NumericR e
-> ForeignAcc (Array DIM1 (Vec2 e) -> Array DIM1 (Vec2 e))
fft1D Mode
mode NumericR e
eR = String
-> (Array DIM1 (Vec2 e) -> Par PTX (Future (Array DIM1 (Vec2 e))))
-> ForeignAcc (Array DIM1 (Vec2 e) -> Array DIM1 (Vec2 e))
forall a b.
String -> (a -> Par PTX (Future b)) -> ForeignAcc (a -> b)
ForeignAcc String
"cuda.fft1d" ((Array DIM1 (Vec2 e) -> Par PTX (Future (Array DIM1 (Vec2 e))))
-> ForeignAcc (Array DIM1 (Vec2 e) -> Array DIM1 (Vec2 e)))
-> (Array DIM1 (Vec2 e) -> Par PTX (Future (Array DIM1 (Vec2 e))))
-> ForeignAcc (Array DIM1 (Vec2 e) -> Array DIM1 (Vec2 e))
forall a b. (a -> b) -> a -> b
$ Plans (DIM1, Type)
-> Mode
-> ShapeR DIM1
-> NumericR e
-> Array DIM1 (Vec2 e)
-> Par PTX (Future (Array DIM1 (Vec2 e)))
forall sh e.
Plans (sh, Type)
-> Mode
-> ShapeR sh
-> NumericR e
-> Array sh (Vec2 e)
-> Par PTX (Future (Array sh (Vec2 e)))
fft' Plans (DIM1, Type)
fft1D_plans Mode
mode ShapeR DIM1
dim1 NumericR e
eR
fft2D :: Mode -> NumericR e -> ForeignAcc (Array DIM2 (Vec2 e) -> Array DIM2 (Vec2 e))
fft2D :: Mode
-> NumericR e
-> ForeignAcc (Array DIM2 (Vec2 e) -> Array DIM2 (Vec2 e))
fft2D Mode
mode NumericR e
eR = String
-> (Array DIM2 (Vec2 e) -> Par PTX (Future (Array DIM2 (Vec2 e))))
-> ForeignAcc (Array DIM2 (Vec2 e) -> Array DIM2 (Vec2 e))
forall a b.
String -> (a -> Par PTX (Future b)) -> ForeignAcc (a -> b)
ForeignAcc String
"cuda.fft2d" ((Array DIM2 (Vec2 e) -> Par PTX (Future (Array DIM2 (Vec2 e))))
-> ForeignAcc (Array DIM2 (Vec2 e) -> Array DIM2 (Vec2 e)))
-> (Array DIM2 (Vec2 e) -> Par PTX (Future (Array DIM2 (Vec2 e))))
-> ForeignAcc (Array DIM2 (Vec2 e) -> Array DIM2 (Vec2 e))
forall a b. (a -> b) -> a -> b
$ Plans (DIM2, Type)
-> Mode
-> ShapeR DIM2
-> NumericR e
-> Array DIM2 (Vec2 e)
-> Par PTX (Future (Array DIM2 (Vec2 e)))
forall sh e.
Plans (sh, Type)
-> Mode
-> ShapeR sh
-> NumericR e
-> Array sh (Vec2 e)
-> Par PTX (Future (Array sh (Vec2 e)))
fft' Plans (DIM2, Type)
fft2D_plans Mode
mode ShapeR DIM2
dim2 NumericR e
eR
fft3D :: Mode -> NumericR e -> ForeignAcc (Array DIM3 (Vec2 e) -> Array DIM3 (Vec2 e))
fft3D :: Mode
-> NumericR e
-> ForeignAcc (Array DIM3 (Vec2 e) -> Array DIM3 (Vec2 e))
fft3D Mode
mode NumericR e
eR = String
-> (Array DIM3 (Vec2 e) -> Par PTX (Future (Array DIM3 (Vec2 e))))
-> ForeignAcc (Array DIM3 (Vec2 e) -> Array DIM3 (Vec2 e))
forall a b.
String -> (a -> Par PTX (Future b)) -> ForeignAcc (a -> b)
ForeignAcc String
"cuda.fft3d" ((Array DIM3 (Vec2 e) -> Par PTX (Future (Array DIM3 (Vec2 e))))
-> ForeignAcc (Array DIM3 (Vec2 e) -> Array DIM3 (Vec2 e)))
-> (Array DIM3 (Vec2 e) -> Par PTX (Future (Array DIM3 (Vec2 e))))
-> ForeignAcc (Array DIM3 (Vec2 e) -> Array DIM3 (Vec2 e))
forall a b. (a -> b) -> a -> b
$ Plans (DIM3, Type)
-> Mode
-> ShapeR DIM3
-> NumericR e
-> Array DIM3 (Vec2 e)
-> Par PTX (Future (Array DIM3 (Vec2 e)))
forall sh e.
Plans (sh, Type)
-> Mode
-> ShapeR sh
-> NumericR e
-> Array sh (Vec2 e)
-> Par PTX (Future (Array sh (Vec2 e)))
fft' Plans (DIM3, Type)
fft3D_plans Mode
mode ShapeR DIM3
dim3 NumericR e
eR
{-# INLINEABLE fft' #-}
fft' :: forall sh e.
Plans (sh, FFT.Type)
-> Mode
-> ShapeR sh
-> NumericR e
-> Array sh (Vec2 e)
-> Par PTX (Future (Array sh (Vec2 e)))
fft' :: Plans (sh, Type)
-> Mode
-> ShapeR sh
-> NumericR e
-> Array sh (Vec2 e)
-> Par PTX (Future (Array sh (Vec2 e)))
fft' Plans (sh, Type)
plans Mode
mode ShapeR sh
shR NumericR e
eR =
let
go :: ArrayR (Array sh (Vec2 e)) -> Array sh (Vec2 e) -> Par PTX (Future (Array sh (Vec2 e)))
go :: ArrayR (Array sh (Vec2 e))
-> Array sh (Vec2 e) -> Par PTX (Future (Array sh (Vec2 e)))
go ArrayR (Array sh (Vec2 e))
aR Array sh (Vec2 e)
ain = do
let
sh :: sh
sh = Array sh (Vec2 e) -> sh
forall sh e. Array sh e -> sh
shape Array sh (Vec2 e)
ain
t :: Type
t = NumericR e -> Type
forall e. NumericR e -> Type
fftType NumericR e
eR
Array sh (Vec2 e)
aout <- ArrayR (Array sh (Vec2 e)) -> sh -> Par PTX (Array sh (Vec2 e))
forall arch sh e.
Remote arch =>
ArrayR (Array sh e) -> sh -> Par arch (Array sh e)
allocateRemote ArrayR (Array sh (Vec2 e))
aR sh
sh
Stream
stream <- (ParState -> Stream) -> Par PTX Stream
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks ParState -> Stream
ptxStream
Future (Array sh (Vec2 e))
future <- Par PTX (Future (Array sh (Vec2 e)))
forall arch a.
(Async arch, HasCallStack) =>
Par arch (FutureR arch a)
new
LLVM PTX () -> Par PTX ()
forall arch a.
(Async arch, HasCallStack) =>
LLVM arch a -> Par arch a
liftPar (LLVM PTX () -> Par PTX ()) -> LLVM PTX () -> Par PTX ()
forall a b. (a -> b) -> a -> b
$
NumericR e
-> Array sh (Vec2 e)
-> Stream
-> (DevicePtr e -> LLVM PTX ())
-> LLVM PTX ()
forall e sh b.
NumericR e
-> Array sh (Vec2 e)
-> Stream
-> (DevicePtr e -> LLVM PTX b)
-> LLVM PTX b
withArray NumericR e
eR Array sh (Vec2 e)
ain Stream
stream ((DevicePtr e -> LLVM PTX ()) -> LLVM PTX ())
-> (DevicePtr e -> LLVM PTX ()) -> LLVM PTX ()
forall a b. (a -> b) -> a -> b
$ \DevicePtr e
d_in -> do
NumericR e
-> Array sh (Vec2 e)
-> Stream
-> (DevicePtr e -> LLVM PTX ())
-> LLVM PTX ()
forall e sh b.
NumericR e
-> Array sh (Vec2 e)
-> Stream
-> (DevicePtr e -> LLVM PTX b)
-> LLVM PTX b
withArray NumericR e
eR Array sh (Vec2 e)
aout Stream
stream ((DevicePtr e -> LLVM PTX ()) -> LLVM PTX ())
-> (DevicePtr e -> LLVM PTX ()) -> LLVM PTX ()
forall a b. (a -> b) -> a -> b
$ \DevicePtr e
d_out -> do
Plans (sh, Type)
-> (sh, Type) -> (Handle -> LLVM PTX ()) -> LLVM PTX ()
forall a b. Plans a -> a -> (Handle -> LLVM PTX b) -> LLVM PTX b
withPlan Plans (sh, Type)
plans (sh
sh,Type
t) ((Handle -> LLVM PTX ()) -> LLVM PTX ())
-> (Handle -> LLVM PTX ()) -> LLVM PTX ()
forall a b. (a -> b) -> a -> b
$ \Handle
h -> do
IO () -> LLVM PTX ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> LLVM PTX ()) -> IO () -> LLVM PTX ()
forall a b. (a -> b) -> a -> b
$ NumericR e
-> Handle
-> Mode
-> Stream
-> DevicePtr (Complex e)
-> DevicePtr (Complex e)
-> IO ()
forall e.
NumericR e
-> Handle
-> Mode
-> Stream
-> DevicePtr (Complex e)
-> DevicePtr (Complex e)
-> IO ()
cuFFT NumericR e
eR Handle
h Mode
mode Stream
stream (DevicePtr e -> DevicePtr (Complex e)
forall a b. DevicePtr a -> DevicePtr b
castDevPtr DevicePtr e
d_in) (DevicePtr e -> DevicePtr (Complex e)
forall a b. DevicePtr a -> DevicePtr b
castDevPtr DevicePtr e
d_out)
FutureR PTX (Array sh (Vec2 e)) -> Array sh (Vec2 e) -> Par PTX ()
forall arch a.
(Async arch, HasCallStack) =>
FutureR arch a -> a -> Par arch ()
put FutureR PTX (Array sh (Vec2 e))
Future (Array sh (Vec2 e))
future Array sh (Vec2 e)
aout
Future (Array sh (Vec2 e)) -> Par PTX (Future (Array sh (Vec2 e)))
forall (m :: * -> *) a. Monad m => a -> m a
return Future (Array sh (Vec2 e))
future
in
case NumericR e
eR of
NumericR e
NumericRfloat32 -> ArrayR (Array sh (Vec2 e))
-> Array sh (Vec2 e) -> Par PTX (Future (Array sh (Vec2 e)))
go (ShapeR sh -> TypeR (Vec2 e) -> ArrayR (Array sh (Vec2 e))
forall sh e. ShapeR sh -> TypeR e -> ArrayR (Array sh e)
ArrayR ShapeR sh
shR (Elt (Complex Float) => TypeR (EltR (Complex Float))
forall a. Elt a => TypeR (EltR a)
eltR @(Complex Float)))
NumericR e
NumericRfloat64 -> ArrayR (Array sh (Vec2 e))
-> Array sh (Vec2 e) -> Par PTX (Future (Array sh (Vec2 e)))
go (ShapeR sh -> TypeR (Vec2 e) -> ArrayR (Array sh (Vec2 e))
forall sh e. ShapeR sh -> TypeR e -> ArrayR (Array sh e)
ArrayR ShapeR sh
shR (Elt (Complex Double) => TypeR (EltR (Complex Double))
forall a. Elt a => TypeR (EltR a)
eltR @(Complex Double)))
{-# INLINE cuFFT #-}
cuFFT :: NumericR e
-> FFT.Handle
-> Mode
-> Stream
-> DevicePtr (Complex e)
-> DevicePtr (Complex e)
-> IO ()
cuFFT :: NumericR e
-> Handle
-> Mode
-> Stream
-> DevicePtr (Complex e)
-> DevicePtr (Complex e)
-> IO ()
cuFFT NumericR e
eR Handle
p Mode
mode Stream
stream DevicePtr (Complex e)
d_in DevicePtr (Complex e)
d_out =
Stream -> (Stream -> IO ()) -> IO ()
forall a b. Lifetime a -> (a -> IO b) -> IO b
withLifetime Stream
stream ((Stream -> IO ()) -> IO ()) -> (Stream -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Stream
s -> do
Handle -> Stream -> IO ()
FFT.setStream Handle
p Stream
s
case NumericR e
eR of
NumericR e
NumericRfloat32 -> Handle
-> Mode
-> DevicePtr (Complex Float)
-> DevicePtr (Complex Float)
-> IO ()
FFT.execC2C Handle
p (Mode -> Mode
fftMode Mode
mode) DevicePtr (Complex e)
DevicePtr (Complex Float)
d_in DevicePtr (Complex e)
DevicePtr (Complex Float)
d_out
NumericR e
NumericRfloat64 -> Handle
-> Mode
-> DevicePtr (Complex Double)
-> DevicePtr (Complex Double)
-> IO ()
FFT.execZ2Z Handle
p (Mode -> Mode
fftMode Mode
mode) DevicePtr (Complex e)
DevicePtr (Complex Double)
d_in DevicePtr (Complex e)
DevicePtr (Complex Double)
d_out
fftType :: NumericR e -> FFT.Type
fftType :: NumericR e -> Type
fftType NumericR e
NumericRfloat32 = Type
FFT.C2C
fftType NumericR e
NumericRfloat64 = Type
FFT.Z2Z
fftMode :: Mode -> FFT.Mode
fftMode :: Mode -> Mode
fftMode Mode
Forward = Mode
FFT.Forward
fftMode Mode
_ = Mode
FFT.Inverse
{-# NOINLINE fft1D_plans #-}
fft1D_plans :: Plans (DIM1, FFT.Type)
fft1D_plans :: Plans (DIM1, Type)
fft1D_plans
= IO (Plans (DIM1, Type)) -> Plans (DIM1, Type)
forall a. IO a -> a
unsafePerformIO
(IO (Plans (DIM1, Type)) -> Plans (DIM1, Type))
-> IO (Plans (DIM1, Type)) -> Plans (DIM1, Type)
forall a b. (a -> b) -> a -> b
$ ((DIM1, Type) -> IO Handle)
-> ((DIM1, Type) -> Int) -> IO (Plans (DIM1, Type))
forall a. (a -> IO Handle) -> (a -> Int) -> IO (Plans a)
createPlan (\(((), Int
n), Type
t) -> Int -> Type -> Int -> IO Handle
FFT.plan1D Int
n Type
t Int
1)
(\(((), Int
n), Type
t) -> Type -> Int
forall a. Enum a => a -> Int
fromEnum Type
t Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
n)
{-# NOINLINE fft2D_plans #-}
fft2D_plans :: Plans (DIM2, FFT.Type)
fft2D_plans :: Plans (DIM2, Type)
fft2D_plans
= IO (Plans (DIM2, Type)) -> Plans (DIM2, Type)
forall a. IO a -> a
unsafePerformIO
(IO (Plans (DIM2, Type)) -> Plans (DIM2, Type))
-> IO (Plans (DIM2, Type)) -> Plans (DIM2, Type)
forall a b. (a -> b) -> a -> b
$ ((DIM2, Type) -> IO Handle)
-> ((DIM2, Type) -> Int) -> IO (Plans (DIM2, Type))
forall a. (a -> IO Handle) -> (a -> Int) -> IO (Plans a)
createPlan (\((((),Int
h),Int
w), Type
t) -> Int -> Int -> Type -> IO Handle
FFT.plan2D Int
h Int
w Type
t)
(\((((),Int
h),Int
w), Type
t) -> Type -> Int
forall a. Enum a => a -> Int
fromEnum Type
t Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
h Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
w)
{-# NOINLINE fft3D_plans #-}
fft3D_plans :: Plans (DIM3, FFT.Type)
fft3D_plans :: Plans (DIM3, Type)
fft3D_plans
= IO (Plans (DIM3, Type)) -> Plans (DIM3, Type)
forall a. IO a -> a
unsafePerformIO
(IO (Plans (DIM3, Type)) -> Plans (DIM3, Type))
-> IO (Plans (DIM3, Type)) -> Plans (DIM3, Type)
forall a b. (a -> b) -> a -> b
$ ((DIM3, Type) -> IO Handle)
-> ((DIM3, Type) -> Int) -> IO (Plans (DIM3, Type))
forall a. (a -> IO Handle) -> (a -> Int) -> IO (Plans a)
createPlan (\(((((),Int
d),Int
h),Int
w), Type
t) -> Int -> Int -> Int -> Type -> IO Handle
FFT.plan3D Int
d Int
h Int
w Type
t)
(\(((((),Int
d),Int
h),Int
w), Type
t) -> Type -> Int
forall a. Enum a => a -> Int
fromEnum Type
t Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
d Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
h Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
w)
{-# NOINLINE fft2DMany_plans #-}
fft2DMany_plans :: Plans (DIM2, FFT.Type)
fft2DMany_plans :: Plans (DIM2, Type)
fft2DMany_plans
= IO (Plans (DIM2, Type)) -> Plans (DIM2, Type)
forall a. IO a -> a
unsafePerformIO
(IO (Plans (DIM2, Type)) -> Plans (DIM2, Type))
-> IO (Plans (DIM2, Type)) -> Plans (DIM2, Type)
forall a b. (a -> b) -> a -> b
$ ((DIM2, Type) -> IO Handle)
-> ((DIM2, Type) -> Int) -> IO (Plans (DIM2, Type))
forall a. (a -> IO Handle) -> (a -> Int) -> IO (Plans a)
createPlan (\((((),Int
h),Int
w), Type
t) -> [Int]
-> Maybe ([Int], Int, Int)
-> Maybe ([Int], Int, Int)
-> Type
-> Int
-> IO Handle
FFT.planMany [Int
w] Maybe ([Int], Int, Int)
forall a. Maybe a
Nothing Maybe ([Int], Int, Int)
forall a. Maybe a
Nothing Type
t Int
h)
(\((((),Int
h),Int
w), Type
t) -> Type -> Int
forall a. Enum a => a -> Int
fromEnum Type
t Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
h Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
w)
{-# NOINLINE fft3DMany_plans #-}
fft3DMany_plans :: Plans (DIM3, FFT.Type)
fft3DMany_plans :: Plans (DIM3, Type)
fft3DMany_plans
= IO (Plans (DIM3, Type)) -> Plans (DIM3, Type)
forall a. IO a -> a
unsafePerformIO
(IO (Plans (DIM3, Type)) -> Plans (DIM3, Type))
-> IO (Plans (DIM3, Type)) -> Plans (DIM3, Type)
forall a b. (a -> b) -> a -> b
$ ((DIM3, Type) -> IO Handle)
-> ((DIM3, Type) -> Int) -> IO (Plans (DIM3, Type))
forall a. (a -> IO Handle) -> (a -> Int) -> IO (Plans a)
createPlan (\(((((()),Int
d),Int
h),Int
w), Type
t) -> [Int]
-> Maybe ([Int], Int, Int)
-> Maybe ([Int], Int, Int)
-> Type
-> Int
-> IO Handle
FFT.planMany [Int
w] Maybe ([Int], Int, Int)
forall a. Maybe a
Nothing Maybe ([Int], Int, Int)
forall a. Maybe a
Nothing Type
t (Int
dInt -> Int -> Int
forall a. Num a => a -> a -> a
*Int
h))
(\(((((()),Int
d),Int
h),Int
w), Type
t) -> Type -> Int
forall a. Enum a => a -> Int
fromEnum Type
t Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
d Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
h Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
w)