Rust const fn compile time mandelbrot


Back in 2017 I wrote a rust compile time mandelbrot using horrid hacks using associated types, but then Rust 1.46.0 landed with const fn being able to use loops and if's and I thought I'd try a rewrite.

The code

// (c) Dave Gilbert dave@treblig.org 2020
const LSIZE: usize = 32;
const SSIZE: usize = LSIZE*(LSIZE+1);

const fn manpoint(x: i64, y: i64) -> u8 {
    let mut ti : i64 = 0;
    let mut tr : i64 = 0;
    let mut zi : i64 = 0;
    let mut zr : i64 = 0;
    let mut iter : u8 = 128;

    while iter > 0  && (ti + tr < (4 << 16)) {
        zi = (((((2<<16)*zr) >> 16) * zi)>>16) + y;
        zr = tr-ti+x;
        tr = (zr*zr) >> 16;
        ti = (zi*zi) >> 16;
        iter-=1;
    }
    (iter % 20) + 64
}

const fn manline() -> [u8;SSIZE] {
    let mut y : i64 = -2 << 16;
    let xstep : i64 = (4 << 16) / (LSIZE as i64);
    let ystep : i64 = (4 << 16) / (LSIZE as i64);
    let mut yi = 0;
    let mut res : [u8;SSIZE] = [32;SSIZE];

    while yi < LSIZE {
        let mut x : i64 = -2 << 16;
        let mut xi = 0;
        while xi < LSIZE {
            res[yi*(LSIZE+1)+xi] = manpoint(x, y);
            x+=xstep;
            xi+=1;
        }
        res[yi*(LSIZE+1)+LSIZE]=10;
        y+=ystep;
        yi+=1;
    }

    res
}

const BROT: [u8;SSIZE] = manline();
fn main() {
    println!("Const val={}", std::str::from_utf8(&BROT).unwrap());
}

Heck that's boring!

So now lets compile it

[dg@major ~]$ rustc -O const.rs --emit asm; grep -i ascii const.s|tr '\\' '\012'
	.ascii	"called `Result::unwrap()` on an `Err` value"
	.ascii	"Const val="
	.ascii	"GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
nGGGGGGGGGGGFFFFFFFFFFFGGGGGGGGGG
nGGGGGGGGGFFFFFFFFFFFFFFFGGGGGGGG
nGGGGGGGFFFFFFFFFFFFFFFFFFFGGGGGG
nGGGGGGFFFFFFFFFFFFFFFFFFFFFGGGGG
nGGGGGFFFFFFFFFFFFFFFFFFFFFFFGGGG
nGGGGFFFFFEEEEEEEFFFFFFFFFFFFFGGG
nGGGFFFEEEEEEEDCCDEEFFFFFFFFFFFGG
nGGGFFEEEEEEDDCBO@DDEFFFFFFFFFFGG
nGGFEEEEEEEDDDCO@SCDDEEFFFFFFFFFG
nGGFEEEEEEDDCBAF@NACDEEFFFFFFFFFG
nGFEEEEEDDCCSHH@@@@KQDEEFFFFFFFFF
nGEEEEEDCCCBP@@@@@@@SCEEEFFFFFFFF
nGEEDDCNA@A@@@@@@@@@KCDEEFFFFFFFF
nGDDDCBS@@DO@@@@@@@@@CDEEFFFFFFFF
nGDDBAQI@@@B@@@@@@@@KCDEEFFFFFFFF
nG@@@@@@@@@@@@@@@@@@ACDEEFFFFFFFF
nGDDBAQI@@@B@@@@@@@@KCDEEFFFFFFFF
nGDDDCBS@@DO@@@@@@@@@CDEEFFFFFFFF
nGEEDDCNA@A@@@@@@@@@KCDEEFFFFFFFF
nGEEEEEDCCCBP@@@@@@@SCEEEFFFFFFFF
nGFEEEEEDDCCSH@@@@@JQDEEFFFFFFFFF
nGGFEEEEEEDDCBAF@NACDEEFFFFFFFFFG
nGGFEEEEEEEDDDCO@SCDDEEFFFFFFFFFG
nGGGFFEEEEEEDDCBO@DDEFFFFFFFFFFGG
nGGGFFFEEEEEEEDCCDEEFFFFFFFFFFFGG
nGGGGFFFFFEEEEEEEFFFFFFFFFFFFFGGG
nGGGGGFFFFFFFFFFFFFFFFFFFFFFFGGGG
nGGGGGGFFFFFFFFFFFFFFFFFFFFFGGGGG
nGGGGGGGFFFFFFFFFFFFFFFFFFFGGGGGG
nGGGGGGGGGFFFFFFFFFFFFFFFGGGGGGGG
nGGGGGGGGGGGFFFFFFFFFFFGGGGGGGGGG
n"
	.ascii	"const.rs"
and there we are.

Boring!

Notes

The compiler isn't required to compile stuff at compile time unless you force it to be used in a constant context, hence the BROT in that code.

In 1.46.0 you can't use floating point yet, so we're still using integer.

(c)David Alan Gilbert 2020

mail: fromwebpage@treblig.org irc: penguin42 on freenode | matrix: penguin42 on matrix.org | mastodon: penguin42 on mastodon.org.uk

My home page