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 |
pure subroutine get_partial_gno_agg_features_val( & this, upstream_grad, output) !! In-place gradient w.r.t. features implicit none ! Arguments class(array_type), intent(in) :: this !! Forward result node containing saved operands real(real32), dimension(:,:), intent(in) :: upstream_grad !! Upstream gradient values real(real32), dimension(:,:), intent(out) :: output !! Output gradient values for node features ! Local variables integer :: F_in, F_out, num_v, i, j, jj, edge_idx !! Inferred dimensions and traversal indices ! Infer dimensions from operands F_in = size(this%left_operand%val, 1) F_out = size(upstream_grad, 1) num_v = size(this%left_operand%val, 2) output = 0.0_real32 do i = 1, num_v do jj = this%indices(i), this%indices(i+1) - 1 j = this%adj_ja(1, jj) edge_idx = this%adj_ja(2, jj) ! grad_h(j) += kappa_e^T @ upstream(:,i) ! kappa_e is [F_out*F_in] → reshape to [F_out, F_in] ! kappa_e^T is [F_in, F_out] output(:, j) = output(:, j) + & matmul( & transpose(reshape( & this%right_operand%val(:, edge_idx), [F_out, F_in])), & upstream_grad(:, i) & ) end do end do end subroutine get_partial_gno_agg_features_val