ralna / RALFit

A non-linear least squares solver
Other
25 stars 6 forks source link

Removal of Automatic Arrays #76

Closed talassio closed 3 years ago

talassio commented 4 years ago

Remove automatic arrays from source

Code has TWO type of triggers for mallocs:

Type one

Calls of the form

Subroutine a(n)
      Integer, Intent(In) :: n
      Real(Kind=wp) :: vector(n)
...

Trigger mallocs and should be removed. A fix could be to propagate workspaces...

Subroutine a(n, vector)
      Integer, Intent(In) :: n
      Real(Kind=wp), Intent(Inout) :: vector(n)
...

Outstanding RALFit mallocs are

Other mallocs are related to calling routines with expresion of the form -vector(1:n)

Call routine(n, -1.0_wp * vector(1:n))

mallocs for the result of -1.0_wp * vector(1:n).

Type two

Dummy arguments assumed shape/size translation

j(*) is addressed as a contiguous block of memory.

j(:) is a structure which varies by compiler

The j(:) memory metadata has to be traversed and flattened to contiguity before passing to j(*), which is why the temp is created.

Giving j(:) the Contiguous attribute should help, that would require it to always be passed 'sensible' Allocatable stuff without strides, and not Pointers.

Proposal for get_Hi

Issue partially fixed by #78, still need to address automatic array ei(m)

     Recursive subroutine get_Hi(n, m, X, params, i, Hi, eval_HF, inform, ei, weights)
       Implicit None
       integer, intent(in) :: n, m
       real(wp), intent(in) :: X(:)
       class( params_base_type ), intent(inout) :: params
       integer, intent(in) :: i
       real(wp), intent(out) :: Hi(:,:)
       procedure( eval_hf_type ) :: eval_HF
       type( nlls_inform ), intent( inout ) :: inform
       real( wp ), dimension( m ), intent( in ), optional :: weights
       real( wp ), Intent(Inout) :: ei( m ) ! <--- Avoid automatic arrays, trigger malloc on demand

       ei(:) = 0.0_wp
       If ( present(weights) ) Then
        ei(i) = weights(i)
       Else
        ei(i) = 1.0_wp
       End If

!      call eval_HF(inform%external_return, n, m, X, weights(1:m)*ei, Hi, params) !<---- avoid trigger to malloc 
!      for the storage of weights(:)*ei wich is double waste of space and work.
!      We should inform the user NOT do to the HP product blindly, first check non-zero entries of ei, which 
!      by construction here has only ONE non-zero.

       call eval_HF(inform%external_return, n, m, X, ei, Hi, params)

       inform%h_eval = inform%h_eval + 1
       If (inform%external_return/=0) Then
         inform%status = NLLS_ERROR_EVALUATION
         inform%external_name = "eval_HF"
         inform%external_return = 2513
       End iF
     end subroutine get_Hi
talassio commented 4 years ago

@tyronerees is already updating this

talassio commented 4 years ago

Updated list of automatic array allocation

Type one fixed by #78

Type one

Ring-fenced GALAHAD code

Type two

talassio commented 4 years ago

This will be closed by the box_logic pull request.