Skip to content

Commit f8d8679

Browse files
committed
Stabilize smoke workload targets and runtime guards
1 parent 98d96fe commit f8d8679

2 files changed

Lines changed: 173 additions & 56 deletions

File tree

tests/CMakeLists.txt

Lines changed: 55 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ set(WEBVULKAN_SPIRV_WASM_PACKAGE "lights0123/llvm-spir" CACHE STRING "Wasmer pac
2626
set(WEBVULKAN_SPIRV_WASM_ENTRYPOINT "clspv" CACHE STRING "Wasmer command used for SPIR-V probe in clang wasm smoke")
2727
set(WEBVULKAN_RUNTIME_BENCH_ITERATIONS "5" CACHE STRING "Timed dispatch iterations per lavapipe runtime mode smoke")
2828
set(WEBVULKAN_RUNTIME_WARMUP_ITERATIONS "1" CACHE STRING "Warmup dispatch iterations per lavapipe runtime mode smoke")
29+
option(
30+
WEBVULKAN_ENABLE_EXPERIMENTAL_ATOMIC_WORKLOAD_SMOKE
31+
"Enable experimental workload smoke targets that currently require unsupported LLVM interpreter intrinsics"
32+
OFF
33+
)
2934

3035
if(NOT COMMAND CPMAddPackage)
3136
if(NOT DEFINED WEBVULKAN_CPM_VERSION OR WEBVULKAN_CPM_VERSION STREQUAL "")
@@ -383,54 +388,60 @@ add_dependencies(lavapipe_runtime_smoke_hot_loop
383388
lavapipe_runtime_smoke_raw_llvm_ir_hot_loop
384389
)
385390

386-
webvulkan_add_lavapipe_runtime_mode_smoke_target(
387-
lavapipe_runtime_smoke_fast_wasm_atomic_single_counter
388-
fast_wasm
389-
hot_loop_single_dispatch
390-
atomic_single_counter
391-
)
392-
webvulkan_add_lavapipe_runtime_mode_smoke_target(
393-
lavapipe_runtime_smoke_raw_llvm_ir_atomic_single_counter
394-
raw_llvm_ir
395-
hot_loop_single_dispatch
396-
atomic_single_counter
391+
add_custom_target(lavapipe_runtime_smoke_shader_workloads)
392+
add_dependencies(lavapipe_runtime_smoke_shader_workloads
393+
lavapipe_runtime_smoke_fast_wasm_micro
394+
lavapipe_runtime_smoke_raw_llvm_ir_micro
397395
)
398396

399-
webvulkan_add_lavapipe_runtime_mode_smoke_target(
400-
lavapipe_runtime_smoke_fast_wasm_atomic_per_workgroup
401-
fast_wasm
402-
hot_loop_single_dispatch
403-
atomic_per_workgroup
404-
)
405-
webvulkan_add_lavapipe_runtime_mode_smoke_target(
406-
lavapipe_runtime_smoke_raw_llvm_ir_atomic_per_workgroup
407-
raw_llvm_ir
408-
hot_loop_single_dispatch
409-
atomic_per_workgroup
410-
)
397+
if(WEBVULKAN_ENABLE_EXPERIMENTAL_ATOMIC_WORKLOAD_SMOKE)
398+
webvulkan_add_lavapipe_runtime_mode_smoke_target(
399+
lavapipe_runtime_smoke_fast_wasm_no_race_unique_writes
400+
fast_wasm
401+
hot_loop_single_dispatch
402+
no_race_unique_writes
403+
)
404+
webvulkan_add_lavapipe_runtime_mode_smoke_target(
405+
lavapipe_runtime_smoke_raw_llvm_ir_no_race_unique_writes
406+
raw_llvm_ir
407+
hot_loop_single_dispatch
408+
no_race_unique_writes
409+
)
410+
webvulkan_add_lavapipe_runtime_mode_smoke_target(
411+
lavapipe_runtime_smoke_fast_wasm_atomic_single_counter
412+
fast_wasm
413+
hot_loop_single_dispatch
414+
atomic_single_counter
415+
)
416+
webvulkan_add_lavapipe_runtime_mode_smoke_target(
417+
lavapipe_runtime_smoke_raw_llvm_ir_atomic_single_counter
418+
raw_llvm_ir
419+
hot_loop_single_dispatch
420+
atomic_single_counter
421+
)
411422

412-
webvulkan_add_lavapipe_runtime_mode_smoke_target(
413-
lavapipe_runtime_smoke_fast_wasm_no_race_unique_writes
414-
fast_wasm
415-
hot_loop_single_dispatch
416-
no_race_unique_writes
417-
)
418-
webvulkan_add_lavapipe_runtime_mode_smoke_target(
419-
lavapipe_runtime_smoke_raw_llvm_ir_no_race_unique_writes
420-
raw_llvm_ir
421-
hot_loop_single_dispatch
422-
no_race_unique_writes
423-
)
423+
webvulkan_add_lavapipe_runtime_mode_smoke_target(
424+
lavapipe_runtime_smoke_fast_wasm_atomic_per_workgroup
425+
fast_wasm
426+
hot_loop_single_dispatch
427+
atomic_per_workgroup
428+
)
429+
webvulkan_add_lavapipe_runtime_mode_smoke_target(
430+
lavapipe_runtime_smoke_raw_llvm_ir_atomic_per_workgroup
431+
raw_llvm_ir
432+
hot_loop_single_dispatch
433+
atomic_per_workgroup
434+
)
424435

425-
add_custom_target(lavapipe_runtime_smoke_shader_workloads)
426-
add_dependencies(lavapipe_runtime_smoke_shader_workloads
427-
lavapipe_runtime_smoke_fast_wasm_atomic_single_counter
428-
lavapipe_runtime_smoke_raw_llvm_ir_atomic_single_counter
429-
lavapipe_runtime_smoke_fast_wasm_atomic_per_workgroup
430-
lavapipe_runtime_smoke_raw_llvm_ir_atomic_per_workgroup
431-
lavapipe_runtime_smoke_fast_wasm_no_race_unique_writes
432-
lavapipe_runtime_smoke_raw_llvm_ir_no_race_unique_writes
433-
)
436+
add_dependencies(lavapipe_runtime_smoke_shader_workloads
437+
lavapipe_runtime_smoke_fast_wasm_no_race_unique_writes
438+
lavapipe_runtime_smoke_raw_llvm_ir_no_race_unique_writes
439+
lavapipe_runtime_smoke_fast_wasm_atomic_single_counter
440+
lavapipe_runtime_smoke_raw_llvm_ir_atomic_single_counter
441+
lavapipe_runtime_smoke_fast_wasm_atomic_per_workgroup
442+
lavapipe_runtime_smoke_raw_llvm_ir_atomic_per_workgroup
443+
)
444+
endif()
434445

435446
add_custom_target(lavapipe_runtime_smoke)
436447
add_dependencies(lavapipe_runtime_smoke lavapipe_runtime_smoke_fast_wasm lavapipe_runtime_smoke_raw_llvm_ir)

tests/wasm/tools/smoke_runtime.mjs

Lines changed: 118 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,82 @@ function runtimeShaderThreadgroupSizeX(workloadName) {
4747
return workloadName === "write_const" ? 1 : 64;
4848
}
4949

50-
async function compileRuntimeSpirv(storeValue, workloadName) {
51-
const storeConst = `0x${(storeValue >>> 0).toString(16)}u`;
52-
const threadgroupSizeX = runtimeShaderThreadgroupSizeX(workloadName);
53-
const dxcWasmJs = process.env.WEBVULKAN_DXC_WASM_JS || "";
54-
if (dxcWasmJs) {
55-
const hlslSource = `
50+
function runtimeBenchProfileDescriptor(profileName) {
51+
switch (profileName) {
52+
case "micro":
53+
return { dispatchesPerSubmit: 1024, dispatchX: 1, dispatchY: 1, dispatchZ: 1 };
54+
case "realistic":
55+
return { dispatchesPerSubmit: 64, dispatchX: 4, dispatchY: 1, dispatchZ: 1 };
56+
case "hot_loop_single_dispatch":
57+
return { dispatchesPerSubmit: 1, dispatchX: 256, dispatchY: 1, dispatchZ: 1 };
58+
default:
59+
throw new Error(`Unsupported runtime bench profile '${profileName}'`);
60+
}
61+
}
62+
63+
function runtimeShaderEntrypoint(workloadName) {
64+
switch (workloadName) {
65+
case "atomic_single_counter":
66+
return "atomic_single_counter";
67+
case "atomic_per_workgroup":
68+
return "atomic_per_workgroup";
69+
case "no_race_unique_writes":
70+
return "no_race_unique_writes";
71+
case "write_const":
72+
return "write_const";
73+
default:
74+
throw new Error(`Unsupported runtime shader workload '${workloadName}'`);
75+
}
76+
}
77+
78+
function runtimeShaderHlslSource(
79+
storeConst,
80+
threadgroupSizeX,
81+
workloadName,
82+
dispatchInvocationsPerSubmit,
83+
dispatchWorkgroupsPerSubmit
84+
) {
85+
const entrypoint = runtimeShaderEntrypoint(workloadName);
86+
if (workloadName === "atomic_single_counter") {
87+
return `
88+
RWStructuredBuffer<uint> OutBuf : register(u0);
89+
90+
[numthreads(${threadgroupSizeX}, 1, 1)]
91+
void ${entrypoint}(uint3 tid : SV_DispatchThreadID) {
92+
InterlockedAdd(OutBuf[0], 1u);
93+
}
94+
`;
95+
}
96+
97+
if (workloadName === "atomic_per_workgroup") {
98+
return `
99+
RWStructuredBuffer<uint> OutBuf : register(u0);
100+
101+
[numthreads(${threadgroupSizeX}, 1, 1)]
102+
void ${entrypoint}(uint3 groupThreadId : SV_GroupThreadID) {
103+
if (groupThreadId.x == 0u) {
104+
InterlockedAdd(OutBuf[0], 1u);
105+
}
106+
}
107+
`;
108+
}
109+
110+
if (workloadName === "no_race_unique_writes") {
111+
return `
112+
RWStructuredBuffer<uint> OutBuf : register(u0);
113+
114+
[numthreads(${threadgroupSizeX}, 1, 1)]
115+
void ${entrypoint}(uint3 tid : SV_DispatchThreadID) {
116+
if (tid.x == 0u && tid.y == 0u && tid.z == 0u) {
117+
OutBuf[0] = ${dispatchInvocationsPerSubmit}u;
118+
}
119+
uint idx = tid.x;
120+
OutBuf[1u + idx] = idx + 1u;
121+
}
122+
`;
123+
}
124+
125+
return `
56126
RWStructuredBuffer<uint> OutBuf : register(u0);
57127
58128
uint webvulkan_mix_const(uint v, uint salt) {
@@ -72,14 +142,36 @@ uint webvulkan_compile_time_chain() {
72142
}
73143
74144
[numthreads(${threadgroupSizeX}, 1, 1)]
75-
void write_const(uint3 tid : SV_DispatchThreadID) {
145+
void ${entrypoint}(uint3 tid : SV_DispatchThreadID) {
76146
uint folded = webvulkan_compile_time_chain();
77147
if (folded == 0xdeadbeefu) {
78148
OutBuf[1] = folded;
79149
}
80150
OutBuf[0] = ${storeConst};
81151
}
82152
`;
153+
}
154+
155+
async function compileRuntimeSpirv(storeValue, workloadName) {
156+
const storeConst = `0x${(storeValue >>> 0).toString(16)}u`;
157+
const threadgroupSizeX = runtimeShaderThreadgroupSizeX(workloadName);
158+
const shaderEntrypoint = runtimeShaderEntrypoint(workloadName);
159+
const profile = runtimeBenchProfileDescriptor(runtimeBenchProfile);
160+
const dispatchWorkgroupsPerSubmit =
161+
profile.dispatchesPerSubmit *
162+
profile.dispatchX *
163+
profile.dispatchY *
164+
profile.dispatchZ;
165+
const dispatchInvocationsPerSubmit = dispatchWorkgroupsPerSubmit * threadgroupSizeX;
166+
const dxcWasmJs = process.env.WEBVULKAN_DXC_WASM_JS || "";
167+
if (dxcWasmJs) {
168+
const hlslSource = runtimeShaderHlslSource(
169+
storeConst,
170+
threadgroupSizeX,
171+
workloadName,
172+
dispatchInvocationsPerSubmit,
173+
dispatchWorkgroupsPerSubmit
174+
);
83175

84176
const scratchDir = await mkdtemp(join(tmpdir(), "webvulkan-dxc-wasm-"));
85177
const inputFile = "runtime_smoke.hlsl";
@@ -94,7 +186,7 @@ void write_const(uint3 tid : SV_DispatchThreadID) {
94186
"-T",
95187
"cs_6_0",
96188
"-E",
97-
"write_const",
189+
shaderEntrypoint,
98190
"-Fo",
99191
outputFile,
100192
inputFile
@@ -117,10 +209,14 @@ void write_const(uint3 tid : SV_DispatchThreadID) {
117209
return {
118210
provider: `dxc-wasm:${dxcWasmJs}`,
119211
bytes,
120-
entrypoint: "write_const"
212+
entrypoint: shaderEntrypoint
121213
};
122214
}
123215

216+
if (workloadName !== "write_const") {
217+
throw new Error(`Workload '${workloadName}' requires WEBVULKAN_DXC_WASM_JS`);
218+
}
219+
124220
const wasmerBin = process.env.WEBVULKAN_WASMER_BIN;
125221
if (!wasmerBin) {
126222
throw new Error("WEBVULKAN_WASMER_BIN is required when SMOKE_REQUIRE_RUNTIME_SPIRV=1");
@@ -146,7 +242,7 @@ uint webvulkan_compile_time_chain() {
146242
}
147243
148244
__attribute__((reqd_work_group_size(${threadgroupSizeX}, 1, 1)))
149-
__kernel void write_const(__global uint* out) {
245+
__kernel void ${shaderEntrypoint}(__global uint* out) {
150246
uint folded = webvulkan_compile_time_chain();
151247
if (folded == (uint)0xdeadbeefu) {
152248
out[1] = folded;
@@ -200,7 +296,7 @@ __kernel void write_const(__global uint* out) {
200296
return {
201297
provider: attempt.provider,
202298
bytes: result.stdout,
203-
entrypoint: "write_const"
299+
entrypoint: shaderEntrypoint
204300
};
205301
}
206302

@@ -519,7 +615,14 @@ async function runFastWasmSmoke(shaderValue) {
519615
console.log(` runtime_wasm.bytes=${runtimeWasm.bytes.length}`);
520616

521617
console.log("runtime smoke discover_key");
522-
invokeSmokeOnce();
618+
if (runtimeShaderWorkload === "write_const") {
619+
invokeSmokeOnce();
620+
} else {
621+
const discoverRc = smokeFn();
622+
if (discoverRc !== 0) {
623+
console.log(`runtime smoke discover_key observed_nonzero_rc=${discoverRc} before runtime module registration`);
624+
}
625+
}
523626

524627
const hasCapturedKey = runtime.ccall("webvulkan_runtime_has_captured_shader_key", "number", [], []) !== 0;
525628
if (!hasCapturedKey) {
@@ -576,6 +679,9 @@ async function runFastWasmSmoke(shaderValue) {
576679
}
577680

578681
async function runRawLlvmIrSmoke(shaderValue) {
682+
if (runtimeShaderWorkload !== "write_const") {
683+
throw new Error(`raw_llvm_ir mode currently supports only write_const workload, got '${runtimeShaderWorkload}'`);
684+
}
579685
const spirv = await compileRuntimeSpirv(shaderValue, runtimeShaderWorkload);
580686
setRuntimeBenchProfile(runtimeBenchProfileValue);
581687
setRuntimeShaderWorkload(runtimeShaderWorkloadValue);

0 commit comments

Comments
 (0)