AccelerateHS/accelerate — pull request #78 by robeverest (2013-02-15 05:50:16+00:00)
Title: An FFI for the array language

I've added support for foreign functions to the array language. As per discussions with @tmcdonell, it allows different backends to provide foreign functions in whatever fashion is best for the them. In addition, a foreign call also requires that the user supply a pure Accelerate version of the function as well. This is for backends that do not support foreign functions or if the foreign function is intended for a different backend. For example:

let
f = ... a normal Accelerate function
f' = ... a more efficient foreign function for the CUDA backend
args = ... the arguments to the function (as an Accelerate tuple)
in foreignAcc (cudaFF f') f args

This also allows for different versions of a foreign function for different backends to be chained together, like so:

let
f = ... a normal Accelerate function
f' = ... a more efficient foreign function for the CUDA backend
f'' = ... an also efficient foreign function for a Repa backend
args = ... the arguments to the function (as an Accelerate tuple)
in foreignAcc (cudaFF f') (foreignAcc repaFF f'' f) args

The last part can also be written more simply like this

foreignAcc2 (cudaFF f') (repaFF f'') f args

In order for a backend to implement a foreign function interface, it needs to provide an instance of the ForeignFun class. Look at my pull request for accelerate-cuda to get an example of this.