Livt packages

Livt.ML

Version 1.6.1

Fixed-size quantized inference, tensor storage, attention, and transformer building blocks for Livt.

Published files (132)

tests/linear/MatrixVectorMultiplicationTest.lvt

namespace Livt.ML.Tests.Linear

using Livt.ML.Linear

/**
 * Exercises MatrixVectorMultiplication with a shared fixture instance. Each scenario
 * establishes the inputs and state it needs.
 */
@Test
component MatrixVectorMultiplicationTest
{
	// Shared fixture instances, signals, and observation state.
	mv: MatrixVectorMultiplication

	/**
	 * Creates the shared fixture instances (MatrixVectorMultiplication). Tests initialize the
	 * state required by their scenario.
	 */
	new()
	{
		mv = new MatrixVectorMultiplication()
	}

	/**
	 * Checks that zero weights produce zero output.
	 */
	@Test
	fn ZeroWeightsGiveZeroOutput()
	{
		mv.SetRowValues(0, 0, 0, 0, 0, 0, 0, 0, 0)
		mv.SetRowValues(1, 0, 0, 0, 0, 0, 0, 0, 0)
		mv.SetRowValues(2, 0, 0, 0, 0, 0, 0, 0, 0)
		mv.SetRowValues(3, 0, 0, 0, 0, 0, 0, 0, 0)

		var input: int[8] = [1, 2, 3, 4, 5, 6, 7, 8]

		mv.Compute(input)

		assert mv.GetOutput(0) == 0
		assert mv.GetOutput(1) == 0
		assert mv.GetOutput(2) == 0
		assert mv.GetOutput(3) == 0
	}

	/**
	 * Checks that identity rows select their corresponding input elements.
	 */
	@Test
	fn IdentityRowsExtractInputs()
	{
		mv.SetRowValues(0, 1, 0, 0, 0, 0, 0, 0, 0)
		mv.SetRowValues(1, 0, 1, 0, 0, 0, 0, 0, 0)
		mv.SetRowValues(2, 0, 0, 1, 0, 0, 0, 0, 0)
		mv.SetRowValues(3, 0, 0, 0, 1, 0, 0, 0, 0)

		var input: int[8] = [10, 20, 30, 40, 50, 60, 70, 80]

		mv.Compute(input)

		assert mv.GetOutput(0) == 10
		assert mv.GetOutput(1) == 20
		assert mv.GetOutput(2) == 30
		assert mv.GetOutput(3) == 40
	}

	/**
	 * Checks the uniform rows scale sums case.
	 */
	@Test
	fn UniformRowsScaleSums()
	{
		mv.SetRowValues(0, 1, 1, 1, 1, 1, 1, 1, 1)
		mv.SetRowValues(1, 2, 2, 2, 2, 2, 2, 2, 2)
		mv.SetRowValues(2, 3, 3, 3, 3, 3, 3, 3, 3)
		mv.SetRowValues(3, 4, 4, 4, 4, 4, 4, 4, 4)

		var input: int[8] = [1, 1, 1, 1, 1, 1, 1, 1]

		mv.Compute(input)

		assert mv.GetOutput(0) == 8
		assert mv.GetOutput(1) == 16
		assert mv.GetOutput(2) == 24
		assert mv.GetOutput(3) == 32
	}

	/**
	 * Checks that the component supports array row setter.
	 */
	@Test
	fn SupportsArrayRowSetter()
	{
		var weights: int[8] = [5, 0, 0, 0, 0, 0, 0, 0]
		var input: int[8] = [3, 0, 0, 0, 0, 0, 0, 0]

		mv.SetRow(0, weights)
		mv.SetRow(99, weights)
		mv.Compute(input)

		assert mv.GetOutput(0) == 15
		assert mv.GetOutput(99) == 0
	}

	/**
	 * Checks that the component saturates outputs.
	 */
	@Test
	fn SaturatesOutputs()
	{
		mv.SetRowValues(0, 100, 100, 100, 100, 100, 100, 100, 100)

		var input: int[8] = [100, 100, 100, 100, 100, 100, 100, 100]

		mv.Compute(input)

		assert mv.GetOutput(0) == DotProduct.ACC_MAX
	}
}