Livt packages

Livt.ML

Version 1.6.1

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

Published files (132)

src/activation/GeluNewApproxQ8.lvt

namespace Livt.ML.Activation

/**
 * Approximates GPT-Neo gelu_new for Q8.8 values.
 *
 * A 0.25-spaced lookup covers [-4, 4] and linear interpolation covers values
 * between entries. More-negative values return zero and more-positive values
 * pass through, matching GELU's saturated tails.
 */
component GeluNewApproxQ8
{
	// Compile-time dimensions, bounds, and numeric constants.
	public const SCALE: int = 256
	const STEP: int = 64
	const LAST_INDEX: int = 32

	// Owned approximation table in the component numeric scale.
	lut: int[33]

	/**
	 * Loads the owned quarter-step Q8.8 GELU approximation table.
	 */
	new()
	{
		lut[0] = 0
		lut[1] = 0
		lut[2] = 0
		lut[3] = 0
		lut[4] = -1
		lut[5] = -2
		lut[6] = -4
		lut[7] = -7
		lut[8] = -12
		lut[9] = -18
		lut[10] = -26
		lut[11] = -34
		lut[12] = -41
		lut[13] = -44
		lut[14] = -39
		lut[15] = -26
		lut[16] = 0
		lut[17] = 38
		lut[18] = 89
		lut[19] = 148
		lut[20] = 215
		lut[21] = 286
		lut[22] = 358
		lut[23] = 430
		lut[24] = 500
		lut[25] = 569
		lut[26] = 636
		lut[27] = 702
		lut[28] = 767
		lut[29] = 832
		lut[30] = 896
		lut[31] = 960
		lut[32] = 1024
	}

	/**
	 * Applies the Q8.8 GELU-new approximation.
	 */
	public fn Apply(input: int) int
	{
		if (input <= -1024) {
			return 0
		}

		if (input >= 1024) {
			return input
		}

		var shifted = input + 1024
		var index = shifted >> 6
		var remainder = shifted & 63
		var lower = lut[index]
		var upper = lut[index + 1]
		var interpolation = (upper - lower) * remainder

		state {
		}

		// Signed division truncates toward zero, whereas an arithmetic right
		// shift rounds negative values toward minus infinity. Correct the shifted
		// quotient when discarded negative bits are non-zero so this retains the
		// original `/ STEP` numerical behavior without inferring a divider.
		var interpolationQuotient = interpolation >> 6

		if (interpolation < 0 && (interpolation & 63) != 0) {
			interpolationQuotient++
		}

		return lower + interpolationQuotient
	}
}