@kaminos/webgpu-inference-kit 0.1.2 → 0.1.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaminos/webgpu-inference-kit",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Composable browser WebGPU inference route contracts, runtime profiles, and scheduler envelopes.",
@@ -1,4 +1,4 @@
1
- export const WEBGPU_INFERENCE_KIT_VERSION = '0.1.2';
1
+ export const WEBGPU_INFERENCE_KIT_VERSION = '0.1.3';
2
2
  const DEFAULT_KIT_VERSION = WEBGPU_INFERENCE_KIT_VERSION;
3
3
  const DEFAULT_TIMING_SOURCE = 'queue-submit-wait';
4
4
 
@@ -95,6 +95,49 @@ function optionalRoleNames(roles) {
95
95
  return roles.filter(role => role.required === false).map(role => role.role);
96
96
  }
97
97
 
98
+ function routeTimingStageNames(timings = {}) {
99
+ const names = new Set();
100
+ const addStageName = stage => {
101
+ if (isNonEmptyString(stage)) names.add(stage);
102
+ if (isNonEmptyString(stage?.name)) names.add(stage.name);
103
+ };
104
+
105
+ if (Array.isArray(timings.stages)) {
106
+ timings.stages.forEach(addStageName);
107
+ }
108
+
109
+ const profile = timings.profile;
110
+ if (profile && typeof profile === 'object') {
111
+ if (Array.isArray(profile.stageNames)) {
112
+ profile.stageNames.forEach(addStageName);
113
+ }
114
+ if (Array.isArray(profile.stages)) {
115
+ profile.stages.forEach(addStageName);
116
+ }
117
+ }
118
+
119
+ return names;
120
+ }
121
+
122
+ function validateRouteTiming(errors, receipt, route) {
123
+ const timings = receipt?.timings;
124
+ if (!timings || !route) return;
125
+
126
+ if (isNonEmptyString(route.timingSource) && timings.source !== route.timingSource) {
127
+ errors.push(`receipt.timings.source must be ${route.timingSource}`);
128
+ }
129
+
130
+ const requiredStages = Array.isArray(route.requiredStages) ? route.requiredStages : [];
131
+ if (requiredStages.length === 0) return;
132
+
133
+ const stageNames = routeTimingStageNames(timings);
134
+ for (const stageName of requiredStages) {
135
+ if (!stageNames.has(stageName)) {
136
+ errors.push(`receipt.timings missing required stage ${stageName}`);
137
+ }
138
+ }
139
+ }
140
+
98
141
  function validateArtifacts(errors, artifacts, roles, path, { requireHash }) {
99
142
  const knownRoles = roleSet(roles);
100
143
  const artifactsByRole = new Map();
@@ -322,6 +365,7 @@ export function validateRouteWorkerResult(result, route) {
322
365
  if (result.receipt.effectiveRouteId !== route.routeId) {
323
366
  errors.push('receipt.effectiveRouteId must match route definition');
324
367
  }
368
+ if (routeResult.ok) validateRouteTiming(errors, result.receipt, route);
325
369
  }
326
370
 
327
371
  const backendResult = validateWebGpuBackendIdentity(result.backend);