fftw-ffi-0.0: tool/GenerateForeignImport.hs
import System.Environment (getArgs)
import Text.Printf (printf)
import qualified Data.List as List
import Data.Foldable (forM_)
import Data.Char (toLower)
data Safety = Unsafe | Safe deriving (Show)
formatSafety :: Safety -> String
formatSafety s =
case s of
Unsafe -> "unsafe"
Safe -> "safe"
lowerInit :: String -> String
lowerInit (c:cs) = toLower c : cs
lowerInit "" = ""
list :: [(String, Safety, String, [String])]
list =
("plan_dft_1d", Safe,
"PlanDFT1d",
"C.CInt ->" :
"Ptr (Complex a) -> Ptr (Complex a) ->" :
"Sign -> Flags -> IO (Plan a)" :
[]) :
("plan_dft_2d", Safe,
"PlanDFT2d",
"C.CInt -> C.CInt ->" :
"Ptr (Complex a) -> Ptr (Complex a) ->" :
"Sign -> Flags -> IO (Plan a)" :
[]) :
("plan_dft_3d", Safe,
"PlanDFT3d",
"C.CInt -> C.CInt -> C.CInt ->" :
"Ptr (Complex a) -> Ptr (Complex a) ->" :
"Sign -> Flags -> IO (Plan a)" :
[]) :
("plan_dft", Safe,
"PlanDFT",
"C.CInt -> Ptr C.CInt ->" :
"Ptr (Complex a) -> Ptr (Complex a) ->" :
"Sign -> Flags -> IO (Plan a)" :
[]) :
("plan_dft_r2c_1d", Safe,
"PlanDFTr2c1d",
"C.CInt ->" :
"Ptr a -> Ptr (Complex a) ->" :
"Flags -> IO (Plan a)" :
[]) :
("plan_dft_r2c_2d", Safe,
"PlanDFTr2c2d",
"C.CInt -> C.CInt ->" :
"Ptr a -> Ptr (Complex a) ->" :
"Flags -> IO (Plan a)" :
[]) :
("plan_dft_r2c_3d", Safe,
"PlanDFTr2c3d",
"C.CInt -> C.CInt -> C.CInt ->" :
"Ptr a -> Ptr (Complex a) ->" :
"Flags -> IO (Plan a)" :
[]) :
("plan_dft_r2c", Safe,
"PlanDFTr2c",
"C.CInt -> Ptr C.CInt ->" :
"Ptr a -> Ptr (Complex a) ->" :
"Flags -> IO (Plan a)" :
[]) :
("plan_dft_c2r_1d", Safe,
"PlanDFTc2r1d",
"C.CInt ->" :
"Ptr (Complex a) -> Ptr a ->" :
"Flags -> IO (Plan a)" :
[]) :
("plan_dft_c2r_2d", Safe,
"PlanDFTc2r2d",
"C.CInt -> C.CInt ->" :
"Ptr (Complex a) -> Ptr a ->" :
"Flags -> IO (Plan a)" :
[]) :
("plan_dft_c2r_3d", Safe,
"PlanDFTc2r3d",
"C.CInt -> C.CInt -> C.CInt ->" :
"Ptr (Complex a) -> Ptr a ->" :
"Flags -> IO (Plan a)" :
[]) :
("plan_dft_c2r", Safe,
"PlanDFTc2r",
"C.CInt -> Ptr C.CInt ->" :
"Ptr (Complex a) -> Ptr a ->" :
"Flags -> IO (Plan a)" :
[]) :
("plan_r2r_1d", Safe,
"PlanR2r1d",
"C.CInt ->" :
"Ptr a -> Ptr a ->" :
"Kind -> Flags -> IO (Plan a)" :
[]) :
("plan_r2r_2d", Safe,
"PlanR2r2d",
"C.CInt -> C.CInt ->" :
"Ptr a -> Ptr a ->" :
"Kind -> Kind -> Flags -> IO (Plan a)" :
[]) :
("plan_r2r_3d", Safe,
"PlanR2r3d",
"C.CInt -> C.CInt -> C.CInt ->" :
"Ptr a -> Ptr a ->" :
"Kind -> Kind -> Kind -> Flags -> IO (Plan a)" :
[]) :
("plan_r2r", Safe,
"PlanR2r",
"C.CInt -> Ptr C.CInt ->" :
"Ptr a -> Ptr a ->" :
"Ptr Kind -> Flags -> IO (Plan a)" :
[]) :
("plan_many_dft", Safe,
"PlanManyDFT",
"C.CInt -> Ptr C.CInt -> C.CInt ->" :
"Ptr (Complex a) -> Ptr C.CInt ->" :
"C.CInt -> C.CInt ->" :
"Ptr (Complex a) -> Ptr C.CInt ->" :
"C.CInt -> C.CInt ->" :
"Sign -> Flags -> IO (Plan a)" :
[]) :
("plan_many_dft_r2c", Safe,
"PlanManyDFTr2c",
"C.CInt -> Ptr C.CInt -> C.CInt ->" :
"Ptr a -> Ptr C.CInt ->" :
"C.CInt -> C.CInt ->" :
"Ptr (Complex a) -> Ptr C.CInt ->" :
"C.CInt -> C.CInt ->" :
"Flags -> IO (Plan a)" :
[]) :
("plan_many_dft_c2r", Safe,
"PlanManyDFTc2r",
"C.CInt -> Ptr C.CInt -> C.CInt ->" :
"Ptr (Complex a) -> Ptr C.CInt ->" :
"C.CInt -> C.CInt ->" :
"Ptr a -> Ptr C.CInt ->" :
"C.CInt -> C.CInt ->" :
"Flags -> IO (Plan a)" :
[]) :
("plan_many_r2r", Safe,
"PlanManyR2r",
"C.CInt -> Ptr C.CInt -> C.CInt ->" :
"Ptr a -> Ptr C.CInt ->" :
"C.CInt -> C.CInt ->" :
"Ptr a -> Ptr C.CInt ->" :
"C.CInt -> C.CInt ->" :
"Ptr Kind -> Flags -> IO (Plan a)" :
[]) :
("plan_guru_dft", Safe,
"PlanGuruDFT",
"C.CInt -> Ptr IODim -> C.CInt -> Ptr IODim ->" :
"Ptr (Complex a) -> Ptr (Complex a) -> Sign -> Flags -> IO (Plan a)" :
[]) :
("plan_guru_dft_r2c", Safe,
"PlanGuruDFTr2c",
"C.CInt -> Ptr IODim -> C.CInt -> Ptr IODim ->" :
"Ptr a -> Ptr (Complex a) -> Flags -> IO (Plan a)" :
[]) :
("plan_guru_dft_c2r", Safe,
"PlanGuruDFTc2r",
"C.CInt -> Ptr IODim -> C.CInt -> Ptr IODim ->" :
"Ptr (Complex a) -> Ptr a -> Flags -> IO (Plan a)" :
[]) :
("plan_guru_r2r", Safe,
"PlanGuruR2r",
"C.CInt -> Ptr IODim -> C.CInt -> Ptr IODim ->" :
"Ptr a -> Ptr a -> Ptr Kind -> Flags -> IO (Plan a)" :
[]) :
("plan_guru_split_dft", Safe,
"PlanGuruSplitDFT",
"C.CInt -> Ptr IODim -> C.CInt -> Ptr IODim ->" :
"Ptr a -> Ptr a -> Ptr a -> Ptr a -> Flags -> IO (Plan a)" :
[]) :
("plan_guru_split_dft_r2c", Safe,
"PlanGuruSplitDFTr2c",
"C.CInt -> Ptr IODim -> C.CInt -> Ptr IODim ->" :
"Ptr a -> Ptr a -> Ptr a -> Flags -> IO (Plan a)" :
[]) :
("plan_guru_split_dft_c2r", Safe,
"PlanGuruSplitDFTc2r",
"C.CInt -> Ptr IODim -> C.CInt -> Ptr IODim ->" :
"Ptr a -> Ptr a -> Ptr a -> Flags -> IO (Plan a)" :
[]) :
("destroy_plan", Safe,
"DestroyPlan",
"Plan a -> IO ()" :
[]) :
("execute", Safe,
"Execute",
"Plan a -> IO ()" :
[]) :
("execute_dft", Safe,
"ExecuteDFT",
"Plan a -> Ptr (Complex a) -> Ptr (Complex a) -> IO ()" :
[]) :
("execute_dft_r2c", Safe,
"ExecuteDFTr2c",
"Plan a -> Ptr a -> Ptr (Complex a) -> IO ()" :
[]) :
("execute_dft_c2r", Safe,
"ExecuteDFTc2r",
"Plan a -> Ptr (Complex a) -> Ptr a -> IO ()" :
[]) :
("execute_r2r", Safe,
"ExecuteR2r",
"Plan a -> Ptr a -> Ptr a -> IO ()" :
[]) :
("execute_split_dft", Safe,
"ExecuteSplitDFT",
"Plan a -> Ptr a -> Ptr a -> Ptr a -> Ptr a -> IO ()" :
[]) :
("execute_split_dft_r2c", Safe,
"ExecuteSplitDFTr2c",
"Plan a -> Ptr a -> Ptr a -> Ptr a -> IO ()" :
[]) :
("execute_split_dft_c2r", Safe,
"ExecuteSplitDFTc2r",
"Plan a -> Ptr a -> Ptr a -> Ptr a -> IO ()" :
[]) :
("malloc", Unsafe,
"Malloc",
"C.CSize -> IO (Ptr a)" :
[]) :
("free", Unsafe,
"Free",
"Ptr a -> IO ()" :
[]) :
("alloc_real", Unsafe,
"AllocReal",
"C.CSize -> IO (Ptr a)" :
[]) :
("alloc_complex", Unsafe,
"AllocComplex",
"C.CSize -> IO (Ptr (Complex a))" :
[]) :
("free", Unsafe,
"FreeComplex",
"Ptr (Complex a) -> IO ()" :
[]) :
[]
-- cf. lapack-ffi-tools
insertExportList :: [String] -> String -> String
insertExportList exports modul =
(\(prefix,suffixes) ->
map fst prefix ++
case suffixes of
[] -> []
(_,suffix):_ ->
"(\n" ++ unlines (map (printf " %s,") exports) ++
" ) " ++ suffix) $
break (List.isPrefixOf "where" . snd) $
zip modul (List.tails modul)
main :: IO ()
main = do
args <- getArgs
case args of
[] ->
forM_ list $ \(_,_,funcName,typeExpr) -> do
printf "\ntype %s a =\n" funcName
mapM_ (printf " %s\n") typeExpr
["--generic", tmplPath] -> do
tmpl <- readFile tmplPath
let export (_,_,funcType,_) =
printf "FFT.%s, %s" funcType (lowerInit funcType)
putStr $ insertExportList (map export list) tmpl
forM_ list $ \(_,_,funcType,_) -> do
let funcName = lowerInit funcType
printf "\n"
printf "newtype %s a =\n" funcType
printf " %s {run%s :: FFT.%s a}\n" funcType funcType funcType
printf "\n"
printf "%s :: (Class.Real a) => FFT.%s a\n" funcName funcType
printf "%s =\n" funcName
printf " run%s $\n" funcType
printf " Class.switchReal\n"
printf " (%s FFTF.%s)\n" funcType funcName
printf " (%s FFTD.%s)\n" funcType funcName
[floatName, cPrefix] ->
forM_ list $ \(cName,safety,funcName,_) -> do
printf "\nforeign import ccall %s \"fftw3.h %s_%s\"\n"
(formatSafety safety) cPrefix cName
printf " %s :: FFT.%s %s\n"
(lowerInit funcName) funcName floatName
_ -> fail "wrong number of arguments"