ppef 1.0.0 → 1.0.1

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.
Files changed (199) hide show
  1. package/README.md +172 -0
  2. package/dist/__tests__/framework-pipeline.integration.test.d.ts +7 -0
  3. package/dist/__tests__/framework-pipeline.integration.test.d.ts.map +1 -0
  4. package/dist/__tests__/framework-pipeline.integration.test.js +413 -0
  5. package/dist/__tests__/framework-pipeline.integration.test.js.map +1 -0
  6. package/dist/__tests__/registry-executor.integration.test.d.ts +5 -0
  7. package/dist/__tests__/registry-executor.integration.test.d.ts.map +1 -0
  8. package/dist/__tests__/registry-executor.integration.test.js +349 -0
  9. package/dist/__tests__/registry-executor.integration.test.js.map +1 -0
  10. package/dist/__tests__/test-helpers.d.ts +94 -0
  11. package/dist/__tests__/test-helpers.d.ts.map +1 -0
  12. package/dist/__tests__/test-helpers.js +271 -0
  13. package/dist/__tests__/test-helpers.js.map +1 -0
  14. package/dist/aggregation/aggregators.d.ts +54 -0
  15. package/dist/aggregation/aggregators.d.ts.map +1 -0
  16. package/dist/aggregation/aggregators.js +228 -0
  17. package/dist/aggregation/aggregators.js.map +1 -0
  18. package/dist/aggregation/index.d.ts +8 -0
  19. package/dist/aggregation/index.d.ts.map +1 -0
  20. package/dist/aggregation/index.js +8 -0
  21. package/dist/aggregation/index.js.map +1 -0
  22. package/dist/aggregation/pipeline.d.ts +38 -0
  23. package/dist/aggregation/pipeline.d.ts.map +1 -0
  24. package/dist/aggregation/pipeline.js +198 -0
  25. package/dist/aggregation/pipeline.js.map +1 -0
  26. package/dist/claims/evaluator.d.ts +33 -0
  27. package/dist/claims/evaluator.d.ts.map +1 -0
  28. package/dist/claims/evaluator.js +174 -0
  29. package/dist/claims/evaluator.js.map +1 -0
  30. package/dist/claims/index.d.ts +7 -0
  31. package/dist/claims/index.d.ts.map +1 -0
  32. package/dist/claims/index.js +7 -0
  33. package/dist/claims/index.js.map +1 -0
  34. package/dist/collector/index.d.ts +8 -0
  35. package/dist/collector/index.d.ts.map +1 -0
  36. package/dist/collector/index.js +8 -0
  37. package/dist/collector/index.js.map +1 -0
  38. package/dist/collector/result-collector.d.ts +159 -0
  39. package/dist/collector/result-collector.d.ts.map +1 -0
  40. package/dist/collector/result-collector.js +213 -0
  41. package/dist/collector/result-collector.js.map +1 -0
  42. package/dist/collector/schema.d.ts +34 -0
  43. package/dist/collector/schema.d.ts.map +1 -0
  44. package/dist/collector/schema.js +145 -0
  45. package/dist/collector/schema.js.map +1 -0
  46. package/dist/executor/__tests__/checkpoint-hash-bug.diagnostic.test.d.ts +10 -0
  47. package/dist/executor/__tests__/checkpoint-hash-bug.diagnostic.test.d.ts.map +1 -0
  48. package/dist/executor/__tests__/checkpoint-hash-bug.diagnostic.test.js +122 -0
  49. package/dist/executor/__tests__/checkpoint-hash-bug.diagnostic.test.js.map +1 -0
  50. package/dist/executor/__tests__/checkpoint-manager.integration.test.d.ts +7 -0
  51. package/dist/executor/__tests__/checkpoint-manager.integration.test.d.ts.map +1 -0
  52. package/dist/executor/__tests__/checkpoint-manager.integration.test.js +330 -0
  53. package/dist/executor/__tests__/checkpoint-manager.integration.test.js.map +1 -0
  54. package/dist/executor/__tests__/checkpoint-manager.unit.test.d.ts +7 -0
  55. package/dist/executor/__tests__/checkpoint-manager.unit.test.d.ts.map +1 -0
  56. package/dist/executor/__tests__/checkpoint-manager.unit.test.js +449 -0
  57. package/dist/executor/__tests__/checkpoint-manager.unit.test.js.map +1 -0
  58. package/dist/executor/__tests__/checkpoint-merge-bug.diagnostic.test.d.ts +11 -0
  59. package/dist/executor/__tests__/checkpoint-merge-bug.diagnostic.test.d.ts.map +1 -0
  60. package/dist/executor/__tests__/checkpoint-merge-bug.diagnostic.test.js +224 -0
  61. package/dist/executor/__tests__/checkpoint-merge-bug.diagnostic.test.js.map +1 -0
  62. package/dist/executor/__tests__/checkpoint-merge-bug.unit.test.d.ts +8 -0
  63. package/dist/executor/__tests__/checkpoint-merge-bug.unit.test.d.ts.map +1 -0
  64. package/dist/executor/__tests__/checkpoint-merge-bug.unit.test.js +164 -0
  65. package/dist/executor/__tests__/checkpoint-merge-bug.unit.test.js.map +1 -0
  66. package/dist/executor/__tests__/checkpoint-storage.unit.test.d.ts +7 -0
  67. package/dist/executor/__tests__/checkpoint-storage.unit.test.d.ts.map +1 -0
  68. package/dist/executor/__tests__/checkpoint-storage.unit.test.js +386 -0
  69. package/dist/executor/__tests__/checkpoint-storage.unit.test.js.map +1 -0
  70. package/dist/executor/__tests__/executor.unit.test.d.ts +7 -0
  71. package/dist/executor/__tests__/executor.unit.test.d.ts.map +1 -0
  72. package/dist/executor/__tests__/executor.unit.test.js +134 -0
  73. package/dist/executor/__tests__/executor.unit.test.js.map +1 -0
  74. package/dist/executor/__tests__/parallel-checkpoint-merge.integration.test.d.ts +12 -0
  75. package/dist/executor/__tests__/parallel-checkpoint-merge.integration.test.d.ts.map +1 -0
  76. package/dist/executor/__tests__/parallel-checkpoint-merge.integration.test.js +196 -0
  77. package/dist/executor/__tests__/parallel-checkpoint-merge.integration.test.js.map +1 -0
  78. package/dist/executor/__tests__/parallel-executor.integration.test.d.ts +7 -0
  79. package/dist/executor/__tests__/parallel-executor.integration.test.d.ts.map +1 -0
  80. package/dist/executor/__tests__/parallel-executor.integration.test.js +249 -0
  81. package/dist/executor/__tests__/parallel-executor.integration.test.js.map +1 -0
  82. package/dist/executor/__tests__/parallel-executor.unit.test.d.ts +7 -0
  83. package/dist/executor/__tests__/parallel-executor.unit.test.d.ts.map +1 -0
  84. package/dist/executor/__tests__/parallel-executor.unit.test.js +203 -0
  85. package/dist/executor/__tests__/parallel-executor.unit.test.js.map +1 -0
  86. package/dist/executor/checkpoint-manager.d.ts +231 -0
  87. package/dist/executor/checkpoint-manager.d.ts.map +1 -0
  88. package/dist/executor/checkpoint-manager.js +395 -0
  89. package/dist/executor/checkpoint-manager.js.map +1 -0
  90. package/dist/executor/checkpoint-storage.d.ts +230 -0
  91. package/dist/executor/checkpoint-storage.d.ts.map +1 -0
  92. package/dist/executor/checkpoint-storage.js +370 -0
  93. package/dist/executor/checkpoint-storage.js.map +1 -0
  94. package/dist/executor/checkpoint-types.d.ts +48 -0
  95. package/dist/executor/checkpoint-types.d.ts.map +1 -0
  96. package/dist/executor/checkpoint-types.js +8 -0
  97. package/dist/executor/checkpoint-types.js.map +1 -0
  98. package/dist/executor/executor.d.ts +164 -0
  99. package/dist/executor/executor.d.ts.map +1 -0
  100. package/dist/executor/executor.js +408 -0
  101. package/dist/executor/executor.js.map +1 -0
  102. package/dist/executor/index.d.ts +11 -0
  103. package/dist/executor/index.d.ts.map +1 -0
  104. package/dist/executor/index.js +11 -0
  105. package/dist/executor/index.js.map +1 -0
  106. package/dist/executor/memory-monitor.d.ts +115 -0
  107. package/dist/executor/memory-monitor.d.ts.map +1 -0
  108. package/dist/executor/memory-monitor.js +168 -0
  109. package/dist/executor/memory-monitor.js.map +1 -0
  110. package/dist/executor/parallel-executor.d.ts +53 -0
  111. package/dist/executor/parallel-executor.d.ts.map +1 -0
  112. package/dist/executor/parallel-executor.js +194 -0
  113. package/dist/executor/parallel-executor.js.map +1 -0
  114. package/dist/executor/run-id.d.ts +71 -0
  115. package/dist/executor/run-id.d.ts.map +1 -0
  116. package/dist/executor/run-id.js +67 -0
  117. package/dist/executor/run-id.js.map +1 -0
  118. package/dist/executor/worker-entry.d.ts +8 -0
  119. package/dist/executor/worker-entry.d.ts.map +1 -0
  120. package/dist/executor/worker-entry.js +67 -0
  121. package/dist/executor/worker-entry.js.map +1 -0
  122. package/dist/index.cjs +11 -0
  123. package/dist/index.d.ts +15 -0
  124. package/dist/index.d.ts.map +1 -0
  125. package/dist/index.js +24 -0
  126. package/dist/index.js.map +1 -0
  127. package/dist/registry/case-registry.d.ts +113 -0
  128. package/dist/registry/case-registry.d.ts.map +1 -0
  129. package/dist/registry/case-registry.js +160 -0
  130. package/dist/registry/case-registry.js.map +1 -0
  131. package/dist/registry/index.d.ts +8 -0
  132. package/dist/registry/index.d.ts.map +1 -0
  133. package/dist/registry/index.js +8 -0
  134. package/dist/registry/index.js.map +1 -0
  135. package/dist/registry/sut-registry.d.ts +96 -0
  136. package/dist/registry/sut-registry.d.ts.map +1 -0
  137. package/dist/registry/sut-registry.js +126 -0
  138. package/dist/registry/sut-registry.js.map +1 -0
  139. package/dist/renderers/index.d.ts +10 -0
  140. package/dist/renderers/index.d.ts.map +1 -0
  141. package/dist/renderers/index.js +9 -0
  142. package/dist/renderers/index.js.map +1 -0
  143. package/dist/renderers/latex-renderer.d.ts +84 -0
  144. package/dist/renderers/latex-renderer.d.ts.map +1 -0
  145. package/dist/renderers/latex-renderer.js +208 -0
  146. package/dist/renderers/latex-renderer.js.map +1 -0
  147. package/dist/renderers/types.d.ts +106 -0
  148. package/dist/renderers/types.d.ts.map +1 -0
  149. package/dist/renderers/types.js +23 -0
  150. package/dist/renderers/types.js.map +1 -0
  151. package/dist/robustness/analyzer.d.ts +61 -0
  152. package/dist/robustness/analyzer.d.ts.map +1 -0
  153. package/dist/robustness/analyzer.js +191 -0
  154. package/dist/robustness/analyzer.js.map +1 -0
  155. package/dist/robustness/index.d.ts +8 -0
  156. package/dist/robustness/index.d.ts.map +1 -0
  157. package/dist/robustness/index.js +8 -0
  158. package/dist/robustness/index.js.map +1 -0
  159. package/dist/robustness/perturbations.d.ts +46 -0
  160. package/dist/robustness/perturbations.d.ts.map +1 -0
  161. package/dist/robustness/perturbations.js +184 -0
  162. package/dist/robustness/perturbations.js.map +1 -0
  163. package/dist/statistical/index.d.ts +8 -0
  164. package/dist/statistical/index.d.ts.map +1 -0
  165. package/dist/statistical/index.js +8 -0
  166. package/dist/statistical/index.js.map +1 -0
  167. package/dist/statistical/mann-whitney-u.d.ts +62 -0
  168. package/dist/statistical/mann-whitney-u.d.ts.map +1 -0
  169. package/dist/statistical/mann-whitney-u.js +127 -0
  170. package/dist/statistical/mann-whitney-u.js.map +1 -0
  171. package/dist/types/aggregate.d.ts +124 -0
  172. package/dist/types/aggregate.d.ts.map +1 -0
  173. package/dist/types/aggregate.js +9 -0
  174. package/dist/types/aggregate.js.map +1 -0
  175. package/dist/types/case.d.ts +105 -0
  176. package/dist/types/case.d.ts.map +1 -0
  177. package/dist/types/case.js +10 -0
  178. package/dist/types/case.js.map +1 -0
  179. package/dist/types/claims.d.ts +122 -0
  180. package/dist/types/claims.d.ts.map +1 -0
  181. package/dist/types/claims.js +14 -0
  182. package/dist/types/claims.js.map +1 -0
  183. package/dist/types/index.d.ts +12 -0
  184. package/dist/types/index.d.ts.map +1 -0
  185. package/dist/types/index.js +7 -0
  186. package/dist/types/index.js.map +1 -0
  187. package/dist/types/perturbation.d.ts +105 -0
  188. package/dist/types/perturbation.d.ts.map +1 -0
  189. package/dist/types/perturbation.js +9 -0
  190. package/dist/types/perturbation.js.map +1 -0
  191. package/dist/types/result.d.ts +150 -0
  192. package/dist/types/result.d.ts.map +1 -0
  193. package/dist/types/result.js +12 -0
  194. package/dist/types/result.js.map +1 -0
  195. package/dist/types/sut.d.ts +128 -0
  196. package/dist/types/sut.d.ts.map +1 -0
  197. package/dist/types/sut.js +12 -0
  198. package/dist/types/sut.js.map +1 -0
  199. package/package.json +283 -7
@@ -0,0 +1,168 @@
1
+ /**
2
+ * Memory Monitoring for Experiment Execution
3
+ *
4
+ * Tracks memory usage during experiment execution to:
5
+ * 1. Detect memory leaks and excessive consumption
6
+ * 2. Provide early warning before OOM kills
7
+ * 3. Record memory statistics in provenance data
8
+ * 4. Enable automatic throttling or abort on memory pressure
9
+ */
10
+ import { hrtime } from "node:process";
11
+ /**
12
+ * Memory warning levels.
13
+ */
14
+ export var MemoryWarningLevel;
15
+ (function (MemoryWarningLevel) {
16
+ /** No warning (memory usage is normal) */
17
+ MemoryWarningLevel["NORMAL"] = "normal";
18
+ /** Warning (memory usage is elevated) */
19
+ MemoryWarningLevel["WARNING"] = "warning";
20
+ /** Critical (memory usage is dangerously high) */
21
+ MemoryWarningLevel["CRITICAL"] = "critical";
22
+ /** Emergency (process is near OOM) */
23
+ MemoryWarningLevel["EMERGENCY"] = "emergency";
24
+ })(MemoryWarningLevel || (MemoryWarningLevel = {}));
25
+ /**
26
+ * Default memory monitoring configuration.
27
+ */
28
+ export const DEFAULT_MEMORY_CONFIG = {
29
+ warningThresholdMb: 1024, // 1GB
30
+ criticalThresholdMb: 2048, // 2GB
31
+ emergencyThresholdMb: Math.floor((Number(process.env.MEMORY_LIMIT_MB) || 16_384) * 0.8), // 80% of limit or 13GB
32
+ verbose: false,
33
+ };
34
+ /**
35
+ * Memory monitor for tracking usage during execution.
36
+ */
37
+ export class MemoryMonitor {
38
+ config;
39
+ currentLevel = MemoryWarningLevel.NORMAL;
40
+ startTime;
41
+ constructor(config) {
42
+ this.config = { ...DEFAULT_MEMORY_CONFIG, ...config };
43
+ this.startTime = hrtime.bigint();
44
+ }
45
+ /**
46
+ * Get current memory usage statistics.
47
+ */
48
+ getStats() {
49
+ const mem = process.memoryUsage();
50
+ // RSS is already in bytes on most platforms
51
+ const rssBytes = mem.rss;
52
+ const rssMb = rssBytes / (1024 * 1024);
53
+ const heapTotalBytes = mem.heapTotal;
54
+ const heapUsedBytes = mem.heapUsed;
55
+ const heapUsagePercent = (heapUsedBytes / heapTotalBytes) * 100;
56
+ // Calculate elapsed time in milliseconds
57
+ const elapsedHr = hrtime.bigint() - this.startTime;
58
+ const timestamp = Number(elapsedHr) / 1_000_000;
59
+ return {
60
+ rssBytes,
61
+ heapTotalBytes,
62
+ heapUsedBytes,
63
+ externalBytes: mem.external,
64
+ arrayBuffersBytes: mem.arrayBuffers,
65
+ rssMb,
66
+ heapUsagePercent,
67
+ timestamp,
68
+ };
69
+ }
70
+ /**
71
+ * Get current warning level based on memory usage.
72
+ * @param stats
73
+ */
74
+ getWarningLevel(stats) {
75
+ const current = stats ?? this.getStats();
76
+ if (current.rssMb >= this.config.emergencyThresholdMb) {
77
+ return MemoryWarningLevel.EMERGENCY;
78
+ }
79
+ if (current.rssMb >= this.config.criticalThresholdMb) {
80
+ return MemoryWarningLevel.CRITICAL;
81
+ }
82
+ if (current.rssMb >= this.config.warningThresholdMb) {
83
+ return MemoryWarningLevel.WARNING;
84
+ }
85
+ return MemoryWarningLevel.NORMAL;
86
+ }
87
+ /**
88
+ * Check memory usage and trigger warnings if needed.
89
+ *
90
+ * @returns Current warning level
91
+ */
92
+ check() {
93
+ const stats = this.getStats();
94
+ const level = this.getWarningLevel(stats);
95
+ // Trigger callback if level changed
96
+ if (level !== this.currentLevel) {
97
+ this.currentLevel = level;
98
+ if (this.config.onWarningLevelChange) {
99
+ this.config.onWarningLevelChange(level, stats);
100
+ }
101
+ }
102
+ // Log warning if verbose
103
+ if (this.config.verbose && level !== MemoryWarningLevel.NORMAL) {
104
+ this.logWarning(level, stats);
105
+ }
106
+ return level;
107
+ }
108
+ /**
109
+ * Log memory warning with details.
110
+ * @param level
111
+ * @param stats
112
+ */
113
+ logWarning(level, stats) {
114
+ const levelColors = {
115
+ [MemoryWarningLevel.WARNING]: "\u001B[33m", // Yellow
116
+ [MemoryWarningLevel.CRITICAL]: "\u001B[31m", // Red
117
+ [MemoryWarningLevel.EMERGENCY]: "\u001B[35m", // Magenta
118
+ [MemoryWarningLevel.NORMAL]: "\u001B[32m", // Green
119
+ };
120
+ const reset = "\u001B[0m";
121
+ const color = levelColors[level];
122
+ console.warn(`${color}[Memory ${level.toUpperCase()}]${reset} ` +
123
+ `RSS: ${stats.rssMb.toFixed(1)}MB ` +
124
+ `| Heap: ${(stats.heapUsedBytes / 1024 / 1024).toFixed(1)}MB / ${(stats.heapTotalBytes / 1024 / 1024).toFixed(1)}MB ` +
125
+ `(${stats.heapUsagePercent.toFixed(1)}%)`);
126
+ }
127
+ /**
128
+ * Create a memory snapshot for provenance tracking.
129
+ */
130
+ snapshot() {
131
+ return this.getStats();
132
+ }
133
+ /**
134
+ * Format memory stats for logging.
135
+ * @param stats
136
+ */
137
+ format(stats) {
138
+ const current = stats ?? this.getStats();
139
+ return `RSS: ${current.rssMb.toFixed(1)}MB, Heap: ${(current.heapUsedBytes / 1024 / 1024).toFixed(1)}MB`;
140
+ }
141
+ }
142
+ /**
143
+ * Global memory monitor instance for convenience.
144
+ */
145
+ let globalMonitor = null;
146
+ /**
147
+ * Get or create the global memory monitor.
148
+ * @param config
149
+ */
150
+ export const getGlobalMemoryMonitor = (config) => {
151
+ globalMonitor ??= new MemoryMonitor(config);
152
+ return globalMonitor;
153
+ };
154
+ /**
155
+ * Check memory usage using the global monitor.
156
+ */
157
+ export const checkMemoryUsage = () => {
158
+ const monitor = getGlobalMemoryMonitor();
159
+ return monitor.check();
160
+ };
161
+ /**
162
+ * Get current memory stats using the global monitor.
163
+ */
164
+ export const getMemoryStats = () => {
165
+ const monitor = getGlobalMemoryMonitor();
166
+ return monitor.getStats();
167
+ };
168
+ //# sourceMappingURL=memory-monitor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-monitor.js","sourceRoot":"","sources":["../../src/executor/memory-monitor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Parallel executor using child processes.
3
+ *
4
+ * Spawns multiple Node.js processes, each executing a subset of runs.
5
+ * Each worker writes to its own sharded checkpoint file to avoid race conditions.
6
+ *
7
+ * Sharded checkpoint files:
8
+ * results/execute/checkpoint-worker-00.json
9
+ * results/execute/checkpoint-worker-01.json
10
+ * ...
11
+ */
12
+ import type { EvaluationResult } from "../types/result.js";
13
+ import type { ExecutorConfig, PlannedRun } from "./executor.js";
14
+ export interface ParallelExecutorOptions {
15
+ /** Number of parallel processes (default: CPU count) */
16
+ workers?: number;
17
+ /** Path to node executable */
18
+ nodePath?: string;
19
+ /** Checkpoint directory (defaults to "results/execute") */
20
+ checkpointDir?: string;
21
+ /** Per-run timeout in milliseconds (0 = no timeout) */
22
+ timeoutMs?: number;
23
+ }
24
+ /**
25
+ * Generate sharded checkpoint path for a worker.
26
+ *
27
+ * @param checkpointDir - Base checkpoint directory
28
+ * @param workerIndex - Worker index (0-based)
29
+ * @returns Path to the worker's checkpoint file
30
+ */
31
+ export declare const shardPath: (checkpointDir: string, workerIndex: number) => string;
32
+ /**
33
+ * Execute runs using multiple parallel processes.
34
+ *
35
+ * Each worker writes to its own sharded checkpoint file to avoid race conditions.
36
+ * After all workers complete, the main process should merge the shards.
37
+ *
38
+ * @param runs - Planned runs to execute
39
+ * @param suts - SUT definitions (not used directly, passed to workers)
40
+ * @param cases - Case definitions (not used directly, passed to workers)
41
+ * @param config - Executor configuration
42
+ * @param options - Parallel executor options
43
+ */
44
+ export declare const executeParallel: (runs: PlannedRun[], suts: unknown, cases: unknown[], config: ExecutorConfig & {
45
+ onResult?: (result: EvaluationResult) => void;
46
+ }, options?: ParallelExecutorOptions) => Promise<{
47
+ results: EvaluationResult[];
48
+ errors: {
49
+ runId: string;
50
+ error: string;
51
+ }[];
52
+ }>;
53
+ //# sourceMappingURL=parallel-executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parallel-executor.d.ts","sourceRoot":"","sources":["../../src/executor/parallel-executor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAOH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AA0BhE,MAAM,WAAW,uBAAuB;IACvC,wDAAwD;IACxD,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,2DAA2D;IAC3D,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AA8ED;;;;;;GAMG;AACH,eAAO,MAAM,SAAS,GAAI,eAAe,MAAM,EAAE,aAAa,MAAM,KAAG,MACkB,CAAC;AAE1F;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,eAAe,GAC3B,MAAM,UAAU,EAAE,EAClB,MAAM,OAAO,EACb,OAAO,OAAO,EAAE,EAChB,QAAQ,cAAc,GAAG;IAAE,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAA;CAAE,EAC1E,UAAS,uBAA4B,KACnC,OAAO,CAAC;IAAE,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAAC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAAE,CAkFrF,CAAC"}
@@ -0,0 +1,194 @@
1
+ /**
2
+ * Parallel executor using child processes.
3
+ *
4
+ * Spawns multiple Node.js processes, each executing a subset of runs.
5
+ * Each worker writes to its own sharded checkpoint file to avoid race conditions.
6
+ *
7
+ * Sharded checkpoint files:
8
+ * results/execute/checkpoint-worker-00.json
9
+ * results/execute/checkpoint-worker-01.json
10
+ * ...
11
+ */
12
+ import { spawn } from "node:child_process";
13
+ import { randomBytes } from "node:crypto";
14
+ import { cpus } from "node:os";
15
+ import { dirname, resolve } from "node:path";
16
+ /**
17
+ * Get the package root directory by resolving from the entry point script.
18
+ * The CLI entry point is dist/cli.js, so we go up one level from there.
19
+ */
20
+ const getPackageRoot = () => {
21
+ // Get the directory containing the entry point script
22
+ // process.argv[1] is the path to the executed script (e.g., /path/to/graphbox/dist/cli.js)
23
+ const entryPoint = process.argv[1];
24
+ // Resolve to absolute path first (handles relative paths like "dist/cli.js")
25
+ const absoluteEntry = resolve(entryPoint);
26
+ const entryDir = dirname(absoluteEntry);
27
+ // If entry point is in dist/, go up one level to get package root
28
+ if (entryDir.endsWith("/dist") || entryDir.endsWith(String.raw `\dist`)) {
29
+ return entryDir.slice(0, -5); // Remove "/dist"
30
+ }
31
+ // Fallback: use current directory
32
+ return process.cwd();
33
+ };
34
+ const PACKAGE_ROOT = getPackageRoot();
35
+ /**
36
+ * Generate random worker names using tech-themed adjectives.
37
+ * Returns unique names for each worker.
38
+ * @param count
39
+ */
40
+ const generateWorkerNames = (count) => {
41
+ const adjectives = [
42
+ "swift",
43
+ "nimble",
44
+ "quick",
45
+ "brisk",
46
+ "speedy",
47
+ "rapid",
48
+ "fast",
49
+ "agile",
50
+ "crisp",
51
+ "snappy",
52
+ "zippy",
53
+ "flash",
54
+ "bolt",
55
+ "dash",
56
+ "zoom",
57
+ "jet",
58
+ "rocket",
59
+ "comet",
60
+ "meteor",
61
+ "star",
62
+ "nova",
63
+ "spark",
64
+ "flare",
65
+ "blaze",
66
+ "quantum",
67
+ "cyber",
68
+ "digital",
69
+ "pixel",
70
+ "byte",
71
+ "bit",
72
+ "logic",
73
+ "circuit",
74
+ ];
75
+ const nouns = [
76
+ "runner",
77
+ "worker",
78
+ "processor",
79
+ "executor",
80
+ "cruncher",
81
+ "solver",
82
+ "engine",
83
+ "motor",
84
+ "driver",
85
+ "pilot",
86
+ "agent",
87
+ "bot",
88
+ "node",
89
+ "core",
90
+ ];
91
+ // Generate unique names using random adjectives + nouns + hex suffix
92
+ const usedNames = new Set();
93
+ const names = [];
94
+ while (names.length < count) {
95
+ const adj = adjectives[Math.floor(Math.random() * adjectives.length)];
96
+ const noun = nouns[Math.floor(Math.random() * nouns.length)];
97
+ const suffix = randomBytes(2).toString("hex");
98
+ const name = `${adj}-${noun}-${suffix}`;
99
+ if (!usedNames.has(name)) {
100
+ usedNames.add(name);
101
+ names.push(name);
102
+ }
103
+ }
104
+ return names;
105
+ };
106
+ /**
107
+ * Generate sharded checkpoint path for a worker.
108
+ *
109
+ * @param checkpointDir - Base checkpoint directory
110
+ * @param workerIndex - Worker index (0-based)
111
+ * @returns Path to the worker's checkpoint file
112
+ */
113
+ export const shardPath = (checkpointDir, workerIndex) => resolve(checkpointDir, `checkpoint-worker-${String(workerIndex).padStart(2, "0")}.json`);
114
+ /**
115
+ * Execute runs using multiple parallel processes.
116
+ *
117
+ * Each worker writes to its own sharded checkpoint file to avoid race conditions.
118
+ * After all workers complete, the main process should merge the shards.
119
+ *
120
+ * @param runs - Planned runs to execute
121
+ * @param suts - SUT definitions (not used directly, passed to workers)
122
+ * @param cases - Case definitions (not used directly, passed to workers)
123
+ * @param config - Executor configuration
124
+ * @param options - Parallel executor options
125
+ */
126
+ export const executeParallel = async (runs, suts, cases, config, options = {}) => {
127
+ const numberWorkers = options.workers ?? cpus().length;
128
+ const nodePath = options.nodePath ?? process.execPath;
129
+ const checkpointDir = options.checkpointDir ?? resolve(PACKAGE_ROOT, "results/execute");
130
+ const timeoutMs = options.timeoutMs ?? config.timeoutMs;
131
+ console.log(`ParallelExecutor: Spawning ${numberWorkers} processes for ${runs.length} runs`);
132
+ console.log(`Checkpoint directory: ${checkpointDir}`);
133
+ if (timeoutMs > 0) {
134
+ console.log(`Per-run timeout: ${timeoutMs}ms (${Math.round(timeoutMs / 1000)}s)`);
135
+ }
136
+ // Generate unique names for each worker
137
+ const workerNames = generateWorkerNames(numberWorkers);
138
+ console.log(`Workers: ${workerNames.map((name, index) => `${index + 1}. ${name}`).join(", ")}`);
139
+ // Split runs into batches
140
+ const batchSize = Math.ceil(runs.length / numberWorkers);
141
+ const batches = [];
142
+ for (let index = 0; index < runs.length; index += batchSize) {
143
+ batches.push(runs.slice(index, index + batchSize));
144
+ }
145
+ // Create a run filter function for each batch
146
+ const runFilters = batches.map((batch, _index) => {
147
+ const runIds = new Set(batch.map((r) => r.runId));
148
+ const filter = JSON.stringify([...runIds]);
149
+ const firstRunId = batch[0]?.runId ?? "none";
150
+ const lastRunId = batch.at(-1)?.runId ?? "none";
151
+ console.log(`DEBUG: Batch ${_index} has ${batch.length} runs, filter length: ${filter.length}`);
152
+ console.log(`DEBUG: First run: ${firstRunId}, Last run: ${lastRunId}`);
153
+ return filter;
154
+ });
155
+ // Spawn worker processes
156
+ const workers = runFilters.map((runFilter, index) => {
157
+ const workerName = workerNames[index];
158
+ const workerCheckpointPath = shardPath(checkpointDir, index);
159
+ const arguments_ = [
160
+ resolve(PACKAGE_ROOT, "dist/cli.js"),
161
+ "evaluate",
162
+ "--phase=execute",
163
+ "--checkpoint-mode=file",
164
+ `--run-filter=${runFilter}`, // JSON array - needs to be quoted in shell but spawn() handles this
165
+ ];
166
+ // Add timeout if specified
167
+ if (timeoutMs > 0) {
168
+ arguments_.push(`--timeout=${timeoutMs}`);
169
+ }
170
+ return spawn(nodePath, arguments_, {
171
+ stdio: "inherit",
172
+ cwd: PACKAGE_ROOT, // Ensure workers use the package root as working directory
173
+ env: {
174
+ ...process.env,
175
+ NODE_OPTIONS: "--max-old-space-size=4096",
176
+ GRAPHBOX_WORKER_NAME: workerName,
177
+ GRAPHBOX_WORKER_INDEX: index.toString(),
178
+ GRAPHBOX_TOTAL_WORKERS: numberWorkers.toString(),
179
+ GRAPHBOX_CHECKPOINT_DIR: checkpointDir,
180
+ GRAPHBOX_CHECKPOINT_PATH: workerCheckpointPath,
181
+ },
182
+ });
183
+ });
184
+ // Wait for all workers to complete
185
+ await Promise.all(workers.map((w) => new Promise((resolve) => {
186
+ w.on("exit", (code) => {
187
+ resolve(code);
188
+ });
189
+ })));
190
+ // Load and return aggregated results
191
+ // For now, return empty - the CLI will handle results and merge shards
192
+ return { results: [], errors: [] };
193
+ };
194
+ //# sourceMappingURL=parallel-executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parallel-executor.js","sourceRoot":"","sources":["../../src/executor/parallel-executor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Deterministic Run ID Generation
3
+ *
4
+ * Generates reproducible run IDs based on canonical inputs.
5
+ * The same inputs will always produce the same run ID, enabling
6
+ * exact result matching across executions.
7
+ */
8
+ /**
9
+ * Input components for run ID generation.
10
+ */
11
+ export interface RunIdInputs {
12
+ /** SUT identifier */
13
+ sutId: string;
14
+ /** Case identifier */
15
+ caseId: string;
16
+ /** Random seed (if applicable) */
17
+ seed?: number;
18
+ /** Configuration hash (optional) */
19
+ configHash?: string;
20
+ /** Repetition number for statistical runs */
21
+ repetition?: number;
22
+ }
23
+ /**
24
+ * Generate a deterministic run ID from inputs.
25
+ *
26
+ * The run ID is a SHA-256 hash of the canonical JSON representation
27
+ * of the inputs, truncated to 16 hex characters.
28
+ *
29
+ * @param inputs - Components to hash
30
+ * @returns 16-character hex string
31
+ *
32
+ * @example
33
+ * ```typescript
34
+ * const runId = generateRunId({
35
+ * sutId: "degree-prioritised-v1.0.0",
36
+ * caseId: "karate-v1",
37
+ * seed: 42,
38
+ * repetition: 1,
39
+ * });
40
+ * // Always returns the same value for the same inputs
41
+ * ```
42
+ */
43
+ export declare const generateRunId: (inputs: RunIdInputs) => string;
44
+ /**
45
+ * Generate a configuration hash from arbitrary config object.
46
+ *
47
+ * @param config - Configuration object
48
+ * @returns 8-character hex string
49
+ */
50
+ export declare const generateConfigHash: (config: Record<string, unknown>) => string;
51
+ /**
52
+ * Validate that a run ID matches expected inputs.
53
+ *
54
+ * @param runId - Run ID to validate
55
+ * @param inputs - Expected inputs
56
+ * @returns true if run ID matches
57
+ */
58
+ export declare const validateRunId: (runId: string, inputs: RunIdInputs) => boolean;
59
+ /**
60
+ * Parse a run ID into its components.
61
+ * Note: This is not reversible - run IDs are hashes.
62
+ * This function only validates the format.
63
+ *
64
+ * @param runId - Run ID to parse
65
+ * @returns Object with validation info
66
+ */
67
+ export declare const parseRunId: (runId: string) => {
68
+ valid: boolean;
69
+ length: number;
70
+ };
71
+ //# sourceMappingURL=run-id.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-id.d.ts","sourceRoot":"","sources":["../../src/executor/run-id.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH;;GAEG;AACH,MAAM,WAAW,WAAW;IAC3B,qBAAqB;IACrB,KAAK,EAAE,MAAM,CAAC;IAEd,sBAAsB;IACtB,MAAM,EAAE,MAAM,CAAC;IAEf,kCAAkC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,oCAAoC;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,6CAA6C;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,aAAa,GAAI,QAAQ,WAAW,KAAG,MAInD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAAI,QAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,MAGpE,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,GAAI,OAAO,MAAM,EAAE,QAAQ,WAAW,KAAG,OACnC,CAAC;AAEjC;;;;;;;GAOG;AACH,eAAO,MAAM,UAAU,GAAI,OAAO,MAAM,KAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAM1E,CAAC"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Deterministic Run ID Generation
3
+ *
4
+ * Generates reproducible run IDs based on canonical inputs.
5
+ * The same inputs will always produce the same run ID, enabling
6
+ * exact result matching across executions.
7
+ */
8
+ import { createHash } from "node:crypto";
9
+ /**
10
+ * Generate a deterministic run ID from inputs.
11
+ *
12
+ * The run ID is a SHA-256 hash of the canonical JSON representation
13
+ * of the inputs, truncated to 16 hex characters.
14
+ *
15
+ * @param inputs - Components to hash
16
+ * @returns 16-character hex string
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * const runId = generateRunId({
21
+ * sutId: "degree-prioritised-v1.0.0",
22
+ * caseId: "karate-v1",
23
+ * seed: 42,
24
+ * repetition: 1,
25
+ * });
26
+ * // Always returns the same value for the same inputs
27
+ * ```
28
+ */
29
+ export const generateRunId = (inputs) => {
30
+ // Sort keys for canonical ordering
31
+ const canonical = JSON.stringify(inputs, Object.keys(inputs).sort());
32
+ return createHash("sha256").update(canonical).digest("hex").slice(0, 16);
33
+ };
34
+ /**
35
+ * Generate a configuration hash from arbitrary config object.
36
+ *
37
+ * @param config - Configuration object
38
+ * @returns 8-character hex string
39
+ */
40
+ export const generateConfigHash = (config) => {
41
+ const canonical = JSON.stringify(config, Object.keys(config).sort());
42
+ return createHash("sha256").update(canonical).digest("hex").slice(0, 8);
43
+ };
44
+ /**
45
+ * Validate that a run ID matches expected inputs.
46
+ *
47
+ * @param runId - Run ID to validate
48
+ * @param inputs - Expected inputs
49
+ * @returns true if run ID matches
50
+ */
51
+ export const validateRunId = (runId, inputs) => runId === generateRunId(inputs);
52
+ /**
53
+ * Parse a run ID into its components.
54
+ * Note: This is not reversible - run IDs are hashes.
55
+ * This function only validates the format.
56
+ *
57
+ * @param runId - Run ID to parse
58
+ * @returns Object with validation info
59
+ */
60
+ export const parseRunId = (runId) => {
61
+ const isHex = /^[0-9a-f]+$/i.test(runId);
62
+ return {
63
+ valid: isHex && runId.length === 16,
64
+ length: runId.length,
65
+ };
66
+ };
67
+ //# sourceMappingURL=run-id.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-id.js","sourceRoot":"","sources":["../../src/executor/run-id.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAsBzC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,MAAmB,EAAU,EAAE;IAC5D,mCAAmC;IACnC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACrE,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAC1E,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,MAA+B,EAAU,EAAE;IAC7E,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACrE,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACzE,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,KAAa,EAAE,MAAmB,EAAW,EAAE,CAC5E,KAAK,KAAK,aAAa,CAAC,MAAM,CAAC,CAAC;AAEjC;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,KAAa,EAAsC,EAAE;IAC/E,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACzC,OAAO;QACN,KAAK,EAAE,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,EAAE;QACnC,MAAM,EAAE,KAAK,CAAC,MAAM;KACpB,CAAC;AACH,CAAC,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Worker entry point for parallel execution.
3
+ *
4
+ * This file is loaded as a worker thread and receives messages
5
+ * with batches of runs to execute.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=worker-entry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-entry.d.ts","sourceRoot":"","sources":["../../src/executor/worker-entry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Worker entry point for parallel execution.
3
+ *
4
+ * This file is loaded as a worker thread and receives messages
5
+ * with batches of runs to execute.
6
+ */
7
+ import { dirname, resolve } from "node:path";
8
+ import { fileURLToPath } from "node:url";
9
+ import { parentPort } from "node:worker_threads";
10
+ const __filename = fileURLToPath(import.meta.url);
11
+ const __dirname = dirname(__filename);
12
+ const projectRoot = resolve(__dirname, "../../../");
13
+ // Dynamically import the main code
14
+ const executeBatch = async (message) => {
15
+ // Import the executor and other dependencies
16
+ const executorModule = (await import(`${projectRoot}/dist/experiments/framework/executor/executor.js`));
17
+ const evaluateModule = (await import(`${projectRoot}/dist/cli-commands/evaluate.js`));
18
+ const registryModule = (await import(`${projectRoot}/dist/experiments/framework/registry/index.js`));
19
+ const sutsModule = (await import(`${projectRoot}/dist/experiments/framework/suts/index.js`));
20
+ const datasetsModule = (await import(`${projectRoot}/dist/experiments/evaluation/fixtures/benchmark-datasets.js`));
21
+ // Register all datasets and SUTs
22
+ await datasetsModule.registerBenchmarkDatasets();
23
+ sutsModule.registerAllSuts();
24
+ const caseRegistry = await registryModule.registerAllBenchmarkCases();
25
+ const sutRegistry = {
26
+ list: () => ["degree-prioritised", "standard-bfs", "frontier-balanced", "random-priority"],
27
+ getFactory: () => {
28
+ // This would need to be implemented properly
29
+ return null;
30
+ },
31
+ };
32
+ const suts = evaluateModule.getSutDefinitions(sutRegistry);
33
+ const cases = evaluateModule.getCaseDefinitions(caseRegistry);
34
+ // Create executor with no onResult callback (workers don't save checkpoints)
35
+ const executor = new executorModule.Executor({
36
+ repetitions: message.config.repetitions,
37
+ seedBase: message.config.seedBase,
38
+ continueOnError: message.config.continueOnError,
39
+ timeoutMs: message.config.timeoutMs,
40
+ collectProvenance: message.config.collectProvenance,
41
+ });
42
+ // Execute the runs
43
+ const results = await executor.execute(suts, cases, () => ({}));
44
+ return {
45
+ results: results.results,
46
+ errors: results.errors,
47
+ };
48
+ };
49
+ // Listen for messages from parent thread
50
+ parentPort?.on("message", (data) => {
51
+ // Validate message structure
52
+ const message = data;
53
+ // Execute asynchronously without returning the promise
54
+ void (async () => {
55
+ try {
56
+ const result = await executeBatch(message);
57
+ parentPort?.postMessage({ type: "done", ...result });
58
+ }
59
+ catch (error) {
60
+ parentPort?.postMessage({
61
+ type: "error",
62
+ error: error instanceof Error ? error.message : String(error),
63
+ });
64
+ }
65
+ })();
66
+ });
67
+ //# sourceMappingURL=worker-entry.js.map