Giter VIP home page Giter VIP logo

futhask's Introduction

Futhask

Futhask is a code generator that aims to create safe, Haskell friendly wrappers for Futhark libraries.

Installation

stack install

Use

Generate Code

futhask [Backend] [Futhark.h] [HaskellSourceDir] [ModuleName]

Example

futhark opencl --library myprogram.fut
futhask opencl myprogram.h src MyLibrary

For a simple example of how generated haskell code can be used, see FuthaskExample

Import Code

import [ModuleName]
import [ModuleName].Entries

If using stack add c-sources: [Futhark.c] to the library section of package.yaml

OpenCL

extra-libraries: OpenCL

CUDA

include-dirs: /opt/cuda/include
extra-lib-dirs: /opt/cuda/lib
extra-libraries: cuda cudart nvrtc

Dependencies

transformers and massiv are required for all backends. The codes generated for OpenCL and CUDA, both refer to types from the OpenCL and cuda packages respectively. This is only relevant if one wants to use certain functions in the raw interface, but, without modification, the generated code will not compile without these dependencies.

Generated Code

The generated code can be split in two main parts, raw and wrapped. The raw interface is simply the C-functions wrapped in the IO-monad, providing no added safety and requiring manual memory management. The wrapped interface uses newForeignPtr to introduce all Futhark pointers to the GC, and provides function types closer to those used within Futhark, returning tuples instead of writing to pointers.

Context Generation

getContext :: [ContextOption] -> IO Context

Available context options will depend on backend used.

The Fut monad

To make the wrappers safe, and reduce clutter from explicitly passing around the context, the Fut monad is introduced. The Fut monad is an environment monad that implicitly passes the context around as necessary.

To run computations, the function

runFutIn :: Context -> Fut a -> a

is used. Additionally

runFutWith :: [ContextOption] -> Fut a -> a
runFut :: Fut a -> a

are defined for convienience for cases where the context doesn't need to be reused.

The FutT transformer

For more flexibility, the FutT monad transformer can be used. For convenience the type synonyms

type Fut = FutT Identity
type FutIO = FutT IO

are defined, but entry-points are in the general Monad m => FutT m.

To run the transformer

runFutTIn :: Context -> FutT m a -> m a
runFutTWith :: [ContextOption] -> FutT  m a -> m a
runFutT :: FutT m a -> m a

For lifting

mapFutT :: (m a -> n b) -> FutT m a -> FutT n b
map2FutT :: (m a -> n b -> k c) -> FutT m a -> FutT n b -> FutT k c
pureFut :: Monad m => Fut a -> FutT m a
unsafeFromFutIO :: FutIO a -> Fut a

Input and Output

For conversion between Futhark values and Haskell values, two classes are defined.

class Input fo ho where
    toFuthark :: Monad m => ho -> FutT m fo

class Output fo ho where
    fromFuthark :: Monad m => fo -> FutT m ho

Instances of Input and Output are generated for all transparent Futhark-arrays. The Haskell representation is Array S from Data.Massiv.Array. The absence of functional dependencies in the definitions might require more explicit type signatures, but gives more flexibility to define new instances. For tuples of instances, functions on the form fromFutharkTN, where N is the tuple size, are defined.

Memory management

All of the wrapped values have finalizers, and should eventually be garbage collected. However, GHCs GC does not know how much memory the context is using, and so collection will not always be triggered frequently enough. This is primarily an issue when the program iterates on Futhark values, without any Haskell-side allocations.

One way to deal with this is to manually manage the memory using

finalizeFO :: (MonadIO m, FutharkObject wrapped raw) => wrapped -> FutT m ()

As with any manual memory management, the programmer is responsible for ensuring that the finalized value will not be used afterwards. For cases where the object is used in more than one thread without synchronisation,

addReferenceFO :: (MonadIO m, FutharkObject wrapped raw) => wrapped -> FutT m ()

can be used. addReferenceFO increments the reference counter of the object and finalizeFO will just decrement this counter until it's 0.

futhask's People

Contributors

ianmbloom avatar fluxusmagna avatar camdenkuwahara avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.