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,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* fp32 divide-add FLOPS probe. Same shape as {@link flopsF32ScalarWgsl}
|
|
3
|
+
* (eight independent chains, unrolled 4x) but with the multiply replaced by
|
|
4
|
+
* a divide: `x = x / a + b`. `a` is kept > 1 so each step is a contraction
|
|
5
|
+
* (bounded, no risk of overflow/underflow over hundreds of iterations).
|
|
6
|
+
* 64 ops (32 divides + 32 adds) per loop iteration, same MAC-as-2 convention
|
|
7
|
+
* as the multiply version, so throughput is directly comparable.
|
|
8
|
+
*/
|
|
9
|
+
export declare const flopsF32DivWgsl = "\nstruct Params {\n threads: u32,\n iterations: u32,\n};\n\n@group(0) @binding(0) var<uniform> params: Params;\n@group(0) @binding(1) var<storage, read_write> out: array<f32>;\n\n@compute @workgroup_size(64)\nfn main(@builtin(global_invocation_id) gid: vec3<u32>) {\n let idx = gid.x;\n if (idx >= params.threads) {\n return;\n }\n let a: f32 = 1.2 + f32(idx & 15u) * 0.05;\n let b: f32 = 0.5 + f32(idx & 7u) * 0.001;\n var x0: f32 = f32(idx & 255u) * 0.0001 + 0.01;\n var x1: f32 = f32(idx & 255u) * 0.0001 + 0.02;\n var x2: f32 = f32(idx & 255u) * 0.0001 + 0.03;\n var x3: f32 = f32(idx & 255u) * 0.0001 + 0.04;\n var x4: f32 = f32(idx & 255u) * 0.0001 + 0.05;\n var x5: f32 = f32(idx & 255u) * 0.0001 + 0.06;\n var x6: f32 = f32(idx & 255u) * 0.0001 + 0.07;\n var x7: f32 = f32(idx & 255u) * 0.0001 + 0.08;\n for (var i: u32 = 0u; i < params.iterations; i = i + 1u) {\n x0 = x0 / a + b;\n x1 = x1 / a + b;\n x2 = x2 / a + b;\n x3 = x3 / a + b;\n x4 = x4 / a + b;\n x5 = x5 / a + b;\n x6 = x6 / a + b;\n x7 = x7 / a + b;\n x0 = x0 / a + b;\n x1 = x1 / a + b;\n x2 = x2 / a + b;\n x3 = x3 / a + b;\n x4 = x4 / a + b;\n x5 = x5 / a + b;\n x6 = x6 / a + b;\n x7 = x7 / a + b;\n x0 = x0 / a + b;\n x1 = x1 / a + b;\n x2 = x2 / a + b;\n x3 = x3 / a + b;\n x4 = x4 / a + b;\n x5 = x5 / a + b;\n x6 = x6 / a + b;\n x7 = x7 / a + b;\n x0 = x0 / a + b;\n x1 = x1 / a + b;\n x2 = x2 / a + b;\n x3 = x3 / a + b;\n x4 = x4 / a + b;\n x5 = x5 / a + b;\n x6 = x6 / a + b;\n x7 = x7 / a + b;\n }\n out[idx] = x0 + x1 + x2 + x3 + x4 + x5 + x6 + x7;\n}\n";
|
|
10
|
+
//# sourceMappingURL=flopsF32Div.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flopsF32Div.d.ts","sourceRoot":"","sources":["../../src/shaders/flopsF32Div.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,6nDA6D3B,CAAC"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* fp32 divide-add FLOPS probe. Same shape as {@link flopsF32ScalarWgsl}
|
|
3
|
+
* (eight independent chains, unrolled 4x) but with the multiply replaced by
|
|
4
|
+
* a divide: `x = x / a + b`. `a` is kept > 1 so each step is a contraction
|
|
5
|
+
* (bounded, no risk of overflow/underflow over hundreds of iterations).
|
|
6
|
+
* 64 ops (32 divides + 32 adds) per loop iteration, same MAC-as-2 convention
|
|
7
|
+
* as the multiply version, so throughput is directly comparable.
|
|
8
|
+
*/
|
|
9
|
+
export const flopsF32DivWgsl = /* wgsl */ `
|
|
10
|
+
struct Params {
|
|
11
|
+
threads: u32,
|
|
12
|
+
iterations: u32,
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
@group(0) @binding(0) var<uniform> params: Params;
|
|
16
|
+
@group(0) @binding(1) var<storage, read_write> out: array<f32>;
|
|
17
|
+
|
|
18
|
+
@compute @workgroup_size(64)
|
|
19
|
+
fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
20
|
+
let idx = gid.x;
|
|
21
|
+
if (idx >= params.threads) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
let a: f32 = 1.2 + f32(idx & 15u) * 0.05;
|
|
25
|
+
let b: f32 = 0.5 + f32(idx & 7u) * 0.001;
|
|
26
|
+
var x0: f32 = f32(idx & 255u) * 0.0001 + 0.01;
|
|
27
|
+
var x1: f32 = f32(idx & 255u) * 0.0001 + 0.02;
|
|
28
|
+
var x2: f32 = f32(idx & 255u) * 0.0001 + 0.03;
|
|
29
|
+
var x3: f32 = f32(idx & 255u) * 0.0001 + 0.04;
|
|
30
|
+
var x4: f32 = f32(idx & 255u) * 0.0001 + 0.05;
|
|
31
|
+
var x5: f32 = f32(idx & 255u) * 0.0001 + 0.06;
|
|
32
|
+
var x6: f32 = f32(idx & 255u) * 0.0001 + 0.07;
|
|
33
|
+
var x7: f32 = f32(idx & 255u) * 0.0001 + 0.08;
|
|
34
|
+
for (var i: u32 = 0u; i < params.iterations; i = i + 1u) {
|
|
35
|
+
x0 = x0 / a + b;
|
|
36
|
+
x1 = x1 / a + b;
|
|
37
|
+
x2 = x2 / a + b;
|
|
38
|
+
x3 = x3 / a + b;
|
|
39
|
+
x4 = x4 / a + b;
|
|
40
|
+
x5 = x5 / a + b;
|
|
41
|
+
x6 = x6 / a + b;
|
|
42
|
+
x7 = x7 / a + b;
|
|
43
|
+
x0 = x0 / a + b;
|
|
44
|
+
x1 = x1 / a + b;
|
|
45
|
+
x2 = x2 / a + b;
|
|
46
|
+
x3 = x3 / a + b;
|
|
47
|
+
x4 = x4 / a + b;
|
|
48
|
+
x5 = x5 / a + b;
|
|
49
|
+
x6 = x6 / a + b;
|
|
50
|
+
x7 = x7 / a + b;
|
|
51
|
+
x0 = x0 / a + b;
|
|
52
|
+
x1 = x1 / a + b;
|
|
53
|
+
x2 = x2 / a + b;
|
|
54
|
+
x3 = x3 / a + b;
|
|
55
|
+
x4 = x4 / a + b;
|
|
56
|
+
x5 = x5 / a + b;
|
|
57
|
+
x6 = x6 / a + b;
|
|
58
|
+
x7 = x7 / a + b;
|
|
59
|
+
x0 = x0 / a + b;
|
|
60
|
+
x1 = x1 / a + b;
|
|
61
|
+
x2 = x2 / a + b;
|
|
62
|
+
x3 = x3 / a + b;
|
|
63
|
+
x4 = x4 / a + b;
|
|
64
|
+
x5 = x5 / a + b;
|
|
65
|
+
x6 = x6 / a + b;
|
|
66
|
+
x7 = x7 / a + b;
|
|
67
|
+
}
|
|
68
|
+
out[idx] = x0 + x1 + x2 + x3 + x4 + x5 + x6 + x7;
|
|
69
|
+
}
|
|
70
|
+
`;
|
|
71
|
+
//# sourceMappingURL=flopsF32Div.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flopsF32Div.js","sourceRoot":"","sources":["../../src/shaders/flopsF32Div.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6DzC,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* fp32<->fp16 conversion FLOPS probe, using the core `pack2x16float` /
|
|
3
|
+
* `unpack2x16float` builtins (round each of a vec2<f32>'s lanes to fp16 and
|
|
4
|
+
* back) — these don't need the `shader-f16` device feature, unlike the
|
|
5
|
+
* flops-f16-* kernels which compute *in* f16. Eight independent vec2<f32>
|
|
6
|
+
* lanes; each step: pack (1 op) + unpack (1 op) + a vec2 FMA to keep the
|
|
7
|
+
* chain moving and bounded (4 ops: 2 muls + 2 adds) = 6 ops/lane/step,
|
|
8
|
+
* unrolled 4x. 192 ops per loop iteration.
|
|
9
|
+
*/
|
|
10
|
+
export declare const flopsF32F16ConvertWgsl = "\nstruct Params {\n threads: u32,\n iterations: u32,\n};\n\n@group(0) @binding(0) var<uniform> params: Params;\n@group(0) @binding(1) var<storage, read_write> out: array<f32>;\n\n@compute @workgroup_size(64)\nfn main(@builtin(global_invocation_id) gid: vec3<u32>) {\n let idx = gid.x;\n if (idx >= params.threads) {\n return;\n }\n let a: vec2<f32> = vec2<f32>(0.97 + f32(idx & 15u) * 0.001);\n let b: vec2<f32> = vec2<f32>(0.5 + f32(idx & 7u) * 0.001);\n var x0: vec2<f32> = vec2<f32>(f32(idx & 255u) * 0.0001 + 0.01);\n var x1: vec2<f32> = vec2<f32>(f32(idx & 255u) * 0.0001 + 0.02);\n var x2: vec2<f32> = vec2<f32>(f32(idx & 255u) * 0.0001 + 0.03);\n var x3: vec2<f32> = vec2<f32>(f32(idx & 255u) * 0.0001 + 0.04);\n var x4: vec2<f32> = vec2<f32>(f32(idx & 255u) * 0.0001 + 0.05);\n var x5: vec2<f32> = vec2<f32>(f32(idx & 255u) * 0.0001 + 0.06);\n var x6: vec2<f32> = vec2<f32>(f32(idx & 255u) * 0.0001 + 0.07);\n var x7: vec2<f32> = vec2<f32>(f32(idx & 255u) * 0.0001 + 0.08);\n for (var i: u32 = 0u; i < params.iterations; i = i + 1u) {\n x0 = unpack2x16float(pack2x16float(x0)) * a + b;\n x1 = unpack2x16float(pack2x16float(x1)) * a + b;\n x2 = unpack2x16float(pack2x16float(x2)) * a + b;\n x3 = unpack2x16float(pack2x16float(x3)) * a + b;\n x4 = unpack2x16float(pack2x16float(x4)) * a + b;\n x5 = unpack2x16float(pack2x16float(x5)) * a + b;\n x6 = unpack2x16float(pack2x16float(x6)) * a + b;\n x7 = unpack2x16float(pack2x16float(x7)) * a + b;\n x0 = unpack2x16float(pack2x16float(x0)) * a + b;\n x1 = unpack2x16float(pack2x16float(x1)) * a + b;\n x2 = unpack2x16float(pack2x16float(x2)) * a + b;\n x3 = unpack2x16float(pack2x16float(x3)) * a + b;\n x4 = unpack2x16float(pack2x16float(x4)) * a + b;\n x5 = unpack2x16float(pack2x16float(x5)) * a + b;\n x6 = unpack2x16float(pack2x16float(x6)) * a + b;\n x7 = unpack2x16float(pack2x16float(x7)) * a + b;\n x0 = unpack2x16float(pack2x16float(x0)) * a + b;\n x1 = unpack2x16float(pack2x16float(x1)) * a + b;\n x2 = unpack2x16float(pack2x16float(x2)) * a + b;\n x3 = unpack2x16float(pack2x16float(x3)) * a + b;\n x4 = unpack2x16float(pack2x16float(x4)) * a + b;\n x5 = unpack2x16float(pack2x16float(x5)) * a + b;\n x6 = unpack2x16float(pack2x16float(x6)) * a + b;\n x7 = unpack2x16float(pack2x16float(x7)) * a + b;\n x0 = unpack2x16float(pack2x16float(x0)) * a + b;\n x1 = unpack2x16float(pack2x16float(x1)) * a + b;\n x2 = unpack2x16float(pack2x16float(x2)) * a + b;\n x3 = unpack2x16float(pack2x16float(x3)) * a + b;\n x4 = unpack2x16float(pack2x16float(x4)) * a + b;\n x5 = unpack2x16float(pack2x16float(x5)) * a + b;\n x6 = unpack2x16float(pack2x16float(x6)) * a + b;\n x7 = unpack2x16float(pack2x16float(x7)) * a + b;\n }\n let s0 = x0 + x1 + x2 + x3 + x4 + x5 + x6 + x7;\n out[idx] = s0.x + s0.y;\n}\n";
|
|
11
|
+
//# sourceMappingURL=flopsF32F16Convert.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flopsF32F16Convert.d.ts","sourceRoot":"","sources":["../../src/shaders/flopsF32F16Convert.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,k0FA8DlC,CAAC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* fp32<->fp16 conversion FLOPS probe, using the core `pack2x16float` /
|
|
3
|
+
* `unpack2x16float` builtins (round each of a vec2<f32>'s lanes to fp16 and
|
|
4
|
+
* back) — these don't need the `shader-f16` device feature, unlike the
|
|
5
|
+
* flops-f16-* kernels which compute *in* f16. Eight independent vec2<f32>
|
|
6
|
+
* lanes; each step: pack (1 op) + unpack (1 op) + a vec2 FMA to keep the
|
|
7
|
+
* chain moving and bounded (4 ops: 2 muls + 2 adds) = 6 ops/lane/step,
|
|
8
|
+
* unrolled 4x. 192 ops per loop iteration.
|
|
9
|
+
*/
|
|
10
|
+
export const flopsF32F16ConvertWgsl = /* wgsl */ `
|
|
11
|
+
struct Params {
|
|
12
|
+
threads: u32,
|
|
13
|
+
iterations: u32,
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
@group(0) @binding(0) var<uniform> params: Params;
|
|
17
|
+
@group(0) @binding(1) var<storage, read_write> out: array<f32>;
|
|
18
|
+
|
|
19
|
+
@compute @workgroup_size(64)
|
|
20
|
+
fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
21
|
+
let idx = gid.x;
|
|
22
|
+
if (idx >= params.threads) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
let a: vec2<f32> = vec2<f32>(0.97 + f32(idx & 15u) * 0.001);
|
|
26
|
+
let b: vec2<f32> = vec2<f32>(0.5 + f32(idx & 7u) * 0.001);
|
|
27
|
+
var x0: vec2<f32> = vec2<f32>(f32(idx & 255u) * 0.0001 + 0.01);
|
|
28
|
+
var x1: vec2<f32> = vec2<f32>(f32(idx & 255u) * 0.0001 + 0.02);
|
|
29
|
+
var x2: vec2<f32> = vec2<f32>(f32(idx & 255u) * 0.0001 + 0.03);
|
|
30
|
+
var x3: vec2<f32> = vec2<f32>(f32(idx & 255u) * 0.0001 + 0.04);
|
|
31
|
+
var x4: vec2<f32> = vec2<f32>(f32(idx & 255u) * 0.0001 + 0.05);
|
|
32
|
+
var x5: vec2<f32> = vec2<f32>(f32(idx & 255u) * 0.0001 + 0.06);
|
|
33
|
+
var x6: vec2<f32> = vec2<f32>(f32(idx & 255u) * 0.0001 + 0.07);
|
|
34
|
+
var x7: vec2<f32> = vec2<f32>(f32(idx & 255u) * 0.0001 + 0.08);
|
|
35
|
+
for (var i: u32 = 0u; i < params.iterations; i = i + 1u) {
|
|
36
|
+
x0 = unpack2x16float(pack2x16float(x0)) * a + b;
|
|
37
|
+
x1 = unpack2x16float(pack2x16float(x1)) * a + b;
|
|
38
|
+
x2 = unpack2x16float(pack2x16float(x2)) * a + b;
|
|
39
|
+
x3 = unpack2x16float(pack2x16float(x3)) * a + b;
|
|
40
|
+
x4 = unpack2x16float(pack2x16float(x4)) * a + b;
|
|
41
|
+
x5 = unpack2x16float(pack2x16float(x5)) * a + b;
|
|
42
|
+
x6 = unpack2x16float(pack2x16float(x6)) * a + b;
|
|
43
|
+
x7 = unpack2x16float(pack2x16float(x7)) * a + b;
|
|
44
|
+
x0 = unpack2x16float(pack2x16float(x0)) * a + b;
|
|
45
|
+
x1 = unpack2x16float(pack2x16float(x1)) * a + b;
|
|
46
|
+
x2 = unpack2x16float(pack2x16float(x2)) * a + b;
|
|
47
|
+
x3 = unpack2x16float(pack2x16float(x3)) * a + b;
|
|
48
|
+
x4 = unpack2x16float(pack2x16float(x4)) * a + b;
|
|
49
|
+
x5 = unpack2x16float(pack2x16float(x5)) * a + b;
|
|
50
|
+
x6 = unpack2x16float(pack2x16float(x6)) * a + b;
|
|
51
|
+
x7 = unpack2x16float(pack2x16float(x7)) * a + b;
|
|
52
|
+
x0 = unpack2x16float(pack2x16float(x0)) * a + b;
|
|
53
|
+
x1 = unpack2x16float(pack2x16float(x1)) * a + b;
|
|
54
|
+
x2 = unpack2x16float(pack2x16float(x2)) * a + b;
|
|
55
|
+
x3 = unpack2x16float(pack2x16float(x3)) * a + b;
|
|
56
|
+
x4 = unpack2x16float(pack2x16float(x4)) * a + b;
|
|
57
|
+
x5 = unpack2x16float(pack2x16float(x5)) * a + b;
|
|
58
|
+
x6 = unpack2x16float(pack2x16float(x6)) * a + b;
|
|
59
|
+
x7 = unpack2x16float(pack2x16float(x7)) * a + b;
|
|
60
|
+
x0 = unpack2x16float(pack2x16float(x0)) * a + b;
|
|
61
|
+
x1 = unpack2x16float(pack2x16float(x1)) * a + b;
|
|
62
|
+
x2 = unpack2x16float(pack2x16float(x2)) * a + b;
|
|
63
|
+
x3 = unpack2x16float(pack2x16float(x3)) * a + b;
|
|
64
|
+
x4 = unpack2x16float(pack2x16float(x4)) * a + b;
|
|
65
|
+
x5 = unpack2x16float(pack2x16float(x5)) * a + b;
|
|
66
|
+
x6 = unpack2x16float(pack2x16float(x6)) * a + b;
|
|
67
|
+
x7 = unpack2x16float(pack2x16float(x7)) * a + b;
|
|
68
|
+
}
|
|
69
|
+
let s0 = x0 + x1 + x2 + x3 + x4 + x5 + x6 + x7;
|
|
70
|
+
out[idx] = s0.x + s0.y;
|
|
71
|
+
}
|
|
72
|
+
`;
|
|
73
|
+
//# sourceMappingURL=flopsF32F16Convert.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flopsF32F16Convert.js","sourceRoot":"","sources":["../../src/shaders/flopsF32F16Convert.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8DhD,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* fp32 ln-add FLOPS probe. Same shape as {@link flopsF32ScalarWgsl} but
|
|
3
|
+
* `x = log(x) + b` (natural log) in place of the FMA. `b` is kept large
|
|
4
|
+
* (10-17) so it dominates the small log(x) term and the chain stays
|
|
5
|
+
* comfortably positive forever — log of a negative/zero argument is
|
|
6
|
+
* undefined, so this is the stabilization that matters here. 64 ops (32
|
|
7
|
+
* logs + 32 adds) per loop iteration, same MAC-as-2 convention as the
|
|
8
|
+
* multiply version.
|
|
9
|
+
*/
|
|
10
|
+
export declare const flopsF32LogWgsl = "\nstruct Params {\n threads: u32,\n iterations: u32,\n};\n\n@group(0) @binding(0) var<uniform> params: Params;\n@group(0) @binding(1) var<storage, read_write> out: array<f32>;\n\n@compute @workgroup_size(64)\nfn main(@builtin(global_invocation_id) gid: vec3<u32>) {\n let idx = gid.x;\n if (idx >= params.threads) {\n return;\n }\n let b: f32 = 10.0 + f32(idx & 7u);\n var x0: f32 = 10.0 + f32(idx & 255u) * 0.01;\n var x1: f32 = 11.0 + f32(idx & 255u) * 0.01;\n var x2: f32 = 12.0 + f32(idx & 255u) * 0.01;\n var x3: f32 = 13.0 + f32(idx & 255u) * 0.01;\n var x4: f32 = 14.0 + f32(idx & 255u) * 0.01;\n var x5: f32 = 15.0 + f32(idx & 255u) * 0.01;\n var x6: f32 = 16.0 + f32(idx & 255u) * 0.01;\n var x7: f32 = 17.0 + f32(idx & 255u) * 0.01;\n for (var i: u32 = 0u; i < params.iterations; i = i + 1u) {\n x0 = log(x0) + b;\n x1 = log(x1) + b;\n x2 = log(x2) + b;\n x3 = log(x3) + b;\n x4 = log(x4) + b;\n x5 = log(x5) + b;\n x6 = log(x6) + b;\n x7 = log(x7) + b;\n x0 = log(x0) + b;\n x1 = log(x1) + b;\n x2 = log(x2) + b;\n x3 = log(x3) + b;\n x4 = log(x4) + b;\n x5 = log(x5) + b;\n x6 = log(x6) + b;\n x7 = log(x7) + b;\n x0 = log(x0) + b;\n x1 = log(x1) + b;\n x2 = log(x2) + b;\n x3 = log(x3) + b;\n x4 = log(x4) + b;\n x5 = log(x5) + b;\n x6 = log(x6) + b;\n x7 = log(x7) + b;\n x0 = log(x0) + b;\n x1 = log(x1) + b;\n x2 = log(x2) + b;\n x3 = log(x3) + b;\n x4 = log(x4) + b;\n x5 = log(x5) + b;\n x6 = log(x6) + b;\n x7 = log(x7) + b;\n }\n out[idx] = x0 + x1 + x2 + x3 + x4 + x5 + x6 + x7;\n}\n";
|
|
11
|
+
//# sourceMappingURL=flopsF32Log.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flopsF32Log.d.ts","sourceRoot":"","sources":["../../src/shaders/flopsF32Log.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,ylDA4D3B,CAAC"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* fp32 ln-add FLOPS probe. Same shape as {@link flopsF32ScalarWgsl} but
|
|
3
|
+
* `x = log(x) + b` (natural log) in place of the FMA. `b` is kept large
|
|
4
|
+
* (10-17) so it dominates the small log(x) term and the chain stays
|
|
5
|
+
* comfortably positive forever — log of a negative/zero argument is
|
|
6
|
+
* undefined, so this is the stabilization that matters here. 64 ops (32
|
|
7
|
+
* logs + 32 adds) per loop iteration, same MAC-as-2 convention as the
|
|
8
|
+
* multiply version.
|
|
9
|
+
*/
|
|
10
|
+
export const flopsF32LogWgsl = /* wgsl */ `
|
|
11
|
+
struct Params {
|
|
12
|
+
threads: u32,
|
|
13
|
+
iterations: u32,
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
@group(0) @binding(0) var<uniform> params: Params;
|
|
17
|
+
@group(0) @binding(1) var<storage, read_write> out: array<f32>;
|
|
18
|
+
|
|
19
|
+
@compute @workgroup_size(64)
|
|
20
|
+
fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
21
|
+
let idx = gid.x;
|
|
22
|
+
if (idx >= params.threads) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
let b: f32 = 10.0 + f32(idx & 7u);
|
|
26
|
+
var x0: f32 = 10.0 + f32(idx & 255u) * 0.01;
|
|
27
|
+
var x1: f32 = 11.0 + f32(idx & 255u) * 0.01;
|
|
28
|
+
var x2: f32 = 12.0 + f32(idx & 255u) * 0.01;
|
|
29
|
+
var x3: f32 = 13.0 + f32(idx & 255u) * 0.01;
|
|
30
|
+
var x4: f32 = 14.0 + f32(idx & 255u) * 0.01;
|
|
31
|
+
var x5: f32 = 15.0 + f32(idx & 255u) * 0.01;
|
|
32
|
+
var x6: f32 = 16.0 + f32(idx & 255u) * 0.01;
|
|
33
|
+
var x7: f32 = 17.0 + f32(idx & 255u) * 0.01;
|
|
34
|
+
for (var i: u32 = 0u; i < params.iterations; i = i + 1u) {
|
|
35
|
+
x0 = log(x0) + b;
|
|
36
|
+
x1 = log(x1) + b;
|
|
37
|
+
x2 = log(x2) + b;
|
|
38
|
+
x3 = log(x3) + b;
|
|
39
|
+
x4 = log(x4) + b;
|
|
40
|
+
x5 = log(x5) + b;
|
|
41
|
+
x6 = log(x6) + b;
|
|
42
|
+
x7 = log(x7) + b;
|
|
43
|
+
x0 = log(x0) + b;
|
|
44
|
+
x1 = log(x1) + b;
|
|
45
|
+
x2 = log(x2) + b;
|
|
46
|
+
x3 = log(x3) + b;
|
|
47
|
+
x4 = log(x4) + b;
|
|
48
|
+
x5 = log(x5) + b;
|
|
49
|
+
x6 = log(x6) + b;
|
|
50
|
+
x7 = log(x7) + b;
|
|
51
|
+
x0 = log(x0) + b;
|
|
52
|
+
x1 = log(x1) + b;
|
|
53
|
+
x2 = log(x2) + b;
|
|
54
|
+
x3 = log(x3) + b;
|
|
55
|
+
x4 = log(x4) + b;
|
|
56
|
+
x5 = log(x5) + b;
|
|
57
|
+
x6 = log(x6) + b;
|
|
58
|
+
x7 = log(x7) + b;
|
|
59
|
+
x0 = log(x0) + b;
|
|
60
|
+
x1 = log(x1) + b;
|
|
61
|
+
x2 = log(x2) + b;
|
|
62
|
+
x3 = log(x3) + b;
|
|
63
|
+
x4 = log(x4) + b;
|
|
64
|
+
x5 = log(x5) + b;
|
|
65
|
+
x6 = log(x6) + b;
|
|
66
|
+
x7 = log(x7) + b;
|
|
67
|
+
}
|
|
68
|
+
out[idx] = x0 + x1 + x2 + x3 + x4 + x5 + x6 + x7;
|
|
69
|
+
}
|
|
70
|
+
`;
|
|
71
|
+
//# sourceMappingURL=flopsF32Log.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flopsF32Log.js","sourceRoot":"","sources":["../../src/shaders/flopsF32Log.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4DzC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* fp32 mat4 FLOPS probe: `x = m * x + c` chained in a register, `m` a
|
|
3
|
+
* 4x4 matrix. `m` is a row-stochastic contraction (rows sum to 1, every
|
|
4
|
+
* entry runtime-derived and non-zero) so the recurrence stays bounded for
|
|
5
|
+
* any iteration count while still exercising a full, non-degenerate
|
|
6
|
+
* mat4x4 * vec4 multiply every iteration.
|
|
7
|
+
*/
|
|
8
|
+
export declare const flopsF32Mat4Wgsl = "\nstruct Params {\n threads: u32,\n iterations: u32,\n};\n\n@group(0) @binding(0) var<uniform> params: Params;\n@group(0) @binding(1) var<storage, read_write> out: array<f32>;\n\n@compute @workgroup_size(64)\nfn main(@builtin(global_invocation_id) gid: vec3<u32>) {\n let idx = gid.x;\n if (idx >= params.threads) {\n return;\n }\n let s: f32 = f32(idx & 15u) * 0.001 + 0.0001;\n let m: mat4x4<f32> = mat4x4<f32>(\n vec4<f32>(1.0 - 3.0 * s, s, s, s),\n vec4<f32>(s, 1.0 - 3.0 * s, s, s),\n vec4<f32>(s, s, 1.0 - 3.0 * s, s),\n vec4<f32>(s, s, s, 1.0 - 3.0 * s),\n );\n let c: vec4<f32> = vec4<f32>(s, s, s, s);\n var x: vec4<f32> = vec4<f32>(f32(idx & 255u) * 0.0001);\n for (var i: u32 = 0u; i < params.iterations; i = i + 1u) {\n x = m * x + c;\n }\n out[idx] = x.x + x.y + x.z + x.w;\n}\n";
|
|
9
|
+
//# sourceMappingURL=flopsF32Mat4.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flopsF32Mat4.d.ts","sourceRoot":"","sources":["../../src/shaders/flopsF32Mat4.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,2zBA6B5B,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* fp32 mat4 FLOPS probe: `x = m * x + c` chained in a register, `m` a
|
|
3
|
+
* 4x4 matrix. `m` is a row-stochastic contraction (rows sum to 1, every
|
|
4
|
+
* entry runtime-derived and non-zero) so the recurrence stays bounded for
|
|
5
|
+
* any iteration count while still exercising a full, non-degenerate
|
|
6
|
+
* mat4x4 * vec4 multiply every iteration.
|
|
7
|
+
*/
|
|
8
|
+
export const flopsF32Mat4Wgsl = /* wgsl */ `
|
|
9
|
+
struct Params {
|
|
10
|
+
threads: u32,
|
|
11
|
+
iterations: u32,
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
@group(0) @binding(0) var<uniform> params: Params;
|
|
15
|
+
@group(0) @binding(1) var<storage, read_write> out: array<f32>;
|
|
16
|
+
|
|
17
|
+
@compute @workgroup_size(64)
|
|
18
|
+
fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
19
|
+
let idx = gid.x;
|
|
20
|
+
if (idx >= params.threads) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
let s: f32 = f32(idx & 15u) * 0.001 + 0.0001;
|
|
24
|
+
let m: mat4x4<f32> = mat4x4<f32>(
|
|
25
|
+
vec4<f32>(1.0 - 3.0 * s, s, s, s),
|
|
26
|
+
vec4<f32>(s, 1.0 - 3.0 * s, s, s),
|
|
27
|
+
vec4<f32>(s, s, 1.0 - 3.0 * s, s),
|
|
28
|
+
vec4<f32>(s, s, s, 1.0 - 3.0 * s),
|
|
29
|
+
);
|
|
30
|
+
let c: vec4<f32> = vec4<f32>(s, s, s, s);
|
|
31
|
+
var x: vec4<f32> = vec4<f32>(f32(idx & 255u) * 0.0001);
|
|
32
|
+
for (var i: u32 = 0u; i < params.iterations; i = i + 1u) {
|
|
33
|
+
x = m * x + c;
|
|
34
|
+
}
|
|
35
|
+
out[idx] = x.x + x.y + x.z + x.w;
|
|
36
|
+
}
|
|
37
|
+
`;
|
|
38
|
+
//# sourceMappingURL=flopsF32Mat4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flopsF32Mat4.js","sourceRoot":"","sources":["../../src/shaders/flopsF32Mat4.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6B1C,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Register-resident matvec tile, fp32: a 4-row x 8-column weight tile held in
|
|
3
|
+
* registers (8 x vec4<f32>, hashed from the thread id so every thread has a
|
|
4
|
+
* different tile), applied to an 8-wide input vector every iteration. Each
|
|
5
|
+
* output row is two 4-wide dot() calls; the 4 outputs then become the next
|
|
6
|
+
* 4 input lanes (the other 4 shift over), so the loop is genuinely
|
|
7
|
+
* loop-carried and can't be hoisted. This is the same dot-product-and-
|
|
8
|
+
* accumulate shape as a real matvec/GEMV inner loop, but with no storage
|
|
9
|
+
* buffer traffic at all: it isolates how fast this dtype's dot products run
|
|
10
|
+
* on the ALU once bandwidth is out of the picture. 32 MACs (64 FLOPs) per
|
|
11
|
+
* loop iteration.
|
|
12
|
+
*/
|
|
13
|
+
export declare const flopsF32MatvecWgsl = "\nstruct Params {\n threads: u32,\n iterations: u32,\n};\n\n@group(0) @binding(0) var<uniform> params: Params;\n@group(0) @binding(1) var<storage, read_write> out: array<f32>;\n\n// Hashes a seed into four pseudo-random weights in about [-1/32, 1/32] (small\n// enough that the 8-wide dot products below are a contraction, so the\n// recurrence stays bounded for any iteration count).\nfn weights(seed: u32) -> vec4<f32> {\n let h = seed * 0x9e3779b1u;\n let bytes = vec4<u32>(h & 0xffu, (h >> 8u) & 0xffu, (h >> 16u) & 0xffu, h >> 24u);\n return (vec4<f32>(bytes) - vec4<f32>(127.5)) * (1.0 / 4096.0);\n}\n\n@compute @workgroup_size(64)\nfn main(@builtin(global_invocation_id) gid: vec3<u32>) {\n let idx = gid.x;\n if (idx >= params.threads) {\n return;\n }\n let w00: vec4<f32> = weights(idx * 8u + 1u);\n let w01: vec4<f32> = weights(idx * 8u + 2u);\n let w10: vec4<f32> = weights(idx * 8u + 3u);\n let w11: vec4<f32> = weights(idx * 8u + 4u);\n let w20: vec4<f32> = weights(idx * 8u + 5u);\n let w21: vec4<f32> = weights(idx * 8u + 6u);\n let w30: vec4<f32> = weights(idx * 8u + 7u);\n let w31: vec4<f32> = weights(idx * 8u + 8u);\n var x0: vec4<f32> = vec4<f32>(f32(idx & 255u) * 0.001 + 0.1, 0.2, 0.3, 0.4);\n var x1: vec4<f32> = vec4<f32>(f32(idx & 255u) * 0.001 + 0.2, 0.4, 0.6, 0.8);\n for (var i: u32 = 0u; i < params.iterations; i = i + 1u) {\n let o0 = dot(w00, x0) + dot(w01, x1);\n let o1 = dot(w10, x0) + dot(w11, x1);\n let o2 = dot(w20, x0) + dot(w21, x1);\n let o3 = dot(w30, x0) + dot(w31, x1);\n x0 = x1;\n x1 = vec4<f32>(o0, o1, o2, o3);\n }\n out[idx] = x0.x + x0.y + x0.z + x0.w + x1.x + x1.y + x1.z + x1.w;\n}\n";
|
|
14
|
+
//# sourceMappingURL=flopsF32Matvec.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flopsF32Matvec.d.ts","sourceRoot":"","sources":["../../src/shaders/flopsF32Matvec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,kBAAkB,mpDA4C9B,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Register-resident matvec tile, fp32: a 4-row x 8-column weight tile held in
|
|
3
|
+
* registers (8 x vec4<f32>, hashed from the thread id so every thread has a
|
|
4
|
+
* different tile), applied to an 8-wide input vector every iteration. Each
|
|
5
|
+
* output row is two 4-wide dot() calls; the 4 outputs then become the next
|
|
6
|
+
* 4 input lanes (the other 4 shift over), so the loop is genuinely
|
|
7
|
+
* loop-carried and can't be hoisted. This is the same dot-product-and-
|
|
8
|
+
* accumulate shape as a real matvec/GEMV inner loop, but with no storage
|
|
9
|
+
* buffer traffic at all: it isolates how fast this dtype's dot products run
|
|
10
|
+
* on the ALU once bandwidth is out of the picture. 32 MACs (64 FLOPs) per
|
|
11
|
+
* loop iteration.
|
|
12
|
+
*/
|
|
13
|
+
export const flopsF32MatvecWgsl = /* wgsl */ `
|
|
14
|
+
struct Params {
|
|
15
|
+
threads: u32,
|
|
16
|
+
iterations: u32,
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
@group(0) @binding(0) var<uniform> params: Params;
|
|
20
|
+
@group(0) @binding(1) var<storage, read_write> out: array<f32>;
|
|
21
|
+
|
|
22
|
+
// Hashes a seed into four pseudo-random weights in about [-1/32, 1/32] (small
|
|
23
|
+
// enough that the 8-wide dot products below are a contraction, so the
|
|
24
|
+
// recurrence stays bounded for any iteration count).
|
|
25
|
+
fn weights(seed: u32) -> vec4<f32> {
|
|
26
|
+
let h = seed * 0x9e3779b1u;
|
|
27
|
+
let bytes = vec4<u32>(h & 0xffu, (h >> 8u) & 0xffu, (h >> 16u) & 0xffu, h >> 24u);
|
|
28
|
+
return (vec4<f32>(bytes) - vec4<f32>(127.5)) * (1.0 / 4096.0);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@compute @workgroup_size(64)
|
|
32
|
+
fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
33
|
+
let idx = gid.x;
|
|
34
|
+
if (idx >= params.threads) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
let w00: vec4<f32> = weights(idx * 8u + 1u);
|
|
38
|
+
let w01: vec4<f32> = weights(idx * 8u + 2u);
|
|
39
|
+
let w10: vec4<f32> = weights(idx * 8u + 3u);
|
|
40
|
+
let w11: vec4<f32> = weights(idx * 8u + 4u);
|
|
41
|
+
let w20: vec4<f32> = weights(idx * 8u + 5u);
|
|
42
|
+
let w21: vec4<f32> = weights(idx * 8u + 6u);
|
|
43
|
+
let w30: vec4<f32> = weights(idx * 8u + 7u);
|
|
44
|
+
let w31: vec4<f32> = weights(idx * 8u + 8u);
|
|
45
|
+
var x0: vec4<f32> = vec4<f32>(f32(idx & 255u) * 0.001 + 0.1, 0.2, 0.3, 0.4);
|
|
46
|
+
var x1: vec4<f32> = vec4<f32>(f32(idx & 255u) * 0.001 + 0.2, 0.4, 0.6, 0.8);
|
|
47
|
+
for (var i: u32 = 0u; i < params.iterations; i = i + 1u) {
|
|
48
|
+
let o0 = dot(w00, x0) + dot(w01, x1);
|
|
49
|
+
let o1 = dot(w10, x0) + dot(w11, x1);
|
|
50
|
+
let o2 = dot(w20, x0) + dot(w21, x1);
|
|
51
|
+
let o3 = dot(w30, x0) + dot(w31, x1);
|
|
52
|
+
x0 = x1;
|
|
53
|
+
x1 = vec4<f32>(o0, o1, o2, o3);
|
|
54
|
+
}
|
|
55
|
+
out[idx] = x0.x + x0.y + x0.z + x0.w + x1.x + x1.y + x1.z + x1.w;
|
|
56
|
+
}
|
|
57
|
+
`;
|
|
58
|
+
//# sourceMappingURL=flopsF32Matvec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flopsF32Matvec.js","sourceRoot":"","sources":["../../src/shaders/flopsF32Matvec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4C5C,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* fp32 pow-add FLOPS probe. Same shape as {@link flopsF32ScalarWgsl} but
|
|
3
|
+
* `x = pow(x, e) + b` in place of the FMA. `e` is a per-lane exponent in
|
|
4
|
+
* (0, 1): for any x > 0, x^e is a contraction towards 1, so adding a
|
|
5
|
+
* positive `b` each step keeps the chain bounded and positive forever. 64
|
|
6
|
+
* ops (32 pows + 32 adds) per loop iteration, same MAC-as-2 convention as
|
|
7
|
+
* the multiply version.
|
|
8
|
+
*/
|
|
9
|
+
export declare const flopsF32PowWgsl = "\nstruct Params {\n threads: u32,\n iterations: u32,\n};\n\n@group(0) @binding(0) var<uniform> params: Params;\n@group(0) @binding(1) var<storage, read_write> out: array<f32>;\n\n@compute @workgroup_size(64)\nfn main(@builtin(global_invocation_id) gid: vec3<u32>) {\n let idx = gid.x;\n if (idx >= params.threads) {\n return;\n }\n let e: f32 = 0.4 + f32(idx & 15u) * 0.02;\n let b: f32 = 0.5 + f32(idx & 7u) * 0.001;\n var x0: f32 = f32(idx & 255u) * 0.0001 + 0.01;\n var x1: f32 = f32(idx & 255u) * 0.0001 + 0.02;\n var x2: f32 = f32(idx & 255u) * 0.0001 + 0.03;\n var x3: f32 = f32(idx & 255u) * 0.0001 + 0.04;\n var x4: f32 = f32(idx & 255u) * 0.0001 + 0.05;\n var x5: f32 = f32(idx & 255u) * 0.0001 + 0.06;\n var x6: f32 = f32(idx & 255u) * 0.0001 + 0.07;\n var x7: f32 = f32(idx & 255u) * 0.0001 + 0.08;\n for (var i: u32 = 0u; i < params.iterations; i = i + 1u) {\n x0 = pow(x0, e) + b;\n x1 = pow(x1, e) + b;\n x2 = pow(x2, e) + b;\n x3 = pow(x3, e) + b;\n x4 = pow(x4, e) + b;\n x5 = pow(x5, e) + b;\n x6 = pow(x6, e) + b;\n x7 = pow(x7, e) + b;\n x0 = pow(x0, e) + b;\n x1 = pow(x1, e) + b;\n x2 = pow(x2, e) + b;\n x3 = pow(x3, e) + b;\n x4 = pow(x4, e) + b;\n x5 = pow(x5, e) + b;\n x6 = pow(x6, e) + b;\n x7 = pow(x7, e) + b;\n x0 = pow(x0, e) + b;\n x1 = pow(x1, e) + b;\n x2 = pow(x2, e) + b;\n x3 = pow(x3, e) + b;\n x4 = pow(x4, e) + b;\n x5 = pow(x5, e) + b;\n x6 = pow(x6, e) + b;\n x7 = pow(x7, e) + b;\n x0 = pow(x0, e) + b;\n x1 = pow(x1, e) + b;\n x2 = pow(x2, e) + b;\n x3 = pow(x3, e) + b;\n x4 = pow(x4, e) + b;\n x5 = pow(x5, e) + b;\n x6 = pow(x6, e) + b;\n x7 = pow(x7, e) + b;\n }\n out[idx] = x0 + x1 + x2 + x3 + x4 + x5 + x6 + x7;\n}\n";
|
|
10
|
+
//# sourceMappingURL=flopsF32Pow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flopsF32Pow.d.ts","sourceRoot":"","sources":["../../src/shaders/flopsF32Pow.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,6vDA6D3B,CAAC"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* fp32 pow-add FLOPS probe. Same shape as {@link flopsF32ScalarWgsl} but
|
|
3
|
+
* `x = pow(x, e) + b` in place of the FMA. `e` is a per-lane exponent in
|
|
4
|
+
* (0, 1): for any x > 0, x^e is a contraction towards 1, so adding a
|
|
5
|
+
* positive `b` each step keeps the chain bounded and positive forever. 64
|
|
6
|
+
* ops (32 pows + 32 adds) per loop iteration, same MAC-as-2 convention as
|
|
7
|
+
* the multiply version.
|
|
8
|
+
*/
|
|
9
|
+
export const flopsF32PowWgsl = /* wgsl */ `
|
|
10
|
+
struct Params {
|
|
11
|
+
threads: u32,
|
|
12
|
+
iterations: u32,
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
@group(0) @binding(0) var<uniform> params: Params;
|
|
16
|
+
@group(0) @binding(1) var<storage, read_write> out: array<f32>;
|
|
17
|
+
|
|
18
|
+
@compute @workgroup_size(64)
|
|
19
|
+
fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
20
|
+
let idx = gid.x;
|
|
21
|
+
if (idx >= params.threads) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
let e: f32 = 0.4 + f32(idx & 15u) * 0.02;
|
|
25
|
+
let b: f32 = 0.5 + f32(idx & 7u) * 0.001;
|
|
26
|
+
var x0: f32 = f32(idx & 255u) * 0.0001 + 0.01;
|
|
27
|
+
var x1: f32 = f32(idx & 255u) * 0.0001 + 0.02;
|
|
28
|
+
var x2: f32 = f32(idx & 255u) * 0.0001 + 0.03;
|
|
29
|
+
var x3: f32 = f32(idx & 255u) * 0.0001 + 0.04;
|
|
30
|
+
var x4: f32 = f32(idx & 255u) * 0.0001 + 0.05;
|
|
31
|
+
var x5: f32 = f32(idx & 255u) * 0.0001 + 0.06;
|
|
32
|
+
var x6: f32 = f32(idx & 255u) * 0.0001 + 0.07;
|
|
33
|
+
var x7: f32 = f32(idx & 255u) * 0.0001 + 0.08;
|
|
34
|
+
for (var i: u32 = 0u; i < params.iterations; i = i + 1u) {
|
|
35
|
+
x0 = pow(x0, e) + b;
|
|
36
|
+
x1 = pow(x1, e) + b;
|
|
37
|
+
x2 = pow(x2, e) + b;
|
|
38
|
+
x3 = pow(x3, e) + b;
|
|
39
|
+
x4 = pow(x4, e) + b;
|
|
40
|
+
x5 = pow(x5, e) + b;
|
|
41
|
+
x6 = pow(x6, e) + b;
|
|
42
|
+
x7 = pow(x7, e) + b;
|
|
43
|
+
x0 = pow(x0, e) + b;
|
|
44
|
+
x1 = pow(x1, e) + b;
|
|
45
|
+
x2 = pow(x2, e) + b;
|
|
46
|
+
x3 = pow(x3, e) + b;
|
|
47
|
+
x4 = pow(x4, e) + b;
|
|
48
|
+
x5 = pow(x5, e) + b;
|
|
49
|
+
x6 = pow(x6, e) + b;
|
|
50
|
+
x7 = pow(x7, e) + b;
|
|
51
|
+
x0 = pow(x0, e) + b;
|
|
52
|
+
x1 = pow(x1, e) + b;
|
|
53
|
+
x2 = pow(x2, e) + b;
|
|
54
|
+
x3 = pow(x3, e) + b;
|
|
55
|
+
x4 = pow(x4, e) + b;
|
|
56
|
+
x5 = pow(x5, e) + b;
|
|
57
|
+
x6 = pow(x6, e) + b;
|
|
58
|
+
x7 = pow(x7, e) + b;
|
|
59
|
+
x0 = pow(x0, e) + b;
|
|
60
|
+
x1 = pow(x1, e) + b;
|
|
61
|
+
x2 = pow(x2, e) + b;
|
|
62
|
+
x3 = pow(x3, e) + b;
|
|
63
|
+
x4 = pow(x4, e) + b;
|
|
64
|
+
x5 = pow(x5, e) + b;
|
|
65
|
+
x6 = pow(x6, e) + b;
|
|
66
|
+
x7 = pow(x7, e) + b;
|
|
67
|
+
}
|
|
68
|
+
out[idx] = x0 + x1 + x2 + x3 + x4 + x5 + x6 + x7;
|
|
69
|
+
}
|
|
70
|
+
`;
|
|
71
|
+
//# sourceMappingURL=flopsF32Pow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flopsF32Pow.js","sourceRoot":"","sources":["../../src/shaders/flopsF32Pow.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6DzC,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* fp32 rsqrt-add FLOPS probe. Same shape as {@link flopsF32ScalarWgsl} but
|
|
3
|
+
* `x = inverseSqrt(x) + b` in place of the FMA. inverseSqrt(x) is always
|
|
4
|
+
* positive for x > 0, so `x` is bounded below by `b` from the second step
|
|
5
|
+
* on — always positive, never blows up. This is the op behind every
|
|
6
|
+
* `normalize()`: most GPUs have a dedicated fast-rsqrt path distinct from
|
|
7
|
+
* sqrt-then-divide, which is what the gap against flops-f32-sqrt shows. 64
|
|
8
|
+
* ops (32 rsqrts + 32 adds) per loop iteration, same MAC-as-2 convention as
|
|
9
|
+
* the multiply version.
|
|
10
|
+
*/
|
|
11
|
+
export declare const flopsF32RsqrtWgsl = "\nstruct Params {\n threads: u32,\n iterations: u32,\n};\n\n@group(0) @binding(0) var<uniform> params: Params;\n@group(0) @binding(1) var<storage, read_write> out: array<f32>;\n\n@compute @workgroup_size(64)\nfn main(@builtin(global_invocation_id) gid: vec3<u32>) {\n let idx = gid.x;\n if (idx >= params.threads) {\n return;\n }\n let b: f32 = 0.5 + f32(idx & 7u) * 0.001;\n var x0: f32 = f32(idx & 255u) * 0.0001 + 0.01;\n var x1: f32 = f32(idx & 255u) * 0.0001 + 0.02;\n var x2: f32 = f32(idx & 255u) * 0.0001 + 0.03;\n var x3: f32 = f32(idx & 255u) * 0.0001 + 0.04;\n var x4: f32 = f32(idx & 255u) * 0.0001 + 0.05;\n var x5: f32 = f32(idx & 255u) * 0.0001 + 0.06;\n var x6: f32 = f32(idx & 255u) * 0.0001 + 0.07;\n var x7: f32 = f32(idx & 255u) * 0.0001 + 0.08;\n for (var i: u32 = 0u; i < params.iterations; i = i + 1u) {\n x0 = inverseSqrt(x0) + b;\n x1 = inverseSqrt(x1) + b;\n x2 = inverseSqrt(x2) + b;\n x3 = inverseSqrt(x3) + b;\n x4 = inverseSqrt(x4) + b;\n x5 = inverseSqrt(x5) + b;\n x6 = inverseSqrt(x6) + b;\n x7 = inverseSqrt(x7) + b;\n x0 = inverseSqrt(x0) + b;\n x1 = inverseSqrt(x1) + b;\n x2 = inverseSqrt(x2) + b;\n x3 = inverseSqrt(x3) + b;\n x4 = inverseSqrt(x4) + b;\n x5 = inverseSqrt(x5) + b;\n x6 = inverseSqrt(x6) + b;\n x7 = inverseSqrt(x7) + b;\n x0 = inverseSqrt(x0) + b;\n x1 = inverseSqrt(x1) + b;\n x2 = inverseSqrt(x2) + b;\n x3 = inverseSqrt(x3) + b;\n x4 = inverseSqrt(x4) + b;\n x5 = inverseSqrt(x5) + b;\n x6 = inverseSqrt(x6) + b;\n x7 = inverseSqrt(x7) + b;\n x0 = inverseSqrt(x0) + b;\n x1 = inverseSqrt(x1) + b;\n x2 = inverseSqrt(x2) + b;\n x3 = inverseSqrt(x3) + b;\n x4 = inverseSqrt(x4) + b;\n x5 = inverseSqrt(x5) + b;\n x6 = inverseSqrt(x6) + b;\n x7 = inverseSqrt(x7) + b;\n }\n out[idx] = x0 + x1 + x2 + x3 + x4 + x5 + x6 + x7;\n}\n";
|
|
12
|
+
//# sourceMappingURL=flopsF32Rsqrt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flopsF32Rsqrt.d.ts","sourceRoot":"","sources":["../../src/shaders/flopsF32Rsqrt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,g3DA4D7B,CAAC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* fp32 rsqrt-add FLOPS probe. Same shape as {@link flopsF32ScalarWgsl} but
|
|
3
|
+
* `x = inverseSqrt(x) + b` in place of the FMA. inverseSqrt(x) is always
|
|
4
|
+
* positive for x > 0, so `x` is bounded below by `b` from the second step
|
|
5
|
+
* on — always positive, never blows up. This is the op behind every
|
|
6
|
+
* `normalize()`: most GPUs have a dedicated fast-rsqrt path distinct from
|
|
7
|
+
* sqrt-then-divide, which is what the gap against flops-f32-sqrt shows. 64
|
|
8
|
+
* ops (32 rsqrts + 32 adds) per loop iteration, same MAC-as-2 convention as
|
|
9
|
+
* the multiply version.
|
|
10
|
+
*/
|
|
11
|
+
export const flopsF32RsqrtWgsl = /* wgsl */ `
|
|
12
|
+
struct Params {
|
|
13
|
+
threads: u32,
|
|
14
|
+
iterations: u32,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
@group(0) @binding(0) var<uniform> params: Params;
|
|
18
|
+
@group(0) @binding(1) var<storage, read_write> out: array<f32>;
|
|
19
|
+
|
|
20
|
+
@compute @workgroup_size(64)
|
|
21
|
+
fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
22
|
+
let idx = gid.x;
|
|
23
|
+
if (idx >= params.threads) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
let b: f32 = 0.5 + f32(idx & 7u) * 0.001;
|
|
27
|
+
var x0: f32 = f32(idx & 255u) * 0.0001 + 0.01;
|
|
28
|
+
var x1: f32 = f32(idx & 255u) * 0.0001 + 0.02;
|
|
29
|
+
var x2: f32 = f32(idx & 255u) * 0.0001 + 0.03;
|
|
30
|
+
var x3: f32 = f32(idx & 255u) * 0.0001 + 0.04;
|
|
31
|
+
var x4: f32 = f32(idx & 255u) * 0.0001 + 0.05;
|
|
32
|
+
var x5: f32 = f32(idx & 255u) * 0.0001 + 0.06;
|
|
33
|
+
var x6: f32 = f32(idx & 255u) * 0.0001 + 0.07;
|
|
34
|
+
var x7: f32 = f32(idx & 255u) * 0.0001 + 0.08;
|
|
35
|
+
for (var i: u32 = 0u; i < params.iterations; i = i + 1u) {
|
|
36
|
+
x0 = inverseSqrt(x0) + b;
|
|
37
|
+
x1 = inverseSqrt(x1) + b;
|
|
38
|
+
x2 = inverseSqrt(x2) + b;
|
|
39
|
+
x3 = inverseSqrt(x3) + b;
|
|
40
|
+
x4 = inverseSqrt(x4) + b;
|
|
41
|
+
x5 = inverseSqrt(x5) + b;
|
|
42
|
+
x6 = inverseSqrt(x6) + b;
|
|
43
|
+
x7 = inverseSqrt(x7) + b;
|
|
44
|
+
x0 = inverseSqrt(x0) + b;
|
|
45
|
+
x1 = inverseSqrt(x1) + b;
|
|
46
|
+
x2 = inverseSqrt(x2) + b;
|
|
47
|
+
x3 = inverseSqrt(x3) + b;
|
|
48
|
+
x4 = inverseSqrt(x4) + b;
|
|
49
|
+
x5 = inverseSqrt(x5) + b;
|
|
50
|
+
x6 = inverseSqrt(x6) + b;
|
|
51
|
+
x7 = inverseSqrt(x7) + b;
|
|
52
|
+
x0 = inverseSqrt(x0) + b;
|
|
53
|
+
x1 = inverseSqrt(x1) + b;
|
|
54
|
+
x2 = inverseSqrt(x2) + b;
|
|
55
|
+
x3 = inverseSqrt(x3) + b;
|
|
56
|
+
x4 = inverseSqrt(x4) + b;
|
|
57
|
+
x5 = inverseSqrt(x5) + b;
|
|
58
|
+
x6 = inverseSqrt(x6) + b;
|
|
59
|
+
x7 = inverseSqrt(x7) + b;
|
|
60
|
+
x0 = inverseSqrt(x0) + b;
|
|
61
|
+
x1 = inverseSqrt(x1) + b;
|
|
62
|
+
x2 = inverseSqrt(x2) + b;
|
|
63
|
+
x3 = inverseSqrt(x3) + b;
|
|
64
|
+
x4 = inverseSqrt(x4) + b;
|
|
65
|
+
x5 = inverseSqrt(x5) + b;
|
|
66
|
+
x6 = inverseSqrt(x6) + b;
|
|
67
|
+
x7 = inverseSqrt(x7) + b;
|
|
68
|
+
}
|
|
69
|
+
out[idx] = x0 + x1 + x2 + x3 + x4 + x5 + x6 + x7;
|
|
70
|
+
}
|
|
71
|
+
`;
|
|
72
|
+
//# sourceMappingURL=flopsF32Rsqrt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flopsF32Rsqrt.js","sourceRoot":"","sources":["../../src/shaders/flopsF32Rsqrt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4D3C,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Raw fp32 FLOPS probe. Eight *independent* scalar FMA chains per thread,
|
|
3
|
+
* with the loop body unrolled 4x, so the ALU always has work in flight:
|
|
4
|
+
* a single dependent chain would measure FMA latency (plus loop overhead)
|
|
5
|
+
* rather than throughput. `a`/`b`/the trip count are runtime values, and
|
|
6
|
+
* every chain starts from a different value so the compiler can't merge
|
|
7
|
+
* them. One tiny write per thread at the end; everything else is pure ALU.
|
|
8
|
+
* 8 chains x 4 unrolled steps = 32 FMAs (64 FLOPs) per loop iteration.
|
|
9
|
+
*/
|
|
10
|
+
export declare const flopsF32ScalarWgsl = "\nstruct Params {\n threads: u32,\n iterations: u32,\n};\n\n@group(0) @binding(0) var<uniform> params: Params;\n@group(0) @binding(1) var<storage, read_write> out: array<f32>;\n\n@compute @workgroup_size(64)\nfn main(@builtin(global_invocation_id) gid: vec3<u32>) {\n let idx = gid.x;\n if (idx >= params.threads) {\n return;\n }\n let a: f32 = 1.0 - f32(idx & 15u) * 0.001;\n let b: f32 = 0.5 + f32(idx & 7u) * 0.001;\n var x0: f32 = f32(idx & 255u) * 0.0001 + 0.01;\n var x1: f32 = f32(idx & 255u) * 0.0001 + 0.02;\n var x2: f32 = f32(idx & 255u) * 0.0001 + 0.03;\n var x3: f32 = f32(idx & 255u) * 0.0001 + 0.04;\n var x4: f32 = f32(idx & 255u) * 0.0001 + 0.05;\n var x5: f32 = f32(idx & 255u) * 0.0001 + 0.06;\n var x6: f32 = f32(idx & 255u) * 0.0001 + 0.07;\n var x7: f32 = f32(idx & 255u) * 0.0001 + 0.08;\n for (var i: u32 = 0u; i < params.iterations; i = i + 1u) {\n x0 = x0 * a + b;\n x1 = x1 * a + b;\n x2 = x2 * a + b;\n x3 = x3 * a + b;\n x4 = x4 * a + b;\n x5 = x5 * a + b;\n x6 = x6 * a + b;\n x7 = x7 * a + b;\n x0 = x0 * a + b;\n x1 = x1 * a + b;\n x2 = x2 * a + b;\n x3 = x3 * a + b;\n x4 = x4 * a + b;\n x5 = x5 * a + b;\n x6 = x6 * a + b;\n x7 = x7 * a + b;\n x0 = x0 * a + b;\n x1 = x1 * a + b;\n x2 = x2 * a + b;\n x3 = x3 * a + b;\n x4 = x4 * a + b;\n x5 = x5 * a + b;\n x6 = x6 * a + b;\n x7 = x7 * a + b;\n x0 = x0 * a + b;\n x1 = x1 * a + b;\n x2 = x2 * a + b;\n x3 = x3 * a + b;\n x4 = x4 * a + b;\n x5 = x5 * a + b;\n x6 = x6 * a + b;\n x7 = x7 * a + b;\n }\n out[idx] = x0 + x1 + x2 + x3 + x4 + x5 + x6 + x7;\n}\n";
|
|
11
|
+
//# sourceMappingURL=flopsF32Scalar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flopsF32Scalar.d.ts","sourceRoot":"","sources":["../../src/shaders/flopsF32Scalar.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,8nDA6D9B,CAAC"}
|