@camstack/addon-pipeline 1.2.293 → 1.2.295
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/THIRD_PARTY_MODELS.md +233 -0
- package/dist/audio-analyzer/index.js +2 -2
- package/dist/audio-analyzer/index.mjs +2 -2
- package/dist/{default-detection-model-DCQlW9fx.mjs → default-detection-model-CAUBVbgK.mjs} +53 -19
- package/dist/{default-detection-model-DTKHLLcC.js → default-detection-model-wNEISVA9.js} +58 -18
- package/dist/detection-pipeline/index.js +286 -458
- package/dist/detection-pipeline/index.mjs +286 -458
- package/dist/{dist-Ce8s7XqV.js → dist-BsVcf5wO.js} +1321 -833
- package/dist/{dist-C0Fr4hM5.mjs → dist-CuxSNLKW.mjs} +1316 -834
- package/dist/motion-wasm/index.js +1 -1
- package/dist/motion-wasm/index.mjs +1 -1
- package/dist/{node-Xm7amG2e.mjs → node-Cqb1QiXk.mjs} +1 -1
- package/dist/{node-DpOrymbW.js → node-UFk6I2f6.js} +1 -1
- package/dist/pipeline-runner/index.js +266 -72
- package/dist/pipeline-runner/index.mjs +266 -72
- package/dist/{process-memory-CBRjuhyg.js → process-memory-CJV29sPf.js} +1 -1
- package/dist/{process-memory-BN5qYGsD.mjs → process-memory-D0Nvs9rr.mjs} +1 -1
- package/dist/recorder/index.js +12 -2
- package/dist/recorder/index.mjs +12 -2
- package/dist/{segment-demux-js-BhMlS_Ow.js → segment-demux-js-DGwmf5hu.js} +1 -1
- package/dist/{segment-demux-js-Bhwpj5Wl.mjs → segment-demux-js-DIDWw1iE.mjs} +1 -1
- package/dist/stream-broker/_stub.js +2 -2
- package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-DKd7oYba.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-B7nBFqva.mjs} +2 -2
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CCIyBvRa.mjs +26 -0
- package/dist/stream-broker/{_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-DoyA71_q.mjs → _virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-DeD_UFdb.mjs} +1 -1
- package/dist/stream-broker/demux-worker-child.js +1 -1
- package/dist/stream-broker/demux-worker-child.mjs +1 -1
- package/dist/stream-broker/{hostInit-CCMIHjff.mjs → hostInit-BKlb3qac.mjs} +2 -2
- package/dist/stream-broker/index.js +3 -3
- package/dist/stream-broker/index.mjs +3 -3
- package/dist/stream-broker/remoteEntry.js +1 -1
- package/package.json +3 -2
- package/python/postprocessors/__init__.py +2 -0
- package/python/postprocessors/ssd.py +73 -17
- package/python/postprocessors/test_ssd.py +205 -0
- package/python/postprocessors/test_yunet.py +292 -0
- package/python/postprocessors/testdata/ssdlite_mobiledet_outputs.json +1 -0
- package/python/postprocessors/yunet.py +275 -0
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-6IHzlLJ_.mjs +0 -26
|
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const require_dist = require("../dist-
|
|
5
|
+
const require_dist = require("../dist-BsVcf5wO.js");
|
|
6
6
|
const require_lazy_sharp = require("../lazy-sharp-BuwKlQLR.js");
|
|
7
7
|
let node_fs = require("node:fs");
|
|
8
8
|
let node_path = require("node:path");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Et as motionDetectionCapability, _n as hydrateSchema, dn as DeviceType, lt as evaluateZoneRules, sn as BaseAddon } from "../dist-CuxSNLKW.mjs";
|
|
2
2
|
import { t as getSharp } from "../lazy-sharp-DXsqwpph.mjs";
|
|
3
3
|
import { readFileSync } from "node:fs";
|
|
4
4
|
import { join } from "node:path";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { an as isSoftwareDecode, en as errMsg, nn as Fmp4BoxSplitter, rn as buildFfmpegArgs } from "./dist-CuxSNLKW.mjs";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
3
|
import { realpathSync } from "node:fs";
|
|
4
4
|
import path from "node:path";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const require_chunk = require("./chunk-emK7D4bc.js");
|
|
2
|
-
const require_dist = require("./dist-
|
|
2
|
+
const require_dist = require("./dist-BsVcf5wO.js");
|
|
3
3
|
let node_crypto = require("node:crypto");
|
|
4
4
|
let node_fs = require("node:fs");
|
|
5
5
|
node_fs = require_chunk.__toESM(node_fs, 1);
|
|
@@ -3,9 +3,9 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../chunk-emK7D4bc.js");
|
|
6
|
-
const require_dist = require("../dist-
|
|
7
|
-
const require_node = require("../node-
|
|
8
|
-
const require_default_detection_model = require("../default-detection-model-
|
|
6
|
+
const require_dist = require("../dist-BsVcf5wO.js");
|
|
7
|
+
const require_node = require("../node-UFk6I2f6.js");
|
|
8
|
+
const require_default_detection_model = require("../default-detection-model-wNEISVA9.js");
|
|
9
9
|
const require_worker_protocol = require("../worker-protocol-B2MfQLlu.js");
|
|
10
10
|
const require_hub_hostname = require("../hub-hostname-DAJXlOgV.js");
|
|
11
11
|
const require_lazy_sharp = require("../lazy-sharp-BuwKlQLR.js");
|
|
@@ -1024,6 +1024,68 @@ var ParkedFrameStore = class {
|
|
|
1024
1024
|
}
|
|
1025
1025
|
}
|
|
1026
1026
|
};
|
|
1027
|
+
/**
|
|
1028
|
+
* The key prefix the hub parks a face's SOURCE frame under (D644). The hub
|
|
1029
|
+
* owns the key; the runner reads only this prefix, to keep those parcels in
|
|
1030
|
+
* their own budget. Mirrors `FACE_SOURCE_PARK_PREFIX` in addon-post-analysis
|
|
1031
|
+
* (`runtime/face-source-park-port.ts`) — both specs pin the literal.
|
|
1032
|
+
*/
|
|
1033
|
+
var FACE_SOURCE_PARCEL_PREFIX = "face-src:";
|
|
1034
|
+
/** Is this key a face source parcel? */
|
|
1035
|
+
function isFaceSourceParcelKey(trackId) {
|
|
1036
|
+
return trackId.startsWith(FACE_SOURCE_PARCEL_PREFIX);
|
|
1037
|
+
}
|
|
1038
|
+
/**
|
|
1039
|
+
* Track parcels and face source parcels in TWO stores with two budgets (D644).
|
|
1040
|
+
*
|
|
1041
|
+
* A face source parcel is a full native frame parked on every held best face.
|
|
1042
|
+
* In the shared store its eviction took the GLOBALLY oldest parcel — a
|
|
1043
|
+
* track's `keyFrame` or `thumbnail` — so a busy face scene could cost a track
|
|
1044
|
+
* its best frame (D58: media a later pass depends on must land). Here a face
|
|
1045
|
+
* parcel can only ever evict another face parcel.
|
|
1046
|
+
*/
|
|
1047
|
+
var PartitionedParkedFrameStore = class {
|
|
1048
|
+
track;
|
|
1049
|
+
faceSource;
|
|
1050
|
+
constructor(options = {}) {
|
|
1051
|
+
this.track = new ParkedFrameStore(options.track);
|
|
1052
|
+
this.faceSource = new ParkedFrameStore({
|
|
1053
|
+
budgetBytes: 16 * 1024 * 1024,
|
|
1054
|
+
perDeviceMax: 4,
|
|
1055
|
+
...options.faceSource
|
|
1056
|
+
});
|
|
1057
|
+
}
|
|
1058
|
+
storeFor(trackId) {
|
|
1059
|
+
return isFaceSourceParcelKey(trackId) ? this.faceSource : this.track;
|
|
1060
|
+
}
|
|
1061
|
+
get size() {
|
|
1062
|
+
return this.track.size + this.faceSource.size;
|
|
1063
|
+
}
|
|
1064
|
+
get bytes() {
|
|
1065
|
+
return this.track.bytes + this.faceSource.bytes;
|
|
1066
|
+
}
|
|
1067
|
+
park(deviceId, trackId, kind, frame) {
|
|
1068
|
+
return this.storeFor(trackId).park(deviceId, trackId, kind, frame);
|
|
1069
|
+
}
|
|
1070
|
+
get(deviceId, trackId, kind) {
|
|
1071
|
+
return this.storeFor(trackId).get(deviceId, trackId, kind);
|
|
1072
|
+
}
|
|
1073
|
+
release(deviceId, trackId) {
|
|
1074
|
+
return this.storeFor(trackId).release(deviceId, trackId);
|
|
1075
|
+
}
|
|
1076
|
+
statsByDevice(deviceId) {
|
|
1077
|
+
const a = this.track.statsByDevice(deviceId);
|
|
1078
|
+
const b = this.faceSource.statsByDevice(deviceId);
|
|
1079
|
+
return {
|
|
1080
|
+
parcels: a.parcels + b.parcels,
|
|
1081
|
+
bytes: a.bytes + b.bytes
|
|
1082
|
+
};
|
|
1083
|
+
}
|
|
1084
|
+
clear() {
|
|
1085
|
+
this.track.clear();
|
|
1086
|
+
this.faceSource.clear();
|
|
1087
|
+
}
|
|
1088
|
+
};
|
|
1027
1089
|
/** {@link RETAINED_FRAME_BUDGET_MB} in bytes. */
|
|
1028
1090
|
var RETAINED_FRAME_BUDGET_BYTES = (() => {
|
|
1029
1091
|
const raw = Number(process.env["CAMSTACK_SESSION_RETAIN_MB"]);
|
|
@@ -2173,28 +2235,17 @@ function onboardRootDetections(slot, frame, gate) {
|
|
|
2173
2235
|
//#endregion
|
|
2174
2236
|
//#region src/pipeline-runner/bench-step-schema.ts
|
|
2175
2237
|
/**
|
|
2176
|
-
* Shared bench-facing schemas: the minimal recursive step tree
|
|
2177
|
-
*
|
|
2178
|
-
*
|
|
2179
|
-
*
|
|
2180
|
-
*
|
|
2181
|
-
*
|
|
2182
|
-
*
|
|
2183
|
-
*
|
|
2184
|
-
*
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
runtime: require_dist._enum(["node", "python"]),
|
|
2188
|
-
backend: require_dist.string(),
|
|
2189
|
-
format: require_dist._enum([
|
|
2190
|
-
"onnx",
|
|
2191
|
-
"coreml",
|
|
2192
|
-
"openvino",
|
|
2193
|
-
"tflite",
|
|
2194
|
-
"pt"
|
|
2195
|
-
]),
|
|
2196
|
-
device: require_dist.string().optional()
|
|
2197
|
-
});
|
|
2238
|
+
* Shared bench-facing schemas: the minimal recursive step tree. Extracted from
|
|
2239
|
+
* `bench-actions.ts` so the capacity-ramp schemas (`capacity/capacity-schemas.ts`)
|
|
2240
|
+
* can reuse it without a bench-actions ↔ capacity-schemas import cycle.
|
|
2241
|
+
*
|
|
2242
|
+
* Local mirror of pipeline-executor's step shape ON PURPOSE (not a cap-package
|
|
2243
|
+
* coupling): addonId + modelId + enabled + children.
|
|
2244
|
+
*
|
|
2245
|
+
* There is no engine choice here any more (D646). A bench names the pool it
|
|
2246
|
+
* measures by `deviceKey`; the engine override it used to carry was honoured by
|
|
2247
|
+
* swapping the executor's shared engine state under live cameras.
|
|
2248
|
+
*/
|
|
2198
2249
|
var BenchStepSchema = require_dist.lazy(() => require_dist.object({
|
|
2199
2250
|
addonId: require_dist.string(),
|
|
2200
2251
|
modelId: require_dist.string(),
|
|
@@ -2230,7 +2281,6 @@ var RunCapacityRampInputSchema = require_dist.object({
|
|
|
2230
2281
|
sessionId: require_dist.string(),
|
|
2231
2282
|
nodeId: require_dist.string().optional(),
|
|
2232
2283
|
deviceKey: require_dist.string().optional(),
|
|
2233
|
-
engine: BenchEngineChoiceSchema.optional(),
|
|
2234
2284
|
slo: CapacitySloSchema.optional(),
|
|
2235
2285
|
allowActiveCameras: require_dist.boolean().optional(),
|
|
2236
2286
|
drainTimeoutSec: require_dist.number().min(1).max(300).optional()
|
|
@@ -2419,16 +2469,15 @@ var CacheBenchFrameResultSchema = require_dist.object({
|
|
|
2419
2469
|
});
|
|
2420
2470
|
var ReleaseBenchFrameInputSchema = require_dist.object({ frameId: require_dist.string() });
|
|
2421
2471
|
var ReleaseBenchFrameResultSchema = require_dist.object({ released: require_dist.boolean() });
|
|
2422
|
-
var
|
|
2472
|
+
var StartSyntheticBenchInputSchema = require_dist.object({
|
|
2423
2473
|
frameId: require_dist.string(),
|
|
2424
2474
|
steps: require_dist.array(BenchStepSchema).min(1),
|
|
2425
2475
|
parallel: require_dist.number().int().min(1).max(32),
|
|
2426
2476
|
iterations: require_dist.number().int().min(1).max(1e4),
|
|
2427
2477
|
warmup: require_dist.number().int().min(0).max(100).optional(),
|
|
2428
|
-
sessionId: require_dist.string().
|
|
2478
|
+
sessionId: require_dist.string().min(1),
|
|
2429
2479
|
simulatePipeline: require_dist.boolean().optional(),
|
|
2430
2480
|
nodeId: require_dist.string().optional(),
|
|
2431
|
-
engine: BenchEngineChoiceSchema.optional(),
|
|
2432
2481
|
deviceKey: require_dist.string().optional(),
|
|
2433
2482
|
plane: require_dist._enum(["full", "frame"]).optional()
|
|
2434
2483
|
});
|
|
@@ -2438,7 +2487,16 @@ var TimingSplitSchema = require_dist.object({
|
|
|
2438
2487
|
p95: require_dist.number(),
|
|
2439
2488
|
p99: require_dist.number()
|
|
2440
2489
|
});
|
|
2441
|
-
var
|
|
2490
|
+
var BenchPoolSchema = require_dist.object({
|
|
2491
|
+
nodeId: require_dist.string(),
|
|
2492
|
+
deviceKey: require_dist.string().nullable(),
|
|
2493
|
+
runtime: require_dist.string().nullable(),
|
|
2494
|
+
numWorkers: require_dist.number().nullable(),
|
|
2495
|
+
concurrency: require_dist.number().nullable(),
|
|
2496
|
+
batchMode: require_dist.string().nullable(),
|
|
2497
|
+
maxBatchSize: require_dist.number().nullable()
|
|
2498
|
+
});
|
|
2499
|
+
var SyntheticBenchResultSchema = require_dist.object({
|
|
2442
2500
|
runs: require_dist.number(),
|
|
2443
2501
|
wallSec: require_dist.number(),
|
|
2444
2502
|
fps: require_dist.number(),
|
|
@@ -2450,23 +2508,52 @@ var RunSyntheticBenchResultSchema = require_dist.object({
|
|
|
2450
2508
|
predictMs: require_dist.number(),
|
|
2451
2509
|
batchSizeMean: require_dist.number(),
|
|
2452
2510
|
batchSizeMax: require_dist.number(),
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
windowMs: require_dist.number(),
|
|
2461
|
-
maxBatchSize: require_dist.number(),
|
|
2462
|
-
concurrency: require_dist.number()
|
|
2463
|
-
}).optional(),
|
|
2464
|
-
path: require_dist.string().optional()
|
|
2511
|
+
pool: BenchPoolSchema,
|
|
2512
|
+
path: require_dist.string()
|
|
2513
|
+
});
|
|
2514
|
+
/** `startSyntheticBench` answers at once; the run continues in the background. */
|
|
2515
|
+
var StartSyntheticBenchAcceptedSchema = require_dist.object({
|
|
2516
|
+
accepted: require_dist.literal(true),
|
|
2517
|
+
sessionId: require_dist.string()
|
|
2465
2518
|
});
|
|
2519
|
+
var SyntheticBenchKeySchema = require_dist.object({ sessionId: require_dist.string() });
|
|
2520
|
+
var SyntheticBenchStatusSchema = require_dist.object({
|
|
2521
|
+
sessionId: require_dist.string(),
|
|
2522
|
+
state: require_dist._enum([
|
|
2523
|
+
"running",
|
|
2524
|
+
"done",
|
|
2525
|
+
"failed",
|
|
2526
|
+
"aborted"
|
|
2527
|
+
]),
|
|
2528
|
+
startedAtMs: require_dist.number(),
|
|
2529
|
+
finishedAtMs: require_dist.number().nullable(),
|
|
2530
|
+
progress: require_dist.object({
|
|
2531
|
+
runs: require_dist.number(),
|
|
2532
|
+
totalRuns: require_dist.number()
|
|
2533
|
+
}).nullable(),
|
|
2534
|
+
result: SyntheticBenchResultSchema.nullable(),
|
|
2535
|
+
error: require_dist.string().nullable()
|
|
2536
|
+
}).nullable();
|
|
2466
2537
|
var pipelineRunnerBenchActions = require_dist.defineCustomActions({
|
|
2467
2538
|
cacheBenchFrame: require_dist.customAction(CacheBenchFrameInputSchema, CacheBenchFrameResultSchema, { kind: "mutation" }),
|
|
2468
2539
|
releaseBenchFrame: require_dist.customAction(ReleaseBenchFrameInputSchema, ReleaseBenchFrameResultSchema, { kind: "mutation" }),
|
|
2469
|
-
|
|
2540
|
+
/**
|
|
2541
|
+
* START a synthetic bench and return at once (D646). Up to 32 parallel ×
|
|
2542
|
+
* 10 000 iterations does not fit the UDS addon-call plane's 60 s request
|
|
2543
|
+
* timeout, and a synchronous call was abandoned by its caller while it kept
|
|
2544
|
+
* loading the node. Poll `getSyntheticBenchStatus {sessionId}`; stop early
|
|
2545
|
+
* with `abortSyntheticBench {sessionId}`. One bench per runner at a time —
|
|
2546
|
+
* the measurement owns the pool.
|
|
2547
|
+
*/
|
|
2548
|
+
startSyntheticBench: require_dist.customAction(StartSyntheticBenchInputSchema, StartSyntheticBenchAcceptedSchema, {
|
|
2549
|
+
kind: "mutation",
|
|
2550
|
+
auth: "admin"
|
|
2551
|
+
}),
|
|
2552
|
+
getSyntheticBenchStatus: require_dist.customAction(SyntheticBenchKeySchema, SyntheticBenchStatusSchema),
|
|
2553
|
+
abortSyntheticBench: require_dist.customAction(SyntheticBenchKeySchema, require_dist.object({ aborted: require_dist.boolean() }), {
|
|
2554
|
+
kind: "mutation",
|
|
2555
|
+
auth: "admin"
|
|
2556
|
+
}),
|
|
2470
2557
|
/**
|
|
2471
2558
|
* OPEN-loop capacity ramp (spec `2026-08-02-capacity-test-design.md` §4):
|
|
2472
2559
|
* paced N×`fpsPerCamera` single-frame `runPipeline` calls with raw RGB —
|
|
@@ -2531,12 +2618,24 @@ function buildBenchRunPipelineInput(req) {
|
|
|
2531
2618
|
return {
|
|
2532
2619
|
steps: [...req.steps],
|
|
2533
2620
|
frame: req.frame,
|
|
2534
|
-
...req.engine ? { engine: req.engine } : {},
|
|
2535
2621
|
...req.deviceKey ? { deviceKey: req.deviceKey } : {},
|
|
2536
2622
|
...req.plane ? { plane: req.plane } : {}
|
|
2537
2623
|
};
|
|
2538
2624
|
}
|
|
2539
2625
|
/**
|
|
2626
|
+
* The tuning query for the pool a bench MEASURED (D646). It asked the node
|
|
2627
|
+
* default of whatever node answered first, so an NPU run was recorded beside
|
|
2628
|
+
* the onnx pool's `concurrency: 4`. Absent `deviceKey`, never
|
|
2629
|
+
* present-and-undefined, for the same `.loose()` reason as
|
|
2630
|
+
* {@link buildBenchRunPipelineInput}.
|
|
2631
|
+
*/
|
|
2632
|
+
function buildBenchTuningQuery(target) {
|
|
2633
|
+
return {
|
|
2634
|
+
nodeId: target.nodeId,
|
|
2635
|
+
input: target.deviceKey ? { deviceKey: target.deviceKey } : {}
|
|
2636
|
+
};
|
|
2637
|
+
}
|
|
2638
|
+
/**
|
|
2540
2639
|
* How long a box stays "seen".
|
|
2541
2640
|
*
|
|
2542
2641
|
* Sized on the gate's own clock, not on a guess: `maxDeferralMs` defaults to
|
|
@@ -3298,7 +3397,14 @@ function toDetailResult(detection, stepId, crop) {
|
|
|
3298
3397
|
...label.modelId !== void 0 ? { labelModelId: label.modelId } : {}
|
|
3299
3398
|
} : {},
|
|
3300
3399
|
...detection.faceAlignedCrop !== void 0 ? { alignedCropJpeg: detection.faceAlignedCrop } : {},
|
|
3301
|
-
...detection.nativeFaceShortSidePx !== void 0 ? { nativeFaceShortSidePx: detection.nativeFaceShortSidePx } : {}
|
|
3400
|
+
...detection.nativeFaceShortSidePx !== void 0 ? { nativeFaceShortSidePx: detection.nativeFaceShortSidePx } : {},
|
|
3401
|
+
...detection.landmarks !== void 0 ? { landmarks: detection.landmarks.map((p) => mapPointToFrameSpace(p, crop)) } : {}
|
|
3402
|
+
};
|
|
3403
|
+
}
|
|
3404
|
+
function mapPointToFrameSpace(point, crop) {
|
|
3405
|
+
return {
|
|
3406
|
+
x: crop.frameSpace.x + point.x * (crop.frameSpace.w / crop.width),
|
|
3407
|
+
y: crop.frameSpace.y + point.y * (crop.frameSpace.h / crop.height)
|
|
3302
3408
|
};
|
|
3303
3409
|
}
|
|
3304
3410
|
/**
|
|
@@ -6605,6 +6711,7 @@ var PipelineRunner = class {
|
|
|
6605
6711
|
//#endregion
|
|
6606
6712
|
//#region src/pipeline-runner/stateless-step.ts
|
|
6607
6713
|
function modelServability(step, modelId, format) {
|
|
6714
|
+
if (require_default_detection_model.RETIRED_MODEL_IDS[step.id]?.includes(modelId) === true) return { kind: "retired" };
|
|
6608
6715
|
const entry = step.models.find((m) => m.id === modelId);
|
|
6609
6716
|
if (entry === void 0) return { kind: "custom-model" };
|
|
6610
6717
|
if (entry.formats[format] !== void 0) return { kind: "catalog-build" };
|
|
@@ -6649,6 +6756,7 @@ async function runStatelessStep(deps, input) {
|
|
|
6649
6756
|
const format = await deps.executionFormat();
|
|
6650
6757
|
if (format === null) return refuse(deps, input, "model-not-servable", "this node could not report the engine format it would dispatch on, so the model pin cannot be verified — running anyway would risk a silent format substitution");
|
|
6651
6758
|
const servability = modelServability(definition, input.modelId, format);
|
|
6759
|
+
if (servability.kind === "retired") return refuse(deps, input, "model-not-servable", `model "${input.modelId}" was retired from the ${definition.id} catalog — this node would have substituted the step default`);
|
|
6652
6760
|
if (servability.kind === "no-build") return refuse(deps, input, "model-not-servable", `model "${input.modelId}" has no ${format} build (catalog ships: ${servability.availableFormats.join(", ") || "none"}) — this node would have substituted the ${format} default`);
|
|
6653
6761
|
let decodeError = null;
|
|
6654
6762
|
const crop = await cutFromFullFrame(input.frameJpeg, {
|
|
@@ -7504,6 +7612,26 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
7504
7612
|
benchFrameCache = /* @__PURE__ */ new Map();
|
|
7505
7613
|
benchFrameSweeper = null;
|
|
7506
7614
|
/**
|
|
7615
|
+
* Synthetic benches, start-then-poll (D646). One at a time on this runner —
|
|
7616
|
+
* the measurement owns the pool — and the last few finished ones kept for a
|
|
7617
|
+
* late poll. In RAM: a bench belongs to this process.
|
|
7618
|
+
*/
|
|
7619
|
+
syntheticBenches = new require_dist.BackgroundRunRegistry({
|
|
7620
|
+
maxConcurrent: 1,
|
|
7621
|
+
keepFinished: 5,
|
|
7622
|
+
onSettled: (status) => {
|
|
7623
|
+
const line = { meta: {
|
|
7624
|
+
sessionId: status.runId,
|
|
7625
|
+
state: status.state,
|
|
7626
|
+
error: status.error,
|
|
7627
|
+
runs: status.result?.runs ?? null,
|
|
7628
|
+
fps: status.result?.fps ?? null
|
|
7629
|
+
} };
|
|
7630
|
+
if (status.state === "failed") this.ctx.logger.warn("synthetic bench failed", line);
|
|
7631
|
+
else this.ctx.logger.info("synthetic bench finished", line);
|
|
7632
|
+
}
|
|
7633
|
+
});
|
|
7634
|
+
/**
|
|
7507
7635
|
* In-flight + recent capacity-ramp runs, keyed by sessionId. The ramp is
|
|
7508
7636
|
* fire-and-poll (a full run outlives the UDS addon-call 60s timeout), so
|
|
7509
7637
|
* completed results are kept here for `getCapacityRampStatus` to collect;
|
|
@@ -7582,7 +7710,11 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
7582
7710
|
nodeId: this.nodeId,
|
|
7583
7711
|
continuousRetain: isContinuousRetainEnabled()
|
|
7584
7712
|
});
|
|
7585
|
-
|
|
7713
|
+
const onEvict = (eviction) => this.noteParkedEviction(eviction.deviceId, eviction.cause);
|
|
7714
|
+
this.parkedFrames = new PartitionedParkedFrameStore({
|
|
7715
|
+
track: { onEvict },
|
|
7716
|
+
faceSource: { onEvict }
|
|
7717
|
+
});
|
|
7586
7718
|
this.runner = new PipelineRunner({
|
|
7587
7719
|
maxQueueDepth: this.config.maxQueueDepth,
|
|
7588
7720
|
maxConcurrentInferences: this.config.maxConcurrentInferences,
|
|
@@ -7700,7 +7832,9 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
7700
7832
|
actionHandlers: {
|
|
7701
7833
|
cacheBenchFrame: async (input) => this.cacheBenchFrame(input),
|
|
7702
7834
|
releaseBenchFrame: async (input) => this.releaseBenchFrame(input),
|
|
7703
|
-
|
|
7835
|
+
startSyntheticBench: async (input) => this.startSyntheticBench(input),
|
|
7836
|
+
getSyntheticBenchStatus: async (input) => this.getSyntheticBenchStatus(input.sessionId),
|
|
7837
|
+
abortSyntheticBench: async (input) => ({ aborted: this.syntheticBenches.abort(input.sessionId) }),
|
|
7704
7838
|
runCapacityRamp: async (input) => this.runCapacityRampAction(input),
|
|
7705
7839
|
getCapacityRampStatus: async (input) => this.getCapacityRampStatusAction(input),
|
|
7706
7840
|
listCapacityRamps: async () => this.listCapacityRampsAction(),
|
|
@@ -7722,6 +7856,7 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
7722
7856
|
this.benchFrameSweeper = null;
|
|
7723
7857
|
}
|
|
7724
7858
|
this.benchFrameCache.clear();
|
|
7859
|
+
this.syntheticBenches.abortAll();
|
|
7725
7860
|
for (const entry of this.capacityRuns.values()) entry.abortFlag.aborted = true;
|
|
7726
7861
|
this.capacityRuns.clear();
|
|
7727
7862
|
if (this.unsubMotionEvents) {
|
|
@@ -7801,7 +7936,34 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
7801
7936
|
const now = Date.now();
|
|
7802
7937
|
for (const [id, entry] of this.benchFrameCache) if (entry.expiresAt < now) this.benchFrameCache.delete(id);
|
|
7803
7938
|
}
|
|
7804
|
-
|
|
7939
|
+
/**
|
|
7940
|
+
* Validate the cheap preconditions synchronously (so a bad frame id is a
|
|
7941
|
+
* refusal the caller sees at once), then run the bench in the background
|
|
7942
|
+
* and answer with the receipt (D646).
|
|
7943
|
+
*/
|
|
7944
|
+
startSyntheticBench(input) {
|
|
7945
|
+
if (!this.ctx.api) throw new Error("startSyntheticBench: ctx.api unavailable");
|
|
7946
|
+
if (!this.benchFrameCache.has(input.frameId)) throw new Error(`startSyntheticBench: frameId ${input.frameId} not cached (call cacheBenchFrame first)`);
|
|
7947
|
+
this.syntheticBenches.start(input.sessionId, (run) => this.runSyntheticBench(input, run));
|
|
7948
|
+
return {
|
|
7949
|
+
accepted: true,
|
|
7950
|
+
sessionId: input.sessionId
|
|
7951
|
+
};
|
|
7952
|
+
}
|
|
7953
|
+
getSyntheticBenchStatus(sessionId) {
|
|
7954
|
+
const status = this.syntheticBenches.status(sessionId);
|
|
7955
|
+
if (status === null) return null;
|
|
7956
|
+
return {
|
|
7957
|
+
sessionId: status.runId,
|
|
7958
|
+
state: status.state,
|
|
7959
|
+
startedAtMs: status.startedAtMs,
|
|
7960
|
+
finishedAtMs: status.finishedAtMs,
|
|
7961
|
+
progress: status.progress,
|
|
7962
|
+
result: status.result,
|
|
7963
|
+
error: status.error
|
|
7964
|
+
};
|
|
7965
|
+
}
|
|
7966
|
+
async runSyntheticBench(input, run) {
|
|
7805
7967
|
const ctx = this.ctx;
|
|
7806
7968
|
const api = ctx.api;
|
|
7807
7969
|
if (!api) throw new Error("runSyntheticBench: ctx.api unavailable");
|
|
@@ -7851,8 +8013,7 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
7851
8013
|
}, pin)).frameId;
|
|
7852
8014
|
await api.pipelineExecutor.runPipeline.mutate({ ...buildBenchRunPipelineInput({
|
|
7853
8015
|
steps: stepsToRun,
|
|
7854
|
-
frame: sharedFrame
|
|
7855
|
-
...input.engine ? { engine: input.engine } : {}
|
|
8016
|
+
frame: sharedFrame
|
|
7856
8017
|
}) }, pin);
|
|
7857
8018
|
const warmupCount = input.warmup ?? 1;
|
|
7858
8019
|
for (let w = 0; w < warmupCount; w++) await api.pipelineExecutor.inferCached.mutate({
|
|
@@ -7866,11 +8027,12 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
7866
8027
|
const batchSizes = [];
|
|
7867
8028
|
const detCounts = [];
|
|
7868
8029
|
let _n = 0;
|
|
7869
|
-
const sessionId = input.sessionId
|
|
8030
|
+
const sessionId = input.sessionId;
|
|
7870
8031
|
const totalRuns = input.parallel * input.iterations;
|
|
7871
8032
|
const wallStart = performance.now();
|
|
7872
8033
|
const worker = async () => {
|
|
7873
8034
|
for (let i = 0; i < input.iterations; i++) {
|
|
8035
|
+
if (run.signal.aborted) break;
|
|
7874
8036
|
const t0 = performance.now();
|
|
7875
8037
|
const result = await api.pipelineExecutor.inferCached.mutate({
|
|
7876
8038
|
stepId: rootStep.addonId,
|
|
@@ -7890,6 +8052,10 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
7890
8052
|
batchSizes.push(bs);
|
|
7891
8053
|
detCounts.push(dets);
|
|
7892
8054
|
const n = ++_n;
|
|
8055
|
+
run.report({
|
|
8056
|
+
runs: n,
|
|
8057
|
+
totalRuns
|
|
8058
|
+
});
|
|
7893
8059
|
if (n <= 20) ctx.logger.info("bench call trace (cached)", { meta: {
|
|
7894
8060
|
n,
|
|
7895
8061
|
wallMs: Math.round(wallMs),
|
|
@@ -7942,7 +8108,7 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
7942
8108
|
await Promise.all(Array.from({ length: input.parallel }, () => worker()));
|
|
7943
8109
|
const wallSec = (performance.now() - wallStart) / 1e3;
|
|
7944
8110
|
await api.pipelineExecutor.uncacheFrame.mutate({ frameId: poolFrameId }, pin).catch(() => {});
|
|
7945
|
-
return this.buildBenchResult(wallTimings, inferTimings, preprocessTimings, predictTimings, batchSizes, detCounts, wallSec, "cached");
|
|
8111
|
+
return this.buildBenchResult(wallTimings, inferTimings, preprocessTimings, predictTimings, batchSizes, detCounts, wallSec, "cached", { nodeId: benchNode });
|
|
7946
8112
|
}
|
|
7947
8113
|
ctx.logger.info("synthetic bench: using full runPipeline path", { meta: {
|
|
7948
8114
|
steps: enabledSteps.length,
|
|
@@ -7956,7 +8122,6 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
7956
8122
|
const result = await api.pipelineExecutor.runPipeline.mutate({ ...buildBenchRunPipelineInput({
|
|
7957
8123
|
steps: stepsToRun,
|
|
7958
8124
|
frame: sharedFrame,
|
|
7959
|
-
...input.engine ? { engine: input.engine } : {},
|
|
7960
8125
|
...input.deviceKey ? { deviceKey: input.deviceKey } : {},
|
|
7961
8126
|
...input.plane ? { plane: input.plane } : {}
|
|
7962
8127
|
}) }, pin);
|
|
@@ -7984,11 +8149,12 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
7984
8149
|
const predictTimings = [];
|
|
7985
8150
|
const batchSizes = [];
|
|
7986
8151
|
const detCounts = [];
|
|
7987
|
-
const sessionId = input.sessionId
|
|
8152
|
+
const sessionId = input.sessionId;
|
|
7988
8153
|
const totalRuns = input.parallel * input.iterations;
|
|
7989
8154
|
const wallStart = performance.now();
|
|
7990
8155
|
const worker = async () => {
|
|
7991
8156
|
for (let i = 0; i < input.iterations; i++) {
|
|
8157
|
+
if (run.signal.aborted) break;
|
|
7992
8158
|
const { wallMs, result } = await callOnce();
|
|
7993
8159
|
wallTimings.push(wallMs);
|
|
7994
8160
|
serverWallTimings.push(result.debug?.wallMs ?? 0);
|
|
@@ -7998,6 +8164,10 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
7998
8164
|
batchSizes.push(result.debug?.batchSize ?? 1);
|
|
7999
8165
|
detCounts.push(result.detections?.length ?? 0);
|
|
8000
8166
|
const n = wallTimings.length;
|
|
8167
|
+
run.report({
|
|
8168
|
+
runs: n,
|
|
8169
|
+
totalRuns
|
|
8170
|
+
});
|
|
8001
8171
|
if (n % Math.max(1, input.parallel) === 0 && ctx.eventBus) {
|
|
8002
8172
|
const elapsed = (performance.now() - wallStart) / 1e3;
|
|
8003
8173
|
const fps = elapsed > 0 ? n / elapsed : 0;
|
|
@@ -8038,9 +8208,12 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
8038
8208
|
};
|
|
8039
8209
|
await Promise.all(Array.from({ length: input.parallel }, () => worker()));
|
|
8040
8210
|
const wallSec = (performance.now() - wallStart) / 1e3;
|
|
8041
|
-
return this.buildBenchResult(wallTimings, inferTimings, preprocessTimings, predictTimings, batchSizes, detCounts, wallSec, "pipeline"
|
|
8211
|
+
return this.buildBenchResult(wallTimings, inferTimings, preprocessTimings, predictTimings, batchSizes, detCounts, wallSec, "pipeline", {
|
|
8212
|
+
nodeId: benchNode,
|
|
8213
|
+
...input.deviceKey ? { deviceKey: input.deviceKey } : {}
|
|
8214
|
+
});
|
|
8042
8215
|
}
|
|
8043
|
-
async buildBenchResult(wallTimings, inferTimings, preprocessTimings, predictTimings, batchSizes, detCounts, wallSec, path) {
|
|
8216
|
+
async buildBenchResult(wallTimings, inferTimings, preprocessTimings, predictTimings, batchSizes, detCounts, wallSec, path, target) {
|
|
8044
8217
|
const meanOfArr = (xs) => xs.length > 0 ? xs.reduce((s, v) => s + v, 0) / xs.length : 0;
|
|
8045
8218
|
this.ctx.logger.info("synthetic bench summary", { meta: {
|
|
8046
8219
|
runs: wallTimings.length,
|
|
@@ -8076,24 +8249,47 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
8076
8249
|
batchSizeMean: Math.round(meanOf(batchSizes) * 100) / 100,
|
|
8077
8250
|
batchSizeMax: batchSizes.length > 0 ? Math.max(...batchSizes) : 0,
|
|
8078
8251
|
path,
|
|
8079
|
-
|
|
8252
|
+
pool: await this.readBenchPool(target)
|
|
8080
8253
|
};
|
|
8081
8254
|
}
|
|
8082
|
-
|
|
8255
|
+
/**
|
|
8256
|
+
* The pool a bench measured, and its provisioning — asked of the node it
|
|
8257
|
+
* was pinned to, for the device pool it named (D646). It used to ask the
|
|
8258
|
+
* node DEFAULT of whichever node answered, so an NPU bench was recorded
|
|
8259
|
+
* beside the onnx pool's tuning. A failed read is `null` fields and a line,
|
|
8260
|
+
* never a default (D393).
|
|
8261
|
+
*/
|
|
8262
|
+
async readBenchPool(target) {
|
|
8263
|
+
const unknown = {
|
|
8264
|
+
nodeId: target.nodeId,
|
|
8265
|
+
deviceKey: target.deviceKey ?? null,
|
|
8266
|
+
runtime: null,
|
|
8267
|
+
numWorkers: null,
|
|
8268
|
+
concurrency: null,
|
|
8269
|
+
batchMode: null,
|
|
8270
|
+
maxBatchSize: null
|
|
8271
|
+
};
|
|
8272
|
+
const api = this.ctx.api;
|
|
8273
|
+
if (!api) return unknown;
|
|
8274
|
+
const query = buildBenchTuningQuery(target);
|
|
8083
8275
|
try {
|
|
8084
|
-
const
|
|
8085
|
-
if (!api) return {};
|
|
8086
|
-
const [eng, tuning] = await Promise.all([api.pipelineExecutor.getSelectedEngine.query(), api.pipelineExecutor.getEffectiveTuning.query()]);
|
|
8276
|
+
const tuning = await api.pipelineExecutor.getEffectiveTuning.query({ ...query.input }, require_dist.nodePin(query.nodeId));
|
|
8087
8277
|
return {
|
|
8088
|
-
|
|
8089
|
-
|
|
8090
|
-
|
|
8091
|
-
|
|
8092
|
-
|
|
8093
|
-
|
|
8278
|
+
nodeId: target.nodeId,
|
|
8279
|
+
deviceKey: tuning.deviceKey,
|
|
8280
|
+
runtime: tuning.runtime,
|
|
8281
|
+
numWorkers: tuning.numWorkers,
|
|
8282
|
+
concurrency: tuning.concurrency,
|
|
8283
|
+
batchMode: tuning.batchMode,
|
|
8284
|
+
maxBatchSize: tuning.maxBatchSize
|
|
8094
8285
|
};
|
|
8095
|
-
} catch {
|
|
8096
|
-
|
|
8286
|
+
} catch (err) {
|
|
8287
|
+
this.ctx.logger.warn("synthetic bench: pool tuning read failed — reported as unknown", { meta: {
|
|
8288
|
+
nodeId: target.nodeId,
|
|
8289
|
+
deviceKey: target.deviceKey ?? null,
|
|
8290
|
+
error: require_dist.errMsg(err)
|
|
8291
|
+
} });
|
|
8292
|
+
return unknown;
|
|
8097
8293
|
}
|
|
8098
8294
|
}
|
|
8099
8295
|
/**
|
|
@@ -8216,7 +8412,6 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
8216
8412
|
settleSec,
|
|
8217
8413
|
measureSec,
|
|
8218
8414
|
deviceKey: input.deviceKey ?? null,
|
|
8219
|
-
engine: input.engine ?? null,
|
|
8220
8415
|
contaminatedByActiveCameras,
|
|
8221
8416
|
steps: stepsToRun.map((s) => `${s.addonId}/${s.modelId}${s.enabled ? "" : "[off]"}`)
|
|
8222
8417
|
} });
|
|
@@ -8233,8 +8428,7 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
8233
8428
|
},
|
|
8234
8429
|
plane: "frame",
|
|
8235
8430
|
sessionId,
|
|
8236
|
-
...input.deviceKey ? { deviceKey: input.deviceKey } : {}
|
|
8237
|
-
...input.engine ? { engine: input.engine } : {}
|
|
8431
|
+
...input.deviceKey ? { deviceKey: input.deviceKey } : {}
|
|
8238
8432
|
}, pin);
|
|
8239
8433
|
if (result.debug?.engine !== void 0) engineLabel = result.debug.engine;
|
|
8240
8434
|
if (result.shed === true) return {
|