Skip to content

Skip dataclass

Skip(
    source: str,
    target: str,
    source_layer: int,
    target_layer: int,
    source_in_layer: int,
    target_in_layer: int,
)

One original edge whose endpoints are more than one layer apart.

Metadata, not a second computation: the named edge is already a block of packed unit pairs in LayeredSpec.hops[target_layer - 1], exactly like an adjacent edge, so nothing has to add it back later and nothing can forget to. Read LayeredSpec.skips to inspect which prior-knowledge edges span layers; a forward pass never reads it. parse_layered builds these, never the caller.

Parameters:

Name Type Description Default

source

str

Name of the node the edge leaves, as it appears in LayeredSpec.layer_nodes[source_layer].

required

target

str

Name of the node the edge enters, as it appears in LayeredSpec.layer_nodes[target_layer].

required

source_layer

int

Depth of source: its index into LayeredSpec.layer_nodes.

required

target_layer

int

Depth of target. Always at least two above source_layer; that gap is what makes the edge a skip, and it names the hop carrying it, hops[target_layer - 1].

required

source_in_layer

int

First unit of source inside its layer (the block start). At width 1 this equals the node's index in layer_nodes[source_layer]. It is not a column of the hop's concatenated source axis. LayeredSpec.edge_location returns the packed slots.

required

target_in_layer

int

First unit of target inside its layer (the block start). At width 1 this equals the node's index in layer_nodes[target_layer]. Locating the skip among packed indices means every unit pair in that block is live, not a single (column, row) pair. Use LayeredSpec.edge_location.

required
See Also

Hop : The packed edges this skip is already one of, alongside every other parent of target_layer. LayeredSpec : Holds skips, empty when no edge spans layers. parse_layered : Builds the spec these records come from.

Notes

Every original edge with a depth gap greater than 1 is recorded once; adjacent edges never are. Membership changes nothing about how the edge is computed: its weight, the unit bias, and the fan-in the degree-aware initialization uses all stay on the target layer's PackedLinear or MaskedLinear. Expanding a skip into dummy neurons is not the intended use. At width greater than 1 the stored indices are block starts; every unit pair of that block is a packed index of the hop.

Examples:

Locate a skip among packed indices. This graph is width 1, so the skip is one packed pair:

>>> import pandas as pd
>>> import kpnn2
>>> edgelist = pd.DataFrame(
...     {
...         "source": ["A", "B", "H", "A"],
...         "target": ["H", "H", "C", "C"],
...     }
... )
>>> spec = kpnn2.parse_layered(edgelist)
>>> skip = spec.skips[0]
>>> skip.source, skip.target
('A', 'C')
>>> skip.source_layer, skip.target_layer
(0, 2)
>>> hop_index, packed = spec.edge_location(
...     skip.source,
...     skip.target,
... )
>>> hop_index
1
>>> packed
(0,)