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

make lu! allocate less if possible #104

Closed
wants to merge 5 commits into from
Closed

Conversation

SobhanMP
Copy link
Member

@SobhanMP SobhanMP commented Jun 5, 2022

While at this point it should make things a bit nicer, i have two questions:
1- is there any downside to using broadcase, should i write the loop? and,
2- can we reuse the numeric in umfpack?

Right now, it resizes the fields of the umfpacklu instead of reallocating.

@codecov-commenter
Copy link

codecov-commenter commented Jun 5, 2022

Codecov Report

Merging #104 (672a6bd) into main (7745517) will decrease coverage by 1.32%.
The diff coverage is 81.81%.

@@            Coverage Diff             @@
##             main     #104      +/-   ##
==========================================
- Coverage   34.25%   32.92%   -1.33%     
==========================================
  Files          25       25              
  Lines       21127    21121       -6     
==========================================
- Hits         7237     6955     -282     
- Misses      13890    14166     +276     
Impacted Files Coverage Δ
src/solvers/umfpack.jl 86.72% <81.81%> (+1.35%) ⬆️
src/solvers/lib/x86_64-w64-mingw32.jl 0.00% <0.00%> (-15.97%) ⬇️
src/solvers/lib/i686-w64-mingw32.jl 0.00% <0.00%> (-12.38%) ⬇️
src/sparsematrix.jl 95.32% <0.00%> (+0.04%) ⬆️

📣 Codecov can now indicate which changes are the most critical in Pull Requests. Learn more

@SobhanMP
Copy link
Member Author

can we change the

tmp = Vector{Ptr{Cvoid}}(undef, 1)

to

tmp = Ref{Ptr{Void}}()

in

tmp = Vector{Ptr{Cvoid}}(undef, 1)

?

Also lu! isn't safe in the sense that calling an lu! on a matrix with a different sparsity pattern will result in an error since we reuse the symbolic
(see

if U.symbolic == C_NULL umfpack_symbolic!(U) end
)
but we also support changing the size of the matrix.

One solution would be to provide an argument to recalculate the symbolic. Another would be to just not let any one change the size of the the lu.

@Wimmerer what do you think?

@rayegun
Copy link
Member

rayegun commented Jun 11, 2022

We should probably check that the input pattern is the same when users pass in an entirely new SparseMatrixCSC (they can still pass an nzval vector that's easy to check for length of course). Or mark it as an "expert" method. I'm fine with changing the signature of tmp provided it still works as before.

@rayegun
Copy link
Member

rayegun commented Jun 11, 2022

Also what do you mean reuse the numeric?

@SobhanMP
Copy link
Member Author

i said reuse the symbolic not numeric. Every time umfpack calculates the lu it first calculates the symbolic and then the numeric. The symbolic can be reused if the sparsity pattern is the same (not sure what the speed up is).

@rayegun
Copy link
Member

rayegun commented Jun 11, 2022

While at this point it should make things a bit nicer, i have two questions:
1- is there any downside to using broadcase, should i write the loop? and,
2- can we reuse the numeric in umfpack?

Is what you wrote above, hence my confusion.

Reusing is fine for symbolic, and I'm surprised it wasn't done already. I do it in KLU.jl.

We need to expose the condition number estimates and such if we don't already. You should check those when refactoring.

@SobhanMP
Copy link
Member Author

Ah, you were referring to the comment above, yeah i don't think we can reuse the numeric. To be clear sparse arrays does reuse it. should i leave the error handling to umfpack? or should we also do the checks on the julia side?

what's a condition number estimates?

@rayegun
Copy link
Member

rayegun commented Jun 11, 2022

Leave what error handling you can to UMFPACK, we should be wrapping exceptions there correctly.

rcond is the function, but I'll look into that separately. I'll be home later to look at this PR

@ViralBShah
Copy link
Member

can we change the

tmp = Vector{Ptr{Cvoid}}(undef, 1)

to

tmp = Ref{Ptr{Void}}()

Yes, should be ok to do so. Do you want to add that in this PR?

@SobhanMP
Copy link
Member Author

yes, i'm a bit swamped at the moment, hopefully will have some time to do these changes in a few days.

@ViralBShah
Copy link
Member

ViralBShah commented Jun 19, 2022

No urgency at all. I just have been going through all the issues and PRs today. Needless to say, thanks for all your contributions.

@ViralBShah
Copy link
Member

i said reuse the symbolic not numeric. Every time umfpack calculates the lu it first calculates the symbolic and then the numeric. The symbolic can be reused if the sparsity pattern is the same (not sure what the speed up is).

As a general rule of thumb, I believe symbolic is about 10-15% of the total computation time.

@SobhanMP
Copy link
Member Author

good to know

@SobhanMP
Copy link
Member Author

@Wimmerer @ViralBShah i think this is good to go

@rayegun
Copy link
Member

rayegun commented Jun 23, 2022

We shouldn't need locks anymore now that Control, Info, and workspaces are local to each Factorization right? The correct usage pattern is not to use the locks, but to duplicate the control, info, and workspaces.

@rayegun rayegun self-requested a review June 23, 2022 04:59
@SobhanMP
Copy link
Member Author

i guess, should i remove them? i think that they don't really cost anything and save the headache from unsuspecting people as it's really not intuitive that ldiv! changes the factorization.

@SobhanMP
Copy link
Member Author

also should i add a small footnote about parallel solving to the documentations? like it scales well and stuff i'd use something like

@floop for i in axes(b, 2)
@init w = duplicate(F)
ldiv!(view(x, :, i), w, view(b, :, i))
end

@rayegun
Copy link
Member

rayegun commented Jun 23, 2022

Well I wouldn't put Floops in the official docs yet. But Threads should be good yes.

@SobhanMP
Copy link
Member Author

@Wimmerer i'm still not sure, do i keep the locks? i'll put the parallel stuff in another commit.

@rayegun
Copy link
Member

rayegun commented Jun 23, 2022

Someone more experienced with the pros and cons of locks should probably chime in here :/

Relative to a solve call they're probably a miniscule time loss, so I lean towards leaving them in now.

@ViralBShah
Copy link
Member

@Wimmerer Is this good to merge?

@rayegun
Copy link
Member

rayegun commented Jun 24, 2022

Do the locks make sense to you? It prevents mistakes I guess, even if the intended usage is a thread local view of each Factor.

@ViralBShah
Copy link
Member

Yes, the locks are fairly coarse grained and look ok. @SobhanMP Can we have some tests that do multi-threaded LUs?

@rayegun
Copy link
Member

rayegun commented Jun 24, 2022

I believe they mentioned including those in a separate PR. I may be thinking of docs though. We can merge this part whenever ready.

@ViralBShah
Copy link
Member

Yes, I see multi-threaded LU tests in the testsuite - but wasn't sure if more were needed as part of this PR.

@ViralBShah
Copy link
Member

Actually, let's hold on this one and get an stdlib bump first to get the other recent PRs into Julia nightly - and then merge this one.

@SobhanMP SobhanMP deleted the branch JuliaSparse:main July 12, 2022 18:25
@SobhanMP SobhanMP closed this Jul 12, 2022
@SobhanMP SobhanMP deleted the main branch July 12, 2022 18:25
@ViralBShah
Copy link
Member

What's the reason to close? (out of curiosity).

@SobhanMP
Copy link
Member Author

github bugged, i wanted to make a new branch called main, i thought rename the branch would work

@SobhanMP
Copy link
Member Author

gonna open a new one, if you don't mind

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 this pull request may close these issues.

4 participants