Skip to content

Family spelling

How each dynamic target spells a kernel distribution on host expressions.

family_spelling

How each dynamic target spells a QIEC distribution on host expressions.

A DistributionValue names a family of the semantic registry and supplies its parameters by name. A host runtime needs that construction as an expression of its own language, built from the host expressions its arguments render to. This module owns those spellings: one function per target that takes rendered argument expressions and returns the target's constructor expression, applying the target's parameterization conventions (rate against scale, complemented probabilities, reordered or prepended arguments, leading matrix dimensions, folded half-line families) and naming the runtime helpers the target must graft for families it does not ship.

The conventions here are the ones the sample-step renderers apply to a program's sample and observe steps; a family constructed as a first-class value must score exactly as the same family sampled at a site, so the two spellings agree parameter for parameter.

DYNAMIC_TARGET_LANGUAGES module-attribute

DYNAMIC_TARGET_LANGUAGES: dict[str, str] = {'pyro': 'python', 'numpyro': 'python', 'pymc': 'python', 'edward2': 'python', 'turing': 'julia', 'gen': 'julia', 'webppl': 'javascript', 'church': 'scheme'}

The dynamic targets, each mapped to the host language it renders to.

DistributionSpelling didactic-model

DistributionSpelling(*, expression: str, helpers: tuple[str, ...] = ())

Bases: Model

One target's expression for a distribution construction.

PARAMETER DESCRIPTION
expression

The host expression constructing the distribution.

TYPE: str

helpers

Runtime helper roots the target must graft for the expression to resolve.

TYPE: tuple[str, ...] DEFAULT: ()

bridge_source

bridge_source(target: str) -> str

The target's QIEC distribution bridge.

The bridge defines, in the target's host language, the array conversion tensor-valued arguments pass through, the log-density evaluation a LogDensity term renders to, and any wrapper a support convention needs.

PARAMETER DESCRIPTION
target

A dynamic target.

TYPE: str

RETURNS DESCRIPTION
str

The bridge's source text.

RAISES DESCRIPTION
KeyError

If target is not a dynamic target.

Source code in src/quivers/transpile/family_spelling.py
def bridge_source(target: str) -> str:
    """The target's QIEC distribution bridge.

    The bridge defines, in the target's host language, the array
    conversion tensor-valued arguments pass through, the log-density
    evaluation a ``LogDensity`` term renders to, and any wrapper a
    support convention needs.

    Parameters
    ----------
    target : str
        A dynamic target.

    Returns
    -------
    str
        The bridge's source text.

    Raises
    ------
    KeyError
        If ``target`` is not a dynamic target.
    """
    language = DYNAMIC_TARGET_LANGUAGES[target]
    extension = {"python": "py", "julia": "jl", "javascript": "js", "scheme": "scm"}
    return (_HERE / f"runtime_qiec_{target}.{extension[language]}").read_text()

can_spell

can_spell(target: str, family: str) -> bool

Whether a target spells a family as a first-class distribution.

PARAMETER DESCRIPTION
target

A dynamic target.

TYPE: str

family

A registry family name.

TYPE: str

RETURNS DESCRIPTION
bool

True when :func:spell_distribution has a spelling for the pair.

Source code in src/quivers/transpile/family_spelling.py
def can_spell(target: str, family: str) -> bool:
    """Whether a target spells a family as a first-class distribution.

    Parameters
    ----------
    target : str
        A dynamic target.
    family : str
        A registry family name.

    Returns
    -------
    bool
        ``True`` when :func:`spell_distribution` has a spelling for the
        pair.
    """
    return (
        family in FAMILIES
        and family not in _UNSPELLABLE[target]
        and target in FAMILY_META[family].target_names
    )

spell_distribution

spell_distribution(target: str, family: str, arguments: Mapping[str, str], event_shape: tuple[int, ...] | None) -> DistributionSpelling

Spell a distribution construction for a dynamic target.

PARAMETER DESCRIPTION
target

The dynamic target.

TYPE: str

family

The family's registry name.

TYPE: str

arguments

The supplied parameters, each a host expression, keyed by the registry's parameter names.

TYPE: Mapping[str, str]

event_shape

The literal event shape of the constructed Sampleable, when its type spells one; families whose target takes the matrix dimension as an argument read it from here.

TYPE: tuple[int, ...] or None

RETURNS DESCRIPTION
DistributionSpelling

The expression and the helpers it needs.

RAISES DESCRIPTION
UnsupportedConstruct

If the target has no spelling for the family, or a parameter it needs is absent.

Source code in src/quivers/transpile/family_spelling.py
def spell_distribution(
    target: str,
    family: str,
    arguments: Mapping[str, str],
    event_shape: tuple[int, ...] | None,
) -> DistributionSpelling:
    """Spell a distribution construction for a dynamic target.

    Parameters
    ----------
    target : str
        The dynamic target.
    family : str
        The family's registry name.
    arguments : Mapping[str, str]
        The supplied parameters, each a host expression, keyed by the
        registry's parameter names.
    event_shape : tuple[int, ...] or None
        The literal event shape of the constructed ``Sampleable``, when
        its type spells one; families whose target takes the matrix
        dimension as an argument read it from here.

    Returns
    -------
    DistributionSpelling
        The expression and the helpers it needs.

    Raises
    ------
    UnsupportedConstruct
        If the target has no spelling for the family, or a parameter it
        needs is absent.
    """
    if not can_spell(target, family):
        raise UnsupportedConstruct(
            f"qvr-{target}", [f"qiec:distribution:{family}:no-{target}-spelling"]
        )
    record = FAMILIES[family]
    speller = _SPELLERS[target]
    expression = speller(record, dict(arguments), event_shape)
    return DistributionSpelling(
        expression=expression, helpers=_HELPER_ROOTS[target].get(family, ())
    )

helper_roots

helper_roots(target: str, families: frozenset[str]) -> frozenset[str]

The runtime helper roots a target grafts for the given families.

PARAMETER DESCRIPTION
target

A dynamic target.

TYPE: str

families

Family names constructed by the program.

TYPE: frozenset[str]

RETURNS DESCRIPTION
frozenset[str]

The roots (helper class or function names) those families need.

Source code in src/quivers/transpile/family_spelling.py
def helper_roots(target: str, families: frozenset[str]) -> frozenset[str]:
    """The runtime helper roots a target grafts for the given families.

    Parameters
    ----------
    target : str
        A dynamic target.
    families : frozenset[str]
        Family names constructed by the program.

    Returns
    -------
    frozenset[str]
        The roots (helper class or function names) those families need.
    """
    roots: set[str] = set()
    for family in families:
        roots.update(_HELPER_ROOTS[target].get(family, ()))
    return frozenset(roots)

helper_families

helper_families(target: str) -> frozenset[str]

The families a target serves through grafted runtime helpers.

PARAMETER DESCRIPTION
target

A dynamic target.

TYPE: str

RETURNS DESCRIPTION
frozenset[str]

The family names.

Source code in src/quivers/transpile/family_spelling.py
def helper_families(target: str) -> frozenset[str]:
    """The families a target serves through grafted runtime helpers.

    Parameters
    ----------
    target : str
        A dynamic target.

    Returns
    -------
    frozenset[str]
        The family names.
    """
    return frozenset(_HELPER_ROOTS[target])