Perform backward pass starting from this array
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(array_type), | intent(inout) | :: | this | |||
| logical, | intent(in), | optional | :: | reset_graph |
module subroutine grad_reverse(this, reset_graph) !! Perform backward pass starting from this array implicit none class(array_type), intent(inout) :: this logical, intent(in), optional :: reset_graph if(present(reset_graph))then if(reset_graph) call this%reset_graph() end if call zero_all_fixed_pointer_grads(this) ! Initialise gradient if not allocated if(.not. associated(this%grad))then allocate(this%grad) ! Safely initialise gradient without copying computation graph call this%grad%allocate(array_shape=[this%shape, size(this%val,2)]) this%grad%is_sample_dependent = this%is_sample_dependent this%grad%requires_grad = .true. this%grad%operation = 'none' this%grad%left_operand => null() this%grad%right_operand => null() this%grad%get_partial_left => null() this%grad%get_partial_right => null() this%grad%grad => null() this%grad%owns_gradient = .false. this%owns_gradient = .true. if(allocated(this%indices)) this%grad%indices = this%indices call this%grad%zero_grad() ! Set gradient to ones for starting node this%grad%val = 1.0_real32 this%grad%is_temporary = this%is_temporary end if ! Recursively compute gradients !call reverse_mode_ptr(this, this%grad, 0) call reverse_mode(this, this%grad%val, 0) end subroutine grad_reverse