neml2.schema

Declarative HIT syntax for Python-native objects.

HitSchema is the native counterpart of the C++ expected_options pattern, but intentionally smaller: it records fixed model inputs/outputs and the HIT options needed to construct common leaf models. The Model base class uses it to derive input_spec / output_spec and to provide a default from_hit implementation.

neml2.schema.BLOCK_NAME = <object object>

the variable name defaults to the model’s HIT block name (mirrors C++ Interpolation whose output variable defaults to the object name). Resolved against node.path() at parse time.

Type:

Sentinel default for var_output()

class neml2.schema.HitField(kind: 'str', name: 'str', value_type: 'Any' = None, doc: 'str' = '', default: 'Any' = <object object at 0x7f00bd6ec390>, attr: 'str | None' = None, reader: 'Callable[[nmhit.Node, str], Any] | None' = None, optional_reader: 'Callable[[nmhit.Node, str, Any], Any] | None' = None, factory_getter: 'str | None' = None, allow_nonlinear: 'bool' = False, suffix: 'str | None' = None, override: 'str | None' = None, priority: 'str | None' = None)[source]

Bases: object

Parameters:
  • kind (str)

  • name (str)

  • value_type (Any)

  • doc (str)

  • default (Any)

  • attr (str | None)

  • reader (Callable[[nmhit.Node, str], Any] | None)

  • optional_reader (Callable[[nmhit.Node, str, Any], Any] | None)

  • factory_getter (str | None)

  • allow_nonlinear (bool)

  • suffix (str | None)

  • override (str | None)

  • priority (str | None)

allow_nonlinear: bool = False
attr: str | None = None
property ctor_name: str
default: Any = <object object>
doc: str = ''
factory_getter: str | None = None
property is_input: bool
property is_output: bool
kind: str
name: str
optional_reader: Callable[[nmhit.Node, str, Any], Any] | None = None
override: str | None = None

the name of another HIT option whose non-empty value takes precedence over name + suffix for the resolved variable name. Used by rate overrides — when the user supplies an explicit rate = 'my_rate_var' they bypass the <variable>_rate derivation.

Type:

For input/output fields

priority: str | None = None

an explicit producer priority used by the DependencyResolver when more than one model provides the same variable name. "high" = “my output supersedes any other producer; run me last.” "low" = “my output is overwritten by any other producer; run me first.” None (default) = “I’m the sole producer — duplicate-provider error if not.”

Type:

For output fields

reader: Callable[[nmhit.Node, str], Any] | None = None
property required: bool
suffix: str | None = None

a literal string appended to the HIT-resolved variable name, used to derive the conventional NEML2 secondary-variable names (~1 for history, _rate for rates, _residual for implicit residuals). Multiple input/output fields can share the same name (HIT option) with different ``suffix``es to derive several related variables from one user-supplied base name.

Type:

For input/output fields

value_type: Any = None
property var_type: type[TensorWrapper] | None

The variable TensorWrapper type, for var_* / input / output.

class neml2.schema.HitSchema(*fields)[source]

Bases: object

Ordered declaration of a native object’s HIT surface.

Parameters:

fields (HitField)

property input_spec: dict[str, type[TensorWrapper]]
kwargs_from_hit(node, factory)[source]

Parse constructor kwargs for every schema field.

input / output fields resolve their canonical variable name from HIT (with the option name as the default, or BLOCK_NAME / None per input() / output()); the resolved name is passed under HitField.ctor_name (attr or option name) so Model._store_schema_values can record per-instance input_spec / output_spec keys without going through a separate remapping pass.

derived_input / derived_output fields reference another option by name and reuse that option’s resolution (default included). A precomputed option_values map lets the derived resolver see e.g. time "t" when the option declared default="t" and HIT was silent.

Parameters:
  • node (nmhit.Node)

  • factory (_NativeInputFile)

Return type:

dict[str, Any]

property output_spec: dict[str, type[TensorWrapper]]
reject_unknown_fields(node)[source]

Raise if node carries any HIT field not declared in the schema.

Mirrors the C++ parser’s behaviour: an unrecognised option is a hard error, not a silent skip. Silently ignored options are how stale knobs (e.g. priority on a ComposedModel after the resolver stopped supporting it) survive across refactors.

type is always allowed – it’s read by the factory before the schema-driven kwargs pass to dispatch the registered class. Override option names (an option()’s override= target) are also allowed; they substitute for the primary option’s value when non-empty.

Parameters:

node (nmhit.Node)

Return type:

None

neml2.schema.dependency(name, factory_getter, doc, *, attr=None, default=<object object>)[source]
Parameters:
  • name (str)

  • factory_getter (str)

  • doc (str)

  • attr (str | None)

  • default (Any)

Return type:

HitField

neml2.schema.derived_input(referenced, type_cls, *, attr=None, suffix=None, override=None)[source]

Declare an input variable whose name is derived from another field’s value.

Unlike input(), a derived field does not declare its own HIT option — it references an existing input() / output() / option() field by referenced (the field’s name) and computes the variable name as HIT[referenced] + suffix (or HIT[override] when that override option is set non-empty). This is the schema-driven counterpart to the time-integrator pattern of declaring one base variable input and deriving <variable>~1 / <variable>_rate / <variable>_residual from it: the user sees a single option per logical knob, and the secondary variables fall out automatically. No docstring is required — derived fields don’t appear in the syntax catalog.

Parameters:
Return type:

HitField

neml2.schema.derived_output(referenced, type_cls, *, attr=None, suffix=None, override=None)[source]

Declare an output variable whose name is derived from another field’s value.

See derived_input(). The canonical use is derived_output("variable", T, suffix="_residual") for an implicit residual output named after the base variable option/input.

Parameters:
Return type:

HitField

neml2.schema.input(name, type_cls, doc, *, default=<object object>, attr=None)[source]

Declare an input variable.

The canonical variable name resolves as HIT[name] if specified, else default (which itself defaults to the option name). Pass default=BLOCK_NAME to fall back to the model’s HIT block name, or default=None to keep the resolved name optional (yielding None when HIT is silent — used by leaves that compute a derived default). When attr is given, Model.__init__ stores the resolved name on the instance under that attribute (for leaves that reference the variable name explicitly inside forward, e.g. as a chain-rule action key).

To derive a secondary variable name from another option (time-integration pattern: history ~1, _rate, _residual), use derived_input() / derived_output() instead — those declare a variable without introducing a new HIT option.

Parameters:
Return type:

HitField

neml2.schema.option(name, value_type, doc, *, attr=None, default=<object object>, reader=None, optional_reader=None)[source]

Declare a scalar/list/string HIT option.

When attr is provided and the model uses the inherited Model.__init__, the parsed value is stored directly on the instance under that attribute name. Without attr, the parsed value is passed as a constructor kwarg and a custom __init__ must consume it.

Parameters:
  • name (str)

  • value_type (type)

  • doc (str)

  • attr (str | None)

  • default (Any)

  • reader (Callable[[nmhit.Node, str], Any] | None)

  • optional_reader (Callable[[nmhit.Node, str, Any], Any] | None)

Return type:

HitField

neml2.schema.output(name, type_cls, doc, *, default=<object object>, attr=None, priority=None)[source]

Declare an output variable.

Same resolution rules as input() (HIT override → default → option name); pass default=BLOCK_NAME for “default to the HIT block name” (the C++ Interpolation convention) or default=None for a derived default the leaf computes itself. For secondary names derived from another option, see derived_output().

Set priority to disambiguate composition when multiple sibling models provide the same variable name:

  • "high" — “my output supersedes any other producer; run me last.” The composed model returns this leaf’s value.

  • "low" — “my output is overwritten by any other producer; run me first.” The composed model returns the other (default-priority) leaf’s value.

  • None (default) — claim the name exclusively. Duplicate-provider error if any sibling also provides it.

Used by post-processors like FixOrientation that mutate a sibling’s output in place (input='orientation' / output='orientation').

Parameters:
Return type:

HitField

neml2.schema.parameter(name, type_cls, doc, *, attr=None, default=<object object>, allow_nonlinear=False)[source]
Parameters:
Return type:

HitField

neml2.schema.parameters(name, type_cls, doc, *, attr=None, default=<object object>, allow_nonlinear=False)[source]

Declare a list of parameters, one per token of a HIT list option.

The HIT value is a whitespace-separated list of specs; each token is declared as an independent parameter (named <attr-or-name>_<i>) via Model.declare_typed_parameter(), so each entry can independently resolve as a literal, a [Tensors] cross-ref, a [Models]-output promoted input (mode 3) or a bare-variable promoted input (mode 4) — same as a single parameter(). The list of registered parameter names is stored on self.<attr> for the leaf to iterate inside forward (typically via Model._get_param_list()).

Parameters:
Return type:

HitField

neml2.schema.var_inputs(option_name, type_cls, doc, *, default=<object object>, attr=None, ctor=None)[source]

Declare a list HIT option whose values name several inputs of one type.

The C++ LinearCombination from = 'a b c' pattern: the option is a whitespace-separated list of variable names, each an input of type_cls. When attr is provided, Model.__init__ stores the parsed list[str] on the instance under that attribute (and extends input_spec automatically); otherwise the value is passed as a constructor kwarg. ctor is a deprecated alias for attr.

Parameters:
Return type:

HitField