@simulatte/doppler 0.1.4 → 0.1.6
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/README.md +26 -10
- package/package.json +30 -6
- package/src/client/doppler-api.browser.d.ts +1 -0
- package/src/client/doppler-api.browser.js +288 -0
- package/src/client/doppler-api.js +1 -1
- package/src/client/doppler-provider/types.js +1 -1
- package/src/config/execution-contract-check.d.ts +33 -0
- package/src/config/execution-contract-check.js +72 -0
- package/src/config/execution-v0-contract-check.d.ts +94 -0
- package/src/config/execution-v0-contract-check.js +251 -0
- package/src/config/execution-v0-graph-contract-check.d.ts +20 -0
- package/src/config/execution-v0-graph-contract-check.js +64 -0
- package/src/config/kernel-path-contract-check.d.ts +76 -0
- package/src/config/kernel-path-contract-check.js +479 -0
- package/src/config/kernel-path-loader.d.ts +16 -0
- package/src/config/kernel-path-loader.js +54 -0
- package/src/config/kernels/kernel-ref-digests.js +39 -27
- package/src/config/kernels/registry.json +598 -2
- package/src/config/loader.js +81 -48
- package/src/config/merge-contract-check.d.ts +16 -0
- package/src/config/merge-contract-check.js +321 -0
- package/src/config/merge-helpers.d.ts +58 -0
- package/src/config/merge-helpers.js +54 -0
- package/src/config/merge.js +21 -6
- package/src/config/presets/models/janus-text.json +2 -0
- package/src/config/presets/models/qwen3.json +9 -2
- package/src/config/presets/models/transformer.json +5 -0
- package/src/config/quantization-contract-check.d.ts +12 -0
- package/src/config/quantization-contract-check.js +91 -0
- package/src/config/required-inference-fields-contract-check.d.ts +24 -0
- package/src/config/required-inference-fields-contract-check.js +237 -0
- package/src/config/schema/browser-suite-metrics.schema.d.ts +17 -0
- package/src/config/schema/browser-suite-metrics.schema.js +46 -0
- package/src/config/schema/conversion-report.schema.d.ts +40 -0
- package/src/config/schema/conversion-report.schema.js +108 -0
- package/src/config/schema/doppler.schema.js +12 -18
- package/src/config/schema/index.d.ts +22 -0
- package/src/config/schema/index.js +18 -0
- package/src/config/schema/inference-defaults.schema.js +3 -0
- package/src/config/schema/inference.schema.d.ts +9 -0
- package/src/config/schema/kernel-path.schema.d.ts +6 -0
- package/src/config/schema/manifest.schema.d.ts +6 -0
- package/src/config/schema/manifest.schema.js +3 -0
- package/src/converter/core.d.ts +10 -0
- package/src/converter/core.js +27 -2
- package/src/converter/parsers/diffusion.js +63 -3
- package/src/converter/rope-config.js +42 -0
- package/src/gpu/device.js +58 -0
- package/src/gpu/kernels/attention.js +98 -0
- package/src/gpu/kernels/bias_add.wgsl +8 -6
- package/src/gpu/kernels/bias_add_f16.wgsl +8 -5
- package/src/gpu/kernels/conv2d.js +1 -1
- package/src/gpu/kernels/conv2d.wgsl +7 -8
- package/src/gpu/kernels/conv2d_f16.wgsl +7 -8
- package/src/gpu/kernels/depthwise_conv2d.d.ts +29 -0
- package/src/gpu/kernels/depthwise_conv2d.js +99 -0
- package/src/gpu/kernels/depthwise_conv2d.wgsl +55 -0
- package/src/gpu/kernels/depthwise_conv2d_f16.wgsl +59 -0
- package/src/gpu/kernels/grouped_pointwise_conv2d.d.ts +27 -0
- package/src/gpu/kernels/grouped_pointwise_conv2d.js +93 -0
- package/src/gpu/kernels/grouped_pointwise_conv2d.wgsl +44 -0
- package/src/gpu/kernels/grouped_pointwise_conv2d_f16.wgsl +48 -0
- package/src/gpu/kernels/index.d.ts +30 -0
- package/src/gpu/kernels/index.js +25 -0
- package/src/gpu/kernels/matmul.js +25 -0
- package/src/gpu/kernels/pixel_shuffle.js +1 -1
- package/src/gpu/kernels/pixel_shuffle.wgsl +4 -5
- package/src/gpu/kernels/pixel_shuffle_f16.wgsl +4 -5
- package/src/gpu/kernels/relu.d.ts +18 -0
- package/src/gpu/kernels/relu.js +58 -0
- package/src/gpu/kernels/relu.wgsl +22 -0
- package/src/gpu/kernels/relu_f16.wgsl +24 -0
- package/src/gpu/kernels/repeat_channels.d.ts +21 -0
- package/src/gpu/kernels/repeat_channels.js +60 -0
- package/src/gpu/kernels/repeat_channels.wgsl +28 -0
- package/src/gpu/kernels/repeat_channels_f16.wgsl +30 -0
- package/src/gpu/kernels/residual.js +44 -8
- package/src/gpu/kernels/residual.wgsl +6 -3
- package/src/gpu/kernels/residual_f16.wgsl +2 -1
- package/src/gpu/kernels/residual_f16_vec4.wgsl +2 -1
- package/src/gpu/kernels/residual_vec4.wgsl +2 -1
- package/src/gpu/kernels/rmsnorm.js +58 -6
- package/src/gpu/kernels/rmsnorm.wgsl +14 -6
- package/src/gpu/kernels/rmsnorm_f16.wgsl +10 -2
- package/src/gpu/kernels/rope.d.ts +2 -0
- package/src/gpu/kernels/rope.js +11 -1
- package/src/gpu/kernels/rope.wgsl +56 -40
- package/src/gpu/kernels/sana_linear_attention.d.ts +27 -0
- package/src/gpu/kernels/sana_linear_attention.js +121 -0
- package/src/gpu/kernels/sana_linear_attention_apply.wgsl +43 -0
- package/src/gpu/kernels/sana_linear_attention_apply_f16.wgsl +46 -0
- package/src/gpu/kernels/sana_linear_attention_summary.wgsl +51 -0
- package/src/gpu/kernels/sana_linear_attention_summary_f16.wgsl +53 -0
- package/src/gpu/kernels/silu.d.ts +1 -0
- package/src/gpu/kernels/silu.js +32 -14
- package/src/gpu/kernels/silu.wgsl +19 -9
- package/src/gpu/kernels/silu_f16.wgsl +19 -9
- package/src/gpu/kernels/transpose.js +15 -2
- package/src/gpu/kernels/transpose.wgsl +5 -6
- package/src/gpu/kernels/upsample2d.js +2 -1
- package/src/gpu/kernels/upsample2d.wgsl +6 -9
- package/src/gpu/kernels/upsample2d_f16.wgsl +6 -9
- package/src/gpu/kernels/utils.js +16 -1
- package/src/index-browser.d.ts +1 -1
- package/src/index-browser.js +2 -2
- package/src/index.js +1 -1
- package/src/inference/browser-harness.js +109 -23
- package/src/inference/pipelines/diffusion/init.js +14 -0
- package/src/inference/pipelines/diffusion/pipeline.js +215 -77
- package/src/inference/pipelines/diffusion/sana-transformer.d.ts +53 -0
- package/src/inference/pipelines/diffusion/sana-transformer.js +738 -0
- package/src/inference/pipelines/diffusion/scheduler.d.ts +17 -1
- package/src/inference/pipelines/diffusion/scheduler.js +91 -3
- package/src/inference/pipelines/diffusion/text-encoder-gpu.d.ts +11 -4
- package/src/inference/pipelines/diffusion/text-encoder-gpu.js +282 -0
- package/src/inference/pipelines/diffusion/text-encoder.js +18 -1
- package/src/inference/pipelines/diffusion/types.d.ts +4 -0
- package/src/inference/pipelines/diffusion/vae.js +782 -78
- package/src/inference/pipelines/text/attention/record.js +11 -2
- package/src/inference/pipelines/text/attention/run.js +11 -2
- package/src/inference/pipelines/text/chat-format.js +25 -1
- package/src/inference/pipelines/text/config.d.ts +9 -0
- package/src/inference/pipelines/text/config.js +69 -2
- package/src/inference/pipelines/text/execution-plan.js +23 -31
- package/src/inference/pipelines/text/execution-v0.js +43 -95
- package/src/inference/pipelines/text/ffn/standard.js +3 -0
- package/src/inference/pipelines/text/init.d.ts +4 -0
- package/src/inference/pipelines/text/init.js +56 -9
- package/src/inference/pipelines/text/layer.js +11 -0
- package/src/inference/pipelines/text.js +4 -0
- package/src/inference/tokenizers/bundled.js +156 -33
- package/src/rules/execution-rules-contract-check.d.ts +17 -0
- package/src/rules/execution-rules-contract-check.js +245 -0
- package/src/rules/kernels/depthwise-conv2d.rules.json +6 -0
- package/src/rules/kernels/grouped-pointwise-conv2d.rules.json +6 -0
- package/src/rules/kernels/relu.rules.json +6 -0
- package/src/rules/kernels/repeat-channels.rules.json +6 -0
- package/src/rules/kernels/sana-linear-attention.rules.json +6 -0
- package/src/rules/layer-pattern-contract-check.d.ts +17 -0
- package/src/rules/layer-pattern-contract-check.js +231 -0
- package/src/rules/rule-registry.d.ts +28 -0
- package/src/rules/rule-registry.js +38 -0
- package/src/rules/tooling/command-runtime.rules.json +18 -0
- package/src/tooling/command-api.d.ts +27 -1
- package/src/tooling/command-api.js +142 -3
- package/src/tooling/conversion-config-materializer.d.ts +24 -0
- package/src/tooling/conversion-config-materializer.js +99 -0
- package/src/tooling/lean-execution-contract-runner.d.ts +43 -0
- package/src/tooling/lean-execution-contract-runner.js +158 -0
- package/src/tooling/node-browser-command-runner.d.ts +4 -0
- package/src/tooling/node-browser-command-runner.js +58 -3
- package/src/tooling/node-command-runner.js +15 -0
- package/src/tooling/node-convert.d.ts +10 -0
- package/src/tooling/node-converter.js +59 -0
- package/src/tooling/node-webgpu.js +11 -89
- package/src/training/checkpoint-watch.d.ts +7 -0
- package/src/training/checkpoint-watch.js +106 -0
- package/src/training/checkpoint.d.ts +6 -1
- package/src/training/checkpoint.js +12 -2
- package/src/training/distillation/artifacts.d.ts +71 -0
- package/src/training/distillation/artifacts.js +132 -0
- package/src/training/distillation/checkpoint-watch.d.ts +10 -0
- package/src/training/distillation/checkpoint-watch.js +57 -0
- package/src/training/distillation/dataset.d.ts +59 -0
- package/src/training/distillation/dataset.js +337 -0
- package/src/training/distillation/eval.d.ts +34 -0
- package/src/training/distillation/eval.js +310 -0
- package/src/training/distillation/index.d.ts +29 -0
- package/src/training/distillation/index.js +29 -0
- package/src/training/distillation/runtime.d.ts +20 -0
- package/src/training/distillation/runtime.js +121 -0
- package/src/training/distillation/scoreboard.d.ts +6 -0
- package/src/training/distillation/scoreboard.js +8 -0
- package/src/training/distillation/stage-a.d.ts +45 -0
- package/src/training/distillation/stage-a.js +338 -0
- package/src/training/distillation/stage-b.d.ts +24 -0
- package/src/training/distillation/stage-b.js +20 -0
- package/src/training/index.d.ts +10 -0
- package/src/training/index.js +10 -0
- package/src/training/lora-pipeline.d.ts +40 -0
- package/src/training/lora-pipeline.js +796 -0
- package/src/training/operator-artifacts.d.ts +62 -0
- package/src/training/operator-artifacts.js +140 -0
- package/src/training/operator-command.d.ts +5 -0
- package/src/training/operator-command.js +453 -0
- package/src/training/operator-eval.d.ts +48 -0
- package/src/training/operator-eval.js +230 -0
- package/src/training/operator-scoreboard.d.ts +5 -0
- package/src/training/operator-scoreboard.js +44 -0
- package/src/training/runner.d.ts +52 -0
- package/src/training/runner.js +29 -4
- package/src/training/suite.d.ts +112 -0
- package/src/training/suite.js +9 -9
- package/src/training/workloads.d.ts +164 -0
- package/src/training/workloads.js +539 -0
- package/src/version.d.ts +2 -0
- package/src/version.js +2 -0
- package/tools/convert-safetensors-node.js +47 -0
- package/tools/doppler-cli.js +252 -41
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
|
|
3
|
+
import { createConverterConfig } from '../config/schema/index.js';
|
|
4
|
+
import { resolveConversionPlan } from '../converter/conversion-plan.js';
|
|
5
|
+
|
|
6
|
+
function toSafeString(value) {
|
|
7
|
+
if (typeof value !== 'string') return '';
|
|
8
|
+
const trimmed = value.trim();
|
|
9
|
+
return trimmed || '';
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function normalizeQuantizationTag(value) {
|
|
13
|
+
const raw = toSafeString(value).toUpperCase();
|
|
14
|
+
if (!raw) return 'f16';
|
|
15
|
+
if (raw === 'Q4_K_M' || raw === 'Q4_K') return 'q4k';
|
|
16
|
+
return raw.toLowerCase();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function resolveArchitectureHint(architecture) {
|
|
20
|
+
if (!architecture) return '';
|
|
21
|
+
if (typeof architecture === 'string') return architecture;
|
|
22
|
+
return (
|
|
23
|
+
toSafeString(architecture.id)
|
|
24
|
+
|| toSafeString(architecture.name)
|
|
25
|
+
|| toSafeString(architecture.type)
|
|
26
|
+
|| ''
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function resolveHeadDim(architecture) {
|
|
31
|
+
const headDim = Number(architecture?.headDim ?? architecture?.head_dim);
|
|
32
|
+
return Number.isFinite(headDim) && headDim > 0 ? headDim : null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function extractSourceQuantization(manifest) {
|
|
36
|
+
const explicitWeights = toSafeString(manifest?.quantizationInfo?.weights);
|
|
37
|
+
if (explicitWeights) return explicitWeights;
|
|
38
|
+
const explicitQuant = toSafeString(manifest?.quantization);
|
|
39
|
+
if (explicitQuant) return explicitQuant;
|
|
40
|
+
return 'f16';
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function buildRefreshRawConfig(manifest) {
|
|
44
|
+
const baseConfig = (manifest?.config && typeof manifest.config === 'object')
|
|
45
|
+
? { ...manifest.config }
|
|
46
|
+
: {};
|
|
47
|
+
const manifestLayerTypes = manifest?.inference?.layerPattern?.layerTypes;
|
|
48
|
+
if (Array.isArray(manifestLayerTypes) && manifestLayerTypes.length > 0) {
|
|
49
|
+
return {
|
|
50
|
+
...baseConfig,
|
|
51
|
+
layer_types: [...manifestLayerTypes],
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
return baseConfig;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function extractTensorEntriesFromManifest(manifest) {
|
|
58
|
+
if (!(manifest?.tensors && typeof manifest.tensors === 'object' && !Array.isArray(manifest.tensors))) {
|
|
59
|
+
return [];
|
|
60
|
+
}
|
|
61
|
+
return Object.entries(manifest.tensors).map(([name, tensor]) => ({
|
|
62
|
+
name,
|
|
63
|
+
dtype: tensor?.dtype ?? null,
|
|
64
|
+
shape: tensor?.shape ?? null,
|
|
65
|
+
role: tensor?.role ?? null,
|
|
66
|
+
layout: tensor?.layout ?? null,
|
|
67
|
+
}));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function resolveMaterializedManifestFromConversionConfig(conversionConfigInput, manifest) {
|
|
71
|
+
const converterConfig = createConverterConfig(conversionConfigInput);
|
|
72
|
+
const tensorEntries = extractTensorEntriesFromManifest(manifest);
|
|
73
|
+
const architecture = manifest?.architecture && typeof manifest.architecture === 'object'
|
|
74
|
+
? manifest.architecture
|
|
75
|
+
: null;
|
|
76
|
+
const plan = resolveConversionPlan({
|
|
77
|
+
rawConfig: buildRefreshRawConfig(manifest),
|
|
78
|
+
tensors: tensorEntries,
|
|
79
|
+
converterConfig,
|
|
80
|
+
sourceQuantization: normalizeQuantizationTag(extractSourceQuantization(manifest)),
|
|
81
|
+
modelKind: manifest?.modelType === 'diffusion' ? 'diffusion' : 'transformer',
|
|
82
|
+
architectureHint: resolveArchitectureHint(manifest?.architecture),
|
|
83
|
+
architectureConfig: architecture,
|
|
84
|
+
headDim: resolveHeadDim(architecture),
|
|
85
|
+
presetOverride: converterConfig?.presets?.model || manifest?.inference?.presetId || null,
|
|
86
|
+
});
|
|
87
|
+
return {
|
|
88
|
+
modelId: manifest?.modelId ?? converterConfig?.output?.modelBaseId ?? 'unknown',
|
|
89
|
+
modelType: manifest?.modelType ?? plan?.modelType ?? 'transformer',
|
|
90
|
+
architecture: manifest?.architecture ?? null,
|
|
91
|
+
inference: plan?.manifestInference ?? null,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function inferConversionConfigModelId(configPath, conversionConfigInput) {
|
|
96
|
+
const configuredId = toSafeString(conversionConfigInput?.output?.modelBaseId);
|
|
97
|
+
if (configuredId) return configuredId;
|
|
98
|
+
return path.basename(String(configPath), path.extname(String(configPath)));
|
|
99
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export interface LeanExecutionContractRunResult {
|
|
2
|
+
ok: boolean;
|
|
3
|
+
toolchainRef: string | null;
|
|
4
|
+
generatedPath: string;
|
|
5
|
+
moduleName: string;
|
|
6
|
+
facts: Record<string, unknown>;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export declare function resolveLeanBinary(): string;
|
|
10
|
+
|
|
11
|
+
export declare function runLeanCheck(options: {
|
|
12
|
+
sourcePath: string;
|
|
13
|
+
rootDir: string;
|
|
14
|
+
}): {
|
|
15
|
+
ok: boolean;
|
|
16
|
+
toolchainRef: string;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export declare function writeExecutionContractLeanModuleForManifest(
|
|
20
|
+
manifest: Record<string, unknown>,
|
|
21
|
+
options?: {
|
|
22
|
+
rootDir?: string;
|
|
23
|
+
moduleName?: string;
|
|
24
|
+
emitPath?: string | null;
|
|
25
|
+
}
|
|
26
|
+
): {
|
|
27
|
+
rootDir: string;
|
|
28
|
+
facts: Record<string, unknown>;
|
|
29
|
+
moduleName: string;
|
|
30
|
+
source: string;
|
|
31
|
+
generatedPath: string;
|
|
32
|
+
tempDir: string | null;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export declare function runLeanExecutionContractForManifest(
|
|
36
|
+
manifest: Record<string, unknown>,
|
|
37
|
+
options?: {
|
|
38
|
+
rootDir?: string;
|
|
39
|
+
moduleName?: string;
|
|
40
|
+
emitPath?: string | null;
|
|
41
|
+
check?: boolean;
|
|
42
|
+
}
|
|
43
|
+
): LeanExecutionContractRunResult;
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import os from 'node:os';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { spawnSync } from 'node:child_process';
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
extractExecutionContractFacts,
|
|
8
|
+
renderExecutionContractLeanModule,
|
|
9
|
+
sanitizeLeanModuleName,
|
|
10
|
+
} from './lean-execution-contract.js';
|
|
11
|
+
|
|
12
|
+
export function resolveLeanBinary() {
|
|
13
|
+
const elanLean = path.join(os.homedir(), '.elan', 'bin', 'lean');
|
|
14
|
+
if (fs.existsSync(elanLean)) {
|
|
15
|
+
return elanLean;
|
|
16
|
+
}
|
|
17
|
+
const probe = spawnSync('bash', ['-lc', 'command -v lean'], { encoding: 'utf8' });
|
|
18
|
+
if (probe.status === 0) {
|
|
19
|
+
const resolved = probe.stdout.trim();
|
|
20
|
+
if (resolved) {
|
|
21
|
+
return resolved;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
throw new Error('lean binary not found. Install Lean with elan first.');
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function runLeanCommand({ leanBin, toolchainRef, buildDir, rootDir, sourcePath, outputPath }) {
|
|
28
|
+
const result = spawnSync(
|
|
29
|
+
leanBin,
|
|
30
|
+
[`+${toolchainRef}`, '-o', outputPath, sourcePath],
|
|
31
|
+
{
|
|
32
|
+
cwd: rootDir,
|
|
33
|
+
encoding: 'utf8',
|
|
34
|
+
env: {
|
|
35
|
+
...process.env,
|
|
36
|
+
LEAN_PATH: `${buildDir}:${path.join(rootDir, 'lean')}`,
|
|
37
|
+
},
|
|
38
|
+
}
|
|
39
|
+
);
|
|
40
|
+
if (result.stdout) {
|
|
41
|
+
process.stdout.write(result.stdout);
|
|
42
|
+
}
|
|
43
|
+
if (result.stderr) {
|
|
44
|
+
process.stderr.write(result.stderr);
|
|
45
|
+
}
|
|
46
|
+
if (result.status !== 0) {
|
|
47
|
+
throw new Error(`lean exited with status ${result.status}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function runLeanCheck({ sourcePath, rootDir }) {
|
|
52
|
+
const toolchainVersion = process.env.DOPPLER_LEAN_VERSION ?? '4.16.0';
|
|
53
|
+
const toolchainRef = toolchainVersion.startsWith('v')
|
|
54
|
+
? `leanprover/lean4:${toolchainVersion}`
|
|
55
|
+
: `leanprover/lean4:v${toolchainVersion}`;
|
|
56
|
+
const leanBin = resolveLeanBinary();
|
|
57
|
+
const buildDir = fs.mkdtempSync(path.join(os.tmpdir(), 'doppler-lean-execution-contract-'));
|
|
58
|
+
try {
|
|
59
|
+
fs.mkdirSync(path.join(buildDir, 'Doppler'), { recursive: true });
|
|
60
|
+
runLeanCommand({
|
|
61
|
+
leanBin,
|
|
62
|
+
toolchainRef,
|
|
63
|
+
buildDir,
|
|
64
|
+
rootDir,
|
|
65
|
+
sourcePath: path.join(rootDir, 'lean', 'Doppler', 'Model.lean'),
|
|
66
|
+
outputPath: path.join(buildDir, 'Doppler', 'Model.olean'),
|
|
67
|
+
});
|
|
68
|
+
runLeanCommand({
|
|
69
|
+
leanBin,
|
|
70
|
+
toolchainRef,
|
|
71
|
+
buildDir,
|
|
72
|
+
rootDir,
|
|
73
|
+
sourcePath: path.join(rootDir, 'lean', 'Doppler', 'ExecutionContract.lean'),
|
|
74
|
+
outputPath: path.join(buildDir, 'Doppler', 'ExecutionContract.olean'),
|
|
75
|
+
});
|
|
76
|
+
const generatedOutput = path.join(buildDir, 'GeneratedExecutionContractCheck.olean');
|
|
77
|
+
const result = spawnSync(
|
|
78
|
+
leanBin,
|
|
79
|
+
[`+${toolchainRef}`, '-o', generatedOutput, sourcePath],
|
|
80
|
+
{
|
|
81
|
+
cwd: rootDir,
|
|
82
|
+
encoding: 'utf8',
|
|
83
|
+
env: {
|
|
84
|
+
...process.env,
|
|
85
|
+
LEAN_PATH: `${buildDir}:${path.join(rootDir, 'lean')}`,
|
|
86
|
+
},
|
|
87
|
+
}
|
|
88
|
+
);
|
|
89
|
+
if (result.stdout) {
|
|
90
|
+
process.stdout.write(result.stdout);
|
|
91
|
+
}
|
|
92
|
+
if (result.stderr) {
|
|
93
|
+
process.stderr.write(result.stderr);
|
|
94
|
+
}
|
|
95
|
+
if (result.status !== 0) {
|
|
96
|
+
throw new Error(`lean exited with status ${result.status}`);
|
|
97
|
+
}
|
|
98
|
+
const overallMatch = result.stdout.match(/executionContractOverall:(pass|fail)/);
|
|
99
|
+
if (!overallMatch) {
|
|
100
|
+
throw new Error('unable to parse executionContractOverall from Lean output.');
|
|
101
|
+
}
|
|
102
|
+
return { ok: overallMatch[1] === 'pass', toolchainRef };
|
|
103
|
+
} finally {
|
|
104
|
+
fs.rmSync(buildDir, { recursive: true, force: true });
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export function writeExecutionContractLeanModuleForManifest(manifest, options = {}) {
|
|
109
|
+
const rootDir = path.resolve(String(options.rootDir ?? process.cwd()));
|
|
110
|
+
const facts = extractExecutionContractFacts(manifest);
|
|
111
|
+
const moduleName = sanitizeLeanModuleName(options.moduleName ?? `${facts.modelId}_ExecutionContractCheck`);
|
|
112
|
+
const source = renderExecutionContractLeanModule(facts, { moduleName });
|
|
113
|
+
const tempDir = options.emitPath
|
|
114
|
+
? null
|
|
115
|
+
: fs.mkdtempSync(path.join(rootDir, 'lean', '.generated-'));
|
|
116
|
+
const generatedPath = options.emitPath
|
|
117
|
+
? path.resolve(rootDir, String(options.emitPath))
|
|
118
|
+
: path.join(tempDir, `${moduleName}.lean`);
|
|
119
|
+
fs.mkdirSync(path.dirname(generatedPath), { recursive: true });
|
|
120
|
+
fs.writeFileSync(generatedPath, source);
|
|
121
|
+
return {
|
|
122
|
+
rootDir,
|
|
123
|
+
facts,
|
|
124
|
+
moduleName,
|
|
125
|
+
source,
|
|
126
|
+
generatedPath,
|
|
127
|
+
tempDir,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export function runLeanExecutionContractForManifest(manifest, options = {}) {
|
|
132
|
+
const generated = writeExecutionContractLeanModuleForManifest(manifest, options);
|
|
133
|
+
try {
|
|
134
|
+
if (options.check === false) {
|
|
135
|
+
return {
|
|
136
|
+
ok: true,
|
|
137
|
+
toolchainRef: null,
|
|
138
|
+
generatedPath: generated.generatedPath,
|
|
139
|
+
moduleName: generated.moduleName,
|
|
140
|
+
facts: generated.facts,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
const result = runLeanCheck({
|
|
144
|
+
sourcePath: generated.generatedPath,
|
|
145
|
+
rootDir: generated.rootDir,
|
|
146
|
+
});
|
|
147
|
+
return {
|
|
148
|
+
...result,
|
|
149
|
+
generatedPath: generated.generatedPath,
|
|
150
|
+
moduleName: generated.moduleName,
|
|
151
|
+
facts: generated.facts,
|
|
152
|
+
};
|
|
153
|
+
} finally {
|
|
154
|
+
if (!options.emitPath && generated.tempDir) {
|
|
155
|
+
fs.rmSync(generated.tempDir, { recursive: true, force: true });
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
@@ -7,6 +7,10 @@ import type { BrowserCommandRunResult } from './browser-command-runner.js';
|
|
|
7
7
|
|
|
8
8
|
export interface NodeBrowserCommandRunOptions {
|
|
9
9
|
staticRootDir?: string;
|
|
10
|
+
staticMounts?: Array<{
|
|
11
|
+
urlPrefix: string;
|
|
12
|
+
rootDir: string;
|
|
13
|
+
}>;
|
|
10
14
|
baseUrl?: string;
|
|
11
15
|
host?: string;
|
|
12
16
|
port?: number;
|
|
@@ -67,8 +67,61 @@ function resolveStaticPath(rootDir, requestPath) {
|
|
|
67
67
|
return candidate;
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
function normalizeStaticMounts(mounts = []) {
|
|
71
|
+
if (!Array.isArray(mounts)) {
|
|
72
|
+
throw new Error('browser command: staticMounts must be an array.');
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return mounts.map((mount, index) => {
|
|
76
|
+
if (!mount || typeof mount !== 'object' || Array.isArray(mount)) {
|
|
77
|
+
throw new Error(`browser command: staticMounts[${index}] must be an object.`);
|
|
78
|
+
}
|
|
79
|
+
const urlPrefix = String(mount.urlPrefix || '').trim();
|
|
80
|
+
const rootDir = String(mount.rootDir || '').trim();
|
|
81
|
+
if (!urlPrefix.startsWith('/')) {
|
|
82
|
+
throw new Error(`browser command: staticMounts[${index}].urlPrefix must start with "/".`);
|
|
83
|
+
}
|
|
84
|
+
if (!rootDir) {
|
|
85
|
+
throw new Error(`browser command: staticMounts[${index}].rootDir is required.`);
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
urlPrefix: urlPrefix.replace(/\/+$/u, '') || '/',
|
|
89
|
+
rootDir: path.resolve(rootDir),
|
|
90
|
+
};
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function findStaticRootForRequest(rootDir, mounts, requestPath) {
|
|
95
|
+
const normalizedPath = String(requestPath || '/');
|
|
96
|
+
let bestMount = null;
|
|
97
|
+
|
|
98
|
+
for (const mount of mounts) {
|
|
99
|
+
const prefix = mount.urlPrefix;
|
|
100
|
+
if (normalizedPath !== prefix && !normalizedPath.startsWith(`${prefix}/`)) {
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
if (!bestMount || prefix.length > bestMount.urlPrefix.length) {
|
|
104
|
+
bestMount = mount;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (!bestMount) {
|
|
109
|
+
return {
|
|
110
|
+
effectiveRootDir: rootDir,
|
|
111
|
+
effectivePath: normalizedPath,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const relativePath = normalizedPath.slice(bestMount.urlPrefix.length) || '/';
|
|
116
|
+
return {
|
|
117
|
+
effectiveRootDir: bestMount.rootDir,
|
|
118
|
+
effectivePath: relativePath.startsWith('/') ? relativePath : `/${relativePath}`,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
async function resolveFileForRequest(rootDir, mounts, requestPath) {
|
|
123
|
+
const { effectiveRootDir, effectivePath } = findStaticRootForRequest(rootDir, mounts, requestPath);
|
|
124
|
+
const resolved = resolveStaticPath(effectiveRootDir, effectivePath);
|
|
72
125
|
if (!resolved) return null;
|
|
73
126
|
|
|
74
127
|
let stats;
|
|
@@ -99,6 +152,7 @@ async function createStaticFileServer(options = {}) {
|
|
|
99
152
|
const rootDir = path.resolve(
|
|
100
153
|
options.rootDir || fileURLToPath(new URL('../../', import.meta.url))
|
|
101
154
|
);
|
|
155
|
+
const staticMounts = normalizeStaticMounts(options.staticMounts || []);
|
|
102
156
|
const host = String(options.host || DEFAULT_HOST);
|
|
103
157
|
const port = Number.isFinite(options.port) ? Math.max(0, Math.floor(options.port)) : 0;
|
|
104
158
|
|
|
@@ -120,7 +174,7 @@ async function createStaticFileServer(options = {}) {
|
|
|
120
174
|
return;
|
|
121
175
|
}
|
|
122
176
|
|
|
123
|
-
const resolved = await resolveFileForRequest(rootDir, pathname);
|
|
177
|
+
const resolved = await resolveFileForRequest(rootDir, staticMounts, pathname);
|
|
124
178
|
if (!resolved) {
|
|
125
179
|
res.statusCode = 404;
|
|
126
180
|
res.end('File not found');
|
|
@@ -545,6 +599,7 @@ export async function runBrowserCommandInNode(commandRequest, options = {}) {
|
|
|
545
599
|
? null
|
|
546
600
|
: await createStaticFileServer({
|
|
547
601
|
rootDir: options.staticRootDir,
|
|
602
|
+
staticMounts: options.staticMounts,
|
|
548
603
|
host: options.host,
|
|
549
604
|
port: serverPort,
|
|
550
605
|
}).catch((error) => {
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
getActiveKernelPathSource,
|
|
19
19
|
setActiveKernelPath,
|
|
20
20
|
} from '../config/kernel-path-loader.js';
|
|
21
|
+
import { runTrainingOperatorCommand } from '../training/operator-command.js';
|
|
21
22
|
|
|
22
23
|
function asOptionalPlainObject(value, label) {
|
|
23
24
|
if (value == null) return null;
|
|
@@ -90,6 +91,20 @@ export async function runNodeCommand(commandRequest, options = {}) {
|
|
|
90
91
|
});
|
|
91
92
|
}
|
|
92
93
|
|
|
94
|
+
if (request.command === 'lora' || request.command === 'distill') {
|
|
95
|
+
const gpuOptionalActions = new Set(['compare', 'quality-gate', 'subsets']);
|
|
96
|
+
installNodeFileFetchShim();
|
|
97
|
+
if (!gpuOptionalActions.has(request.action)) {
|
|
98
|
+
await assertNodeWebGPUSupport();
|
|
99
|
+
}
|
|
100
|
+
const result = await runTrainingOperatorCommand(request);
|
|
101
|
+
return createToolingSuccessEnvelope({
|
|
102
|
+
surface: 'node',
|
|
103
|
+
request,
|
|
104
|
+
result,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
93
108
|
await assertNodeWebGPUSupport();
|
|
94
109
|
const modules = await loadRuntimeModules();
|
|
95
110
|
const runtimeBridge = {
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import type { ConverterConfigSchema } from '../config/schema/converter.schema.js';
|
|
2
|
+
import type { ExecutionContractArtifact } from '../config/execution-contract-check.js';
|
|
3
|
+
import type { ExecutionV0GraphContractArtifact } from '../config/execution-v0-graph-contract-check.js';
|
|
4
|
+
import type { ManifestRequiredInferenceFieldsArtifact } from '../config/required-inference-fields-contract-check.js';
|
|
5
|
+
import type { SavedReportInfo } from '../storage/reports.js';
|
|
2
6
|
|
|
3
7
|
export interface NodeConvertProgress {
|
|
4
8
|
stage: string | null;
|
|
@@ -34,6 +38,12 @@ export interface ConvertSafetensorsDirectoryResult {
|
|
|
34
38
|
manifest: Record<string, unknown>;
|
|
35
39
|
shardCount: number;
|
|
36
40
|
tensorCount: number;
|
|
41
|
+
executionContractArtifact: ExecutionContractArtifact | null;
|
|
42
|
+
executionV0GraphContractArtifact: ExecutionV0GraphContractArtifact | null;
|
|
43
|
+
layerPatternContractArtifact: Record<string, unknown> | null;
|
|
44
|
+
requiredInferenceFieldsArtifact: ManifestRequiredInferenceFieldsArtifact | null;
|
|
45
|
+
report: Record<string, unknown>;
|
|
46
|
+
reportInfo: SavedReportInfo;
|
|
37
47
|
presetId: string;
|
|
38
48
|
modelType: string;
|
|
39
49
|
outputDir: string;
|
|
@@ -7,6 +7,11 @@ import { bootstrapNodeWebGPU } from './node-webgpu.js';
|
|
|
7
7
|
import { isPlainObject } from '../utils/plain-object.js';
|
|
8
8
|
import { selectRuleValue } from '../rules/rule-registry.js';
|
|
9
9
|
import { log, trace } from '../debug/index.js';
|
|
10
|
+
import { saveReport } from '../storage/reports.js';
|
|
11
|
+
import {
|
|
12
|
+
CONVERSION_REPORT_SCHEMA_VERSION,
|
|
13
|
+
validateConversionReport,
|
|
14
|
+
} from '../config/schema/conversion-report.schema.js';
|
|
10
15
|
|
|
11
16
|
function asPositiveInteger(value, label) {
|
|
12
17
|
if (!Number.isInteger(value) || value < 1) {
|
|
@@ -594,6 +599,44 @@ function normalizeTokenizerManifest(manifest) {
|
|
|
594
599
|
return manifest;
|
|
595
600
|
}
|
|
596
601
|
|
|
602
|
+
function buildConvertReport(result, context) {
|
|
603
|
+
const manifest = result?.manifest ?? null;
|
|
604
|
+
const inference = manifest?.inference && typeof manifest.inference === 'object'
|
|
605
|
+
? manifest.inference
|
|
606
|
+
: null;
|
|
607
|
+
return validateConversionReport({
|
|
608
|
+
schemaVersion: CONVERSION_REPORT_SCHEMA_VERSION,
|
|
609
|
+
suite: 'convert',
|
|
610
|
+
command: 'convert',
|
|
611
|
+
modelId: manifest?.modelId ?? context.modelId ?? 'unknown',
|
|
612
|
+
timestamp: manifest?.metadata?.convertedAt ?? new Date().toISOString(),
|
|
613
|
+
source: 'doppler',
|
|
614
|
+
result: {
|
|
615
|
+
presetId: context.presetId ?? null,
|
|
616
|
+
modelType: context.modelType ?? null,
|
|
617
|
+
outputDir: context.outputDir ?? null,
|
|
618
|
+
shardCount: result?.shardCount ?? null,
|
|
619
|
+
tensorCount: result?.tensorCount ?? null,
|
|
620
|
+
totalSize: result?.totalSize ?? null,
|
|
621
|
+
},
|
|
622
|
+
manifest: manifest
|
|
623
|
+
? {
|
|
624
|
+
quantization: manifest.quantization ?? null,
|
|
625
|
+
quantizationInfo: manifest.quantizationInfo ?? null,
|
|
626
|
+
inference: {
|
|
627
|
+
presetId: inference?.presetId ?? null,
|
|
628
|
+
schema: inference?.schema ?? null,
|
|
629
|
+
defaultKernelPath: inference?.defaultKernelPath ?? null,
|
|
630
|
+
},
|
|
631
|
+
}
|
|
632
|
+
: null,
|
|
633
|
+
executionContractArtifact: result?.executionContractArtifact ?? null,
|
|
634
|
+
executionV0GraphContractArtifact: result?.executionV0GraphContractArtifact ?? null,
|
|
635
|
+
layerPatternContractArtifact: result?.layerPatternContractArtifact ?? null,
|
|
636
|
+
requiredInferenceFieldsArtifact: result?.requiredInferenceFieldsArtifact ?? null,
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
|
|
597
640
|
function createNodeTensorTransformer(options) {
|
|
598
641
|
const pool = options?.pool;
|
|
599
642
|
const execution = options?.execution;
|
|
@@ -1212,10 +1255,26 @@ export async function convertSafetensorsDirectory(options) {
|
|
|
1212
1255
|
normalizeTokenizerManifest(result.manifest);
|
|
1213
1256
|
await io.writeManifest(result.manifest);
|
|
1214
1257
|
|
|
1258
|
+
const report = buildConvertReport(result, {
|
|
1259
|
+
presetId,
|
|
1260
|
+
modelType: resolvedModelType,
|
|
1261
|
+
outputDir,
|
|
1262
|
+
modelId: result.manifest?.modelId ?? modelId,
|
|
1263
|
+
});
|
|
1264
|
+
const reportInfo = await saveReport(report.modelId, report, {
|
|
1265
|
+
timestamp: report.timestamp,
|
|
1266
|
+
});
|
|
1267
|
+
|
|
1215
1268
|
return {
|
|
1216
1269
|
manifest: result.manifest,
|
|
1217
1270
|
shardCount: result.shardCount,
|
|
1218
1271
|
tensorCount: result.tensorCount,
|
|
1272
|
+
executionContractArtifact: result.executionContractArtifact ?? null,
|
|
1273
|
+
executionV0GraphContractArtifact: result.executionV0GraphContractArtifact ?? null,
|
|
1274
|
+
layerPatternContractArtifact: result.layerPatternContractArtifact ?? null,
|
|
1275
|
+
requiredInferenceFieldsArtifact: result.requiredInferenceFieldsArtifact ?? null,
|
|
1276
|
+
report,
|
|
1277
|
+
reportInfo,
|
|
1219
1278
|
presetId,
|
|
1220
1279
|
modelType: resolvedModelType,
|
|
1221
1280
|
outputDir,
|
|
@@ -2,17 +2,6 @@ import { existsSync, readFileSync, statSync } from 'node:fs';
|
|
|
2
2
|
import { dirname, isAbsolute, resolve } from 'node:path';
|
|
3
3
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
4
4
|
|
|
5
|
-
const DOPPLER_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..', '..');
|
|
6
|
-
|
|
7
|
-
const DEFAULT_LOCAL_DOE_PROVIDER_PATH = resolve(
|
|
8
|
-
dirname(fileURLToPath(import.meta.url)),
|
|
9
|
-
'..',
|
|
10
|
-
'..',
|
|
11
|
-
'..',
|
|
12
|
-
'fawn',
|
|
13
|
-
'nursery',
|
|
14
|
-
'webgpu-core',
|
|
15
|
-
);
|
|
16
5
|
const DEFAULT_DOE_PROVIDER_CREATE_ARGS = 'enable-dawn-features=allow_unsafe_apis';
|
|
17
6
|
|
|
18
7
|
function hasNavigatorGpu() {
|
|
@@ -59,20 +48,7 @@ function resolveCandidateModuleSpecifier(candidate) {
|
|
|
59
48
|
}
|
|
60
49
|
|
|
61
50
|
function resolveDefaultWebgpuModuleSpecifiers() {
|
|
62
|
-
|
|
63
|
-
const localCandidates = [
|
|
64
|
-
resolve(process.cwd(), '..', 'fawn', 'nursery', 'webgpu-core'),
|
|
65
|
-
DEFAULT_LOCAL_DOE_PROVIDER_PATH,
|
|
66
|
-
];
|
|
67
|
-
for (const localCandidate of localCandidates) {
|
|
68
|
-
const resolvedPath = resolveNodeModuleFilePath(localCandidate);
|
|
69
|
-
if (resolvedPath) {
|
|
70
|
-
specifiers.push(pathToFileURL(resolvedPath).href);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
specifiers.push('@doe/webgpu-core');
|
|
74
|
-
specifiers.push('webgpu');
|
|
75
|
-
return [...new Set(specifiers)];
|
|
51
|
+
return ['@simulatte/webgpu', 'webgpu'];
|
|
76
52
|
}
|
|
77
53
|
|
|
78
54
|
function resolveWebgpuModuleSpecifiers() {
|
|
@@ -89,80 +65,26 @@ function resolveWebgpuModuleSpecifiers() {
|
|
|
89
65
|
};
|
|
90
66
|
}
|
|
91
67
|
|
|
92
|
-
function
|
|
93
|
-
|
|
94
|
-
resolve(process.cwd(), 'node_modules', 'webgpu'),
|
|
95
|
-
resolve(DOPPLER_ROOT, 'node_modules', 'webgpu'),
|
|
96
|
-
];
|
|
97
|
-
for (const candidate of candidates) {
|
|
98
|
-
const resolvedPath = resolveNodeModuleFilePath(candidate);
|
|
99
|
-
if (resolvedPath) {
|
|
100
|
-
return resolvedPath;
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
return null;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
function isDoeWebgpuCoreSpecifier(specifier) {
|
|
107
|
-
if (specifier === '@doe/webgpu-core') {
|
|
108
|
-
return true;
|
|
109
|
-
}
|
|
110
|
-
if (typeof specifier !== 'string') {
|
|
111
|
-
return false;
|
|
112
|
-
}
|
|
113
|
-
if (specifier.includes('/webgpu-core/')) {
|
|
68
|
+
function isDoeWebgpuSpecifier(specifier) {
|
|
69
|
+
if (specifier === '@simulatte/webgpu') {
|
|
114
70
|
return true;
|
|
115
71
|
}
|
|
116
|
-
return specifier
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
function resolveDoeProviderOverride(specifier) {
|
|
120
|
-
const explicitProvider = process.env.FAWN_WEBGPU_NODE_PROVIDER_MODULE;
|
|
121
|
-
if (typeof explicitProvider === 'string' && explicitProvider.trim().length > 0) {
|
|
122
|
-
return null;
|
|
123
|
-
}
|
|
124
|
-
if (!isDoeWebgpuCoreSpecifier(specifier)) {
|
|
125
|
-
return null;
|
|
126
|
-
}
|
|
127
|
-
return resolveWorkspaceWebgpuProviderPath();
|
|
72
|
+
return typeof specifier === 'string'
|
|
73
|
+
&& specifier.startsWith('file://')
|
|
74
|
+
&& specifier.includes('@simulatte/webgpu');
|
|
128
75
|
}
|
|
129
76
|
|
|
130
77
|
async function importWithProviderOverride(specifier) {
|
|
131
|
-
const
|
|
132
|
-
const shouldApplyCreateArgsDefault = isDoeWebgpuCoreSpecifier(specifier)
|
|
78
|
+
const shouldApplyCreateArgsDefault = isDoeWebgpuSpecifier(specifier)
|
|
133
79
|
&& !(typeof process.env.FAWN_WEBGPU_CREATE_ARGS === 'string' && process.env.FAWN_WEBGPU_CREATE_ARGS.trim().length > 0);
|
|
134
|
-
if (!
|
|
135
|
-
|
|
136
|
-
return import(specifier);
|
|
137
|
-
}
|
|
138
|
-
process.env.FAWN_WEBGPU_CREATE_ARGS = DEFAULT_DOE_PROVIDER_CREATE_ARGS;
|
|
139
|
-
try {
|
|
140
|
-
return await import(specifier);
|
|
141
|
-
} finally {
|
|
142
|
-
delete process.env.FAWN_WEBGPU_CREATE_ARGS;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
const hadProvider = Object.prototype.hasOwnProperty.call(process.env, 'FAWN_WEBGPU_NODE_PROVIDER_MODULE');
|
|
146
|
-
const previousProvider = process.env.FAWN_WEBGPU_NODE_PROVIDER_MODULE;
|
|
147
|
-
const hadCreateArgs = Object.prototype.hasOwnProperty.call(process.env, 'FAWN_WEBGPU_CREATE_ARGS');
|
|
148
|
-
const previousCreateArgs = process.env.FAWN_WEBGPU_CREATE_ARGS;
|
|
149
|
-
process.env.FAWN_WEBGPU_NODE_PROVIDER_MODULE = providerOverride;
|
|
150
|
-
if (!hadCreateArgs) {
|
|
151
|
-
process.env.FAWN_WEBGPU_CREATE_ARGS = DEFAULT_DOE_PROVIDER_CREATE_ARGS;
|
|
80
|
+
if (!shouldApplyCreateArgsDefault) {
|
|
81
|
+
return import(specifier);
|
|
152
82
|
}
|
|
83
|
+
process.env.FAWN_WEBGPU_CREATE_ARGS = DEFAULT_DOE_PROVIDER_CREATE_ARGS;
|
|
153
84
|
try {
|
|
154
85
|
return await import(specifier);
|
|
155
86
|
} finally {
|
|
156
|
-
|
|
157
|
-
process.env.FAWN_WEBGPU_NODE_PROVIDER_MODULE = previousProvider;
|
|
158
|
-
} else {
|
|
159
|
-
delete process.env.FAWN_WEBGPU_NODE_PROVIDER_MODULE;
|
|
160
|
-
}
|
|
161
|
-
if (hadCreateArgs) {
|
|
162
|
-
process.env.FAWN_WEBGPU_CREATE_ARGS = previousCreateArgs;
|
|
163
|
-
} else {
|
|
164
|
-
delete process.env.FAWN_WEBGPU_CREATE_ARGS;
|
|
165
|
-
}
|
|
87
|
+
delete process.env.FAWN_WEBGPU_CREATE_ARGS;
|
|
166
88
|
}
|
|
167
89
|
}
|
|
168
90
|
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare function watchFinalizedCheckpoints(options: {
|
|
2
|
+
checkpointsDir: string;
|
|
3
|
+
manifestPath: string;
|
|
4
|
+
pollIntervalMs?: number | null;
|
|
5
|
+
stopWhenIdle?: boolean;
|
|
6
|
+
onCheckpoint: (markerPath: string) => Promise<void> | void;
|
|
7
|
+
}): Promise<{ ok: true; processedCount: number; manifestPath: string }>;
|