 Data transfer operations
 Supported kernel operations.
 Supported functions from System.Math and Microsoft.FSharp.Core.Operators: abs, acos, asin, atan, cos, cosh, exp, floor, log, log10, pow, sin, sinh, sqrt, tan, tanh
Array "by index" access is supported.
1:
2:
3:
4:
5:

let command =
<@
fun (range:_1D) (buf:array<_>) >
buf.[1] < buf.[0]
@>

Basic "let" binding is supported. Note, that now we support only "variable bindings". Nested functions, closures are not supported.
1:
2:
3:
4:
5:
6:

let command =
<@
fun (range:_1D) (buf:array<_>) >
let x = 1
let y = (x 1) * (x + 2)
@>

Mutability is available by using of "let mutable" binding.
1:
2:
3:
4:
5:
6:

let command =
<@
fun (range:_1D) (buf:array<_>) >
let mutable x = 1
x < x * 2
@>

Note, that scopes are supported. So, you can "rebind" any name and "F#style" visibility will be emuleted in target code. For example, next code will be translated correctly.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:

let command =
<@
fun (range:_1D) (buf:array<_>) >
let i = 2
for i in 1..3 do
buf.[i] < buf.[i] + 1
buf.[0] < i
@>
let command =
<@
fun (range:_1D) (buf:array<_>) >
for i in 1..3 do
let i = i * 2
buf.[i] < 0
@>

1:
2:
3:
4:
5:
6:

let command =
<@
fun (range:_1D) (buf:array<int>) >
buf.[0] < 2
buf.[1] < 4
@>

1:
2:
3:
4:
5:
6:

let command =
<@
fun (range:_1D) (buf:array<_>) >
while buf.[0] < 5 do
buf.[0] < buf.[0] + 1
@>

1:
2:
3:
4:
5:

let command =
<@
fun (range:_1D) (buf:array<_>) >
for i in 1..3 do buf.[i] < 0
@>

You can use "quotations injection" for code reusing or parameterization. For example, you can write something like this:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:

let myFun = <@ fun x y > y  x @>
let command =
<@
fun (range:_1D) (buf:array<int>) >
buf.[0] < (%myFun) 2 5
buf.[1] < (%myFun) 4 9
@>
let commandTemplate f =
<@
fun (range:_1D) (buf:array<int>) >
buf.[0] < (%f) 2 5
buf.[1] < (%f) 4 9
@>
let cmd1 = commandTemplate <@ fun x y > y  x @>
let cmd2 = commandTemplate <@ fun x y > y + x @>

Structs and tuples transferring and using in kernel code are supported.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:

[<Struct>]
type c =
val x: int
val y: int
new (x1, y1) = {x = x1; y = y1}
new (x1) = {x = x1; y = 0}
let command =
<@
fun(range:_1D) (buf:array<int>) (s:c) >
buf.[0] < s.x + s.y
let s2 = new c(6)
let s3 = new c(s2.y + 6)
buf.[1] < s2.x
@>
let command =
<@
fun(range:_1D) (buf:array<int>) (arr:array<c>) >
buf.[0] < arr.[0].x
@>

Tuples support are limited. Single tuple trunsfer to GPU is supported, but methods Array.ToHost and Array.ToGPU is not.
Also you can use tuples in kernel code.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:

let command =
<@
fun (range:_1D) (buf:array<int>) (k1:int*int) (k2:int64*byte) (k3:float32*int) >
let x = fst k1
buf.[0] < x
buf.[1] < int(fst k3)
@>
let command =
<@
fun (range:_1D) (buf:array<int>) >
let (a, b) = (1, 2)
buf.[0] < a
@>

More examples.