wickra-benchmark-wasm 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +68 -0
- package/package.json +31 -0
- package/wickra_benchmark_wasm.d.ts +28 -0
- package/wickra_benchmark_wasm.js +9 -0
- package/wickra_benchmark_wasm_bg.js +228 -0
- package/wickra_benchmark_wasm_bg.wasm +0 -0
package/README.md
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Wickra Benchmark — WASM
|
|
2
|
+
|
|
3
|
+
Recompute a curated benchmark case or suite with the deterministic Wickra engine
|
|
4
|
+
and confirm its report and hash, compiled to WebAssembly for the browser (and
|
|
5
|
+
any WASM host). Built with [wasm-bindgen].
|
|
6
|
+
|
|
7
|
+
The suite runs sequentially under WASM (no thread pool in a browser sandbox),
|
|
8
|
+
which is byte-identical to the native parallel run — the exact cross-language
|
|
9
|
+
golden check.
|
|
10
|
+
|
|
11
|
+
## Build
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
wasm-pack build --target web # for browsers / bundlers
|
|
15
|
+
wasm-pack build --target nodejs # for Node.js
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
The `pkg/` output (the `.wasm` binary plus the JS glue and TypeScript types) is
|
|
19
|
+
generated, not committed.
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
Everything goes through a `Benchmark` driven by JSON commands — the same command
|
|
24
|
+
protocol every Wickra binding shares.
|
|
25
|
+
|
|
26
|
+
```js
|
|
27
|
+
import init, { Benchmark } from "./pkg/wickra_benchmark_wasm.js";
|
|
28
|
+
|
|
29
|
+
await init(); // load the .wasm module (web target)
|
|
30
|
+
|
|
31
|
+
const bench = new Benchmark(); // stateless: case, suite and data arrive per command
|
|
32
|
+
|
|
33
|
+
const runCase = {
|
|
34
|
+
cmd: "run_case",
|
|
35
|
+
case: {
|
|
36
|
+
id: "sma-crossover-01",
|
|
37
|
+
strategy: {/* a wickra-backtest StrategySpec */},
|
|
38
|
+
dataset_ref: "sma-uptrend.csv",
|
|
39
|
+
expected: {/* the frozen BacktestReport */},
|
|
40
|
+
expected_hash: "b3aa...",
|
|
41
|
+
},
|
|
42
|
+
data: [/* candles */],
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const result = JSON.parse(bench.command(JSON.stringify(runCase)));
|
|
46
|
+
console.log(result.passed && result.hash_match ? "passed" : "failed");
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Commands
|
|
50
|
+
|
|
51
|
+
| `cmd` | Payload | Response |
|
|
52
|
+
|---------------|---------------------|-----------------------------------------|
|
|
53
|
+
| `run_case` | `{case, data}` | the full `CaseResult` |
|
|
54
|
+
| `run_suite` | `{suite, datasets}` | a `SuiteReport` |
|
|
55
|
+
| `list_cases` | `{suite}` | `{ids:[...]}` (sorted) |
|
|
56
|
+
| `version` | — | `{version:...,engine_version:...}` |
|
|
57
|
+
|
|
58
|
+
`data` is an array of candles; `datasets` maps each `dataset_ref` to its candle
|
|
59
|
+
array.
|
|
60
|
+
|
|
61
|
+
Domain errors (a bad case, an unknown command) come back in-band as
|
|
62
|
+
`{ok:false,error:...}`; a malformed command envelope throws a JS error.
|
|
63
|
+
|
|
64
|
+
## License
|
|
65
|
+
|
|
66
|
+
MIT OR Apache-2.0.
|
|
67
|
+
|
|
68
|
+
[wasm-bindgen]: https://github.com/rustwasm/wasm-bindgen
|
package/package.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "wickra-benchmark-wasm",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"collaborators": [
|
|
5
|
+
"wickra-lib"
|
|
6
|
+
],
|
|
7
|
+
"description": "WebAssembly bindings for wickra-benchmark — recompute a curated case or suite and confirm its report and hash, in the browser.",
|
|
8
|
+
"version": "0.1.0",
|
|
9
|
+
"license": "MIT OR Apache-2.0",
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "https://github.com/wickra-lib/wickra-benchmark"
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"wickra_benchmark_wasm_bg.wasm",
|
|
16
|
+
"wickra_benchmark_wasm.js",
|
|
17
|
+
"wickra_benchmark_wasm_bg.js",
|
|
18
|
+
"wickra_benchmark_wasm.d.ts"
|
|
19
|
+
],
|
|
20
|
+
"main": "wickra_benchmark_wasm.js",
|
|
21
|
+
"homepage": "https://github.com/wickra-lib/wickra-benchmark",
|
|
22
|
+
"types": "wickra_benchmark_wasm.d.ts",
|
|
23
|
+
"sideEffects": [
|
|
24
|
+
"./wickra_benchmark_wasm.js",
|
|
25
|
+
"./snippets/*"
|
|
26
|
+
],
|
|
27
|
+
"author": "kingchenc <support@wickra.org>",
|
|
28
|
+
"bugs": {
|
|
29
|
+
"url": "https://github.com/wickra-lib/wickra-benchmark/issues"
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A benchmark runner driven by JSON commands.
|
|
6
|
+
*/
|
|
7
|
+
export class Benchmark {
|
|
8
|
+
free(): void;
|
|
9
|
+
[Symbol.dispose](): void;
|
|
10
|
+
/**
|
|
11
|
+
* Apply a command JSON and return the resulting response JSON.
|
|
12
|
+
*/
|
|
13
|
+
command(cmd_json: string): string;
|
|
14
|
+
/**
|
|
15
|
+
* Create a benchmark runner. It is stateless — the case, suite and data
|
|
16
|
+
* arrive with each command.
|
|
17
|
+
*/
|
|
18
|
+
constructor();
|
|
19
|
+
/**
|
|
20
|
+
* The library version.
|
|
21
|
+
*/
|
|
22
|
+
version(): string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* The library version.
|
|
27
|
+
*/
|
|
28
|
+
export function version(): string;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/* @ts-self-types="./wickra_benchmark_wasm.d.ts" */
|
|
2
|
+
import * as wasm from "./wickra_benchmark_wasm_bg.wasm";
|
|
3
|
+
import { __wbg_set_wasm } from "./wickra_benchmark_wasm_bg.js";
|
|
4
|
+
|
|
5
|
+
__wbg_set_wasm(wasm);
|
|
6
|
+
|
|
7
|
+
export {
|
|
8
|
+
Benchmark, version
|
|
9
|
+
} from "./wickra_benchmark_wasm_bg.js";
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A benchmark runner driven by JSON commands.
|
|
3
|
+
*/
|
|
4
|
+
export class Benchmark {
|
|
5
|
+
__destroy_into_raw() {
|
|
6
|
+
const ptr = this.__wbg_ptr;
|
|
7
|
+
this.__wbg_ptr = 0;
|
|
8
|
+
BenchmarkFinalization.unregister(this);
|
|
9
|
+
return ptr;
|
|
10
|
+
}
|
|
11
|
+
free() {
|
|
12
|
+
const ptr = this.__destroy_into_raw();
|
|
13
|
+
wasm.__wbg_benchmark_free(ptr, 0);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Apply a command JSON and return the resulting response JSON.
|
|
17
|
+
* @param {string} cmd_json
|
|
18
|
+
* @returns {string}
|
|
19
|
+
*/
|
|
20
|
+
command(cmd_json) {
|
|
21
|
+
let deferred3_0;
|
|
22
|
+
let deferred3_1;
|
|
23
|
+
try {
|
|
24
|
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
25
|
+
const ptr0 = passStringToWasm0(cmd_json, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
26
|
+
const len0 = WASM_VECTOR_LEN;
|
|
27
|
+
wasm.benchmark_command(retptr, this.__wbg_ptr, ptr0, len0);
|
|
28
|
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
29
|
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
30
|
+
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
|
|
31
|
+
var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
|
|
32
|
+
var ptr2 = r0;
|
|
33
|
+
var len2 = r1;
|
|
34
|
+
if (r3) {
|
|
35
|
+
ptr2 = 0; len2 = 0;
|
|
36
|
+
throw takeObject(r2);
|
|
37
|
+
}
|
|
38
|
+
deferred3_0 = ptr2;
|
|
39
|
+
deferred3_1 = len2;
|
|
40
|
+
return getStringFromWasm0(ptr2, len2);
|
|
41
|
+
} finally {
|
|
42
|
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
43
|
+
wasm.__wbindgen_export3(deferred3_0, deferred3_1, 1);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Create a benchmark runner. It is stateless — the case, suite and data
|
|
48
|
+
* arrive with each command.
|
|
49
|
+
*/
|
|
50
|
+
constructor() {
|
|
51
|
+
const ret = wasm.benchmark_new();
|
|
52
|
+
this.__wbg_ptr = ret;
|
|
53
|
+
BenchmarkFinalization.register(this, this.__wbg_ptr, this);
|
|
54
|
+
return this;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* The library version.
|
|
58
|
+
* @returns {string}
|
|
59
|
+
*/
|
|
60
|
+
version() {
|
|
61
|
+
let deferred1_0;
|
|
62
|
+
let deferred1_1;
|
|
63
|
+
try {
|
|
64
|
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
65
|
+
wasm.benchmark_version(retptr, this.__wbg_ptr);
|
|
66
|
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
67
|
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
68
|
+
deferred1_0 = r0;
|
|
69
|
+
deferred1_1 = r1;
|
|
70
|
+
return getStringFromWasm0(r0, r1);
|
|
71
|
+
} finally {
|
|
72
|
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
73
|
+
wasm.__wbindgen_export3(deferred1_0, deferred1_1, 1);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (Symbol.dispose) Benchmark.prototype[Symbol.dispose] = Benchmark.prototype.free;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* The library version.
|
|
81
|
+
* @returns {string}
|
|
82
|
+
*/
|
|
83
|
+
export function version() {
|
|
84
|
+
let deferred1_0;
|
|
85
|
+
let deferred1_1;
|
|
86
|
+
try {
|
|
87
|
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
88
|
+
wasm.version(retptr);
|
|
89
|
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
90
|
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
91
|
+
deferred1_0 = r0;
|
|
92
|
+
deferred1_1 = r1;
|
|
93
|
+
return getStringFromWasm0(r0, r1);
|
|
94
|
+
} finally {
|
|
95
|
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
96
|
+
wasm.__wbindgen_export3(deferred1_0, deferred1_1, 1);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
export function __wbg_Error_67e7344beaa85059(arg0, arg1) {
|
|
100
|
+
const ret = Error(getStringFromWasm0(arg0, arg1));
|
|
101
|
+
return addHeapObject(ret);
|
|
102
|
+
}
|
|
103
|
+
export function __wbg___wbindgen_throw_5d9e815e6fdf150f(arg0, arg1) {
|
|
104
|
+
throw new Error(getStringFromWasm0(arg0, arg1));
|
|
105
|
+
}
|
|
106
|
+
const BenchmarkFinalization = (typeof FinalizationRegistry === 'undefined')
|
|
107
|
+
? { register: () => {}, unregister: () => {} }
|
|
108
|
+
: new FinalizationRegistry(ptr => wasm.__wbg_benchmark_free(ptr, 1));
|
|
109
|
+
|
|
110
|
+
function addHeapObject(obj) {
|
|
111
|
+
if (heap_next === heap.length) heap.push(heap.length + 1);
|
|
112
|
+
const idx = heap_next;
|
|
113
|
+
heap_next = heap[idx];
|
|
114
|
+
|
|
115
|
+
heap[idx] = obj;
|
|
116
|
+
return idx;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function dropObject(idx) {
|
|
120
|
+
if (idx < 1028) return;
|
|
121
|
+
heap[idx] = heap_next;
|
|
122
|
+
heap_next = idx;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
let cachedDataViewMemory0 = null;
|
|
126
|
+
function getDataViewMemory0() {
|
|
127
|
+
if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) {
|
|
128
|
+
cachedDataViewMemory0 = new DataView(wasm.memory.buffer);
|
|
129
|
+
}
|
|
130
|
+
return cachedDataViewMemory0;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function getStringFromWasm0(ptr, len) {
|
|
134
|
+
return decodeText(ptr >>> 0, len);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
let cachedUint8ArrayMemory0 = null;
|
|
138
|
+
function getUint8ArrayMemory0() {
|
|
139
|
+
if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {
|
|
140
|
+
cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);
|
|
141
|
+
}
|
|
142
|
+
return cachedUint8ArrayMemory0;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function getObject(idx) { return heap[idx]; }
|
|
146
|
+
|
|
147
|
+
let heap = new Array(1024).fill(undefined);
|
|
148
|
+
heap.push(undefined, null, true, false);
|
|
149
|
+
|
|
150
|
+
let heap_next = heap.length;
|
|
151
|
+
|
|
152
|
+
function passStringToWasm0(arg, malloc, realloc) {
|
|
153
|
+
if (realloc === undefined) {
|
|
154
|
+
const buf = cachedTextEncoder.encode(arg);
|
|
155
|
+
const ptr = malloc(buf.length, 1) >>> 0;
|
|
156
|
+
getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf);
|
|
157
|
+
WASM_VECTOR_LEN = buf.length;
|
|
158
|
+
return ptr;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
let len = arg.length;
|
|
162
|
+
let ptr = malloc(len, 1) >>> 0;
|
|
163
|
+
|
|
164
|
+
const mem = getUint8ArrayMemory0();
|
|
165
|
+
|
|
166
|
+
let offset = 0;
|
|
167
|
+
|
|
168
|
+
for (; offset < len; offset++) {
|
|
169
|
+
const code = arg.charCodeAt(offset);
|
|
170
|
+
if (code > 0x7F) break;
|
|
171
|
+
mem[ptr + offset] = code;
|
|
172
|
+
}
|
|
173
|
+
if (offset !== len) {
|
|
174
|
+
if (offset !== 0) {
|
|
175
|
+
arg = arg.slice(offset);
|
|
176
|
+
}
|
|
177
|
+
ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;
|
|
178
|
+
const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);
|
|
179
|
+
const ret = cachedTextEncoder.encodeInto(arg, view);
|
|
180
|
+
|
|
181
|
+
offset += ret.written;
|
|
182
|
+
ptr = realloc(ptr, len, offset, 1) >>> 0;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
WASM_VECTOR_LEN = offset;
|
|
186
|
+
return ptr;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function takeObject(idx) {
|
|
190
|
+
const ret = getObject(idx);
|
|
191
|
+
dropObject(idx);
|
|
192
|
+
return ret;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
|
196
|
+
cachedTextDecoder.decode();
|
|
197
|
+
const MAX_SAFARI_DECODE_BYTES = 2146435072;
|
|
198
|
+
let numBytesDecoded = 0;
|
|
199
|
+
function decodeText(ptr, len) {
|
|
200
|
+
numBytesDecoded += len;
|
|
201
|
+
if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) {
|
|
202
|
+
cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
|
203
|
+
cachedTextDecoder.decode();
|
|
204
|
+
numBytesDecoded = len;
|
|
205
|
+
}
|
|
206
|
+
return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
const cachedTextEncoder = new TextEncoder();
|
|
210
|
+
|
|
211
|
+
if (!('encodeInto' in cachedTextEncoder)) {
|
|
212
|
+
cachedTextEncoder.encodeInto = function (arg, view) {
|
|
213
|
+
const buf = cachedTextEncoder.encode(arg);
|
|
214
|
+
view.set(buf);
|
|
215
|
+
return {
|
|
216
|
+
read: arg.length,
|
|
217
|
+
written: buf.length
|
|
218
|
+
};
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
let WASM_VECTOR_LEN = 0;
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
let wasm;
|
|
226
|
+
export function __wbg_set_wasm(val) {
|
|
227
|
+
wasm = val;
|
|
228
|
+
}
|
|
Binary file
|