Jraph API¶
Portable jraph: GraphsTuple, batching/padding, and GraphNetwork models on NumPy / JAX / PyTorch / TF.
Segment ops on this module require num_segments (AnyTensor contract).
None node/edge/global features are empty pytrees (jraph / jax.tree).
Narrative docs: Overview. Recipes: Examples.
anytensor.jraph
¶
Portable jraph: GraphsTuple, batching/padding, and GNN models on any tensor.
Public names match :mod:jraph. Segment ops require num_segments
(AnyTensor contract). Feature nests use :mod:anytensor.tree (jax.tree API).
GraphsTuple
¶
Bases: NamedTuple
An ordered collection of graphs in a sparse format.
A port of :class:jraph.GraphsTuple. nodes, edges and globals
may be None or an ArrayTree of features; senders / receivers
are integer index arrays (or None when there are no edges). n_node
and n_edge are integer vectors with one entry per graph in the batch.
Sender and receiver indices are absolute in the batched node array (offset by the nodes of earlier graphs). See the jraph docs for the full field layout.
__tree_batch__ / __tree_unbatch__ implement graph batching (not
fieldwise array concat). :func:anytensor.tree.batch / unbatch are
the same functions as :func:~anytensor.jraph.batch / unbatch; this
type owns the offsetting logic. Custom node/edge/global objects may
define the same methods so feature batching uses their logic.
Source code in anytensor/jraph/graph.py
batch
¶
Batch a sequence of pytrees along axis (leading axis by default).
Same function as :func:anytensor.jraph.batch. If the type defines
__tree_batch__(xs, axis=0), that method is used and children are
not walked. Otherwise leaves are concatenated with
:func:anytensor.concatenate. All-None stays None.
import numpy as np import anytensor.tree as tree tree.batch([np.array([1, 2]), np.array([3])]) array([1, 2, 3])
Source code in anytensor/tree.py
unbatch
¶
Unbatch structure along axis into unit slices.
Same function as :func:anytensor.jraph.unbatch. __tree_unbatch__(axis=0)
on the object wins (GraphsTuple yields one graph per n_node entry).
Nested containers recurse. Top-level None cannot infer a batch size.
import numpy as np import anytensor.tree as tree head, tail = tree.unbatch(np.arange(1, 3)) tuple(int(x) for x in head), tuple(int(x) for x in tail) ((1,), (2,))
Source code in anytensor/tree.py
GAT
¶
Graph Attention Network layer (Veličković et al.). Expects self-edges.
Apply is @cache (same pattern as GraphNetwork). Destination size is
:func:~anytensor.shape of nodes.
Source code in anytensor/jraph/models.py
DeepSets
¶
DeepSets(
update_node_fn,
update_global_fn,
aggregate_nodes_for_globals_fn=segment_sum,
)
DeepSets layer as a configured GraphNetwork.
Source code in anytensor/jraph/models.py
GraphConvolution
¶
GraphConvolution(
update_node_fn,
aggregate_nodes_fn=segment_sum,
add_self_edges=False,
symmetric_normalization=True,
)
GCN layer (Kipf & Welling). No activation after aggregation.
Apply uses the public cache pattern: @cache plus
:meth:~anytensor.cache.lookup / :meth:~anytensor.cache.store on
"gcn" keyed by senders and the constructor flags so stacked applies
and ONNX do not duplicate Shape / Range / Concat.
Source code in anytensor/jraph/models.py
GraphMapFeatures
¶
Embed nodes, edges, and globals independently.
Apply is @cache (same pattern as GraphNetwork).
Source code in anytensor/jraph/models.py
GraphNetGAT
¶
GraphNetGAT(
update_edge_fn,
update_node_fn,
attention_logit_fn,
attention_reduce_fn,
update_global_fn=None,
aggregate_edges_for_nodes_fn=segment_sum,
aggregate_nodes_for_globals_fn=segment_sum,
aggregate_edges_for_globals_fn=segment_sum,
)
GraphNet with required attention on edge features.
Source code in anytensor/jraph/models.py
GraphNetwork
¶
GraphNetwork(
update_edge_fn,
update_node_fn,
update_global_fn=None,
aggregate_edges_for_nodes_fn=segment_sum,
aggregate_nodes_for_globals_fn=segment_sum,
aggregate_edges_for_globals_fn=segment_sum,
attention_logit_fn=None,
attention_normalize_fn=segment_softmax,
attention_reduce_fn=None,
)
Returns a method that applies a configured GraphNetwork.
Follows Algorithm 1 of https://arxiv.org/abs/1806.01261, with separate
sender/receiver aggregations and optional softmax attention. Same call
signature as :func:jraph.GraphNetwork. Apply uses the public cache
pattern: @cache (sticky) plus :func:~anytensor.partition_ids
(cache.lookup / store on "partition", keyed by n_node /
n_edge). Callers write the same @cache apply.
Flattened totals (official sum_n_node / sum_n_edge) are
:func:~anytensor.shape of the node / sender axis — not
sum(n_node) — so they stay symbolic sizes on ONNX export.
Source code in anytensor/jraph/models.py
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 | |
InteractionNetwork
¶
InteractionNetwork(
update_edge_fn,
update_node_fn,
aggregate_edges_for_nodes_fn=segment_sum,
include_sent_messages_in_node_update=False,
)
Interaction network (Battaglia et al.) as a configured GraphNetwork.
Source code in anytensor/jraph/models.py
RelationNetwork
¶
RelationNetwork(
update_edge_fn,
update_global_fn,
aggregate_edges_for_globals_fn=segment_sum,
)
Relation network as a configured GraphNetwork.
Source code in anytensor/jraph/models.py
batch_np
¶
concatenated_args
¶
Decorator that concatenates update_fn arguments along axis.
Source code in anytensor/jraph/utils.py
dynamically_batch
¶
Yield padded batches from an iterator of graphs (jraph algorithm).
Source code in anytensor/jraph/utils.py
get_edge_padding_mask
¶
Boolean mask, True for real edges.
Source code in anytensor/jraph/utils.py
get_fully_connected_graph
¶
get_fully_connected_graph(
n_node_per_graph,
n_graph,
node_features=None,
global_features=None,
add_self_edges=True,
)
Fully connected graphs (optionally without self-edges). n_graph is static.
Source code in anytensor/jraph/utils.py
get_graph_padding_mask
¶
Boolean mask, True for real graphs.
Source code in anytensor/jraph/utils.py
get_node_padding_mask
¶
Boolean mask, True for real nodes. Needs node features (static length).
Source code in anytensor/jraph/utils.py
get_number_of_padding_with_graphs_edges
¶
Number of padding edges (the dummy graph's n_edge).
get_number_of_padding_with_graphs_graphs
¶
Number of padding graphs (dummy + trailing empty). Not for unpadded graphs.
Source code in anytensor/jraph/utils.py
get_number_of_padding_with_graphs_nodes
¶
Number of padding nodes (the dummy graph's n_node).
pad_with_graphs
¶
Pad with a dummy graph (padding nodes/edges) plus empty graphs.
Not compilable (padding sizes are data-dependent). Requires n_graph >= 2.
Source code in anytensor/jraph/utils.py
partition_softmax
¶
Softmax within contiguous partitions of lengths partitions.
Official jraph takes sum_partitions as the third positional and allows
omitting it. AnyTensor requires it (core name total_length;
shape(logits)[0], not a data sum(partitions)). num_segments is
not an argument — it is shape(partitions)[0]. Calls core
:func:~anytensor.partition_softmax, which expands ids through
:func:~anytensor.partition_ids (cache as needed).
Source code in anytensor/jraph/utils.py
segment_max
¶
segment_max(
data,
segment_ids,
num_segments,
indices_are_sorted=False,
unique_indices=False,
sorted=False,
)
Max within segments. num_segments is required.
Source code in anytensor/jraph/utils.py
segment_max_or_constant
¶
segment_max_or_constant(
data,
segment_ids,
num_segments,
indices_are_sorted=False,
unique_indices=False,
constant=0.0,
sorted=False,
)
Segment max with a finite fill for empty segments.
Source code in anytensor/jraph/utils.py
segment_mean
¶
segment_mean(
data,
segment_ids,
num_segments,
indices_are_sorted=False,
unique_indices=False,
sorted=False,
)
Mean within segments. num_segments is required.
Source code in anytensor/jraph/utils.py
segment_min
¶
segment_min(
data,
segment_ids,
num_segments,
indices_are_sorted=False,
unique_indices=False,
sorted=False,
)
Min within segments. num_segments is required.
Source code in anytensor/jraph/utils.py
segment_min_or_constant
¶
segment_min_or_constant(
data,
segment_ids,
num_segments,
indices_are_sorted=False,
unique_indices=False,
constant=0.0,
sorted=False,
)
Segment min with a finite fill for empty segments.
Source code in anytensor/jraph/utils.py
segment_normalize
¶
segment_normalize(
data,
segment_ids,
num_segments,
indices_are_sorted=False,
unique_indices=False,
eps=1e-08,
sorted=False,
)
Z-score normalize within segments (jraph semantics). num_segments is required.
Source code in anytensor/jraph/utils.py
segment_softmax
¶
segment_softmax(
logits,
segment_ids,
num_segments,
indices_are_sorted=False,
unique_indices=False,
sorted=False,
)
Softmax within segments. num_segments is required.
Source code in anytensor/jraph/utils.py
segment_sum
¶
segment_sum(
data,
segment_ids,
num_segments,
indices_are_sorted=False,
unique_indices=False,
sorted=False,
)
Sum within segments. num_segments is required (AnyTensor).
Source code in anytensor/jraph/utils.py
segment_variance
¶
segment_variance(
data,
segment_ids,
num_segments,
indices_are_sorted=False,
unique_indices=False,
sorted=False,
)
Variance within segments. num_segments is required.
Source code in anytensor/jraph/utils.py
sparse_matrix_to_graphs_tuple
¶
COO sparse matrix → graph (values repeat senders/receivers).
Source code in anytensor/jraph/utils.py
unbatch_np
¶
unpad_with_graphs
¶
Remove dummy + empty padding graphs. Not compilable.
Source code in anytensor/jraph/utils.py
with_zero_out_padding_outputs
¶
Wrap a graph-to-graph fn so padded outputs are zeroed.
Source code in anytensor/jraph/utils.py
zero_out_padding
¶
Multiply padding nodes/edges/globals by zero (overflow guard).