Mandelbrot Set
The Mandelbrot set is a classic example of a “compute-bound” kernel. It involves heavy arithmetic operations per pixel with no dependencies between pixels.
Kernel Code
Each thread computes the color of one pixel by iterating the complex function $z_{n+1} = z_n^2 + c$.
open Sarek
let%kernel mandelbrot (output : int32 vector)
(width : int32) (height : int32)
(max_iter : int32) =
let px = get_global_id 0 in (* x-coordinate *)
let py = get_global_id 1 in (* y-coordinate *)
if px < width && py < height then begin
(* Map pixel to complex plane coordinates *)
let x0 = (4.0 *. (float px /. float width)) -. 2.5 in
let y0 = (3.0 *. (float py /. float height)) -. 1.5 in
let x = ref 0.0 in
let y = ref 0.0 in
let iter = ref 0l in
(* Main iteration loop *)
while (!x *. !x) +. (!y *. !y) <= 4.0 && !iter < max_iter do
let xtemp = (!x *. !x) -. (!y *. !y) +. x0 in
y := (2.0 *. !x *. !y) +. y0;
x := xtemp;
iter := !iter + 1l
done;
(* Store iteration count as pixel value *)
output.((py * width) + px) <- !iter
end
Host Code
let run_mandelbrot () =
let width, height = 1024, 1024 in
let max_iter = 256l in
let output = Vector.create Int32 (width * height) in
Execute.run mandelbrot
~device:(Device.get_default ())
~block:(16, 16, 1)
~grid:((width+15)/16, (height+15)/16, 1)
[Vec output; Int32 width; Int32 height; Int32 max_iter]