grad_reverse Module Subroutine

module subroutine grad_reverse(this, reset_graph)

Perform backward pass starting from this array

Arguments

Type IntentOptional Attributes Name
class(array_type), intent(inout) :: this
logical, intent(in), optional :: reset_graph

Source Code

  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