The Computer Language
Benchmarks Game

mandelbrot F# .NET Core #4 program

source code

// The Computer Language Benchmarks Game
// http://benchmarksgame.alioth.debian.org/
//
// ported from C# version by Anthony Lloyd

#nowarn "9"

open System
open System.Numerics
open System.Runtime.CompilerServices
open System.Threading.Tasks
open Microsoft.FSharp.NativeInterop

let inline ptrGet p i =
    Unsafe.Read(IntPtr.Add(NativePtr.toNativeInt p, 8*i).ToPointer())
let inline ptrSet p i v =
    Unsafe.Write(IntPtr.Add(NativePtr.toNativeInt p, 8*i).ToPointer(), v)

let inline getByte (pcrb:nativeptr<float>) (ciby:float) =
    let rec calc i res =
        if i=8 then res
        else
            let vCrbx = ptrGet pcrb i
            let vCiby = Vector ciby
            let rec calc2 j zr zi b0 b1 =
                let nZr = zr * zr - zi * zi + vCrbx
                let nZi = let zrzi = zr * zi in zrzi + zrzi + vCiby
                let t = nZr * nZr + nZi * nZi
                let b0 = b0 || t.[0]>4.0
                let b1 = b1 || t.[1]>4.0
                if b0 && b1 then 3
                elif j=0 then if b0 then 2 elif b1 then 1 else 0
                else calc2 (j-1) nZr nZi b0 b1
            calc (i+2) ((res<<<2) + calc2 48 vCrbx vCiby false false)
    calc 0 0 ^^^ -1 |> byte

[<EntryPoint>]
let main args =
    let size = if args.Length=0 then 200 else int args.[0]
    let lineLength = size >>> 3
    let s = "P4\n"+string size+" "+string size+"\n"
    let data = Array.zeroCreate (size*lineLength+s.Length)
    Text.ASCIIEncoding.ASCII.GetBytes(s, 0, s.Length, data, 0) |> ignore
    let crb = Array.zeroCreate (size+2)
    use pdata = fixed &data.[s.Length]
    use pcrb = fixed &crb.[0]
    let invN = Vector (2.0/float size)
    let onePtFive = Vector 1.5
    let step = Vector 2.0
    let rec loop i value =
        if i<size then
            ptrSet pcrb i (value*invN-onePtFive)
            loop (i+2) (value+step)
    Vector [|0.0;1.0;0.0;0.0;0.0;0.0;0.0;0.0|] |> loop 0
    Parallel.For(0, size, fun y ->
        let ciby = NativePtr.get pcrb y+0.5
        for x = 0 to lineLength-1 do
            getByte (NativePtr.add pcrb (x*8)) ciby
            |> NativePtr.set pdata (y*lineLength+x)
    ) |> ignore
    Console.OpenStandardOutput().Write(data, 0, data.Length)
    exit 0
    

notes, command-line, and program output

NOTES:
64-bit Ubuntu quad core
2.0.2 a04b4bf512
"System.GC.Server": true


Fri, 10 Nov 2017 20:35:26 GMT

MAKE:
cp mandelbrot.fsharpcore-4.fsharpcore Program.fs
cp Include/fsharpcore/tmp.fsproj .
cp Include/fsharpcore/runtimeconfig.template.json .
mkdir obj
cp Include/fsharpcore/project.assets.json ./obj
cp Include/fsharpcore/tmp.fsproj.nuget.g.props ./obj
cp Include/fsharpcore/tmp.fsproj.nuget.g.targets ./obj
/usr/bin/dotnet build -c Release --no-restore
Microsoft (R) Build Engine version 15.4.8.50001 for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.

  tmp -> /home/dunham/benchmarksgame_quadcore/mandelbrot/tmp/bin/Release/netcoreapp2.0/tmp.dll

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:09.31

9.87s to complete and log all make actions

COMMAND LINE:
/usr/bin/dotnet ./bin/Release/netcoreapp2.0/tmp.dll 16000

(BINARY) PROGRAM OUTPUT NOT SHOWN