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/numeric/RequantizeInt8.lvt

namespace Livt.ML.Numeric

using Livt.Math.Arithmetic

/**
 * Runtime division is scheduled; completion latency increases with work.
 * Serialize operations and keep inputs stable until the call or handshake completes.
 *
 * Requantizes an integer accumulator into signed int8 range.
 *
 * Division rounds to nearest with exact ties going to the even result. The
 * output zero point is added after rounding and the result is saturated to
 * [-128, 127]. A non-positive divisor returns the clamped output zero point.
 */
component RequantizeInt8
{
	// Owned divider; calls complete before this component advances.
	divider: IntegerDivision<32>

	// Minimum value represented by a signed int8 tensor element.
	public const MIN_VALUE: int = -128

	// Maximum value represented by a signed int8 tensor element.
	public const MAX_VALUE: int = 127

	/**
	 * Owns the scheduled arithmetic worker; serialize public operations.
	 */
	new()
	{
		divider = new IntegerDivision<32>()
	}

	/**
	 * Divides value by divisor, adds outputZeroPoint, and clamps to int8.
	 */
	public fn Apply(value: int, divisor: int, outputZeroPoint: int) int
	{
		if (divisor <= 0) {
			return this.Clamp(outputZeroPoint)
		}

		var negative = value < 0
		var magnitude = value

		if (negative) {
			magnitude = 0 - value
		}

		divider.Compute(magnitude, divisor)
		var quotient = divider.GetQuotient()
		var remainder = divider.GetRemainder()
		var doubledRemainder = remainder * 2

		if (doubledRemainder > divisor) {
			quotient++
		}

		if (doubledRemainder == divisor) {
			var quotientParity = quotient % 2

			if (quotientParity != 0) {
				quotient++
			}
		}

		var rounded = quotient

		if (negative) {
			rounded = 0 - quotient
		}

		var shifted = rounded + outputZeroPoint
		return this.Clamp(shifted)
	}

	/**
	 * Clamps value into the signed int8 range.
	 */
	fn Clamp(value: int) int
	{
		if (value < MIN_VALUE) {
			return MIN_VALUE
		}

		if (value > MAX_VALUE) {
			return MAX_VALUE
		}

		return value
	}
}