webgpu-bench 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/LICENSE +21 -0
- package/README.md +120 -0
- package/dist/benchmarks/common.d.ts +71 -0
- package/dist/benchmarks/common.d.ts.map +1 -0
- package/dist/benchmarks/common.js +104 -0
- package/dist/benchmarks/common.js.map +1 -0
- package/dist/benchmarks/flopsCommon.d.ts +52 -0
- package/dist/benchmarks/flopsCommon.d.ts.map +1 -0
- package/dist/benchmarks/flopsCommon.js +78 -0
- package/dist/benchmarks/flopsCommon.js.map +1 -0
- package/dist/benchmarks/flopsConvert.d.ts +18 -0
- package/dist/benchmarks/flopsConvert.d.ts.map +1 -0
- package/dist/benchmarks/flopsConvert.js +61 -0
- package/dist/benchmarks/flopsConvert.js.map +1 -0
- package/dist/benchmarks/flopsF16.d.ts +12 -0
- package/dist/benchmarks/flopsF16.d.ts.map +1 -0
- package/dist/benchmarks/flopsF16.js +54 -0
- package/dist/benchmarks/flopsF16.js.map +1 -0
- package/dist/benchmarks/flopsF32.d.ts +12 -0
- package/dist/benchmarks/flopsF32.d.ts.map +1 -0
- package/dist/benchmarks/flopsF32.js +50 -0
- package/dist/benchmarks/flopsF32.js.map +1 -0
- package/dist/benchmarks/flopsI8.d.ts +16 -0
- package/dist/benchmarks/flopsI8.d.ts.map +1 -0
- package/dist/benchmarks/flopsI8.js +83 -0
- package/dist/benchmarks/flopsI8.js.map +1 -0
- package/dist/benchmarks/flopsMath.d.ts +28 -0
- package/dist/benchmarks/flopsMath.d.ts.map +1 -0
- package/dist/benchmarks/flopsMath.js +98 -0
- package/dist/benchmarks/flopsMath.js.map +1 -0
- package/dist/benchmarks/streamBandwidth.d.ts +17 -0
- package/dist/benchmarks/streamBandwidth.d.ts.map +1 -0
- package/dist/benchmarks/streamBandwidth.js +78 -0
- package/dist/benchmarks/streamBandwidth.js.map +1 -0
- package/dist/data/generate.d.ts +23 -0
- package/dist/data/generate.d.ts.map +1 -0
- package/dist/data/generate.js +41 -0
- package/dist/data/generate.js.map +1 -0
- package/dist/gpu/benchmarkRunner.d.ts +98 -0
- package/dist/gpu/benchmarkRunner.d.ts.map +1 -0
- package/dist/gpu/benchmarkRunner.js +178 -0
- package/dist/gpu/benchmarkRunner.js.map +1 -0
- package/dist/gpu/buffers.d.ts +8 -0
- package/dist/gpu/buffers.d.ts.map +1 -0
- package/dist/gpu/buffers.js +41 -0
- package/dist/gpu/buffers.js.map +1 -0
- package/dist/gpu/context.d.ts +16 -0
- package/dist/gpu/context.d.ts.map +1 -0
- package/dist/gpu/context.js +71 -0
- package/dist/gpu/context.js.map +1 -0
- package/dist/gpu/timing.d.ts +20 -0
- package/dist/gpu/timing.d.ts.map +1 -0
- package/dist/gpu/timing.js +55 -0
- package/dist/gpu/timing.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/sampling.d.ts +96 -0
- package/dist/sampling.d.ts.map +1 -0
- package/dist/sampling.js +239 -0
- package/dist/sampling.js.map +1 -0
- package/dist/shaders/flopsF16Mat4.d.ts +7 -0
- package/dist/shaders/flopsF16Mat4.d.ts.map +1 -0
- package/dist/shaders/flopsF16Mat4.js +40 -0
- package/dist/shaders/flopsF16Mat4.js.map +1 -0
- package/dist/shaders/flopsF16Matvec.d.ts +14 -0
- package/dist/shaders/flopsF16Matvec.d.ts.map +1 -0
- package/dist/shaders/flopsF16Matvec.js +58 -0
- package/dist/shaders/flopsF16Matvec.js.map +1 -0
- package/dist/shaders/flopsF16Scalar.d.ts +8 -0
- package/dist/shaders/flopsF16Scalar.d.ts.map +1 -0
- package/dist/shaders/flopsF16Scalar.js +71 -0
- package/dist/shaders/flopsF16Scalar.js.map +1 -0
- package/dist/shaders/flopsF16Vec4.d.ts +7 -0
- package/dist/shaders/flopsF16Vec4.d.ts.map +1 -0
- package/dist/shaders/flopsF16Vec4.js +35 -0
- package/dist/shaders/flopsF16Vec4.js.map +1 -0
- package/dist/shaders/flopsF32Div.d.ts +10 -0
- package/dist/shaders/flopsF32Div.d.ts.map +1 -0
- package/dist/shaders/flopsF32Div.js +71 -0
- package/dist/shaders/flopsF32Div.js.map +1 -0
- package/dist/shaders/flopsF32F16Convert.d.ts +11 -0
- package/dist/shaders/flopsF32F16Convert.d.ts.map +1 -0
- package/dist/shaders/flopsF32F16Convert.js +73 -0
- package/dist/shaders/flopsF32F16Convert.js.map +1 -0
- package/dist/shaders/flopsF32Log.d.ts +11 -0
- package/dist/shaders/flopsF32Log.d.ts.map +1 -0
- package/dist/shaders/flopsF32Log.js +71 -0
- package/dist/shaders/flopsF32Log.js.map +1 -0
- package/dist/shaders/flopsF32Mat4.d.ts +9 -0
- package/dist/shaders/flopsF32Mat4.d.ts.map +1 -0
- package/dist/shaders/flopsF32Mat4.js +38 -0
- package/dist/shaders/flopsF32Mat4.js.map +1 -0
- package/dist/shaders/flopsF32Matvec.d.ts +14 -0
- package/dist/shaders/flopsF32Matvec.d.ts.map +1 -0
- package/dist/shaders/flopsF32Matvec.js +58 -0
- package/dist/shaders/flopsF32Matvec.js.map +1 -0
- package/dist/shaders/flopsF32Pow.d.ts +10 -0
- package/dist/shaders/flopsF32Pow.d.ts.map +1 -0
- package/dist/shaders/flopsF32Pow.js +71 -0
- package/dist/shaders/flopsF32Pow.js.map +1 -0
- package/dist/shaders/flopsF32Rsqrt.d.ts +12 -0
- package/dist/shaders/flopsF32Rsqrt.d.ts.map +1 -0
- package/dist/shaders/flopsF32Rsqrt.js +72 -0
- package/dist/shaders/flopsF32Rsqrt.js.map +1 -0
- package/dist/shaders/flopsF32Scalar.d.ts +11 -0
- package/dist/shaders/flopsF32Scalar.d.ts.map +1 -0
- package/dist/shaders/flopsF32Scalar.js +72 -0
- package/dist/shaders/flopsF32Scalar.js.map +1 -0
- package/dist/shaders/flopsF32Sincos.d.ts +9 -0
- package/dist/shaders/flopsF32Sincos.d.ts.map +1 -0
- package/dist/shaders/flopsF32Sincos.js +68 -0
- package/dist/shaders/flopsF32Sincos.js.map +1 -0
- package/dist/shaders/flopsF32Sqrt.d.ts +9 -0
- package/dist/shaders/flopsF32Sqrt.d.ts.map +1 -0
- package/dist/shaders/flopsF32Sqrt.js +69 -0
- package/dist/shaders/flopsF32Sqrt.js.map +1 -0
- package/dist/shaders/flopsF32Vec4.d.ts +9 -0
- package/dist/shaders/flopsF32Vec4.d.ts.map +1 -0
- package/dist/shaders/flopsF32Vec4.js +33 -0
- package/dist/shaders/flopsF32Vec4.js.map +1 -0
- package/dist/shaders/flopsI32Div.d.ts +10 -0
- package/dist/shaders/flopsI32Div.d.ts.map +1 -0
- package/dist/shaders/flopsI32Div.js +71 -0
- package/dist/shaders/flopsI32Div.js.map +1 -0
- package/dist/shaders/flopsI32F16Convert.d.ts +10 -0
- package/dist/shaders/flopsI32F16Convert.d.ts.map +1 -0
- package/dist/shaders/flopsI32F16Convert.js +71 -0
- package/dist/shaders/flopsI32F16Convert.js.map +1 -0
- package/dist/shaders/flopsI32F32Convert.d.ts +10 -0
- package/dist/shaders/flopsI32F32Convert.d.ts.map +1 -0
- package/dist/shaders/flopsI32F32Convert.js +71 -0
- package/dist/shaders/flopsI32F32Convert.js.map +1 -0
- package/dist/shaders/flopsI8Dp4a.d.ts +23 -0
- package/dist/shaders/flopsI8Dp4a.d.ts.map +1 -0
- package/dist/shaders/flopsI8Dp4a.js +49 -0
- package/dist/shaders/flopsI8Dp4a.js.map +1 -0
- package/dist/shaders/flopsI8Mat4.d.ts +9 -0
- package/dist/shaders/flopsI8Mat4.d.ts.map +1 -0
- package/dist/shaders/flopsI8Mat4.js +41 -0
- package/dist/shaders/flopsI8Mat4.js.map +1 -0
- package/dist/shaders/flopsI8Matvec.d.ts +16 -0
- package/dist/shaders/flopsI8Matvec.d.ts.map +1 -0
- package/dist/shaders/flopsI8Matvec.js +57 -0
- package/dist/shaders/flopsI8Matvec.js.map +1 -0
- package/dist/shaders/flopsI8MatvecDp4a.d.ts +17 -0
- package/dist/shaders/flopsI8MatvecDp4a.d.ts.map +1 -0
- package/dist/shaders/flopsI8MatvecDp4a.js +60 -0
- package/dist/shaders/flopsI8MatvecDp4a.js.map +1 -0
- package/dist/shaders/flopsI8Scalar.d.ts +9 -0
- package/dist/shaders/flopsI8Scalar.d.ts.map +1 -0
- package/dist/shaders/flopsI8Scalar.js +70 -0
- package/dist/shaders/flopsI8Scalar.js.map +1 -0
- package/dist/shaders/flopsI8Vec4.d.ts +7 -0
- package/dist/shaders/flopsI8Vec4.d.ts.map +1 -0
- package/dist/shaders/flopsI8Vec4.js +31 -0
- package/dist/shaders/flopsI8Vec4.js.map +1 -0
- package/dist/shaders/flopsU32PackUnpack.d.ts +11 -0
- package/dist/shaders/flopsU32PackUnpack.d.ts.map +1 -0
- package/dist/shaders/flopsU32PackUnpack.js +55 -0
- package/dist/shaders/flopsU32PackUnpack.js.map +1 -0
- package/dist/shaders/streamRead.d.ts +10 -0
- package/dist/shaders/streamRead.d.ts.map +1 -0
- package/dist/shaders/streamRead.js +33 -0
- package/dist/shaders/streamRead.js.map +1 -0
- package/dist/shaders/streamWrite.d.ts +8 -0
- package/dist/shaders/streamWrite.d.ts.map +1 -0
- package/dist/shaders/streamWrite.js +29 -0
- package/dist/shaders/streamWrite.js.map +1 -0
- package/dist/stats.d.ts +31 -0
- package/dist/stats.d.ts.map +1 -0
- package/dist/stats.js +67 -0
- package/dist/stats.js.map +1 -0
- package/dist/suite.d.ts +25 -0
- package/dist/suite.d.ts.map +1 -0
- package/dist/suite.js +196 -0
- package/dist/suite.js.map +1 -0
- package/dist/types.d.ts +171 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +45 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { prepareFlopsBenchmark } from "./flopsCommon.js";
|
|
2
|
+
import { flopsF16ScalarWgsl } from "../shaders/flopsF16Scalar.js";
|
|
3
|
+
import { flopsF16Vec4Wgsl } from "../shaders/flopsF16Vec4.js";
|
|
4
|
+
import { flopsF16Mat4Wgsl } from "../shaders/flopsF16Mat4.js";
|
|
5
|
+
import { flopsF16MatvecWgsl } from "../shaders/flopsF16Matvec.js";
|
|
6
|
+
/** Raw fp16 FLOPS: eight independent scalar f16 FMA chains per thread, unrolled 4x. */
|
|
7
|
+
export function prepareFlopsF16Scalar(ctx, harness = {}) {
|
|
8
|
+
return prepareFlopsBenchmark(ctx, {
|
|
9
|
+
id: 'flops-f16-scalar',
|
|
10
|
+
label: 'fp16 scalar FMA FLOPS',
|
|
11
|
+
description: 'Same eight independent, 4x-unrolled FMA chains as the fp32 scalar test, but every operand and accumulator is f16, so the chains run entirely in half precision.',
|
|
12
|
+
wgsl: flopsF16ScalarWgsl,
|
|
13
|
+
flopsPerIteration: 64,
|
|
14
|
+
defaultIterations: 256,
|
|
15
|
+
requiresF16: true,
|
|
16
|
+
}, harness);
|
|
17
|
+
}
|
|
18
|
+
/** fp16 vec4 FLOPS: one f16 FMA chain on a vec4<f16> register (4 independent lanes). */
|
|
19
|
+
export function prepareFlopsF16Vec4(ctx, harness = {}) {
|
|
20
|
+
return prepareFlopsBenchmark(ctx, {
|
|
21
|
+
id: 'flops-f16-vec4',
|
|
22
|
+
label: 'fp16 vec4 FLOPS',
|
|
23
|
+
description: 'Same single FMA chain as the fp32 vec4 test, but held in a vec4<f16> register: 4 independent half-precision lanes per step. Only GPUs with packed-half ALUs run this faster than fp32.',
|
|
24
|
+
wgsl: flopsF16Vec4Wgsl,
|
|
25
|
+
flopsPerIteration: 8,
|
|
26
|
+
defaultIterations: 1024,
|
|
27
|
+
requiresF16: true,
|
|
28
|
+
}, harness);
|
|
29
|
+
}
|
|
30
|
+
/** fp16 mat4 FLOPS: x = m*x + c chained with a mat4x4<f16>. */
|
|
31
|
+
export function prepareFlopsF16Mat4(ctx, harness = {}) {
|
|
32
|
+
return prepareFlopsBenchmark(ctx, {
|
|
33
|
+
id: 'flops-f16-mat4',
|
|
34
|
+
label: 'fp16 mat4 FLOPS',
|
|
35
|
+
description: 'Same bounded x = m * x + c recurrence as the fp32 mat4 test, but m, c, and x are all f16, so the mat4x4 x vec4 multiply runs entirely in half precision.',
|
|
36
|
+
wgsl: flopsF16Mat4Wgsl,
|
|
37
|
+
flopsPerIteration: 32,
|
|
38
|
+
defaultIterations: 1024,
|
|
39
|
+
requiresF16: true,
|
|
40
|
+
}, harness);
|
|
41
|
+
}
|
|
42
|
+
/** fp16 register-resident matvec tile: 4x8 f16 weights in registers, two dot() calls per output row. */
|
|
43
|
+
export function prepareFlopsF16Matvec(ctx, harness = {}) {
|
|
44
|
+
return prepareFlopsBenchmark(ctx, {
|
|
45
|
+
id: 'flops-f16-matvec',
|
|
46
|
+
label: 'fp16 matvec FLOPS',
|
|
47
|
+
description: 'Same register-resident 4x8 matvec tile as the fp32 matvec test, but weights, inputs, and dot() accumulation are all f16. Pure ALU: the fp16 win here comes only from the ALU, not from halved memory traffic.',
|
|
48
|
+
wgsl: flopsF16MatvecWgsl,
|
|
49
|
+
flopsPerIteration: 64,
|
|
50
|
+
defaultIterations: 512,
|
|
51
|
+
requiresF16: true,
|
|
52
|
+
}, harness);
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=flopsF16.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flopsF16.js","sourceRoot":"","sources":["../../src/benchmarks/flopsF16.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAA2B,MAAM,kBAAkB,CAAC;AAClF,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAGlE,uFAAuF;AACvF,MAAM,UAAU,qBAAqB,CAAC,GAAe,EAAE,UAA8B,EAAE;IACrF,OAAO,qBAAqB,CAC1B,GAAG,EACH;QACE,EAAE,EAAE,kBAAkB;QACtB,KAAK,EAAE,uBAAuB;QAC9B,WAAW,EACT,iKAAiK;QACnK,IAAI,EAAE,kBAAkB;QACxB,iBAAiB,EAAE,EAAE;QACrB,iBAAiB,EAAE,GAAG;QACtB,WAAW,EAAE,IAAI;KAClB,EACD,OAAO,CACR,CAAC;AACJ,CAAC;AAED,wFAAwF;AACxF,MAAM,UAAU,mBAAmB,CAAC,GAAe,EAAE,UAA8B,EAAE;IACnF,OAAO,qBAAqB,CAC1B,GAAG,EACH;QACE,EAAE,EAAE,gBAAgB;QACpB,KAAK,EAAE,iBAAiB;QACxB,WAAW,EACT,wLAAwL;QAC1L,IAAI,EAAE,gBAAgB;QACtB,iBAAiB,EAAE,CAAC;QACpB,iBAAiB,EAAE,IAAI;QACvB,WAAW,EAAE,IAAI;KAClB,EACD,OAAO,CACR,CAAC;AACJ,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,mBAAmB,CAAC,GAAe,EAAE,UAA8B,EAAE;IACnF,OAAO,qBAAqB,CAC1B,GAAG,EACH;QACE,EAAE,EAAE,gBAAgB;QACpB,KAAK,EAAE,iBAAiB;QACxB,WAAW,EACT,0JAA0J;QAC5J,IAAI,EAAE,gBAAgB;QACtB,iBAAiB,EAAE,EAAE;QACrB,iBAAiB,EAAE,IAAI;QACvB,WAAW,EAAE,IAAI;KAClB,EACD,OAAO,CACR,CAAC;AACJ,CAAC;AAED,wGAAwG;AACxG,MAAM,UAAU,qBAAqB,CAAC,GAAe,EAAE,UAA8B,EAAE;IACrF,OAAO,qBAAqB,CAC1B,GAAG,EACH;QACE,EAAE,EAAE,kBAAkB;QACtB,KAAK,EAAE,mBAAmB;QAC1B,WAAW,EACT,+MAA+M;QACjN,IAAI,EAAE,kBAAkB;QACxB,iBAAiB,EAAE,EAAE;QACrB,iBAAiB,EAAE,GAAG;QACtB,WAAW,EAAE,IAAI;KAClB,EACD,OAAO,CACR,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { GpuContext } from '../gpu/context.ts';
|
|
2
|
+
import { type FlopsHarnessConfig } from './flopsCommon.ts';
|
|
3
|
+
import type { PreparedBenchmark } from './common.ts';
|
|
4
|
+
/** Raw fp32 FLOPS: eight independent scalar FMA chains per thread, unrolled 4x. */
|
|
5
|
+
export declare function prepareFlopsF32Scalar(ctx: GpuContext, harness?: FlopsHarnessConfig): Promise<PreparedBenchmark>;
|
|
6
|
+
/** fp32 vec4 FLOPS: one FMA chain on a vec4<f32> register (4 independent lanes). */
|
|
7
|
+
export declare function prepareFlopsF32Vec4(ctx: GpuContext, harness?: FlopsHarnessConfig): Promise<PreparedBenchmark>;
|
|
8
|
+
/** fp32 mat4 FLOPS: x = m*x + c chained with a mat4x4<f32>. */
|
|
9
|
+
export declare function prepareFlopsF32Mat4(ctx: GpuContext, harness?: FlopsHarnessConfig): Promise<PreparedBenchmark>;
|
|
10
|
+
/** fp32 register-resident matvec tile: 4x8 weights in registers, two dot() calls per output row. */
|
|
11
|
+
export declare function prepareFlopsF32Matvec(ctx: GpuContext, harness?: FlopsHarnessConfig): Promise<PreparedBenchmark>;
|
|
12
|
+
//# sourceMappingURL=flopsF32.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flopsF32.d.ts","sourceRoot":"","sources":["../../src/benchmarks/flopsF32.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAyB,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAKlF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD,mFAAmF;AACnF,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAcnH;AAED,oFAAoF;AACpF,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAcjH;AAED,+DAA+D;AAC/D,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAcjH;AAED,oGAAoG;AACpG,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAcnH"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { prepareFlopsBenchmark } from "./flopsCommon.js";
|
|
2
|
+
import { flopsF32ScalarWgsl } from "../shaders/flopsF32Scalar.js";
|
|
3
|
+
import { flopsF32Vec4Wgsl } from "../shaders/flopsF32Vec4.js";
|
|
4
|
+
import { flopsF32Mat4Wgsl } from "../shaders/flopsF32Mat4.js";
|
|
5
|
+
import { flopsF32MatvecWgsl } from "../shaders/flopsF32Matvec.js";
|
|
6
|
+
/** Raw fp32 FLOPS: eight independent scalar FMA chains per thread, unrolled 4x. */
|
|
7
|
+
export function prepareFlopsF32Scalar(ctx, harness = {}) {
|
|
8
|
+
return prepareFlopsBenchmark(ctx, {
|
|
9
|
+
id: 'flops-f32-scalar',
|
|
10
|
+
label: 'fp32 scalar FMA FLOPS',
|
|
11
|
+
description: 'Eight independent scalar f32 fused multiply-add chains per thread, unrolled 4x, so the ALU always has work in flight and the number reflects throughput rather than FMA latency. ~no memory traffic.',
|
|
12
|
+
wgsl: flopsF32ScalarWgsl,
|
|
13
|
+
flopsPerIteration: 64,
|
|
14
|
+
defaultIterations: 256,
|
|
15
|
+
}, harness);
|
|
16
|
+
}
|
|
17
|
+
/** fp32 vec4 FLOPS: one FMA chain on a vec4<f32> register (4 independent lanes). */
|
|
18
|
+
export function prepareFlopsF32Vec4(ctx, harness = {}) {
|
|
19
|
+
return prepareFlopsBenchmark(ctx, {
|
|
20
|
+
id: 'flops-f32-vec4',
|
|
21
|
+
label: 'fp32 vec4 FLOPS',
|
|
22
|
+
description: 'A single FMA chain held in a vec4<f32> register. On scalar-SIMT GPUs (Apple, NVIDIA, AMD) this compiles to 4 independent scalar FMAs per step, so it measures how well 4-wide instruction-level parallelism hides latency, not a wider ALU.',
|
|
23
|
+
wgsl: flopsF32Vec4Wgsl,
|
|
24
|
+
flopsPerIteration: 8,
|
|
25
|
+
defaultIterations: 1024,
|
|
26
|
+
}, harness);
|
|
27
|
+
}
|
|
28
|
+
/** fp32 mat4 FLOPS: x = m*x + c chained with a mat4x4<f32>. */
|
|
29
|
+
export function prepareFlopsF32Mat4(ctx, harness = {}) {
|
|
30
|
+
return prepareFlopsBenchmark(ctx, {
|
|
31
|
+
id: 'flops-f32-mat4',
|
|
32
|
+
label: 'fp32 mat4 FLOPS',
|
|
33
|
+
description: 'x = m * x + c chained in a register with a mat4x4<f32> (a bounded contraction so it stays numerically stable): 16 FMAs per step with plenty of independent work, exercising the full mat4 x vec4 multiply.',
|
|
34
|
+
wgsl: flopsF32Mat4Wgsl,
|
|
35
|
+
flopsPerIteration: 32,
|
|
36
|
+
defaultIterations: 1024,
|
|
37
|
+
}, harness);
|
|
38
|
+
}
|
|
39
|
+
/** fp32 register-resident matvec tile: 4x8 weights in registers, two dot() calls per output row. */
|
|
40
|
+
export function prepareFlopsF32Matvec(ctx, harness = {}) {
|
|
41
|
+
return prepareFlopsBenchmark(ctx, {
|
|
42
|
+
id: 'flops-f32-matvec',
|
|
43
|
+
label: 'fp32 matvec FLOPS',
|
|
44
|
+
description: 'A 4-row x 8-column f32 weight tile held in registers, applied to an 8-wide input every iteration via dot() (outputs feed back as the next inputs). The dot-product-accumulate shape of a GEMV inner loop with zero buffer traffic: pure ALU.',
|
|
45
|
+
wgsl: flopsF32MatvecWgsl,
|
|
46
|
+
flopsPerIteration: 64,
|
|
47
|
+
defaultIterations: 512,
|
|
48
|
+
}, harness);
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=flopsF32.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flopsF32.js","sourceRoot":"","sources":["../../src/benchmarks/flopsF32.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAA2B,MAAM,kBAAkB,CAAC;AAClF,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAGlE,mFAAmF;AACnF,MAAM,UAAU,qBAAqB,CAAC,GAAe,EAAE,UAA8B,EAAE;IACrF,OAAO,qBAAqB,CAC1B,GAAG,EACH;QACE,EAAE,EAAE,kBAAkB;QACtB,KAAK,EAAE,uBAAuB;QAC9B,WAAW,EACT,sMAAsM;QACxM,IAAI,EAAE,kBAAkB;QACxB,iBAAiB,EAAE,EAAE;QACrB,iBAAiB,EAAE,GAAG;KACvB,EACD,OAAO,CACR,CAAC;AACJ,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,mBAAmB,CAAC,GAAe,EAAE,UAA8B,EAAE;IACnF,OAAO,qBAAqB,CAC1B,GAAG,EACH;QACE,EAAE,EAAE,gBAAgB;QACpB,KAAK,EAAE,iBAAiB;QACxB,WAAW,EACT,6OAA6O;QAC/O,IAAI,EAAE,gBAAgB;QACtB,iBAAiB,EAAE,CAAC;QACpB,iBAAiB,EAAE,IAAI;KACxB,EACD,OAAO,CACR,CAAC;AACJ,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,mBAAmB,CAAC,GAAe,EAAE,UAA8B,EAAE;IACnF,OAAO,qBAAqB,CAC1B,GAAG,EACH;QACE,EAAE,EAAE,gBAAgB;QACpB,KAAK,EAAE,iBAAiB;QACxB,WAAW,EACT,4MAA4M;QAC9M,IAAI,EAAE,gBAAgB;QACtB,iBAAiB,EAAE,EAAE;QACrB,iBAAiB,EAAE,IAAI;KACxB,EACD,OAAO,CACR,CAAC;AACJ,CAAC;AAED,oGAAoG;AACpG,MAAM,UAAU,qBAAqB,CAAC,GAAe,EAAE,UAA8B,EAAE;IACrF,OAAO,qBAAqB,CAC1B,GAAG,EACH;QACE,EAAE,EAAE,kBAAkB;QACtB,KAAK,EAAE,mBAAmB;QAC1B,WAAW,EACT,8OAA8O;QAChP,IAAI,EAAE,kBAAkB;QACxB,iBAAiB,EAAE,EAAE;QACrB,iBAAiB,EAAE,GAAG;KACvB,EACD,OAAO,CACR,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { GpuContext } from '../gpu/context.ts';
|
|
2
|
+
import { type FlopsHarnessConfig } from './flopsCommon.ts';
|
|
3
|
+
import type { PreparedBenchmark } from './common.ts';
|
|
4
|
+
/** Raw int8-range FLOPS: eight independent scalar i32 multiply-add chains per thread, unrolled 4x. */
|
|
5
|
+
export declare function prepareFlopsI8Scalar(ctx: GpuContext, harness?: FlopsHarnessConfig): Promise<PreparedBenchmark>;
|
|
6
|
+
/** int8-range vec4 FLOPS: one integer FMA chain on a vec4<i32> register (4 independent lanes). */
|
|
7
|
+
export declare function prepareFlopsI8Vec4(ctx: GpuContext, harness?: FlopsHarnessConfig): Promise<PreparedBenchmark>;
|
|
8
|
+
/** int8-range mat4 FLOPS: a 4x4 integer matvec emulated via four dot(vec4<i32>) calls (WGSL has no mat4x4<i32>). */
|
|
9
|
+
export declare function prepareFlopsI8Mat4(ctx: GpuContext, harness?: FlopsHarnessConfig): Promise<PreparedBenchmark>;
|
|
10
|
+
/** int8 register-resident matvec tile with weights unpacked to vec4<i32>, two integer dot() calls per output row. */
|
|
11
|
+
export declare function prepareFlopsI8Matvec(ctx: GpuContext, harness?: FlopsHarnessConfig): Promise<PreparedBenchmark>;
|
|
12
|
+
/** int8 register-resident matvec tile on packed u32 words, two dot4I8Packed calls per output row. */
|
|
13
|
+
export declare function prepareFlopsI8MatvecDp4a(ctx: GpuContext, harness?: FlopsHarnessConfig): Promise<PreparedBenchmark>;
|
|
14
|
+
/** int8 packed-dot-product FLOPS: dot4I8Packed from the packed_4x8_integer_dot_product extension, run in a tight accumulation loop. */
|
|
15
|
+
export declare function prepareFlopsI8Dp4a(ctx: GpuContext, harness?: FlopsHarnessConfig): Promise<PreparedBenchmark>;
|
|
16
|
+
//# sourceMappingURL=flopsI8.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flopsI8.d.ts","sourceRoot":"","sources":["../../src/benchmarks/flopsI8.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAyB,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAQlF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD,sGAAsG;AACtG,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAelH;AAED,kGAAkG;AAClG,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAehH;AAED,oHAAoH;AACpH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAehH;AAED,qHAAqH;AACrH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAelH;AAED,qGAAqG;AACrG,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,UAAU,EACf,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,iBAAiB,CAAC,CAgB5B;AAED,uIAAuI;AACvI,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAgBhH"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { prepareFlopsBenchmark } from "./flopsCommon.js";
|
|
2
|
+
import { OPS_METRIC } from "./common.js";
|
|
3
|
+
import { flopsI8ScalarWgsl } from "../shaders/flopsI8Scalar.js";
|
|
4
|
+
import { flopsI8Vec4Wgsl } from "../shaders/flopsI8Vec4.js";
|
|
5
|
+
import { flopsI8Mat4Wgsl } from "../shaders/flopsI8Mat4.js";
|
|
6
|
+
import { flopsI8Dp4aWgsl } from "../shaders/flopsI8Dp4a.js";
|
|
7
|
+
import { flopsI8MatvecWgsl } from "../shaders/flopsI8Matvec.js";
|
|
8
|
+
import { flopsI8MatvecDp4aWgsl } from "../shaders/flopsI8MatvecDp4a.js";
|
|
9
|
+
/** Raw int8-range FLOPS: eight independent scalar i32 multiply-add chains per thread, unrolled 4x. */
|
|
10
|
+
export function prepareFlopsI8Scalar(ctx, harness = {}) {
|
|
11
|
+
return prepareFlopsBenchmark(ctx, {
|
|
12
|
+
id: 'flops-i8-scalar',
|
|
13
|
+
label: 'int8-range scalar FMA FLOPS',
|
|
14
|
+
description: 'Same eight independent, 4x-unrolled multiply-add chains as the fp32 scalar test, but on i32 (WGSL has no first-class i8 type). Measures integer multiply-add throughput; overflow wraps.',
|
|
15
|
+
wgsl: flopsI8ScalarWgsl,
|
|
16
|
+
metric: OPS_METRIC,
|
|
17
|
+
flopsPerIteration: 64,
|
|
18
|
+
defaultIterations: 256,
|
|
19
|
+
}, harness);
|
|
20
|
+
}
|
|
21
|
+
/** int8-range vec4 FLOPS: one integer FMA chain on a vec4<i32> register (4 independent lanes). */
|
|
22
|
+
export function prepareFlopsI8Vec4(ctx, harness = {}) {
|
|
23
|
+
return prepareFlopsBenchmark(ctx, {
|
|
24
|
+
id: 'flops-i8-vec4',
|
|
25
|
+
label: 'int8-range vec4 FLOPS',
|
|
26
|
+
description: 'Same single multiply-add chain as the fp32 vec4 test, but held in a vec4<i32> register: 4 independent integer lanes per step.',
|
|
27
|
+
wgsl: flopsI8Vec4Wgsl,
|
|
28
|
+
metric: OPS_METRIC,
|
|
29
|
+
flopsPerIteration: 8,
|
|
30
|
+
defaultIterations: 1024,
|
|
31
|
+
}, harness);
|
|
32
|
+
}
|
|
33
|
+
/** int8-range mat4 FLOPS: a 4x4 integer matvec emulated via four dot(vec4<i32>) calls (WGSL has no mat4x4<i32>). */
|
|
34
|
+
export function prepareFlopsI8Mat4(ctx, harness = {}) {
|
|
35
|
+
return prepareFlopsBenchmark(ctx, {
|
|
36
|
+
id: 'flops-i8-mat4',
|
|
37
|
+
label: 'int8-range mat4 FLOPS',
|
|
38
|
+
description: 'x = m * x + c chained in a register, where m is a 4x4 integer matrix emulated as four vec4<i32> rows combined with dot() (WGSL has no mat4x4<i32>): the same 4 dot products a real int4x4 multiply compiles to.',
|
|
39
|
+
wgsl: flopsI8Mat4Wgsl,
|
|
40
|
+
metric: OPS_METRIC,
|
|
41
|
+
flopsPerIteration: 32,
|
|
42
|
+
defaultIterations: 1024,
|
|
43
|
+
}, harness);
|
|
44
|
+
}
|
|
45
|
+
/** int8 register-resident matvec tile with weights unpacked to vec4<i32>, two integer dot() calls per output row. */
|
|
46
|
+
export function prepareFlopsI8Matvec(ctx, harness = {}) {
|
|
47
|
+
return prepareFlopsBenchmark(ctx, {
|
|
48
|
+
id: 'flops-i8-matvec',
|
|
49
|
+
label: 'int8 matvec FLOPS (i32 dot)',
|
|
50
|
+
description: 'Same register-resident 4x8 matvec tile as the fp32 matvec test, with int8-range weights and inputs held unpacked as vec4<i32> and accumulated with integer dot(). The no-extension int8 path: what dot4I8Packed is competing against.',
|
|
51
|
+
wgsl: flopsI8MatvecWgsl,
|
|
52
|
+
metric: OPS_METRIC,
|
|
53
|
+
flopsPerIteration: 64,
|
|
54
|
+
defaultIterations: 512,
|
|
55
|
+
}, harness);
|
|
56
|
+
}
|
|
57
|
+
/** int8 register-resident matvec tile on packed u32 words, two dot4I8Packed calls per output row. */
|
|
58
|
+
export function prepareFlopsI8MatvecDp4a(ctx, harness = {}) {
|
|
59
|
+
return prepareFlopsBenchmark(ctx, {
|
|
60
|
+
id: 'flops-i8-matvec-dp4a',
|
|
61
|
+
label: 'int8 matvec FLOPS (dot4I8Packed)',
|
|
62
|
+
description: "Same 4x8 matvec tile, but weights and inputs stay packed four int8 lanes per u32 and each 4-wide dot product is one dot4I8Packed call from the packed_4x8_integer_dot_product extension. On GPUs without a native dp4a instruction this runs the extension's polyfill.",
|
|
63
|
+
wgsl: flopsI8MatvecDp4aWgsl,
|
|
64
|
+
metric: OPS_METRIC,
|
|
65
|
+
flopsPerIteration: 64,
|
|
66
|
+
defaultIterations: 512,
|
|
67
|
+
requiresI8Dot: true,
|
|
68
|
+
}, harness);
|
|
69
|
+
}
|
|
70
|
+
/** int8 packed-dot-product FLOPS: dot4I8Packed from the packed_4x8_integer_dot_product extension, run in a tight accumulation loop. */
|
|
71
|
+
export function prepareFlopsI8Dp4a(ctx, harness = {}) {
|
|
72
|
+
return prepareFlopsBenchmark(ctx, {
|
|
73
|
+
id: 'flops-i8-dp4a',
|
|
74
|
+
label: 'int8 dot4I8Packed FLOPS',
|
|
75
|
+
description: "One thread per lane, accumulating dot4I8Packed(a, b) — the packed_4x8_integer_dot_product extension's 4-wide int8 dot-product instruction — in a tight loop to measure its peak throughput in isolation.",
|
|
76
|
+
wgsl: flopsI8Dp4aWgsl,
|
|
77
|
+
metric: OPS_METRIC,
|
|
78
|
+
flopsPerIteration: 8,
|
|
79
|
+
defaultIterations: 1024,
|
|
80
|
+
requiresI8Dot: true,
|
|
81
|
+
}, harness);
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=flopsI8.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flopsI8.js","sourceRoot":"","sources":["../../src/benchmarks/flopsI8.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { GpuContext } from '../gpu/context.ts';
|
|
2
|
+
import { type FlopsHarnessConfig } from './flopsCommon.ts';
|
|
3
|
+
import type { PreparedBenchmark } from './common.ts';
|
|
4
|
+
/**
|
|
5
|
+
* "Real" ALU ops beyond multiply-add: division and the transcendentals
|
|
6
|
+
* (sqrt, pow, sin/cos, log) that 3D math leans on constantly (normalize,
|
|
7
|
+
* lighting falloff, exponential roughness/tonemap curves, trig for angles).
|
|
8
|
+
* These aren't FLOPs in the IEEE sense — a GPU's sqrt/sin/pow are either a
|
|
9
|
+
* dedicated special-function-unit instruction or a multi-instruction
|
|
10
|
+
* polynomial approximation, so "ops/s" here means "results/s", not a fixed
|
|
11
|
+
* instruction count — but they're counted with the same MAC-as-2 convention
|
|
12
|
+
* as the multiply-add kernels so the throughput numbers stay comparable.
|
|
13
|
+
*/
|
|
14
|
+
/** fp32 divide-add ops: same shape as the fp32 scalar FMA test, multiply swapped for divide. */
|
|
15
|
+
export declare function prepareFlopsF32Div(ctx: GpuContext, harness?: FlopsHarnessConfig): Promise<PreparedBenchmark>;
|
|
16
|
+
/** i32 divide-add ops: same shape as the int8-range scalar test, multiply swapped for divide. */
|
|
17
|
+
export declare function prepareFlopsI32Div(ctx: GpuContext, harness?: FlopsHarnessConfig): Promise<PreparedBenchmark>;
|
|
18
|
+
/** fp32 sqrt-add ops: sqrt in place of the FMA multiply. */
|
|
19
|
+
export declare function prepareFlopsF32Sqrt(ctx: GpuContext, harness?: FlopsHarnessConfig): Promise<PreparedBenchmark>;
|
|
20
|
+
/** fp32 rsqrt-add ops: inverseSqrt in place of the FMA multiply. */
|
|
21
|
+
export declare function prepareFlopsF32Rsqrt(ctx: GpuContext, harness?: FlopsHarnessConfig): Promise<PreparedBenchmark>;
|
|
22
|
+
/** fp32 pow-add ops: pow in place of the FMA multiply. */
|
|
23
|
+
export declare function prepareFlopsF32Pow(ctx: GpuContext, harness?: FlopsHarnessConfig): Promise<PreparedBenchmark>;
|
|
24
|
+
/** fp32 sin(cos(x)) ops: the trig pair 3D math uses for angles/rotations. */
|
|
25
|
+
export declare function prepareFlopsF32Sincos(ctx: GpuContext, harness?: FlopsHarnessConfig): Promise<PreparedBenchmark>;
|
|
26
|
+
/** fp32 ln-add ops: natural log in place of the FMA multiply. */
|
|
27
|
+
export declare function prepareFlopsF32Log(ctx: GpuContext, harness?: FlopsHarnessConfig): Promise<PreparedBenchmark>;
|
|
28
|
+
//# sourceMappingURL=flopsMath.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flopsMath.d.ts","sourceRoot":"","sources":["../../src/benchmarks/flopsMath.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAyB,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AASlF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD;;;;;;;;;GASG;AAEH,gGAAgG;AAChG,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAchH;AAED,iGAAiG;AACjG,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAehH;AAED,4DAA4D;AAC5D,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAcjH;AAED,oEAAoE;AACpE,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAclH;AAED,0DAA0D;AAC1D,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAchH;AAED,6EAA6E;AAC7E,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAcnH;AAED,iEAAiE;AACjE,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAchH"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { prepareFlopsBenchmark } from "./flopsCommon.js";
|
|
2
|
+
import { flopsF32DivWgsl } from "../shaders/flopsF32Div.js";
|
|
3
|
+
import { flopsI32DivWgsl } from "../shaders/flopsI32Div.js";
|
|
4
|
+
import { flopsF32SqrtWgsl } from "../shaders/flopsF32Sqrt.js";
|
|
5
|
+
import { flopsF32RsqrtWgsl } from "../shaders/flopsF32Rsqrt.js";
|
|
6
|
+
import { flopsF32PowWgsl } from "../shaders/flopsF32Pow.js";
|
|
7
|
+
import { flopsF32SincosWgsl } from "../shaders/flopsF32Sincos.js";
|
|
8
|
+
import { flopsF32LogWgsl } from "../shaders/flopsF32Log.js";
|
|
9
|
+
import { OPS_METRIC } from "./common.js";
|
|
10
|
+
/**
|
|
11
|
+
* "Real" ALU ops beyond multiply-add: division and the transcendentals
|
|
12
|
+
* (sqrt, pow, sin/cos, log) that 3D math leans on constantly (normalize,
|
|
13
|
+
* lighting falloff, exponential roughness/tonemap curves, trig for angles).
|
|
14
|
+
* These aren't FLOPs in the IEEE sense — a GPU's sqrt/sin/pow are either a
|
|
15
|
+
* dedicated special-function-unit instruction or a multi-instruction
|
|
16
|
+
* polynomial approximation, so "ops/s" here means "results/s", not a fixed
|
|
17
|
+
* instruction count — but they're counted with the same MAC-as-2 convention
|
|
18
|
+
* as the multiply-add kernels so the throughput numbers stay comparable.
|
|
19
|
+
*/
|
|
20
|
+
/** fp32 divide-add ops: same shape as the fp32 scalar FMA test, multiply swapped for divide. */
|
|
21
|
+
export function prepareFlopsF32Div(ctx, harness = {}) {
|
|
22
|
+
return prepareFlopsBenchmark(ctx, {
|
|
23
|
+
id: 'flops-f32-div',
|
|
24
|
+
label: 'fp32 div FLOPS',
|
|
25
|
+
description: 'Eight independent scalar f32 divide-add chains per thread, unrolled 4x — the fp32 scalar FMA test with divide in place of multiply, so the gap between the two isolates the cost of division.',
|
|
26
|
+
wgsl: flopsF32DivWgsl,
|
|
27
|
+
flopsPerIteration: 64,
|
|
28
|
+
defaultIterations: 256,
|
|
29
|
+
}, harness);
|
|
30
|
+
}
|
|
31
|
+
/** i32 divide-add ops: same shape as the int8-range scalar test, multiply swapped for divide. */
|
|
32
|
+
export function prepareFlopsI32Div(ctx, harness = {}) {
|
|
33
|
+
return prepareFlopsBenchmark(ctx, {
|
|
34
|
+
id: 'flops-i32-div',
|
|
35
|
+
label: 'i32 div FLOPS',
|
|
36
|
+
description: 'Eight independent scalar i32 divide-add chains per thread, unrolled 4x — the int8-range scalar test with divide in place of multiply. Integer division is typically the slowest basic ALU op on a GPU.',
|
|
37
|
+
wgsl: flopsI32DivWgsl,
|
|
38
|
+
metric: OPS_METRIC,
|
|
39
|
+
flopsPerIteration: 64,
|
|
40
|
+
defaultIterations: 256,
|
|
41
|
+
}, harness);
|
|
42
|
+
}
|
|
43
|
+
/** fp32 sqrt-add ops: sqrt in place of the FMA multiply. */
|
|
44
|
+
export function prepareFlopsF32Sqrt(ctx, harness = {}) {
|
|
45
|
+
return prepareFlopsBenchmark(ctx, {
|
|
46
|
+
id: 'flops-f32-sqrt',
|
|
47
|
+
label: 'fp32 sqrt FLOPS',
|
|
48
|
+
description: 'Eight independent scalar f32 sqrt-add chains per thread, unrolled 4x. sqrt is a common special-function-unit instruction; this measures its throughput in isolation.',
|
|
49
|
+
wgsl: flopsF32SqrtWgsl,
|
|
50
|
+
flopsPerIteration: 64,
|
|
51
|
+
defaultIterations: 256,
|
|
52
|
+
}, harness);
|
|
53
|
+
}
|
|
54
|
+
/** fp32 rsqrt-add ops: inverseSqrt in place of the FMA multiply. */
|
|
55
|
+
export function prepareFlopsF32Rsqrt(ctx, harness = {}) {
|
|
56
|
+
return prepareFlopsBenchmark(ctx, {
|
|
57
|
+
id: 'flops-f32-rsqrt',
|
|
58
|
+
label: 'fp32 rsqrt FLOPS',
|
|
59
|
+
description: 'Eight independent scalar f32 inverseSqrt-add chains per thread, unrolled 4x. The op behind every normalize(); most GPUs have a dedicated fast-rsqrt path, so compare against flops-f32-sqrt to see the gap.',
|
|
60
|
+
wgsl: flopsF32RsqrtWgsl,
|
|
61
|
+
flopsPerIteration: 64,
|
|
62
|
+
defaultIterations: 256,
|
|
63
|
+
}, harness);
|
|
64
|
+
}
|
|
65
|
+
/** fp32 pow-add ops: pow in place of the FMA multiply. */
|
|
66
|
+
export function prepareFlopsF32Pow(ctx, harness = {}) {
|
|
67
|
+
return prepareFlopsBenchmark(ctx, {
|
|
68
|
+
id: 'flops-f32-pow',
|
|
69
|
+
label: 'fp32 pow FLOPS',
|
|
70
|
+
description: 'Eight independent scalar f32 pow-add chains per thread, unrolled 4x. pow(x, e) for a non-integer e is usually exp2(e * log2(x)) under the hood — several instructions — so expect this well below sqrt/div throughput.',
|
|
71
|
+
wgsl: flopsF32PowWgsl,
|
|
72
|
+
flopsPerIteration: 64,
|
|
73
|
+
defaultIterations: 128,
|
|
74
|
+
}, harness);
|
|
75
|
+
}
|
|
76
|
+
/** fp32 sin(cos(x)) ops: the trig pair 3D math uses for angles/rotations. */
|
|
77
|
+
export function prepareFlopsF32Sincos(ctx, harness = {}) {
|
|
78
|
+
return prepareFlopsBenchmark(ctx, {
|
|
79
|
+
id: 'flops-f32-sincos',
|
|
80
|
+
label: 'fp32 sin/cos FLOPS',
|
|
81
|
+
description: 'Eight independent scalar f32 cos(sin(x)) chains per thread, unrolled 4x. Naturally bounded to [-1, 1], so no stabilization term is needed. Measures combined sin+cos throughput.',
|
|
82
|
+
wgsl: flopsF32SincosWgsl,
|
|
83
|
+
flopsPerIteration: 64,
|
|
84
|
+
defaultIterations: 128,
|
|
85
|
+
}, harness);
|
|
86
|
+
}
|
|
87
|
+
/** fp32 ln-add ops: natural log in place of the FMA multiply. */
|
|
88
|
+
export function prepareFlopsF32Log(ctx, harness = {}) {
|
|
89
|
+
return prepareFlopsBenchmark(ctx, {
|
|
90
|
+
id: 'flops-f32-log',
|
|
91
|
+
label: 'fp32 ln FLOPS',
|
|
92
|
+
description: 'Eight independent scalar f32 ln-add chains per thread, unrolled 4x. log(x) is usually log2(x) * ln(2) under the hood, so expect throughput close to a raw log2 special-function call.',
|
|
93
|
+
wgsl: flopsF32LogWgsl,
|
|
94
|
+
flopsPerIteration: 64,
|
|
95
|
+
defaultIterations: 256,
|
|
96
|
+
}, harness);
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=flopsMath.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flopsMath.js","sourceRoot":"","sources":["../../src/benchmarks/flopsMath.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { GpuContext } from '../gpu/context.ts';
|
|
2
|
+
import type { GeneratedData } from '../data/generate.ts';
|
|
3
|
+
import { type HarnessConfig, type PreparedBenchmark } from './common.ts';
|
|
4
|
+
/**
|
|
5
|
+
* Read-bandwidth test: streams the (already-allocated, matrix-sized) input
|
|
6
|
+
* buffer through each thread with nothing but addition, writing back a
|
|
7
|
+
* single scalar per thread. Reads vastly outweigh writes, so `gbps` here is
|
|
8
|
+
* a read-bandwidth-bound number close to the device's peak.
|
|
9
|
+
*/
|
|
10
|
+
export declare function prepareReadBandwidth(ctx: GpuContext, data: GeneratedData, harness?: HarnessConfig): Promise<PreparedBenchmark>;
|
|
11
|
+
/**
|
|
12
|
+
* Write-bandwidth test: streams computed values out into a matrix-sized
|
|
13
|
+
* output buffer. No buffer reads at all, so `gbps` here is a
|
|
14
|
+
* write-bandwidth-bound number close to the device's peak.
|
|
15
|
+
*/
|
|
16
|
+
export declare function prepareWriteBandwidth(ctx: GpuContext, data: GeneratedData, harness?: HarnessConfig): Promise<PreparedBenchmark>;
|
|
17
|
+
//# sourceMappingURL=streamBandwidth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"streamBandwidth.d.ts","sourceRoot":"","sources":["../../src/benchmarks/streamBandwidth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,OAAO,EAIL,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACvB,MAAM,aAAa,CAAC;AAIrB;;;;;GAKG;AACH,wBAAsB,oBAAoB,CACxC,GAAG,EAAE,UAAU,EACf,IAAI,EAAE,aAAa,EACnB,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,iBAAiB,CAAC,CAiC5B;AAED;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,UAAU,EACf,IAAI,EAAE,aAAa,EACnB,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,iBAAiB,CAAC,CA+B5B"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { createUniformBuffer, createStorageBuffer, createEmptyStorageBuffer } from "../gpu/buffers.js";
|
|
2
|
+
import { createPipeline, prepareKernelBenchmark, BYTES_METRIC, } from "./common.js";
|
|
3
|
+
import { streamReadWgsl } from "../shaders/streamRead.js";
|
|
4
|
+
import { streamWriteWgsl } from "../shaders/streamWrite.js";
|
|
5
|
+
/**
|
|
6
|
+
* Read-bandwidth test: streams the (already-allocated, matrix-sized) input
|
|
7
|
+
* buffer through each thread with nothing but addition, writing back a
|
|
8
|
+
* single scalar per thread. Reads vastly outweigh writes, so `gbps` here is
|
|
9
|
+
* a read-bandwidth-bound number close to the device's peak.
|
|
10
|
+
*/
|
|
11
|
+
export async function prepareReadBandwidth(ctx, data, harness = {}) {
|
|
12
|
+
const { device } = ctx;
|
|
13
|
+
const cols4 = data.cols / 4;
|
|
14
|
+
const pipeline = await createPipeline(device, 'stream-read', streamReadWgsl);
|
|
15
|
+
const paramsBuf = createUniformBuffer(device, new Uint32Array([data.rows, cols4]), 'params');
|
|
16
|
+
const dataBuf = createStorageBuffer(device, data.matrix, 'data');
|
|
17
|
+
const outBuf = createEmptyStorageBuffer(device, data.rows * 4, 'out');
|
|
18
|
+
const bindGroup = device.createBindGroup({
|
|
19
|
+
layout: pipeline.getBindGroupLayout(0),
|
|
20
|
+
entries: [
|
|
21
|
+
{ binding: 0, resource: { buffer: paramsBuf } },
|
|
22
|
+
{ binding: 1, resource: { buffer: dataBuf } },
|
|
23
|
+
{ binding: 2, resource: { buffer: outBuf } },
|
|
24
|
+
],
|
|
25
|
+
});
|
|
26
|
+
return prepareKernelBenchmark({
|
|
27
|
+
id: 'read-bandwidth',
|
|
28
|
+
label: 'Read bandwidth',
|
|
29
|
+
description: 'One thread per row; streams a large buffer in via vec4<f32> loads and addition only, writes one scalar. Read-bandwidth-bound.',
|
|
30
|
+
source: streamReadWgsl,
|
|
31
|
+
category: 'bandwidth',
|
|
32
|
+
ctx,
|
|
33
|
+
rows: data.rows,
|
|
34
|
+
cols: data.cols,
|
|
35
|
+
metric: BYTES_METRIC,
|
|
36
|
+
amountPerOp: data.matrix.byteLength,
|
|
37
|
+
workgroupsPerIteration: [Math.ceil(data.rows / 64), 1, 1],
|
|
38
|
+
pipeline,
|
|
39
|
+
bindGroup,
|
|
40
|
+
...harness,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Write-bandwidth test: streams computed values out into a matrix-sized
|
|
45
|
+
* output buffer. No buffer reads at all, so `gbps` here is a
|
|
46
|
+
* write-bandwidth-bound number close to the device's peak.
|
|
47
|
+
*/
|
|
48
|
+
export async function prepareWriteBandwidth(ctx, data, harness = {}) {
|
|
49
|
+
const { device } = ctx;
|
|
50
|
+
const cols4 = data.cols / 4;
|
|
51
|
+
const pipeline = await createPipeline(device, 'stream-write', streamWriteWgsl);
|
|
52
|
+
const paramsBuf = createUniformBuffer(device, new Uint32Array([data.rows, cols4]), 'params');
|
|
53
|
+
const outBuf = createEmptyStorageBuffer(device, data.matrix.byteLength, 'out');
|
|
54
|
+
const bindGroup = device.createBindGroup({
|
|
55
|
+
layout: pipeline.getBindGroupLayout(0),
|
|
56
|
+
entries: [
|
|
57
|
+
{ binding: 0, resource: { buffer: paramsBuf } },
|
|
58
|
+
{ binding: 1, resource: { buffer: outBuf } },
|
|
59
|
+
],
|
|
60
|
+
});
|
|
61
|
+
return prepareKernelBenchmark({
|
|
62
|
+
id: 'write-bandwidth',
|
|
63
|
+
label: 'Write bandwidth',
|
|
64
|
+
description: 'One thread per row; stores computed vec4<f32> values into a large buffer with no buffer reads. Write-bandwidth-bound.',
|
|
65
|
+
source: streamWriteWgsl,
|
|
66
|
+
category: 'bandwidth',
|
|
67
|
+
ctx,
|
|
68
|
+
rows: data.rows,
|
|
69
|
+
cols: data.cols,
|
|
70
|
+
metric: BYTES_METRIC,
|
|
71
|
+
amountPerOp: data.matrix.byteLength,
|
|
72
|
+
workgroupsPerIteration: [Math.ceil(data.rows / 64), 1, 1],
|
|
73
|
+
pipeline,
|
|
74
|
+
bindGroup,
|
|
75
|
+
...harness,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=streamBandwidth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"streamBandwidth.js","sourceRoot":"","sources":["../../src/benchmarks/streamBandwidth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deterministic data generation for the bandwidth benchmarks. Every
|
|
3
|
+
* benchmark run (in every browser, on every machine) sees a byte-identical
|
|
4
|
+
* buffer to stream, so results are reproducible run to run.
|
|
5
|
+
*/
|
|
6
|
+
/** Small, fast, seedable PRNG (mulberry32) — deterministic across platforms. */
|
|
7
|
+
export declare function mulberry32(seed: number): () => number;
|
|
8
|
+
/** Round up to the next multiple of 4 (so vec4/mat4 kernels can index without bounds checks). */
|
|
9
|
+
export declare function padToMultipleOf4(n: number): number;
|
|
10
|
+
export interface GeneratedData {
|
|
11
|
+
rows: number;
|
|
12
|
+
cols: number;
|
|
13
|
+
/** row-major, rows x cols */
|
|
14
|
+
matrix: Float32Array;
|
|
15
|
+
vector: Float32Array;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Generates a deterministic pseudo-random matrix and vector, values in
|
|
19
|
+
* [-1, 1), sized to LLM-weight-like magnitudes (scaled by 1/sqrt(cols) so
|
|
20
|
+
* dot products don't blow up in magnitude as cols grows).
|
|
21
|
+
*/
|
|
22
|
+
export declare function generateMatVecData(rows: number, cols: number, seed?: number): GeneratedData;
|
|
23
|
+
//# sourceMappingURL=generate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/data/generate.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,gFAAgF;AAChF,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,MAAM,CASrD;AAED,iGAAiG;AACjG,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,6BAA6B;IAC7B,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE,YAAY,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,SAAO,GAAG,aAAa,CAiBzF"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deterministic data generation for the bandwidth benchmarks. Every
|
|
3
|
+
* benchmark run (in every browser, on every machine) sees a byte-identical
|
|
4
|
+
* buffer to stream, so results are reproducible run to run.
|
|
5
|
+
*/
|
|
6
|
+
/** Small, fast, seedable PRNG (mulberry32) — deterministic across platforms. */
|
|
7
|
+
export function mulberry32(seed) {
|
|
8
|
+
let a = seed >>> 0;
|
|
9
|
+
return () => {
|
|
10
|
+
a = (a + 0x6d2b79f5) | 0;
|
|
11
|
+
let t = a;
|
|
12
|
+
t = Math.imul(t ^ (t >>> 15), t | 1);
|
|
13
|
+
t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
|
|
14
|
+
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
/** Round up to the next multiple of 4 (so vec4/mat4 kernels can index without bounds checks). */
|
|
18
|
+
export function padToMultipleOf4(n) {
|
|
19
|
+
return Math.ceil(n / 4) * 4;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Generates a deterministic pseudo-random matrix and vector, values in
|
|
23
|
+
* [-1, 1), sized to LLM-weight-like magnitudes (scaled by 1/sqrt(cols) so
|
|
24
|
+
* dot products don't blow up in magnitude as cols grows).
|
|
25
|
+
*/
|
|
26
|
+
export function generateMatVecData(rows, cols, seed = 1234) {
|
|
27
|
+
const paddedRows = padToMultipleOf4(rows);
|
|
28
|
+
const paddedCols = padToMultipleOf4(cols);
|
|
29
|
+
const rand = mulberry32(seed);
|
|
30
|
+
const scale = 1 / Math.sqrt(paddedCols);
|
|
31
|
+
const matrix = new Float32Array(paddedRows * paddedCols);
|
|
32
|
+
for (let i = 0; i < matrix.length; i++) {
|
|
33
|
+
matrix[i] = (rand() * 2 - 1) * scale;
|
|
34
|
+
}
|
|
35
|
+
const vector = new Float32Array(paddedCols);
|
|
36
|
+
for (let i = 0; i < vector.length; i++) {
|
|
37
|
+
vector[i] = rand() * 2 - 1;
|
|
38
|
+
}
|
|
39
|
+
return { rows: paddedRows, cols: paddedCols, matrix, vector };
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=generate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../src/data/generate.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,gFAAgF;AAChF,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,IAAI,CAAC,GAAG,IAAI,KAAK,CAAC,CAAC;IACnB,OAAO,GAAG,EAAE;QACV,CAAC,GAAG,CAAC,CAAC,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;QACzB,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACrC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;QAC1C,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,UAAU,CAAC;IAC/C,CAAC,CAAC;AACJ,CAAC;AAED,iGAAiG;AACjG,MAAM,UAAU,gBAAgB,CAAC,CAAS;IACxC,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;AAC9B,CAAC;AAUD;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY,EAAE,IAAY,EAAE,IAAI,GAAG,IAAI;IACxE,MAAM,UAAU,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAC1C,MAAM,UAAU,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAC9B,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAExC,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,UAAU,GAAG,UAAU,CAAC,CAAC;IACzD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC;IACvC,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,UAAU,CAAC,CAAC;IAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAChE,CAAC"}
|