Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove allocations in FeasibilityFormNLS #77

Closed
7 tasks done
tmigot opened this issue Dec 5, 2022 · 5 comments · Fixed by #112
Closed
7 tasks done

Remove allocations in FeasibilityFormNLS #77

tmigot opened this issue Dec 5, 2022 · 5 comments · Fixed by #112

Comments

@tmigot
Copy link
Member

tmigot commented Dec 5, 2022

I run the following script:

using Pkg
Pkg.activate(".")
using LinearAlgebra, NLPModels, NLPModelsModifiers, using NLPModelsTest

# Test FeasibilityFormNLS Models:
problems = setdiff(NLPModelsTest.nls_problems)
map(
  nlp -> print_nlp_allocations(nlp, test_allocs_nlsmodels(nlp, exclude = [hess])),
  map(x -> FeasibilityFormNLS(eval(Symbol(x))()), problems),
) # this is all 0's!!
map(
  nlp -> print_nlp_allocations(nlp, test_allocs_nlpmodels(nlp, linear_api = true, exclude = [hess])),
  map(x -> FeasibilityFormNLS(eval(Symbol(x))()), problems),
)

and it returns

Problem name: LLS_manual-ffnls
                     jprod_nln!: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0
         jac_op_transpose_prod!: ███████⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 224.0
                      cons_lin!: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0
     jac_nln_op_transpose_prod!: ███⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 80.0
                 jac_structure!: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0
             jac_lin_structure!: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0
                      cons_nln!: ███⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 80.0
                    jtprod_nln!: ███⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 80.0
             jac_nln_structure!: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0
                    jtprod_lin!: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0
                   jac_op_prod!: █████████████⋅⋅⋅⋅⋅⋅⋅ 400.0
     jac_lin_op_transpose_prod!: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0
              hess_lag_op_prod!: ██████████████████⋅⋅ 560.0
               jac_lin_op_prod!: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0
                         hprod!: ████████████████████ 656.0
                         jprod!: █████████████⋅⋅⋅⋅⋅⋅⋅ 400.0
               jac_nln_op_prod!: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0
                          cons!: ████████⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 240.0
                          grad!: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0
                  hess_op_prod!: ████████████████████ 656.0
                     hprod_lag!: ██████████████████⋅⋅ 560.0
                        jtprod!: ███████⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 224.0
                            obj: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0
                     jprod_lin!: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0
                     jac_coord!: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0
                 jac_nln_coord!: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0
                 jac_lin_coord!: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0

  Problem name: MGH01_manual-ffnls
                     jprod_nln!: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0
         jac_op_transpose_prod!: ████⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 80.0
     jac_nln_op_transpose_prod!: ████⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 80.0
                 jac_structure!: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0
                      cons_nln!: ████⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 80.0
                    jtprod_nln!: ████⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 80.0
             jac_nln_structure!: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0
                   jac_op_prod!: █████████████████⋅⋅⋅ 400.0
              hess_lag_op_prod!: █████████████████⋅⋅⋅ 400.0
                         hprod!: ████████████████████ 480.0
                         jprod!: █████████████████⋅⋅⋅ 400.0
               jac_nln_op_prod!: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0
                          cons!: ██████████⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 240.0
                          grad!: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0
                  hess_op_prod!: ████████████████████ 480.0
                     hprod_lag!: █████████████████⋅⋅⋅ 400.0
                        jtprod!: ████⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 80.0
                            obj: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0
                     jac_coord!: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0
                 jac_nln_coord!: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0

  Problem name: NLSHS20_manual-ffnls
                     jprod_nln!: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0
         jac_op_transpose_prod!: ██████████⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 240.0
     jac_nln_op_transpose_prod!: ███████⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 160.0
                 jac_structure!: █████⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 112.0
                      cons_nln!: ████⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 80.0
                    jtprod_nln!: ███████⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 160.0
             jac_nln_structure!: █████⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 112.0
                   jac_op_prod!: ████████████████████ 480.0
              hess_lag_op_prod!: █████████████████⋅⋅⋅ 400.0
                         hprod!: ████████████████████ 496.0
                         jprod!: ████████████████████ 480.0
               jac_nln_op_prod!: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0
                          cons!: █████████████⋅⋅⋅⋅⋅⋅⋅ 320.0
                          grad!: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0
                  hess_op_prod!: ████████████████████ 496.0
                     hprod_lag!: █████████████████⋅⋅⋅ 400.0
                        jtprod!: ██████████⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 240.0
                            obj: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0
                     jac_coord!: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0
                 jac_nln_coord!: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0

  Problem name: NLSLINCON-ffnls
                     jprod_nln!: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0
         jac_op_transpose_prod!: ██⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 496.0
                      cons_lin!: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0
     jac_nln_op_transpose_prod!: █⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 176.0
                 jac_structure!: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0
             jac_lin_structure!: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0
                      cons_nln!: █⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 176.0
                    jtprod_nln!: █⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 176.0
             jac_nln_structure!: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0
                    jtprod_lin!: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0
                   jac_op_prod!: ████⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 880.0
     jac_lin_op_transpose_prod!: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0
              hess_lag_op_prod!: ████████████████████ 5456.0
               jac_lin_op_prod!: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0
                         hprod!: ████████████████████ 5728.0
                         jprod!: ████⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 880.0
               jac_nln_op_prod!: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0
                          cons!: ██⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 528.0
                          grad!: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0
                  hess_op_prod!: ████████████████████ 5728.0
                     hprod_lag!: ████████████████████ 5456.0
                        jtprod!: ██⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 496.0
                            obj: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0
                     jprod_lin!: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0
                     jac_coord!: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0
                 jac_nln_coord!: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0
                 jac_lin_coord!: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0.0

so there is potentially the following list to handle:

@tmigot
Copy link
Member Author

tmigot commented Jan 18, 2023

After #90 , only jtprod! allocates and I have no real idea why... There is something happening with the views that I don't really understand. Here is an illustration:

using NLPModels, NLPModelsModifiers, NLPModelsTest
nlp = NLSLC()
nls = FeasibilityFormNLS(nlp)
x = get_x0(nls)
y = get_y0(nls)
Jtv = similar(x)
jtprod!(nls, x, y, Jtv)
@allocated jtprod!(nls, x, y, Jtv) # 144 - Why would this allocate?
Jl = rand(nls.meta.nlin)
jtprod_lin!(nls, x, Jl, Jtv)
@allocated jtprod_lin!(nls, x, Jl, Jtv) # 0
Jl = rand(nls.meta.nnln)
jtprod_nln!(nls, x, Jl, Jtv)
@allocated jtprod_nln!(nls, x, Jl, Jtv) # 0

# Test on the subproblem with views
x = get_x0(nlp)
y = get_y0(nlp)
Jl = rand(nlp.meta.nlin)
Jtv = similar(x)
jtprod_lin!(nlp, x, Jl, Jtv)
@allocated jtprod_lin!(nlp, x, Jl, Jtv) # 0

jtprod_lin!(nlp, view(x, 1:15), Jl, Jtv)
@allocated jtprod_lin!(nlp, view(x, 1:15), Jl, Jtv) # 48 - Why would this allocate?

@dpo
Copy link
Member

dpo commented Feb 26, 2024

Are you saying that others don’t allocate when you create a view? Isn’t it the view itself that allocates?

Julia> @allocated view(x, 1:15)
48

@tmigot
Copy link
Member Author

tmigot commented Feb 26, 2024

From my understanding, views of connected indices shouldn't allocate. You are right in your example, but this:

julia> x = rand(20);

julia> @allocated view(x, 1:15)
1499872

julia> @allocated view(x, 1:15)
48

julia> function fun(x) view(x, 1:15); return nothing end
fun (generic function with 1 method)

julia> @allocated fun(x)
758064

julia> @allocated fun(x)
0

@dpo
Copy link
Member

dpo commented Feb 26, 2024

Sure, but that’s not really what you’re doing above with jtprod!(). What you are doing is basically:

julia> function fun(x) x .= 2; return nothing end
fun (generic function with 1 method)

julia> x = ones(50);

julia> @allocated fun(x)
1072856

julia> @allocated fun(x)
0

julia> @allocated fun(view(x, 1:15))
3420376

julia> @allocated fun(view(x, 1:15))
48

@tmigot
Copy link
Member Author

tmigot commented Feb 26, 2024

Ok, I see, so the problem would be solve if we had re-implemented jtprod! for the initial problem.

After,

function NLPModels.jtprod!(nlp::NLSLC, x::AbstractVector, v::AbstractVector, Jtv::AbstractVector) 
  return jtprod_lin!(nlp, x, v, Jtv)
end

the allocation is 0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants