FSCL.Compiler


FSCL Compiler

FSCL Compiler is a source-to-source compiler that translates quoted F# function calls and other contructs into valid C99 OpenCL kernel sources, enabling programming OpenCL-enabled parallel devices from within F#.

  • FSCL Repocontribute to FSCL on GitHub

  • FSCL Blogthe FSCL website where tutorials, benchmarks, ideas, updates are continuosly posted

  • FSCL on Twitterkeep up to date with all the FSCL news

How to get FSCL Compiler

The FSCL Compiler library can be installed from NuGet:
PM> Install-Package FSCL.Compiler

Getting started with FSCL.Compiler

FSCL Compiler is able to produce valid OpenCL source code from quoted expressions containing:

  • The name (ref) or call to an FSCL kernel
  • The name (ref) or call to a Array collection function (e.g. Array.reverse, Array.map2)
  • The name (ref) or call to a "regular" function or static/instance method

An FSCL kernel is an F# function or static/instance method marked with [] attribute (to enable the compiler to inspect the AST of its body) and resembling an OpenCL C kernel. Aside from the differences in syntax and in part of the object-model/programming constructs, every OpenCL kernel a programmer can express in C99 can be coded in F# as well. For example, an OpenCL C kernel to execute parallel vector addition would look like:

__kernel void vectorAdd(__global float * a, __global const float * b, __global float * c)
{
    int myId = get_global_id(0);
    c[myId] = a[myId] + b[myId];
}

In FSCL, the same kernel can be coded as follows:

1: 
2: 
3: 
4: 
5: 
6: 
7: 
8: 
open FSCL
open FSCL.Compiler
open FSCL.Language

[<ReflectedDefinition>]
let VectorAdd(a: float32[], b:float32[], c:float32[], wi: WorkItemInfo) =
    let myId = wi.GlobalID(0)
    c.[myId] <- a.[myId] + b.[myId]

The major difference between an OpenCL kernel written in C and the equivalent in FSCL is the additional parameter of type WorkItemInfo, which contains all the functions related to the work items domain (including barrier). Whereas in OpenCL C programmers you use global functions like getglobalid() and getlocalsize(), in FSCL you invoke matching functions exposed by the additional parameter (wi.GlobalId(), wi.LocalSize()).

To compile an FSCL kernel to OpenCL, you need to instantiate the FSCL Compiler and to pass the quoted kernel call or reference to the Compile method.

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
// Instantiate the compiler
let compiler = new Compiler()
// Pass a kernel
let resultCompilingRef = compiler.Compile(<@ VectorAdd @>)
// Or a kernel call
let a = Array.create 1024 2.0f
let b = Array.create 1024 3.0f
let c = Array.zeroCreate<float32> 1024
let size = WorkSize(a.LongLength, 64L)
let resultCompilingCall = compiler.Compile(<@ VectorAdd(a, b, c, size) @>)

Tutorials and Documentation

The FSCL Compiler API documentation is under development and will be available soon. In the meantime, take a look to the following tutorials.

Contributing and copyright

The project is hosted on GitHub where you can report issues, fork the project and submit pull requests. If you're adding new public API, please also consider adding samples that can be turned into a documentation. You might also want to read library design notes to understand how it works.

The library is available under Apache 2.0 license. For more information see the License file in the GitHub repository.

Multiple items
type ReflectedDefinitionAttribute =
  inherit Attribute
  new : unit -> ReflectedDefinitionAttribute

Full name: Microsoft.FSharp.Core.ReflectedDefinitionAttribute

--------------------
new : unit -> ReflectedDefinitionAttribute
val VectorAdd : a:float32 [] * b:float32 [] * c:float32 [] * wi:'a -> unit

Full name: Index.VectorAdd
val a : float32 []
Multiple items
val float32 : value:'T -> float32 (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.float32

--------------------
type float32 = System.Single

Full name: Microsoft.FSharp.Core.float32

--------------------
type float32<'Measure> = float32

Full name: Microsoft.FSharp.Core.float32<_>
val b : float32 []
val c : float32 []
val wi : 'a
val myId : int
val compiler : obj

Full name: Index.compiler
val resultCompilingRef : obj

Full name: Index.resultCompilingRef
val a : float32 []

Full name: Index.a
module Array

from Microsoft.FSharp.Collections
val create : count:int -> value:'T -> 'T []

Full name: Microsoft.FSharp.Collections.Array.create
val b : float32 []

Full name: Index.b
val c : float32 []

Full name: Index.c
val zeroCreate : count:int -> 'T []

Full name: Microsoft.FSharp.Collections.Array.zeroCreate
val size : obj

Full name: Index.size
property System.Array.LongLength: int64
val resultCompilingCall : obj

Full name: Index.resultCompilingCall
Fork me on GitHub