Merge commit 'd803bfe2b1fe7f5e219e50ac20d6801a0a58ac75' as 'vendor/ruvector'

This commit is contained in:
ruv
2026-02-28 14:39:40 -05:00
7854 changed files with 3522914 additions and 0 deletions

View File

@@ -0,0 +1,516 @@
/**
* Learning Module Lifecycle Simulation Tests
* Tests pattern storage, trajectory recording, spike attention, and multi-head routing
*/
const assert = require('assert');
// Mock WASM module for testing
const createMockLearning = () => ({
ReasoningBank: class {
constructor() {
this.patterns = new Map();
this.nextId = 0;
}
store(patternJson) {
try {
const pattern = JSON.parse(patternJson);
const id = this.nextId++;
this.patterns.set(id, {
pattern,
usageCount: 0,
lastUsed: Date.now()
});
return id;
} catch {
return -1;
}
}
lookup(queryJson, k) {
try {
const query = JSON.parse(queryJson);
const results = [];
for (const [id, entry] of this.patterns.entries()) {
const similarity = this.cosineSimilarity(query, entry.pattern.centroid);
results.push({
id,
similarity,
confidence: entry.pattern.confidence,
optimal_allocation: entry.pattern.optimal_allocation,
optimal_energy: entry.pattern.optimal_energy
});
}
results.sort((a, b) => (b.similarity * b.confidence) - (a.similarity * a.confidence));
return JSON.stringify(results.slice(0, k));
} catch {
return '[]';
}
}
cosineSimilarity(a, b) {
if (a.length !== b.length) return 0;
let dot = 0, normA = 0, normB = 0;
for (let i = 0; i < a.length; i++) {
dot += a[i] * b[i];
normA += a[i] * a[i];
normB += b[i] * b[i];
}
normA = Math.sqrt(normA);
normB = Math.sqrt(normB);
return normA === 0 || normB === 0 ? 0 : dot / (normA * normB);
}
prune(minUsage, minConfidence) {
let removed = 0;
for (const [id, entry] of this.patterns.entries()) {
if (entry.usageCount < minUsage || entry.pattern.confidence < minConfidence) {
this.patterns.delete(id);
removed++;
}
}
return removed;
}
count() {
return this.patterns.size;
}
getStats() {
if (this.patterns.size === 0) return '{"total":0}';
const entries = Array.from(this.patterns.values());
const totalSamples = entries.reduce((sum, e) => sum + e.pattern.sample_count, 0);
const avgConfidence = entries.reduce((sum, e) => sum + e.pattern.confidence, 0) / entries.length;
const totalUsage = entries.reduce((sum, e) => sum + e.usageCount, 0);
return JSON.stringify({
total_patterns: this.patterns.size,
total_samples: totalSamples,
avg_confidence: avgConfidence,
total_usage: totalUsage
});
}
},
TrajectoryTracker: class {
constructor(maxSize) {
this.trajectories = [];
this.maxSize = maxSize;
this.writePos = 0;
}
record(trajectoryJson) {
try {
const traj = JSON.parse(trajectoryJson);
if (this.trajectories.length < this.maxSize) {
this.trajectories.push(traj);
} else {
this.trajectories[this.writePos] = traj;
}
this.writePos = (this.writePos + 1) % this.maxSize;
return true;
} catch {
return false;
}
}
getStats() {
if (this.trajectories.length === 0) return '{"total":0}';
const total = this.trajectories.length;
const successful = this.trajectories.filter(t => t.success).length;
const avgLatency = this.trajectories.reduce((sum, t) => sum + t.latency_ms, 0) / total;
const avgEfficiency = this.trajectories.reduce((sum, t) => {
return sum + (t.energy_spent === 0 ? 0 : t.energy_earned / t.energy_spent);
}, 0) / total;
return JSON.stringify({
total,
successful,
success_rate: successful / total,
avg_latency_ms: avgLatency,
avg_efficiency: avgEfficiency
});
}
count() {
return this.trajectories.length;
}
},
SpikeDrivenAttention: class {
energyRatio(seqLen, hiddenDim) {
if (seqLen === 0 || hiddenDim === 0) return 1.0;
const standardMults = 2 * seqLen * seqLen * hiddenDim;
const avgSpikesPerNeuron = 8 * 0.3;
const spikeAdds = seqLen * avgSpikesPerNeuron * hiddenDim;
const multEnergyFactor = 3.7;
const standardEnergy = standardMults * multEnergyFactor;
const spikeEnergy = spikeAdds;
return spikeEnergy === 0 ? 1.0 : standardEnergy / spikeEnergy;
}
},
MultiHeadAttention: class {
constructor(dim, numHeads) {
this.dimValue = dim;
this.numHeadsValue = numHeads;
}
dim() { return this.dimValue; }
numHeads() { return this.numHeadsValue; }
},
NetworkLearning: class {
constructor() {
const mocks = createMockLearning();
this.bank = new mocks.ReasoningBank();
this.tracker = new mocks.TrajectoryTracker(1000);
this.spike = new mocks.SpikeDrivenAttention();
this.attention = new mocks.MultiHeadAttention(64, 4);
}
recordTrajectory(json) { return this.tracker.record(json); }
storePattern(json) { return this.bank.store(json); }
lookupPatterns(json, k) { return this.bank.lookup(json, k); }
getEnergyRatio(seq, hidden) { return this.spike.energyRatio(seq, hidden); }
getStats() {
const bankStats = this.bank.getStats();
const trajStats = this.tracker.getStats();
const energyRatio = this.spike.energyRatio(64, 256);
return JSON.stringify({
reasoning_bank: JSON.parse(bankStats),
trajectories: JSON.parse(trajStats),
spike_energy_ratio: energyRatio,
learning_rate: 0.01
});
}
trajectoryCount() { return this.tracker.count(); }
patternCount() { return this.bank.count(); }
prune(minUsage, minConf) { return this.bank.prune(minUsage, minConf); }
}
});
/**
* Test 1: Pattern Storage and Retrieval Cycles
*/
function testPatternStorageRetrieval() {
console.log('\n=== Test 1: Pattern Storage and Retrieval Cycles ===');
const wasm = createMockLearning();
const learning = new wasm.NetworkLearning();
const patterns = [
{
centroid: [1.0, 0.0, 0.0],
optimal_allocation: 0.8,
optimal_energy: 100,
confidence: 0.9,
sample_count: 10,
avg_latency_ms: 50.0,
avg_success_rate: 0.95
},
{
centroid: [0.0, 1.0, 0.0],
optimal_allocation: 0.7,
optimal_energy: 120,
confidence: 0.85,
sample_count: 8,
avg_latency_ms: 60.0,
avg_success_rate: 0.90
},
{
centroid: [0.707, 0.707, 0.0],
optimal_allocation: 0.75,
optimal_energy: 110,
confidence: 0.88,
sample_count: 9,
avg_latency_ms: 55.0,
avg_success_rate: 0.92
}
];
// Store patterns
const ids = patterns.map(p => learning.storePattern(JSON.stringify(p)));
console.log(`✓ Stored ${ids.length} patterns`);
assert.strictEqual(learning.patternCount(), 3);
// Lookup similar patterns
const query = [0.9, 0.1, 0.0];
const results = JSON.parse(learning.lookupPatterns(JSON.stringify(query), 2));
console.log(`✓ Retrieved ${results.length} similar patterns`);
assert.strictEqual(results.length, 2);
assert.ok(results[0].similarity > results[1].similarity);
// Verify pattern quality
const stats = JSON.parse(learning.getStats());
console.log(`✓ Pattern bank stats:`, stats.reasoning_bank);
assert.strictEqual(stats.reasoning_bank.total_patterns, 3);
assert.ok(stats.reasoning_bank.avg_confidence > 0.8);
console.log('✅ Pattern Storage and Retrieval Test PASSED');
return {
patterns_stored: ids.length,
retrieval_accuracy: results[0].similarity,
avg_confidence: stats.reasoning_bank.avg_confidence
};
}
/**
* Test 2: Trajectory Recording and Analysis
*/
function testTrajectoryRecording() {
console.log('\n=== Test 2: Trajectory Recording and Analysis ===');
const wasm = createMockLearning();
const learning = new wasm.NetworkLearning();
// Record diverse trajectories
const trajectories = [];
for (let i = 0; i < 100; i++) {
const success = Math.random() > 0.2; // 80% success rate
const traj = {
task_vector: Array(16).fill(0).map(() => Math.random()),
latency_ms: 50 + Math.random() * 100,
energy_spent: 50 + Math.floor(Math.random() * 50),
energy_earned: success ? 100 + Math.floor(Math.random() * 50) : 0,
success,
executor_id: `node-${i % 10}`,
timestamp: Date.now() + i * 1000
};
trajectories.push(traj);
learning.recordTrajectory(JSON.stringify(traj));
}
console.log(`✓ Recorded ${trajectories.length} trajectories`);
assert.strictEqual(learning.trajectoryCount(), 100);
// Analyze statistics
const stats = JSON.parse(learning.getStats());
const trajStats = stats.trajectories;
console.log(`✓ Trajectory stats:`, trajStats);
assert.ok(trajStats.success_rate > 0.7);
assert.ok(trajStats.avg_latency_ms > 50 && trajStats.avg_latency_ms < 150);
assert.ok(trajStats.avg_efficiency > 1.0);
console.log('✅ Trajectory Recording Test PASSED');
return {
total_trajectories: trajStats.total,
success_rate: trajStats.success_rate,
avg_efficiency: trajStats.avg_efficiency
};
}
/**
* Test 3: Spike-Driven Attention Energy Efficiency
*/
function testSpikeAttentionEnergy() {
console.log('\n=== Test 3: Spike-Driven Attention Energy Efficiency ===');
const wasm = createMockLearning();
const learning = new wasm.NetworkLearning();
const testCases = [
{ seqLen: 64, hiddenDim: 256, expectedMin: 50, expectedMax: 250 },
{ seqLen: 128, hiddenDim: 512, expectedMin: 70, expectedMax: 500 },
{ seqLen: 32, hiddenDim: 128, expectedMin: 40, expectedMax: 150 }
];
const results = testCases.map(tc => {
const ratio = learning.getEnergyRatio(tc.seqLen, tc.hiddenDim);
console.log(`✓ Seq=${tc.seqLen}, Hidden=${tc.hiddenDim}: ${ratio.toFixed(2)}x energy savings`);
assert.ok(ratio >= tc.expectedMin, `Expected >= ${tc.expectedMin}, got ${ratio}`);
assert.ok(ratio <= tc.expectedMax, `Expected <= ${tc.expectedMax}, got ${ratio}`);
return { seqLen: tc.seqLen, hiddenDim: tc.hiddenDim, ratio };
});
// Verify edge cases
const emptyRatio = learning.getEnergyRatio(0, 0);
assert.strictEqual(emptyRatio, 1.0);
console.log('✓ Empty case handled correctly');
console.log('✅ Spike Attention Energy Test PASSED');
return { energy_savings: results };
}
/**
* Test 4: Multi-Head Attention Task Routing
*/
function testMultiHeadRouting() {
console.log('\n=== Test 4: Multi-Head Attention Task Routing ===');
const wasm = createMockLearning();
const attention = new wasm.MultiHeadAttention(64, 4);
assert.strictEqual(attention.dim(), 64);
assert.strictEqual(attention.numHeads(), 4);
console.log(`✓ Multi-head attention: ${attention.numHeads()} heads, ${attention.dim()} dims`);
// Test different configurations
const configs = [
{ dim: 128, heads: 8 },
{ dim: 256, heads: 16 },
{ dim: 512, heads: 32 }
];
configs.forEach(cfg => {
const attn = new wasm.MultiHeadAttention(cfg.dim, cfg.heads);
assert.strictEqual(attn.dim(), cfg.dim);
assert.strictEqual(attn.numHeads(), cfg.heads);
console.log(`✓ Config validated: ${cfg.heads} heads x ${cfg.dim} dims`);
});
console.log('✅ Multi-Head Routing Test PASSED');
return { configurations_tested: configs.length };
}
/**
* Test 5: Pattern Pruning and Memory Management
*/
function testPatternPruning() {
console.log('\n=== Test 5: Pattern Pruning and Memory Management ===');
const wasm = createMockLearning();
const learning = new wasm.NetworkLearning();
// Store high and low quality patterns
const patterns = [
{ centroid: [1, 0, 0], optimal_allocation: 0.9, optimal_energy: 100, confidence: 0.95, sample_count: 20, avg_latency_ms: 50, avg_success_rate: 0.98 },
{ centroid: [0, 1, 0], optimal_allocation: 0.5, optimal_energy: 100, confidence: 0.4, sample_count: 2, avg_latency_ms: 200, avg_success_rate: 0.5 },
{ centroid: [0, 0, 1], optimal_allocation: 0.3, optimal_energy: 100, confidence: 0.3, sample_count: 1, avg_latency_ms: 300, avg_success_rate: 0.3 }
];
patterns.forEach(p => learning.storePattern(JSON.stringify(p)));
console.log(`✓ Stored ${learning.patternCount()} patterns (mixed quality)`);
// Prune low quality patterns
const pruned = learning.prune(5, 0.5);
console.log(`✓ Pruned ${pruned} low-quality patterns`);
assert.ok(pruned >= 1);
assert.ok(learning.patternCount() < patterns.length);
console.log('✅ Pattern Pruning Test PASSED');
return { patterns_pruned: pruned, patterns_remaining: learning.patternCount() };
}
/**
* Test 6: High-Throughput Learning Pipeline
*/
function testHighThroughputLearning() {
console.log('\n=== Test 6: High-Throughput Learning Pipeline ===');
const wasm = createMockLearning();
const learning = new wasm.NetworkLearning();
const startTime = Date.now();
// Simulate high-throughput scenario
const trajCount = 1000;
const patternCount = 100;
for (let i = 0; i < trajCount; i++) {
learning.recordTrajectory(JSON.stringify({
task_vector: [Math.random(), Math.random(), Math.random()],
latency_ms: 50 + Math.random() * 50,
energy_spent: 50,
energy_earned: Math.random() > 0.2 ? 100 : 0,
success: Math.random() > 0.2,
executor_id: `node-${i % 10}`,
timestamp: Date.now() + i
}));
}
for (let i = 0; i < patternCount; i++) {
learning.storePattern(JSON.stringify({
centroid: [Math.random(), Math.random(), Math.random()],
optimal_allocation: 0.5 + Math.random() * 0.5,
optimal_energy: 100,
confidence: 0.5 + Math.random() * 0.5,
sample_count: 5 + Math.floor(Math.random() * 15),
avg_latency_ms: 50 + Math.random() * 100,
avg_success_rate: 0.7 + Math.random() * 0.3
}));
}
const duration = Date.now() - startTime;
const throughput = (trajCount + patternCount) / (duration / 1000);
console.log(`✓ Processed ${trajCount} trajectories + ${patternCount} patterns in ${duration}ms`);
console.log(`✓ Throughput: ${throughput.toFixed(2)} ops/sec`);
assert.strictEqual(learning.trajectoryCount(), trajCount);
assert.strictEqual(learning.patternCount(), patternCount);
console.log('✅ High-Throughput Learning Test PASSED');
return { throughput_ops_per_sec: throughput, duration_ms: duration };
}
/**
* Run all learning lifecycle tests
*/
function runLearningTests() {
console.log('\n╔══════════════════════════════════════════════════════╗');
console.log('║ Learning Module Lifecycle Simulation Tests ║');
console.log('╚══════════════════════════════════════════════════════╝');
const results = {
timestamp: new Date().toISOString(),
test_suite: 'learning_lifecycle',
tests: {}
};
try {
results.tests.pattern_storage = testPatternStorageRetrieval();
results.tests.trajectory_recording = testTrajectoryRecording();
results.tests.spike_attention = testSpikeAttentionEnergy();
results.tests.multi_head_routing = testMultiHeadRouting();
results.tests.pattern_pruning = testPatternPruning();
results.tests.high_throughput = testHighThroughputLearning();
results.summary = {
total_tests: 6,
passed: 6,
failed: 0,
success_rate: 1.0
};
console.log('\n╔══════════════════════════════════════════════════════╗');
console.log('║ All Learning Lifecycle Tests PASSED ✅ ║');
console.log('╚══════════════════════════════════════════════════════╝\n');
} catch (error) {
console.error('\n❌ Test failed:', error.message);
console.error(error.stack);
results.summary = { total_tests: 6, passed: 0, failed: 1, error: error.message };
process.exit(1);
}
return results;
}
// Run if called directly
if (require.main === module) {
const results = runLearningTests();
const fs = require('fs');
fs.writeFileSync(
'./reports/learning-lifecycle-results.json',
JSON.stringify(results, null, 2)
);
console.log('📊 Results saved to: reports/learning-lifecycle-results.json');
}
module.exports = { runLearningTests, createMockLearning };