Maned

Quantization in practice

Generated by tools/gen_example_pages.py from mnd_scripts/examples/example_quantization.mnd — the output below is a real run, not a transcription. Regenerating the page reruns it.

the quantization preamble — the declaration every Maned program is REQUIRED to open with.

The program#

# ============================================================================
# example_quantization.mnd
# ----------------------------------------------------------------------------
# FUNCTIONALITY: the quantization preamble -- the declaration every Maned
# program is REQUIRED to open with.
#
# A .mnd file that does not declare its numeric contract does not parse. That
# is deliberate: Maned's runtime has no floating point at all, so "what does
# the integer 500 mean?" is not an implementation detail to be discovered later
# -- it is the first thing the file says.
#
#   mnd::quantres=N         values are reals x 10^N   (alias: decimal_places)
#   mnd::quantmax=HI        upper bound of the represented range
#   mnd::quantmin=LO        lower bound
#
# The preamble must supply quantres (or decimal_places) AND quantmax+quantmin.
# From those the toolchain derives the wire dtype: an INT8 MNPK envelope for
# narrow ranges, INT32 for wide ones.
#
# gap_003 honesty note: the historical alternatives are now REFUSED with
# numbered errors instead of being silently ignored -- mnd::quantrange
# (E010: nothing consumed it, so a quantrange-only preamble yielded a 0/0
# quantizer), legacy mnd::quant (E011), and every _fwd/_grad suffixed
# variant (E011: there is no separate forward/gradient pass to consume them).
#
# WHY IT IS A LANGUAGE FEATURE AND NOT A LIBRARY CALL: these directives fill
# the MNPK quant block that ships with the compiled IR to a remote worker.
# The scale is part of the program's identity, so the same file cannot mean one
# thing locally and another on an FPGA.
#
# RUN: ../maned-run examples/example_quantization.mnd
# ============================================================================

# --- the standard preamble --------------------------------------------------
mnd::quantmax=1000;
mnd::quantmin=-1000;
mnd::quantres=3;          # 10^3: the integer 1000 denotes 1.000

# Values at scale 1000: 0.250, 0.500, -0.750, 1.000
in::x = [[250,500],[-750,1000]];
in::one = 1000;            # the number 1.000 at this scale
in::half = 500;            # 0.500

calc::lambda_flow scaled_math(x, one, half) {
    # Addition and subtraction are scale-preserving: no rescale needed.
    x half add shifted =

    # Multiplication is NOT. Two operands at 10^3 give a result at 10^6, so
    # the program divides the scale back out explicitly. Nothing is implicit.
    x x elemwise_mul squared_raw =
    squared_raw one div squared =

    # Multiplying by the unit element leaves a value unchanged only AFTER the
    # rescale -- a useful sanity check on the contract.
    x one elemwise_mul times_one_raw =
    times_one_raw one div times_one =
    times_one x == unit_law_holds =

    # Activations decode against 10^quantres, so sigmoid(0.250) reads as 0.562
    # here and would read as 562 at any other scale only after rescaling.
    x sigmoid activated =
    x tanh hyperbolic =
} return shifted, squared_raw, squared, times_one, unit_law_holds,
         activated, hyperbolic;

The run#

$ maned-run mnd_scripts/examples/example_quantization.mnd
flow 'scaled_math' outputs:
shifted : [2x2] = [750, 1000, -250, 1500]
squared_raw : [2x2] = [62500, 250000, 562500, 1000000]
squared : [2x2] = [62, 250, 562, 1000]
times_one : [2x2] = [250, 500, -750, 1000]
unit_law_holds : [2x2] = [1, 1, 1, 1]
activated : [2x2] = [562, 622, 321, 731]
hyperbolic : [2x2] = [245, 462, -635, 761]

Next#

© 2026 Fabiano Dicheti · Found a problem on this page? Open an issue