futhask-1.0.0: src/Headers.hs
{-# LANGUAGE OverloadedStrings, MultilineStrings #-}
module Headers where
import Data.List (intercalate)
import Backends
import Futhark.Manifest
import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Text.IO as T
import qualified Data.Text.Encoding as T
import qualified Data.ByteString as B
import qualified Data.Char as C
import qualified Data.Map.Strict as M
data Import = N Text | Q Text Text
globalImport (N m) = "import " <> m <> "\n"
globalImport (Q m a) = "import qualified " <> m <> " as " <> a <> "\n"
localImport moduleName (N sub) = globalImport $ N (moduleName <> "." <> sub)
localImport moduleName (Q sub a) = globalImport $ Q (moduleName <> "." <> sub) a
ffi = "ForeignFunctionInterface"
duprec = "DuplicateRecordFields"
typefamilies = "TypeFamilyDependencies"
typesynonyms = "LiberalTypeSynonyms"
undecidable = "UndecidableInstances"
applicativedo = "ApplicativeDo"
ctypes = [ N "Foreign.C.Types hiding (CBool)", N "Foreign.C.String", N "Foreign.Ptr" ]
primtypes = [ N "Futhask.PrimTypes" ]
arrays = [ N "Futhask.Array" ]
mcomment t = "\n{-|\n" <> t <> "\n-}\n"
haskellHeader desc doc exports extensions localImports globalImports moduleName subModuleName
= (if length extensions > 0
then "{-# LANGUAGE " <> T.intercalate ", " extensions <> " #-}"
else "")
<> mcomment desc
<> "module "
<> moduleName <> (case subModuleName of Nothing -> ""; Just n -> "." <> n)
<> (if length exports > 0 then " (" <> T.intercalate ", " exports <> ")" else "")
<> " where\n"
<> mconcat (map (localImport moduleName) localImports)
<> mconcat (map globalImport globalImports)
<> "\n"
<> doc
<> "\n"
exportsHeader name = haskellHeader desc doc [] extensions localImports globalImports name (Nothing)
where
extensions = []
exports =
[ "module M"
, "module T"
, "module E"
, "module C"
, "module F" ]
localImports =
[ N "Monad as M"
, N "Types as T"
, N "EntryPoints as E"
, N "Conversion as C" ]
globalImports = [N "Futhask.Object as F"]
desc = "Export of common interface"
doc = T.replace "LIB" name $
"""
-- * Introduction
-- $introduction
-- This Haskell library was generated from a [Futhark](https://www.futhark-lang.org) program by the futhark-haskell bridge [Futhask](https://gitlab.com/Gusten_Isfeldt/futhask).
-- * Interfaces
-- $interfaces
-- @Futhask@ defines two interfaces, either of which may be appropriate for a use case.
-- ** Raw
-- $rawinterface
-- Defined in the \"LIB.Raw\" module, the raw interface is simply the C-API wrapped in the IO-monad, with no additional safety or convenience. Manual memory management is required and error codes must be handled by the user.
-- This could be useful if working with a small loop where overhead needs to be minimized and manual memory management would be used anyway.
-- Some parts of the C-API are not yet utilized by the wrapped interface and are thus only accessible through the raw interface.
-- ** Wrapped
-- $wrappedinterface
-- Defined in \"LIB\", the wrapped interface provides a safer and more convenient way to use the Futhark functions. It provides types closer to those used within the futhark program, enables garbage collection of all values, conversion to and from futhark types, passes the context implicitly through a reader style monad, and emits any errors from the context.
-- What the wrapper does NOT prevent, and will result in errors:
--
-- - Use after free if *manually* finalizing values with `finalizeFO`
--
-- - Mismatched sizes in arguments
-- * Types
-- $types
-- For each Futhark type in the manifest some types are defined in the generated library. They are all named based on the Futhark type. Named types just have their name capitalized, and unnamed types like records, sums, and arrays, get a name that describes the type structurally. For clarity the original Futhark type is included in the documentation of each module.
-- ** Raw
-- $rawtypes
-- \"LIB.Raw.TypeDec\" defines data types that have no constructor and only serve to parameterize the pointers used in the raw C-API. These are used in the raw interface and internally to create the wrapped interface.
-- ** Wrapped
-- $wrappedtypes
-- \"LIB.TypeDec\" defines the primary types used in the wrapped interface. These data types are wrappers around the raw pointers, and come with reference counters and finalizers. To prevent them from escaping the context to which they belong they are parameterized by a skolem type variable, similar to mutable objects in the @ST@-monad.
-- ** Native
-- $nativetypes
-- \"LIB.Native.Types\" defines haskell native data types and synomyms that correspond to the wrapped types. These are primarily useful for lighter processing of data going into and coming out of the context through the `Convertible` class.
-- ** Unpacked
-- $unpackedtypes
-- \"LIB.Unpacked.Types\" defines types unpacked versions of composite types, such as records, record arrays, and sums. They are used to compose and decompose such values from their components through the `FutharkComposite` class.
-- * Monad
-- $monad
-- Computations in the wrapped interface are in the @Monad m => FutT c m@ monad
-- and can be run by using the functions in \"LIB.Monad\"
-- which is a version of the general \"Futhask.Monad\" specialized to \"LIB.Context\".
"""
nativeTypesHeader name = haskellHeader desc doc [] extensions [] globalImports name (Just "Native.Types")
where
extensions = [duprec, typefamilies, applicativedo]
globalImports = primtypes ++ arrays
desc = "Native types that mirror the types in the manifest"
doc = ""
nativeTypeOpsHeader name = haskellHeader desc doc [] extensions [] globalImports name (Just "Native.TypeOps")
where
extensions = []
globalImports = []
desc = mcomment "Various instances for generated native types"
doc = ""
rawHeader name = haskellHeader desc doc [] extensions localImports globalImports name (Just "Raw (module C, module E, module T)")
where
extensions = []
localImports =
[ N "Raw.Context as C"
, N "Raw.EntryPoints as E"
, N "Raw.Types as T"]
globalImports = []
desc = "export of raw interface"
doc = ""
rawContextHeader name = haskellHeader desc doc [] extensions localImports globalImports name (Just "Raw.Context")
where
extensions = [ffi]
localImports = []
globalImports = ctypes
desc = "raw context operations"
doc = ""
rawTypesHeader name = haskellHeader desc doc [] extensions localImports globalImports name (Just "Raw.Types (module Dec, module Ops)")
where
extensions = []
localImports =
[ N "Raw.TypeDec as Dec"
, N "Raw.TypeOps as Ops"]
globalImports = []
desc = "Reexport of @Raw.TypeDec@ and @Raw.TypeOps@"
doc = ""
rawTypeDecHeader name = haskellHeader desc doc [] extensions localImports globalImports name (Just "Raw.TypeDec")
where
extensions = [ffi]
localImports = []
globalImports = []
desc = "raw types"
doc = ""
rawTypeOpsHeader name = haskellHeader desc doc [] extensions localImports globalImports name (Just "Raw.TypeOps")
where
extensions = [ffi]
localImports =
[ Q "Raw.TypeDec" "Raw", Q "Raw.Context" "C" ]
globalImports = ctypes ++ primtypes
desc = "raw type operations"
doc = ""
rawEntryPointsHeader name = haskellHeader desc doc [] extensions localImports globalImports name (Just "Raw.EntryPoints")
where
extensions = [ffi]
localImports =
[ Q "Raw.Context" "C"
, Q "Raw.TypeDec" "Raw" ]
globalImports =
[ N "Foreign.Ptr", N "Foreign.C.Types(CBool)" ] ++ primtypes
desc = "Raw entry points"
doc = ""
monadHeader name = haskellHeader desc doc [] extensions localImports globalImports name (Just "Monad")
where
extensions = []
localImports =
[ N "Context" ]
globalImports =
[ N "Control.Monad.IO.Class", Q "Futhask.Monad" "Futhask" ]
desc = "This module specializes \"Futhask.Monad\" to the \"" <> name <> ".Context\", for the general version see original module"
doc = ""
contextHeader name = haskellHeader desc doc [] extensions localImports globalImports name (Just "Context(Context, mkContext, Futhask.ContextOption(..))")
where
extensions = [typefamilies]
localImports =
[ Q "Raw.Context" "Raw" ]
globalImports =
[ Q "Futhask.Context" "Futhask", N "Foreign.ForeignPtr" ]
desc = "Context for \"" <> name <> "\", for more functions and more general definitions, see \"Futhask.Context\"."
doc = ""
typeDecHeader name = haskellHeader desc doc [] extensions localImports globalImports name (Just "TypeDec")
where
extensions = []
localImports =
[ Q "Context" "C"
, Q "Raw.TypeDec" "Raw" ]
globalImports =
[ Q "Futhask.Context" "Futhask"
, Q "Foreign.ForeignPtr" "F" ]
desc = "Wrapped types parameterized by a skolem type variable locking them to a context"
doc = ""
typesHeader name = haskellHeader desc doc [] extensions localImports globalImports name (Just "Types(module Dec, module Ops)")
where
extensions = []
localImports =
[ N "TypeDec as Dec"
, N "TypeOps as Ops" ]
globalImports = []
desc = "Rexport @TypeDec@ and @TypeOps@"
doc = ""
typeOpsHeader name = haskellHeader desc doc [] extensions localImports globalImports name (Just "TypeOps")
where
extensions = [typefamilies, typesynonyms]
localImports =
[ Q "Context" "C"
, Q "Raw.TypeDec" "Raw"
, Q "Raw.TypeOps" "Raw"
, Q "TypeDec" "Wrapped"
, Q "Unpacked.Types" "Unpacked"]
globalImports =
[ Q "Futhask.Context" "Futhask"
, N "Futhask.Context"
, Q "Futhask.Object" "Futhask"
, N "Futhask.PrimTypes"
, N "Futhask.Array.Rank"
, N "Futhask.Object"
, N "Futhask.Monad"
--, N "Futhask.Object (wrapFO, FutharkObject, FutharkOpaque, FutharkRecord, FutIndexable, FutharkPrimArray', FutharkOpaqueArray')"
, Q "Foreign.ForeignPtr" "F"
, N "Foreign.Storable (peek)"
, N "Foreign.Marshal.Alloc (alloca)"]
desc = "Various instance declarations"
doc = ""
unpackedTypesHeader name = haskellHeader desc doc [] extensions localImports globalImports name (Just "Unpacked.Types")
where
extensions = [duprec]
localImports =
[ Q "TypeDec" "Packed" ]
globalImports = primtypes
desc = "Unpacked types for value composition and decomposition"
doc = ""
entryPointsHeader name = haskellHeader desc doc [] extensions localImports globalImports name (Just "EntryPoints")
where
extensions = []
localImports =
[ Q "Monad" "M"
, N "Types"
, Q "Raw.EntryPoints" "RawEntry"
, Q "Raw.TypeOps" "Raw" ]
globalImports =
[ N "Control.Monad.IO.Class"
, Q "Futhask.Context" "C"
, Q "Futhask.Object" "O"
, Q "Foreign.Marshal.Alloc" "F"
, Q "Foreign.Storable" "F"
, Q "Foreign.Marshal.Utils" "F"]
++ primtypes
desc = "This module provides wrapped entry points. The input and output types are intended to mimic the Futhark types as closely as possible, by packing tuple inputs and unpacking tuple outputs internally. The functions are in the general @Monad => FutT c m@ monad, unless any inputs are unique, in which case they will be restricted to the @MonadIO m => FutT c m@ monad. Unique inputs are finalized on use and may no longer be used after."
doc = ""
conversionHeader name = haskellHeader desc doc [] extensions localImports globalImports name (Just "Conversion")
where
extensions = [typefamilies, undecidable, typesynonyms]
localImports =
[ N "Monad"
, N "TypeOps"
, Q "TypeDec" "Futhark"
, Q "Unpacked.Types" "Unpacked"
, Q "Native.Types" "Haskell"
, Q "Raw.TypeOps" "Raw"]
globalImports =
[ N "Futhask.Object"
, N "Futhask.Array as A"
, N "Futhask.Context"
, Q "Foreign.ForeignPtr" "F"
, Q "Foreign.Storable" "F"
, Q "Foreign.Marshal.Array" "F" ]
desc = "Conversion of values to and from Futhark"
doc = ""