-
Notifications
You must be signed in to change notification settings - Fork 0
/
multi-backend.ts
104 lines (88 loc) · 2.46 KB
/
multi-backend.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import binaryen from "binaryen";
import { Algebra, BackEnd, Scalar } from "../src/Algebra";
import { makeLetterNames } from "../src/componentNaming";
import NumericBackEnd from "../src/NumericBackEnd";
import WASMBackEnd from "../src/WASMBackEnd";
import WebGLBackEnd from "../src/WebGLBackEnd";
import { p, q_ } from "./utils";
import { euclidean } from "../src/euclidean";
p(`// Multi-back-end example\n`);
// This example is not about its geometry.
// It rather shows that the same geometric code can be used with
// multiple back ends.
const coords = "xyz";
function slerpTest<T>(
be: BackEnd<T>,
metric: Scalar<T>[],
v1Components: Scalar<T>[],
v2Components: Scalar<T>[],
) {
const alg = new Algebra(metric, be, makeLetterNames(coords));
const v1 = alg.vec(v1Components);
const v2 = alg.vec(v2Components);
const slerpArc = alg.slerp(v1, v2);
return slerpArc(.3);
}
{
const be = new WebGLBackEnd();
be.comment("slerpTest: " + slerpTest(
be,
// Mixed symbolic and numeric input:
[1, 1, "metricZ"],
["myX", 2, 0],
[1, "myY", 4],
));
p(be.text);
}
{
const f64List = (size: number) => new Array(size).fill(binaryen.f64);
const f64Tuple = (size: number) => binaryen.createType(f64List(size));
// TODO provide more utilities to simplify this user-side code
const mod = new binaryen.Module();
mod.setFeatures(binaryen.Features.Multivalue);
for (const [name, arity] of [
["max", 2],
["sqrt", 1],
["sin", 1],
["atan2", 2],
] as [string, number][]) {
mod.addFunctionImport(name, name, "Math", f64Tuple(arity), binaryen.f64);
}
const be = new WASMBackEnd(mod, ["myX", "myY", "metricZ"]);
const {myX, myY, metricZ} = be.paramsByHint;
const result = slerpTest(
be,
[ 1, 1, metricZ],
[myX, 2, 0],
[ 1, myY, 4],
);
be.body.push(
mod.return(mod.tuple.make(
[...result].map(([,val]) => be.convertScalar(val))
))
);
const fn = mod.addFunction(
"myTest",
f64Tuple(be.paramCount),
f64Tuple([...result].length),
f64List(be.varCount - be.paramCount),
mod.block(null, be.body),
);
mod.addFunctionExport("myTest", "myTestExt");
p(`// valid: ${Boolean(mod.validate())}`);
mod.optimize();
mod.runPasses([
"flatten",
"simplify-locals-notee",
"vacuum",
"coalesce-locals",
"ssa",
]);
console.log(mod.emitText());
}
q_(coords)("\nresult", slerpTest(
new NumericBackEnd(),
euclidean(coords),
[1, 2, 0],
[1, 1, 4],
));