ballercat / ballercat/walt

Thanks, and a possible example to add: faking a C-stye union

Open
#99 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
4.6k
Forks
119
PR merge metrics
No merged PRs in 30d

Description

So this week, as an experiment, I ported [Paul Mineiro's fast log2 approximation](http://www.machinedlearnings.com/2011/06/fast-approximate-logarithm-exponential.html) ([original C repo here](https://github.com/romeric/fastapprox/)) to plain JavaScript:

```js
// Fake a C-union using a typed array
const unionU32 = new Uint32Array(1),
unionF32 = new Float32Array(unionU32.buffer);

function fastlog2(x) {
unionF32[0] = x;
let vx_u = unionU32[0];
unionU32[0] = (vx_u & 0x007FFFFF) | 0x3F000000;
let mx_f = unionF32[0];
return (vx_u * 1.1920928955078125e-7) - 124.22551499 - 1.498030302 * mx_f - 1.72587999 / (0.3520887068 + mx_f);
}
```

It actually seems to be slightly faster, despite all the overhead involved. Then I figured *"I wonder if WASM works... but I don't want to involve a big toolchain just to test that"*. A bit of searching later, I found Walt, and using your on-line explorer I created this:

```js
const memory: Memory = { 'initial': 1 };

export function fastlog2(x: f32): f32 {
// To use arrays simple define a type with array subscript
// Assign arrays to the same address to mimic a C-union
const uf: f32[] = 1;
const ui: i32[] = 1;
uf[0] = x;
let vx_u : i32 = ui[0];
ui[0] = (vx_u & 8388607) | 1056964608;
let mx_f : f32 = uf[0];
return (vx_u * 0.00000011920928955078125) - 124.22551499 - 1.498030302 * mx_f - 1.72587999 / (0.3520887068 + mx_f);
}
```

... which I extracted (quite crudely), by typing this in the JS tab of the explorer:

```js
function compile(buffer) {
console.log(Array.from(new Uint8Array(buffer)))
}
```

... the output of which was then copied turned into a quick-and-dirty function like this:

```js
WebAssembly.instantiate(Uint8Array.from([0, 97, 115, 109, 1, 0, 0, 0, 1, 6, 1, 96, 1, 125, 1, 125, 3, 2, 1, 0, 5, 3, 1, 0, 1, 7, 12, 1, 8, 102, 97, 115, 116, 108, 111, 103, 50, 0, 0, 10, 125, 1, 123, 4, 1, 127, 1, 127, 1, 127, 1, 125, 65, 1, 33, 1, 65, 1, 33, 2, 32, 1, 65, 0, 65, 2, 116, 106, 32, 0, 56, 2, 0, 32, 2, 65, 0, 65, 2, 116, 106, 40, 2, 0, 33, 3, 32, 2, 65, 0, 65, 2, 116, 106, 32, 3, 65, 255, 255, 255, 3, 113, 65, 128, 128, 128, 248, 3, 114, 54, 2, 0, 32, 1, 65, 0, 65, 2, 116, 106, 42, 2, 0, 33, 4, 32, 3, 178, 67, 0, 0, 0, 52, 148, 67, 119, 115, 248, 66, 147, 67, 117, 191, 191, 63, 32, 4, 148, 147, 67, 163, 233, 220, 63, 67, 249, 68, 180, 62, 32, 4, 146, 149, 147, 15, 11]).buffer).then(result => console.log([0,1,2,3,4,5,67,8,9,10,11,12].map(v => result.instance.exports.fastlog2(v))));
// => [
// -127, -0.000002384185791015625,
// 0.999997615814209,
// 1.584951639175415,
// 1.9999973773956299,
// 2.321864604949951,
// 6.065983772277832,
// 2.99999737739563,
// 3.1697850227355957,
// 3.321864604949951,
// 3.45943021774292,
// 3.584951639175415
// ]
```

It seems to work! Now I just have to figure out how to benchmark it.

Anyway, I haven't seen any examples discussion unions so far. Perhaps this could work for that purpose?

Contributor guide

Open the contributing guide

Research direction

Start with the Walt online explorer and the typed-array and array-aliasing examples shown in the issue. Check whether the proposed union example fits the project's existing example or documentation structure, and verify that it compiles and produces the demonstrated fastlog2 results. Done means the example's placement and expected behavior are documented clearly.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, wasm
Domain
compilers, documentation
Issue type
Documentation
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.