Skip to content

kups.core.assertion.primitives

JAX primitives that record runtime assertions in traced code.

check_assertions(like=None)

A primitive that returns a scalar bool. When not wrapped in with_runtime_assertions, it always returns True. When wrapped, it will return the conjunction of all runtime assertions in the current context.

Parameters:

Name Type Description Default
like Array | None

An array whose device placement and sharding will be used for the output. If None, the output will be placed on the default device.

None

Returns: A scalar boolean array indicating whether all assertions pass.

Source code in src/kups/core/assertion/primitives.py
def check_assertions(like: Array | None = None) -> Array:
    """A primitive that returns a scalar bool. When not wrapped in with_runtime_assertions,
    it always returns True. When wrapped, it will return the conjunction of all
    runtime assertions in the current context.

    Args:
        like: An array whose device placement and sharding will be used for the output.
            If None, the output will be placed on the default device.
    Returns:
        A scalar boolean array indicating whether all assertions pass.
    """
    if like is None:
        like = jnp.array(True, dtype=jnp.bool)
    return check_assertion_p.bind(like)

runtime_assert(predicate, message='', fmt_args=None, exception_type=AssertionError, static_info=None, fix_fn=None, fix_args=NO_ARGS, loop_merge=ELEMENTWISE_MAX)

Create a runtime assertion that integrates with JAX transformations.

This function creates assertions that can be traced through JAX transformations including JIT compilation, automatic differentiation, and vectorization. The assertion acts as an identity function during execution but records assertion metadata for later inspection.

Parameters:

Name Type Description Default
predicate Array

A boolean array indicating whether the assertion passes

required
message str

Error message with optional format placeholders (e.g., "Value {val} is invalid")

''
fmt_args dict[str, Array] | None

Dictionary mapping format placeholder names to values

None
exception_type type[Exception]

Type of exception to raise if assertion fails during checking

AssertionError
static_info dict[str, Any] | None

Additional metadata for debugging (not traced by JAX)

None
fix_fn Fix[State, FixArgs] | None

Optional function to repair state when assertion fails

None
fix_args FixArgs | _NO_ARGS

Arguments for the fix function (can be complex PyTree structures)

NO_ARGS
loop_merge LoopMerge

How scan and while_loop fold fmt_args and fix_args across iterations. Defaults to ELEMENTWISE_MAX.

ELEMENTWISE_MAX

Type Parameters:

Name Bound or Constraints Description Default
State

Type of state that can be modified by the fix function

required
FixArgs

Type of arguments passed to the fix function (supports PyTree structures)

required
Example

Basic assertion:

x = jnp.array(5.0)
runtime_assert(
    predicate=x > 0,
    message="Value must be positive, got {val}",
    fmt_args={"val": x}
)

Assertion with fixing:

runtime_assert(
    predicate=x > threshold,
    message="Value {val} below threshold {thresh}",
    fmt_args={"val": x, "thresh": threshold},
    fix_fn=lambda state, args: jnp.maximum(state, args["min_val"]),
    fix_args={"min_val": jnp.array(1.0)}
)

Complex PyTree fix_args:

complex_args = {
    "thresholds": {"min": jnp.array(0.1), "max": jnp.array(10.0)},
    "multipliers": (jnp.array(2.0), jnp.array(3.0))
}
runtime_assert(
    predicate=x > 0,
    message="Invalid value",
    fix_args=complex_args
)

Note

The fix_args parameter supports arbitrarily nested PyTree structures including dictionaries, tuples, and arrays. These are automatically flattened and unflattened during JAX transformations.

Source code in src/kups/core/assertion/primitives.py
def runtime_assert[State, FixArgs](
    predicate: Array,
    message: str = "",
    fmt_args: dict[str, Array] | None = None,
    exception_type: type[Exception] = AssertionError,
    static_info: dict[str, Any] | None = None,
    fix_fn: Fix[State, FixArgs] | None = None,
    fix_args: FixArgs | _NO_ARGS = NO_ARGS,
    loop_merge: LoopMerge = ELEMENTWISE_MAX,
) -> None:
    """
    Create a runtime assertion that integrates with JAX transformations.

    This function creates assertions that can be traced through JAX transformations
    including JIT compilation, automatic differentiation, and vectorization. The
    assertion acts as an identity function during execution but records assertion
    metadata for later inspection.

    Args:
        predicate: A boolean array indicating whether the assertion passes
        message: Error message with optional format placeholders (e.g., "Value {val} is invalid")
        fmt_args: Dictionary mapping format placeholder names to values
        exception_type: Type of exception to raise if assertion fails during checking
        static_info: Additional metadata for debugging (not traced by JAX)
        fix_fn: Optional function to repair state when assertion fails
        fix_args: Arguments for the fix function (can be complex PyTree structures)
        loop_merge: How ``scan`` and ``while_loop`` fold ``fmt_args`` and
            ``fix_args`` across iterations. Defaults to
            [ELEMENTWISE_MAX][kups.core.assertion.ELEMENTWISE_MAX].

    Type Parameters:
        State: Type of state that can be modified by the fix function
        FixArgs: Type of arguments passed to the fix function (supports PyTree structures)

    Example:
        Basic assertion:
        ```python
        x = jnp.array(5.0)
        runtime_assert(
            predicate=x > 0,
            message="Value must be positive, got {val}",
            fmt_args={"val": x}
        )
        ```

        Assertion with fixing:
        ```python
        runtime_assert(
            predicate=x > threshold,
            message="Value {val} below threshold {thresh}",
            fmt_args={"val": x, "thresh": threshold},
            fix_fn=lambda state, args: jnp.maximum(state, args["min_val"]),
            fix_args={"min_val": jnp.array(1.0)}
        )
        ```

        Complex PyTree fix_args:
        ```python
        complex_args = {
            "thresholds": {"min": jnp.array(0.1), "max": jnp.array(10.0)},
            "multipliers": (jnp.array(2.0), jnp.array(3.0))
        }
        runtime_assert(
            predicate=x > 0,
            message="Invalid value",
            fix_args=complex_args
        )
        ```

    Note:
        The fix_args parameter supports arbitrarily nested PyTree structures including
        dictionaries, tuples, and arrays. These are automatically flattened and
        unflattened during JAX transformations.
    """
    if fmt_args is None:
        fmt_args = {}
    if static_info is None:
        static_info = {}

    tb = _capture_traceback().replace("{", "{{").replace("}", "}}")
    # Convert static_info to hashable format (tuple of key-value pairs)
    static_info_hashable = tuple(sorted(static_info.items()))

    # Prepare inputs: predicate, fmt_args values, fix_args flattened (if present)
    inputs = [predicate, *fmt_args.values()]
    fix_args_tree = None
    if not isinstance(fix_args, _NO_ARGS):
        # Flatten fix_args PyTree and add to inputs
        fix_args_flat, fix_args_tree = jax.tree.flatten(fix_args)
        inputs.extend(fix_args_flat)

    assertion_p.bind(
        *inputs,
        fmt_arg_names=tuple(fmt_args.keys()),
        message=message + f"{_TRACEBACK_MARKER}{tb}",
        exception_type=exception_type,
        static_info_hashable=static_info_hashable,
        fix_fn=fix_fn,
        fix_args_tree=fix_args_tree,
        loop_merge=loop_merge,
    )