Skip to content

Commit

Permalink
add i32 version for mandelbrot and spectral_norm (#137)
Browse files Browse the repository at this point in the history
Signed-off-by: Su Yihan <[email protected]>
  • Loading branch information
yviansu authored Jan 5, 2024
1 parent 6ba5ed6 commit b8e87d8
Show file tree
Hide file tree
Showing 7 changed files with 296 additions and 20 deletions.
1 change: 1 addition & 0 deletions src/backend/binaryen/wasm_expr_gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4030,6 +4030,7 @@ export class WASMExpressionGen {
);
}
}
case ValueTypeKind.INT:
case ValueTypeKind.BOOLEAN: {
return module.i32.const(0);
}
Expand Down
46 changes: 26 additions & 20 deletions src/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1379,6 +1379,17 @@ export class TypeResolver {
return undefined;
}

getFinalCustomType(type: Type, rawName: string | undefined) {
if (rawName) {
if (builtinWasmTypes.has(rawName)) {
type = builtinWasmTypes.get(rawName)!;
} else {
this.modifyTypeByRawName(type, rawName);
}
}
return type;
}

modifyTypeByRawName(type: Type, rawName: string) {
if (type instanceof TSArray) {
const arrayOccurrences = rawName.split('Array').filter(Boolean);
Expand Down Expand Up @@ -1469,9 +1480,7 @@ export class TypeResolver {
return parsedType;
}
let type = this.tsTypeToType(tsType);
if (tsTypeRawName) {
this.modifyTypeByRawName(type, tsTypeRawName);
}
type = this.getFinalCustomType(type, tsTypeRawName);

/* for example, a: string[] = new Array(), the type of new Array() should be string[]
instead of any[]*/
Expand Down Expand Up @@ -1945,47 +1954,44 @@ export class TypeResolver {
} else {
tsFunction.addIsOptionalParam(false);
}
let tsType = this.tsTypeToType(
this.typechecker!.getTypeAtLocation(valueDecl),
);
const tsType = this.typechecker!.getTypeAtLocation(valueDecl);
let customType = this.tsTypeToType(tsType);
// e.g.
// type ItemGenerator<T, U> = (item: T, index: U) => void
// function test_func<T, U>(func: ItemGenerator<U, T>, a: T, b: U) {...}
if (
tsType instanceof TSTypeWithArguments &&
isTypeGeneric(tsType)
customType instanceof TSTypeWithArguments &&
isTypeGeneric(customType)
) {
const param = valueDecl as ts.ParameterDeclaration;
const type = this.typechecker!.getTypeAtLocation(param.type!);
if (type.aliasTypeArguments) {
const typeArguments = type.aliasTypeArguments!.map((t) => {
return this.tsTypeToType(t);
});
tsType = TypeResolver.createSpecializedType(
tsType,
customType = TypeResolver.createSpecializedType(
customType,
typeArguments,
tsType,
customType,
);
}
}

/* builtin wasm types */
const tsTypeRawName = this.getTsTypeRawName(valueDecl);
if (tsTypeRawName && builtinWasmTypes.has(tsTypeRawName)) {
tsType = builtinWasmTypes.get(tsTypeRawName)!;
}

tsFunction.addParamType(tsType);
customType = this.getFinalCustomType(customType, tsTypeRawName);
tsFunction.addParamType(customType);
});

/* parse return type */
const returnType = signature.getReturnType();
tsFunction.returnType = this.tsTypeToType(returnType);
const customType = this.tsTypeToType(returnType);
/* builtin wasm types */
const tsTypeRawName = this.getTsTypeRawName(decl, true);
if (tsTypeRawName && builtinWasmTypes.has(tsTypeRawName)) {
tsFunction.returnType = builtinWasmTypes.get(tsTypeRawName)!;
}
tsFunction.returnType = this.getFinalCustomType(
customType,
tsTypeRawName,
);

this.nodeTypeCache.set(decl, tsFunction);
return tsFunction;
Expand Down
57 changes: 57 additions & 0 deletions tests/benchmark/mandelbrot_i32.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/* This file is generated by tsc */
"use strict";
/* This file is modified base on:
* https://github.com/ColinEberhardt/wasm-mandelbrot/blob/master/assemblyscript/mandelbrot.ts
*/
// const WIDTH = 1200;
// const HEIGHT = 800;
function colour(iteration, offset, scale) {
iteration = (iteration * scale + offset) & 1023;
if (iteration < 256) {
return iteration;
}
else if (iteration < 512) {
return 255 - (iteration - 255);
}
return 0;
}
function iterateEquation(x0, y0, maxiterations) {
var a = 0.0, b = 0.0, rx = 0.0, ry = 0.0, ab;
var iterations = 0;
while (iterations < maxiterations && rx * rx + ry * ry <= 4) {
rx = a * a - b * b + x0;
ab = a * b;
ry = ab + ab + y0;
a = rx;
b = ry;
iterations++;
}
return iterations;
}
function scale(domainStart, domainLength, screenLength, step) {
return domainStart + domainLength * (step * (1.0 / screenLength) - 1);
}
function mandelbrot(data, HEIGHT, WIDTH, maxIterations, cx, cy, diameter) {
var verticalDiameter = (diameter * HEIGHT) / WIDTH;
for (var y = 0; y < HEIGHT; ++y) {
for (var x = 0; x < WIDTH; ++x) {
// convert from screen coordinates to mandelbrot coordinates
var rx = scale(cx, diameter, WIDTH, x);
var ry = scale(cy, verticalDiameter, HEIGHT, y);
var iterations = iterateEquation(rx, ry, maxIterations);
var outside = iterations == maxIterations;
var idx = (x + y * WIDTH) << 2;
data[idx + 0] = outside ? 0 : colour(iterations, 0, 4);
data[idx + 1] = outside ? 0 : colour(iterations, 128, 4);
data[idx + 2] = outside ? 0 : colour(iterations, 356, 4);
data[idx + 3] = 255;
}
}
}
function main() {
var WIDTH = 1200;
var HEIGHT = 800;
var data = new Array(WIDTH * HEIGHT * 4);
mandelbrot(data, HEIGHT, WIDTH, 10000, -0.743644786, 0.1318252536, 0.00029336);
}
main();
93 changes: 93 additions & 0 deletions tests/benchmark/mandelbrot_i32.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/* This file is modified base on:
* https://github.com/ColinEberhardt/wasm-mandelbrot/blob/master/assemblyscript/mandelbrot.ts
*/

// const WIDTH = 1200;
// const HEIGHT = 800;

type i32 = number;

function colour(iteration: i32, offset: i32, scale: i32): i32 {
iteration = (iteration * scale + offset) & 1023;
if (iteration < 256) {
return iteration;
} else if (iteration < 512) {
return 255 - (iteration - 255);
}
return 0;
}

function iterateEquation(x0: number, y0: number, maxiterations: i32): i32 {
let a = 0.0,
b = 0.0,
rx = 0.0,
ry = 0.0,
ab: number;
let iterations: i32 = 0;
while (iterations < maxiterations && rx * rx + ry * ry <= 4) {
rx = a * a - b * b + x0;
ab = a * b;
ry = ab + ab + y0;
a = rx;
b = ry;
iterations++;
}
return iterations;
}

function scale(
domainStart: number,
domainLength: number,
screenLength: number,
step: number,
): number {
return domainStart + domainLength * (step * (1.0 / screenLength) - 1);
}

function mandelbrot(
data: i32[],
HEIGHT: i32,
WIDTH: i32,
maxIterations: i32,
cx: number,
cy: number,
diameter: number,
) {
const verticalDiameter = (diameter * HEIGHT) / WIDTH;
for (let y: i32 = 0; y < HEIGHT; ++y) {
for (let x: i32 = 0; x < WIDTH; ++x) {
// convert from screen coordinates to mandelbrot coordinates
const rx = scale(cx, diameter, WIDTH, x);
const ry = scale(cy, verticalDiameter, HEIGHT, y);
const iterations: i32 = iterateEquation(rx, ry, maxIterations);
const outside = iterations == maxIterations;
const idx: i32 = (x + y * WIDTH) << 2;
const maxIterationValue: i32 = 0;
data[idx + 0] = outside
? maxIterationValue
: colour(iterations, 0, 4);
data[idx + 1] = outside
? maxIterationValue
: colour(iterations, 128, 4);
data[idx + 2] = outside
? maxIterationValue
: colour(iterations, 356, 4);
data[idx + 3] = 255;
}
}
}

export function main() {
const WIDTH: i32 = 1200;
const HEIGHT: i32 = 800;
const data: i32[] = new Array(WIDTH * HEIGHT * 4);
mandelbrot(
data,
HEIGHT,
WIDTH,
10000,
-0.743644786,
0.1318252536,
0.00029336,
);
}
3 changes: 3 additions & 0 deletions tests/benchmark/run_benchmark.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ let benchmark_options = {
'mandelbrot': {
wamr_option: [default_gc_size_option]
},
'mandelbrot_i32': {
wamr_option: [default_gc_size_option]
},
'binarytrees_class': {
wamr_option: [default_gc_size_option]
},
Expand Down
54 changes: 54 additions & 0 deletions tests/benchmark/spectral_norm_i32.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/* This file is generated by tsc */
"use strict";
/* The Computer Language Benchmarks Game
https://salsa.debian.org/benchmarksgame-team/benchmarksgame/
contributed by Isaac Gouy
*/
/* This file is from:
* https://benchmarksgame-team.pages.debian.net/benchmarksgame/program/spectralnorm-typescript-1.html
*/
function approximate(n) {
var u = new Array(n), v = new Array(n);
for (var i = 0; i < n; ++i) {
u[i] = 1.0;
}
for (var i = 0; i < 10; ++i) {
multiplyAtAv(n, u, v);
multiplyAtAv(n, v, u);
}
var vBv = 0.0, vv = 0.0;
for (var i = 0; i < 10; ++i) {
vBv += u[i] * v[i];
vv += v[i] * v[i];
}
return Math.sqrt(vBv / vv);
}
function a(i, j) {
return 1.0 / (((i + j) * (i + j + 1)) / 2 + i + 1);
}
function multiplyAv(n, v, av) {
for (var i = 0; i < n - 1; ++i) {
av[i] = 0.0;
for (var j = 0; j < n - 1; ++j) {
av[i] = av[i] + a(i, j) * v[j];
}
}
}
function multiplyAtv(n, v, atv) {
for (var i = 0; i < n - 1; ++i) {
atv[i] = 0.0;
for (var j = 0; j < n - 1; ++j) {
atv[i] = atv[i] + a(j, i) * v[j];
}
}
}
function multiplyAtAv(n, v, atAv) {
var u = new Array(n);
multiplyAv(n, v, u);
multiplyAtv(n, u, atAv);
}
function main() {
var n = 2000;
approximate(n);
}
main();
62 changes: 62 additions & 0 deletions tests/benchmark/spectral_norm_i32.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/* The Computer Language Benchmarks Game
https://salsa.debian.org/benchmarksgame-team/benchmarksgame/
contributed by Isaac Gouy
*/

/* This file is from:
* https://benchmarksgame-team.pages.debian.net/benchmarksgame/program/spectralnorm-typescript-1.html
*/

type i32 = number;

function approximate(n: i32): number {
const u: number[] = new Array(n as number),
v: number[] = new Array(n as number);
for (let i: i32 = 0; i < n; ++i) {
u[i] = 1.0;
}
for (let i: i32 = 0; i < 10; ++i) {
multiplyAtAv(n, u, v);
multiplyAtAv(n, v, u);
}
let vBv = 0.0,
vv = 0.0;
for (let i: i32 = 0; i < 10; ++i) {
vBv += u[i] * v[i];
vv += v[i] * v[i];
}
return Math.sqrt(vBv / vv);
}

function a(i: number, j: number): number {
return 1.0 / (((i + j) * (i + j + 1)) / 2 + i + 1);
}

function multiplyAv(n: i32, v: number[], av: number[]) {
for (let i: i32 = 0; i < n - 1; ++i) {
av[i] = 0.0;
for (let j: i32 = 0; j < n - 1; ++j) {
av[i] = av[i] + a(i, j) * v[j];
}
}
}

function multiplyAtv(n: i32, v: number[], atv: number[]) {
for (let i: i32 = 0; i < n - 1; ++i) {
atv[i] = 0.0;
for (let j: i32 = 0; j < n - 1; ++j) {
atv[i] = atv[i] + a(j, i) * v[j];
}
}
}

function multiplyAtAv(n: i32, v: number[], atAv: number[]) {
const u: number[] = new Array(n as number);
multiplyAv(n, v, u);
multiplyAtv(n, u, atAv);
}

export function main() {
const n = 2000;
approximate(n);
}

0 comments on commit b8e87d8

Please sign in to comment.