@sparkleideas/performance 3.0.0-alpha.7
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 +256 -0
- package/__tests__/README.md +242 -0
- package/__tests__/attention.test.ts +516 -0
- package/__tests__/benchmarks.test.ts +515 -0
- package/benchmarks/attention/memory-efficiency.bench.ts +569 -0
- package/benchmarks/attention/multi-head-attention.bench.ts +566 -0
- package/benchmarks/startup/agent-spawn.bench.ts +422 -0
- package/benchmarks/startup/cli-cold-start.bench.ts +327 -0
- package/benchmarks/startup/cli-warm-start.bench.ts +277 -0
- package/benchmarks/startup/mcp-server-init.bench.ts +380 -0
- package/docs/ATTENTION.md +277 -0
- package/package.json +29 -0
- package/src/attention-benchmarks.ts +459 -0
- package/src/attention-integration.ts +507 -0
- package/src/examples/flash-attention-demo.ts +160 -0
- package/src/examples/quick-test.ts +62 -0
- package/src/framework/benchmark.ts +583 -0
- package/src/index.ts +63 -0
- package/tmp.json +0 -0
- package/tsconfig.json +9 -0
- package/vitest.config.ts +31 -0
|
@@ -0,0 +1,515 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AttentionBenchmarkRunner Test Suite
|
|
3
|
+
*
|
|
4
|
+
* Comprehensive tests for benchmark runner, suite execution, memory profiling,
|
|
5
|
+
* and V3 performance target validation (2.49x-7.47x speedup).
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
9
|
+
import {
|
|
10
|
+
AttentionBenchmarkRunner,
|
|
11
|
+
quickValidation,
|
|
12
|
+
formatBenchmarkTable,
|
|
13
|
+
formatSuiteReport,
|
|
14
|
+
formatMemoryProfile,
|
|
15
|
+
type ComparisonBenchmark,
|
|
16
|
+
type SuiteResult,
|
|
17
|
+
type MemoryProfile,
|
|
18
|
+
} from '../src/attention-benchmarks.js';
|
|
19
|
+
|
|
20
|
+
describe('AttentionBenchmarkRunner', () => {
|
|
21
|
+
let runner: AttentionBenchmarkRunner;
|
|
22
|
+
|
|
23
|
+
beforeEach(() => {
|
|
24
|
+
runner = new AttentionBenchmarkRunner();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
describe('runComparison()', () => {
|
|
28
|
+
it('should run comparison benchmark with default parameters', () => {
|
|
29
|
+
const result = runner.runComparison(256, 50, 100);
|
|
30
|
+
|
|
31
|
+
expect(result).toBeDefined();
|
|
32
|
+
expect(result.name).toContain('Flash Attention');
|
|
33
|
+
expect(result.name).toContain('256D');
|
|
34
|
+
expect(result.dimension).toBe(256);
|
|
35
|
+
expect(result.numKeys).toBe(50);
|
|
36
|
+
expect(result.iterations).toBe(100);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('should measure Flash Attention performance', () => {
|
|
40
|
+
const result = runner.runComparison(256, 50, 100);
|
|
41
|
+
|
|
42
|
+
expect(result.results.flash).toBeDefined();
|
|
43
|
+
expect(result.results.flash.averageTimeMs).toBeGreaterThan(0);
|
|
44
|
+
expect(result.results.flash.opsPerSecond).toBeGreaterThan(0);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('should measure baseline performance', () => {
|
|
48
|
+
const result = runner.runComparison(256, 50, 100);
|
|
49
|
+
|
|
50
|
+
expect(result.results.baseline).toBeDefined();
|
|
51
|
+
expect(result.results.baseline.averageTimeMs).toBeGreaterThan(0);
|
|
52
|
+
expect(result.results.baseline.opsPerSecond).toBeGreaterThan(0);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('should calculate speedup correctly', () => {
|
|
56
|
+
const result = runner.runComparison(256, 50, 100);
|
|
57
|
+
|
|
58
|
+
const expectedSpeedup =
|
|
59
|
+
result.results.baseline.averageTimeMs / result.results.flash.averageTimeMs;
|
|
60
|
+
|
|
61
|
+
expect(result.results.speedup).toBeCloseTo(expectedSpeedup, 2);
|
|
62
|
+
expect(result.results.speedup).toBeGreaterThan(0);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('should validate against target (2.49x minimum)', () => {
|
|
66
|
+
const result = runner.runComparison(512, 100, 1000);
|
|
67
|
+
|
|
68
|
+
expect(result.meetsTarget).toBe(result.results.speedup >= 2.49);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('should include timestamp', () => {
|
|
72
|
+
const result = runner.runComparison(256, 50, 100);
|
|
73
|
+
|
|
74
|
+
expect(result.timestamp).toBeInstanceOf(Date);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('should handle different dimensions', () => {
|
|
78
|
+
const dimensions = [128, 256, 512, 1024];
|
|
79
|
+
|
|
80
|
+
for (const dim of dimensions) {
|
|
81
|
+
const result = runner.runComparison(dim, 50, 100);
|
|
82
|
+
expect(result.dimension).toBe(dim);
|
|
83
|
+
expect(result.results.speedup).toBeGreaterThan(0);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('should handle varying number of keys', () => {
|
|
88
|
+
const keysCounts = [10, 50, 100, 200];
|
|
89
|
+
|
|
90
|
+
for (const numKeys of keysCounts) {
|
|
91
|
+
const result = runner.runComparison(256, numKeys, 100);
|
|
92
|
+
expect(result.numKeys).toBe(numKeys);
|
|
93
|
+
expect(result.results.speedup).toBeGreaterThan(0);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it('should complete in reasonable time', () => {
|
|
98
|
+
const startTime = performance.now();
|
|
99
|
+
runner.runComparison(128, 20, 50); // Small benchmark
|
|
100
|
+
const endTime = performance.now();
|
|
101
|
+
|
|
102
|
+
const duration = endTime - startTime;
|
|
103
|
+
expect(duration).toBeLessThan(10000); // <10s for small benchmark
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
describe('runComprehensiveSuite()', () => {
|
|
108
|
+
it('should run comprehensive benchmark suite', () => {
|
|
109
|
+
const suite = runner.runComprehensiveSuite();
|
|
110
|
+
|
|
111
|
+
expect(suite).toBeDefined();
|
|
112
|
+
expect(suite.suiteName).toContain('Comprehensive');
|
|
113
|
+
expect(suite.benchmarks).toBeDefined();
|
|
114
|
+
expect(suite.benchmarks.length).toBeGreaterThan(0);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it('should test multiple dimensions', () => {
|
|
118
|
+
const suite = runner.runComprehensiveSuite();
|
|
119
|
+
|
|
120
|
+
// Should test at least 128, 256, 512, 768, 1024
|
|
121
|
+
expect(suite.benchmarks.length).toBeGreaterThanOrEqual(5);
|
|
122
|
+
|
|
123
|
+
const dimensions = suite.benchmarks.map(b => b.dimension);
|
|
124
|
+
expect(dimensions).toContain(128);
|
|
125
|
+
expect(dimensions).toContain(256);
|
|
126
|
+
expect(dimensions).toContain(512);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it('should include summary statistics', () => {
|
|
130
|
+
const suite = runner.runComprehensiveSuite();
|
|
131
|
+
|
|
132
|
+
expect(suite.summary).toBeDefined();
|
|
133
|
+
expect(suite.summary.averageSpeedup).toBeGreaterThan(0);
|
|
134
|
+
expect(suite.summary.minSpeedup).toBeGreaterThan(0);
|
|
135
|
+
expect(suite.summary.maxSpeedup).toBeGreaterThanOrEqual(suite.summary.minSpeedup);
|
|
136
|
+
expect(suite.summary.totalBenchmarks).toBe(suite.benchmarks.length);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it('should calculate success rate', () => {
|
|
140
|
+
const suite = runner.runComprehensiveSuite();
|
|
141
|
+
|
|
142
|
+
expect(suite.summary.successRate).toBeGreaterThanOrEqual(0);
|
|
143
|
+
expect(suite.summary.successRate).toBeLessThanOrEqual(100);
|
|
144
|
+
|
|
145
|
+
const expectedSuccessRate =
|
|
146
|
+
(suite.summary.targetsMet / suite.summary.totalBenchmarks) * 100;
|
|
147
|
+
expect(suite.summary.successRate).toBeCloseTo(expectedSuccessRate, 2);
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it('should track targets met', () => {
|
|
151
|
+
const suite = runner.runComprehensiveSuite();
|
|
152
|
+
|
|
153
|
+
const manualCount = suite.benchmarks.filter(b => b.meetsTarget).length;
|
|
154
|
+
expect(suite.summary.targetsMet).toBe(manualCount);
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
it('should include timestamp', () => {
|
|
158
|
+
const suite = runner.runComprehensiveSuite();
|
|
159
|
+
|
|
160
|
+
expect(suite.timestamp).toBeInstanceOf(Date);
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
describe('runMemoryProfile()', () => {
|
|
165
|
+
it('should run memory profile with default dimensions', () => {
|
|
166
|
+
const profiles = runner.runMemoryProfile();
|
|
167
|
+
|
|
168
|
+
expect(profiles).toBeDefined();
|
|
169
|
+
expect(profiles.length).toBeGreaterThan(0);
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
it('should profile multiple dimensions', () => {
|
|
173
|
+
const dimensions = [128, 256, 512];
|
|
174
|
+
const profiles = runner.runMemoryProfile(dimensions);
|
|
175
|
+
|
|
176
|
+
expect(profiles.length).toBe(dimensions.length);
|
|
177
|
+
|
|
178
|
+
for (let i = 0; i < dimensions.length; i++) {
|
|
179
|
+
expect(profiles[i].dimension).toBe(dimensions[i]);
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
it('should measure Flash Attention memory', () => {
|
|
184
|
+
const profiles = runner.runMemoryProfile([256]);
|
|
185
|
+
|
|
186
|
+
expect(profiles[0].flashMemoryBytes).toBeGreaterThanOrEqual(0);
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
it('should measure baseline memory', () => {
|
|
190
|
+
const profiles = runner.runMemoryProfile([256]);
|
|
191
|
+
|
|
192
|
+
expect(profiles[0].baselineMemoryBytes).toBeGreaterThanOrEqual(0);
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
it('should calculate memory reduction', () => {
|
|
196
|
+
const profiles = runner.runMemoryProfile([256]);
|
|
197
|
+
|
|
198
|
+
expect(profiles[0].reduction).toBeGreaterThanOrEqual(0);
|
|
199
|
+
expect(profiles[0].reductionBytes).toBeGreaterThanOrEqual(0);
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
it('should include number of keys', () => {
|
|
203
|
+
const profiles = runner.runMemoryProfile([512]);
|
|
204
|
+
|
|
205
|
+
expect(profiles[0].numKeys).toBeGreaterThan(0);
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
it('should handle custom dimension arrays', () => {
|
|
209
|
+
const customDims = [64, 128, 256, 512, 1024];
|
|
210
|
+
const profiles = runner.runMemoryProfile(customDims);
|
|
211
|
+
|
|
212
|
+
expect(profiles.length).toBe(customDims.length);
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
describe('runStressTest()', () => {
|
|
217
|
+
it('should run stress test successfully', () => {
|
|
218
|
+
const results = runner.runStressTest();
|
|
219
|
+
|
|
220
|
+
expect(results).toBeDefined();
|
|
221
|
+
expect(results.length).toBeGreaterThan(0);
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
it('should test increasing loads', () => {
|
|
225
|
+
const results = runner.runStressTest();
|
|
226
|
+
|
|
227
|
+
// Should test progressively larger key counts
|
|
228
|
+
const keyCounts = results.map(r => r.numKeys);
|
|
229
|
+
|
|
230
|
+
for (let i = 1; i < keyCounts.length; i++) {
|
|
231
|
+
expect(keyCounts[i]).toBeGreaterThanOrEqual(keyCounts[i - 1]);
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
it('should maintain same dimension', () => {
|
|
236
|
+
const results = runner.runStressTest();
|
|
237
|
+
|
|
238
|
+
const dimensions = results.map(r => r.dimension);
|
|
239
|
+
const uniqueDims = new Set(dimensions);
|
|
240
|
+
|
|
241
|
+
// All stress tests should use same dimension (512)
|
|
242
|
+
expect(uniqueDims.size).toBe(1);
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
it('should handle high key counts', () => {
|
|
246
|
+
const results = runner.runStressTest();
|
|
247
|
+
|
|
248
|
+
// Should test up to 5000 keys
|
|
249
|
+
const maxKeys = Math.max(...results.map(r => r.numKeys));
|
|
250
|
+
expect(maxKeys).toBeGreaterThan(1000);
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
it('should not throw on stress conditions', () => {
|
|
254
|
+
expect(() => runner.runStressTest()).not.toThrow();
|
|
255
|
+
});
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
describe('validateV3Targets()', () => {
|
|
259
|
+
it('should validate V3 performance targets', () => {
|
|
260
|
+
const validation = runner.validateV3Targets();
|
|
261
|
+
|
|
262
|
+
expect(validation).toBeDefined();
|
|
263
|
+
expect(validation.meetsMinimum).toBeDefined();
|
|
264
|
+
expect(validation.meetsMaximum).toBeDefined();
|
|
265
|
+
expect(validation.actualSpeedup).toBeDefined();
|
|
266
|
+
expect(validation.target).toBeDefined();
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
it('should check minimum target (2.49x)', () => {
|
|
270
|
+
const validation = runner.validateV3Targets();
|
|
271
|
+
|
|
272
|
+
expect(validation.target.min).toBe(2.49);
|
|
273
|
+
expect(validation.meetsMinimum).toBe(validation.actualSpeedup >= 2.49);
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
it('should check maximum target (7.47x)', () => {
|
|
277
|
+
const validation = runner.validateV3Targets();
|
|
278
|
+
|
|
279
|
+
expect(validation.target.max).toBe(7.47);
|
|
280
|
+
expect(validation.meetsMaximum).toBe(validation.actualSpeedup <= 7.47);
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
it('should return valid speedup value', () => {
|
|
284
|
+
const validation = runner.validateV3Targets();
|
|
285
|
+
|
|
286
|
+
expect(validation.actualSpeedup).toBeGreaterThan(0);
|
|
287
|
+
expect(validation.actualSpeedup).toBeLessThan(1000); // Sanity check
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
it('should use 512 dimension for validation', () => {
|
|
291
|
+
// Default dimension for V3 validation should be 512
|
|
292
|
+
const validation = runner.validateV3Targets();
|
|
293
|
+
|
|
294
|
+
expect(validation.actualSpeedup).toBeGreaterThan(0);
|
|
295
|
+
});
|
|
296
|
+
});
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
describe('Formatting Functions', () => {
|
|
300
|
+
describe('formatBenchmarkTable()', () => {
|
|
301
|
+
it('should format benchmark as table', () => {
|
|
302
|
+
const runner = new AttentionBenchmarkRunner();
|
|
303
|
+
const benchmark = runner.runComparison(256, 50, 100);
|
|
304
|
+
|
|
305
|
+
const table = formatBenchmarkTable(benchmark);
|
|
306
|
+
|
|
307
|
+
expect(table).toBeDefined();
|
|
308
|
+
expect(typeof table).toBe('string');
|
|
309
|
+
expect(table).toContain('Flash Attention');
|
|
310
|
+
expect(table).toContain('Baseline');
|
|
311
|
+
expect(table).toContain('Speedup');
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
it('should include target status', () => {
|
|
315
|
+
const runner = new AttentionBenchmarkRunner();
|
|
316
|
+
const benchmark = runner.runComparison(256, 50, 100);
|
|
317
|
+
|
|
318
|
+
const table = formatBenchmarkTable(benchmark);
|
|
319
|
+
|
|
320
|
+
expect(table).toContain('Target Met');
|
|
321
|
+
expect(table).toMatch(/YES|NO/);
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
it('should show checkmark for met targets', () => {
|
|
325
|
+
const runner = new AttentionBenchmarkRunner();
|
|
326
|
+
const benchmark = runner.runComparison(512, 100, 1000);
|
|
327
|
+
|
|
328
|
+
const table = formatBenchmarkTable(benchmark);
|
|
329
|
+
|
|
330
|
+
if (benchmark.meetsTarget) {
|
|
331
|
+
expect(table).toContain('✓');
|
|
332
|
+
} else {
|
|
333
|
+
expect(table).toContain('✗');
|
|
334
|
+
}
|
|
335
|
+
});
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
describe('formatSuiteReport()', () => {
|
|
339
|
+
it('should format suite as report', () => {
|
|
340
|
+
const runner = new AttentionBenchmarkRunner();
|
|
341
|
+
const suite = runner.runComprehensiveSuite();
|
|
342
|
+
|
|
343
|
+
const report = formatSuiteReport(suite);
|
|
344
|
+
|
|
345
|
+
expect(report).toBeDefined();
|
|
346
|
+
expect(typeof report).toBe('string');
|
|
347
|
+
expect(report).toContain('Summary');
|
|
348
|
+
expect(report).toContain('Average Speedup');
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
it('should include all benchmarks', () => {
|
|
352
|
+
const runner = new AttentionBenchmarkRunner();
|
|
353
|
+
const suite = runner.runComprehensiveSuite();
|
|
354
|
+
|
|
355
|
+
const report = formatSuiteReport(suite);
|
|
356
|
+
|
|
357
|
+
for (const benchmark of suite.benchmarks) {
|
|
358
|
+
expect(report).toContain(benchmark.name);
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
it('should show summary statistics', () => {
|
|
363
|
+
const runner = new AttentionBenchmarkRunner();
|
|
364
|
+
const suite = runner.runComprehensiveSuite();
|
|
365
|
+
|
|
366
|
+
const report = formatSuiteReport(suite);
|
|
367
|
+
|
|
368
|
+
expect(report).toContain('Min Speedup');
|
|
369
|
+
expect(report).toContain('Max Speedup');
|
|
370
|
+
expect(report).toContain('Targets Met');
|
|
371
|
+
});
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
describe('formatMemoryProfile()', () => {
|
|
375
|
+
it('should format memory profile as table', () => {
|
|
376
|
+
const runner = new AttentionBenchmarkRunner();
|
|
377
|
+
const profiles = runner.runMemoryProfile([256, 512]);
|
|
378
|
+
|
|
379
|
+
const table = formatMemoryProfile(profiles);
|
|
380
|
+
|
|
381
|
+
expect(table).toBeDefined();
|
|
382
|
+
expect(typeof table).toBe('string');
|
|
383
|
+
expect(table).toContain('Memory Profile');
|
|
384
|
+
expect(table).toContain('Flash');
|
|
385
|
+
expect(table).toContain('Baseline');
|
|
386
|
+
expect(table).toContain('Reduction');
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
it('should include all dimensions', () => {
|
|
390
|
+
const dimensions = [128, 256, 512];
|
|
391
|
+
const runner = new AttentionBenchmarkRunner();
|
|
392
|
+
const profiles = runner.runMemoryProfile(dimensions);
|
|
393
|
+
|
|
394
|
+
const table = formatMemoryProfile(profiles);
|
|
395
|
+
|
|
396
|
+
for (const dim of dimensions) {
|
|
397
|
+
expect(table).toContain(dim.toString());
|
|
398
|
+
}
|
|
399
|
+
});
|
|
400
|
+
});
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
describe('quickValidation()', () => {
|
|
404
|
+
it('should run quick validation', () => {
|
|
405
|
+
const result = quickValidation();
|
|
406
|
+
|
|
407
|
+
expect(typeof result).toBe('boolean');
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
it('should return true if meets targets', () => {
|
|
411
|
+
const runner = new AttentionBenchmarkRunner();
|
|
412
|
+
const validation = runner.validateV3Targets();
|
|
413
|
+
|
|
414
|
+
const result = quickValidation();
|
|
415
|
+
|
|
416
|
+
const expected = validation.meetsMinimum && validation.meetsMaximum;
|
|
417
|
+
expect(result).toBe(expected);
|
|
418
|
+
});
|
|
419
|
+
});
|
|
420
|
+
|
|
421
|
+
describe('Performance Validation', () => {
|
|
422
|
+
it('should demonstrate consistent speedup', () => {
|
|
423
|
+
const runner = new AttentionBenchmarkRunner();
|
|
424
|
+
|
|
425
|
+
const result1 = runner.runComparison(256, 50, 100);
|
|
426
|
+
const result2 = runner.runComparison(256, 50, 100);
|
|
427
|
+
|
|
428
|
+
// Speedup should be relatively consistent (within 50% variance)
|
|
429
|
+
const ratio = result1.results.speedup / result2.results.speedup;
|
|
430
|
+
expect(ratio).toBeGreaterThan(0.5);
|
|
431
|
+
expect(ratio).toBeLessThan(2.0);
|
|
432
|
+
});
|
|
433
|
+
|
|
434
|
+
it('should show improved performance with Flash Attention', () => {
|
|
435
|
+
const runner = new AttentionBenchmarkRunner();
|
|
436
|
+
const result = runner.runComparison(512, 100, 1000);
|
|
437
|
+
|
|
438
|
+
// Flash should generally be faster, but allow small variance
|
|
439
|
+
// Due to timing precision and JIT warmup, we check speedup is positive
|
|
440
|
+
expect(result.results.speedup).toBeGreaterThan(0.5); // At least some speedup
|
|
441
|
+
});
|
|
442
|
+
|
|
443
|
+
it('should validate across all test dimensions', () => {
|
|
444
|
+
const runner = new AttentionBenchmarkRunner();
|
|
445
|
+
const suite = runner.runComprehensiveSuite();
|
|
446
|
+
|
|
447
|
+
// All benchmarks should have positive speedup
|
|
448
|
+
for (const benchmark of suite.benchmarks) {
|
|
449
|
+
expect(benchmark.results.speedup).toBeGreaterThan(0);
|
|
450
|
+
}
|
|
451
|
+
});
|
|
452
|
+
|
|
453
|
+
it('should track operations per second correctly', () => {
|
|
454
|
+
const runner = new AttentionBenchmarkRunner();
|
|
455
|
+
const result = runner.runComparison(256, 50, 100);
|
|
456
|
+
|
|
457
|
+
// Ops/sec should be inverse of average time
|
|
458
|
+
const expectedFlashOps = 1000 / result.results.flash.averageTimeMs;
|
|
459
|
+
const expectedBaselineOps = 1000 / result.results.baseline.averageTimeMs;
|
|
460
|
+
|
|
461
|
+
expect(result.results.flash.opsPerSecond).toBeCloseTo(expectedFlashOps, 1);
|
|
462
|
+
expect(result.results.baseline.opsPerSecond).toBeCloseTo(expectedBaselineOps, 1);
|
|
463
|
+
});
|
|
464
|
+
});
|
|
465
|
+
|
|
466
|
+
describe('Edge Cases', () => {
|
|
467
|
+
it('should handle very small dimensions', () => {
|
|
468
|
+
const runner = new AttentionBenchmarkRunner();
|
|
469
|
+
const result = runner.runComparison(32, 10, 50);
|
|
470
|
+
|
|
471
|
+
expect(result).toBeDefined();
|
|
472
|
+
expect(result.results.speedup).toBeGreaterThan(0);
|
|
473
|
+
});
|
|
474
|
+
|
|
475
|
+
it('should handle very large dimensions', () => {
|
|
476
|
+
const runner = new AttentionBenchmarkRunner();
|
|
477
|
+
const result = runner.runComparison(2048, 50, 50);
|
|
478
|
+
|
|
479
|
+
expect(result).toBeDefined();
|
|
480
|
+
expect(result.results.speedup).toBeGreaterThan(0);
|
|
481
|
+
});
|
|
482
|
+
|
|
483
|
+
it('should handle minimal iterations', () => {
|
|
484
|
+
const runner = new AttentionBenchmarkRunner();
|
|
485
|
+
const result = runner.runComparison(256, 50, 10);
|
|
486
|
+
|
|
487
|
+
expect(result).toBeDefined();
|
|
488
|
+
expect(result.iterations).toBe(10);
|
|
489
|
+
});
|
|
490
|
+
|
|
491
|
+
it('should handle many iterations', () => {
|
|
492
|
+
const runner = new AttentionBenchmarkRunner();
|
|
493
|
+
const result = runner.runComparison(128, 20, 5000);
|
|
494
|
+
|
|
495
|
+
expect(result).toBeDefined();
|
|
496
|
+
expect(result.iterations).toBe(5000);
|
|
497
|
+
});
|
|
498
|
+
|
|
499
|
+
it('should handle empty dimension array for memory profile', () => {
|
|
500
|
+
const runner = new AttentionBenchmarkRunner();
|
|
501
|
+
const profiles = runner.runMemoryProfile([]);
|
|
502
|
+
|
|
503
|
+
expect(profiles).toBeDefined();
|
|
504
|
+
expect(profiles.length).toBe(0);
|
|
505
|
+
});
|
|
506
|
+
|
|
507
|
+
it('should handle single dimension for memory profile', () => {
|
|
508
|
+
const runner = new AttentionBenchmarkRunner();
|
|
509
|
+
const profiles = runner.runMemoryProfile([512]);
|
|
510
|
+
|
|
511
|
+
expect(profiles).toBeDefined();
|
|
512
|
+
expect(profiles.length).toBe(1);
|
|
513
|
+
expect(profiles[0].dimension).toBe(512);
|
|
514
|
+
});
|
|
515
|
+
});
|