Submodule containing autodiff operations for the Graph Neural Operator
Provides two differentiable operations:
gno_kernel_eval — evaluates the kernel MLP on each edge:
left_operand → edge_features [d, num_edges]
right_operand → packed kernel params [Hd + H + FH + F, 1]
where F = F_out * F_in
output → [F_out * F_in, num_edges] per-edge kernel values
gno_aggregate — aggregates messages using per-edge kernels:
left_operand → features [F_in, num_vertices]
right_operand → edge_kernels [F_out * F_in, num_edges]
output → [F_out, num_vertices]
gno_aggregate stores adj_ia and adj_ja on the result for
use in the backward pass. Metadata (d, H, F_in, F_out) is stored
in indices of the kernel evaluation result.
Gradient of gno_aggregate w.r.t. features (left operand)
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(array_type), | intent(inout) | :: | this |
Forward result node containing saved operands |
||
| type(array_type), | intent(in) | :: | upstream_grad |
Upstream gradient tensor |
Gradient tensor for node features
Gradient of gno_aggregate w.r.t. edge_kernels (right operand)
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(array_type), | intent(inout) | :: | this |
Forward result node containing saved operands |
||
| type(array_type), | intent(in) | :: | upstream_grad |
Upstream gradient tensor |
Gradient tensor for edge kernels
Gradient of gno_kernel_eval w.r.t. edge features (left operand)
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(array_type), | intent(inout) | :: | this |
Forward result node containing saved operands |
||
| type(array_type), | intent(in) | :: | upstream_grad |
Upstream gradient tensor |
Gradient tensor for coordinates
Gradient of gno_kernel_eval w.r.t. kernel_params (right operand)
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(array_type), | intent(inout) | :: | this |
Forward result node containing saved operands |
||
| type(array_type), | intent(in) | :: | upstream_grad |
Upstream gradient tensor |
Gradient tensor for packed kernel parameters
Gradient of lno_decode with respect to poles.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(array_type), | intent(inout) | :: | this |
Forward result node containing saved operands |
||
| type(array_type), | intent(in) | :: | upstream_grad |
Upstream gradient tensor |
Gradient tensor for poles
Gradient of lno_decode with respect to spectral input.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(array_type), | intent(inout) | :: | this |
Forward result node containing saved operands |
||
| type(array_type), | intent(in) | :: | upstream_grad |
Upstream gradient tensor |
Gradient tensor for spectral input
Gradient of lno_encode with respect to input.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(array_type), | intent(inout) | :: | this |
Forward result node containing saved operands |
||
| type(array_type), | intent(in) | :: | upstream_grad |
Upstream gradient tensor |
Gradient tensor for input
Gradient of lno_encode with respect to poles.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(array_type), | intent(inout) | :: | this |
Forward result node containing saved operands |
||
| type(array_type), | intent(in) | :: | upstream_grad |
Upstream gradient tensor |
Gradient tensor for poles
Gradient of ono_decode with respect to basis weights.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(array_type), | intent(inout) | :: | this |
Forward result node containing saved operands |
||
| type(array_type), | intent(in) | :: | upstream_grad |
Upstream gradient tensor |
Gradient tensor for basis weights
Gradient of ono_decode with respect to mixed input.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(array_type), | intent(inout) | :: | this |
Forward result node containing saved operands |
||
| type(array_type), | intent(in) | :: | upstream_grad |
Upstream gradient tensor |
Gradient tensor for mixed input
Gradient of ono_encode with respect to basis weights.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(array_type), | intent(inout) | :: | this |
Forward result node containing saved operands |
||
| type(array_type), | intent(in) | :: | upstream_grad |
Upstream gradient tensor |
Gradient tensor for basis weights
Gradient of ono_encode with respect to input.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(array_type), | intent(inout) | :: | this |
Forward result node containing saved operands |
||
| type(array_type), | intent(in) | :: | upstream_grad |
Upstream gradient tensor |
Gradient tensor for input
d(out)/d(input): upstream * scale (broadcast scale along samples)
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(array_type), | intent(in) | :: | this |
Forward result node containing saved operands |
||
| real(kind=real32), | intent(in), | dimension(:,:) | :: | upstream_grad |
Upstream gradient values |
|
| real(kind=real32), | intent(out), | dimension(:,:) | :: | output |
Output gradient values for input |
d(out)/d(scale): upstream * input (element-wise, per sample)
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(array_type), | intent(in) | :: | this |
Forward result node containing saved operands |
||
| real(kind=real32), | intent(in), | dimension(:,:) | :: | upstream_grad |
Upstream gradient values |
|
| real(kind=real32), | intent(out), | dimension(:,:) | :: | output |
Output gradient values for scale tensor |
In-place gradient w.r.t. features
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(array_type), | intent(in) | :: | this |
Forward result node containing saved operands |
||
| real(kind=real32), | intent(in), | dimension(:,:) | :: | upstream_grad |
Upstream gradient values |
|
| real(kind=real32), | intent(out), | dimension(:,:) | :: | output |
Output gradient values for node features |
In-place gradient w.r.t. edge_kernels
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(array_type), | intent(in) | :: | this |
Forward result node containing saved operands |
||
| real(kind=real32), | intent(in), | dimension(:,:) | :: | upstream_grad |
Upstream gradient values |
|
| real(kind=real32), | intent(out), | dimension(:,:) | :: | output |
Output gradient values for edge kernels |
In-place gradient w.r.t. edge features
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(array_type), | intent(in) | :: | this |
Forward result node containing saved operands |
||
| real(kind=real32), | intent(in), | dimension(:,:) | :: | upstream_grad |
Upstream gradient values |
|
| real(kind=real32), | intent(out), | dimension(:,:) | :: | output |
Output gradient values for coordinates |
In-place gradient w.r.t. packed kernel params
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(array_type), | intent(in) | :: | this |
Forward result node containing saved operands |
||
| real(kind=real32), | intent(in), | dimension(:,:) | :: | upstream_grad |
Upstream gradient values |
|
| real(kind=real32), | intent(out), | dimension(:,:) | :: | output |
Output gradient values for packed kernel parameters |
dL/dmu_m per sample: output[m,s] = sum_i upstream[i,s](-tau_i)exp(-mu_mtau_i)x[m,s]
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(array_type), | intent(in) | :: | this | |||
| real(kind=real32), | intent(in), | dimension(:,:) | :: | upstream_grad | ||
| real(kind=real32), | intent(out), | dimension(:,:) | :: | output |
dL/dx = D^T @ upstream [M, batch]
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(array_type), | intent(in) | :: | this | |||
| real(kind=real32), | intent(in), | dimension(:,:) | :: | upstream_grad | ||
| real(kind=real32), | intent(out), | dimension(:,:) | :: | output |
dL/du = E^T @ upstream [n_in, batch]
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(array_type), | intent(in) | :: | this | |||
| real(kind=real32), | intent(in), | dimension(:,:) | :: | upstream_grad | ||
| real(kind=real32), | intent(out), | dimension(:,:) | :: | output |
dL/dmu_m per sample: output[m,s] = upstream[m,s] * sum_j (-t_j) * exp(-mu_m*t_j) * u[j,s]
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(array_type), | intent(in) | :: | this | |||
| real(kind=real32), | intent(in), | dimension(:,:) | :: | upstream_grad | ||
| real(kind=real32), | intent(out), | dimension(:,:) | :: | output |
dL/dB per sample through Gram-Schmidt backward.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(array_type), | intent(in) | :: | this | |||
| real(kind=real32), | intent(in), | dimension(:,:) | :: | upstream_grad | ||
| real(kind=real32), | intent(out), | dimension(:,:) | :: | output |
dL/dx = Q^T @ upstream [k, batch]
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(array_type), | intent(in) | :: | this | |||
| real(kind=real32), | intent(in), | dimension(:,:) | :: | upstream_grad | ||
| real(kind=real32), | intent(out), | dimension(:,:) | :: | output |
dL/dB per sample through Gram-Schmidt backward.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(array_type), | intent(in) | :: | this | |||
| real(kind=real32), | intent(in), | dimension(:,:) | :: | upstream_grad | ||
| real(kind=real32), | intent(out), | dimension(:,:) | :: | output |
dL/du = Q @ upstream [n, batch]
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(array_type), | intent(in) | :: | this | |||
| real(kind=real32), | intent(in), | dimension(:,:) | :: | upstream_grad | ||
| real(kind=real32), | intent(out), | dimension(:,:) | :: | output |
Element-wise scaling with explicit support for sample-independent scale.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(array_type), | intent(in), | target | :: | input |
Input tensor [n, batch] |
|
| class(array_type), | intent(in), | target | :: | scale |
Scale tensor [n, 1] |
Scaled output tensor
Aggregate neighbour messages using pre-computed per-edge kernels.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(array_type), | intent(in), | target | :: | features |
Node features [F_in, num_vertices] |
|
| class(array_type), | intent(in), | target | :: | edge_kernels |
Per-edge kernel values [F_out*F_in, num_edges] |
|
| integer, | intent(in), | dimension(:) | :: | adj_ia |
CSR row pointers |
|
| integer, | intent(in), | dimension(:,:) | :: | adj_ja |
CSR column indices |
|
| integer, | intent(in) | :: | F_in |
Feature dimensions |
||
| integer, | intent(in) | :: | F_out |
Feature dimensions |
Aggregated node output tensor
Evaluate the GNO kernel MLP on every directed edge in the graph.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(array_type), | intent(in), | target | :: | coords |
Edge features / relative coordinates [d, num_edges] |
|
| class(array_type), | intent(in), | target | :: | kernel_params |
Packed kernel parameters [Hd + H + FH + F, 1] |
|
| integer, | intent(in), | dimension(:) | :: | adj_ia |
CSR row pointers (size num_vertices + 1) |
|
| integer, | intent(in), | dimension(:,:) | :: | adj_ja |
CSR column indices (adj_ja(1,:) = neighbour index) |
|
| integer, | intent(in) | :: | coord_dim |
Metadata for unpacking kernel_params |
||
| integer, | intent(in) | :: | kernel_hidden |
Metadata for unpacking kernel_params |
||
| integer, | intent(in) | :: | F_in |
Metadata for unpacking kernel_params |
||
| integer, | intent(in) | :: | F_out |
Metadata for unpacking kernel_params |
Output per-edge kernel values
Decode through the Laplace basis built from learnable poles.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(array_type), | intent(in), | target | :: | spectral |
Spectral tensor [M, batch] |
|
| class(array_type), | intent(in), | target | :: | poles |
Learnable poles [M, 1] |
|
| integer, | intent(in) | :: | num_outputs |
Output dimension and number of modes |
||
| integer, | intent(in) | :: | num_modes |
Output dimension and number of modes |
Decoded output tensor
Encode input through the Laplace basis built from learnable poles.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(array_type), | intent(in), | target | :: | input |
Input signal tensor [n_in, batch] |
|
| class(array_type), | intent(in), | target | :: | poles |
Learnable poles [M, 1] |
|
| integer, | intent(in) | :: | num_inputs |
Input dimension and number of modes |
||
| integer, | intent(in) | :: | num_modes |
Input dimension and number of modes |
Encoded output tensor
Decode through an orthogonalised basis.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(array_type), | intent(in), | target | :: | mixed |
Mixed spectral tensor [k, batch] |
|
| class(array_type), | intent(in), | target | :: | basis_weights |
Flattened basis matrix parameters [n*k, 1] |
|
| integer, | intent(in) | :: | num_inputs |
Output dimension and basis size |
||
| integer, | intent(in) | :: | num_basis |
Output dimension and basis size |
Decoded output tensor
Encode input through an orthogonalised basis.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(array_type), | intent(in), | target | :: | input |
Input tensor [n, batch] |
|
| class(array_type), | intent(in), | target | :: | basis_weights |
Flattened basis matrix parameters [n*k, 1] |
|
| integer, | intent(in) | :: | num_inputs |
Input dimension and basis size |
||
| integer, | intent(in) | :: | num_basis |
Input dimension and basis size |
Encoded output tensor