50 lines
1.9 KiB
TypeScript
50 lines
1.9 KiB
TypeScript
|
|
import { expect, test } from 'bun:test';
|
||
|
|
import type { MLArchitecture } from '../src/engine/types';
|
||
|
|
import {
|
||
|
|
completeDimensionMap,
|
||
|
|
remapFlatWeights,
|
||
|
|
remapVector,
|
||
|
|
resizeTarget,
|
||
|
|
} from '../src/engine/io-reshape';
|
||
|
|
|
||
|
|
function arch(inputSize: number, outputSize: number): MLArchitecture {
|
||
|
|
return { inputSize, hidden: [2, 2, 2], outputSize, numLayers: 4, maxExamples: 8 };
|
||
|
|
}
|
||
|
|
|
||
|
|
test('capacity policy only reconstructs when active I/O exceeds capacity', () => {
|
||
|
|
expect(resizeTarget(2, 8, 'capacity')).toBeNull();
|
||
|
|
expect(resizeTarget(9, 8, 'capacity')).toBe(9);
|
||
|
|
expect(resizeTarget(2, 8, 'exact')).toBe(2);
|
||
|
|
expect(resizeTarget(8, 8, 'exact')).toBeNull();
|
||
|
|
});
|
||
|
|
|
||
|
|
test('a middle deletion keeps surviving identities and moves unused slots to the tail', () => {
|
||
|
|
expect(completeDimensionMap([0, 2], 4, 4)).toEqual([0, 2, 1, 3]);
|
||
|
|
});
|
||
|
|
|
||
|
|
test('example vectors remove deleted dimensions and fill additions with placeholders', () => {
|
||
|
|
expect(Array.from(remapVector([10, 20, 30], [0, 2], 2, -1))).toEqual([10, 30]);
|
||
|
|
expect(Array.from(remapVector([10, 20], [0, null, 1], 3, 0.5))).toEqual([10, 0.5, 20]);
|
||
|
|
});
|
||
|
|
|
||
|
|
test('weight remap preserves an arbitrary output row and bias by identity', () => {
|
||
|
|
const oldArch = arch(2, 3);
|
||
|
|
const newArch = arch(2, 2);
|
||
|
|
// 4 layers: weights 4 + 4 + 4 + 6, then biases 2 + 2 + 2 + 3 = 27.
|
||
|
|
const oldWeights = Float32Array.from({ length: 27 }, (_, i) => i + 1);
|
||
|
|
const freshWeights = new Float32Array(24).fill(-1);
|
||
|
|
const remapped = remapFlatWeights(
|
||
|
|
oldWeights,
|
||
|
|
oldArch,
|
||
|
|
freshWeights,
|
||
|
|
newArch,
|
||
|
|
undefined,
|
||
|
|
[0, 2],
|
||
|
|
);
|
||
|
|
// Final-layer weights begin at 12. Old rows: [13,14], [15,16], [17,18].
|
||
|
|
expect(Array.from(remapped.slice(12, 16))).toEqual([13, 14, 17, 18]);
|
||
|
|
// Destination output biases are the final two entries; old output biases
|
||
|
|
// are [25,26,27], so output identity 2 must retain 27 rather than 26.
|
||
|
|
expect(Array.from(remapped.slice(22, 24))).toEqual([25, 27]);
|
||
|
|
});
|