Skip to content

Optimize matrix_cl constructors - #1421

Merged
rok-cesnovar merged 12 commits into
stan-dev:developfrom
bstatcomp:matrix_cl_no_blocking
Dec 10, 2019
Merged

rok-cesnovar merged 12 commits into
stan-dev:developfrom
bstatcomp:matrix_cl_no_blocking

Conversation

@t4c1

@t4c1 t4c1 commented Oct 25, 2019 •

Copy link
Copy Markdown
Contributor

Summary

Added separate constructor to matrix_cl that accepts Eigen Map.

When constructing matrix_cl from rvalue it is moved to heap and deleted after the copy is done.

To achieve that some trait metaprograms were added to is_eigen.hpp.

Tests

None. These are just optimizations that do not change interface.

Side Effects

None.

Checklist

  • Math issue Optimize matrix_cl constructors #1420

  • Copyright holder: Tadej Ciglarič

    The copyright holder is typically you or your assignee, such as a university or company. By submitting this pull request, the copyright holder is agreeing to the license the submitted work under the following licenses:
    - Code: BSD 3-clause (https://opensource.org/licenses/BSD-3-Clause)
    - Documentation: CC-BY 4.0 (https://creativecommons.org/licenses/by/4.0/)

  • the basic tests are passing

    • unit tests pass (to run, use: ./runTests.py test/unit)
    • header checks pass, (make test-headers)
    • docs build, (make doxygen)
    • code passes the built in C++ standards checks (make cpplint)
  • the code is written in idiomatic C++ and changes are documented in the doxygen

  • the new changes are tested

@rok-cesnovar rok-cesnovar self-assigned this Oct 25, 2019
@stan-buildbot

Copy link
Copy Markdown
Contributor

(stat_comp_benchmarks/benchmarks/gp_pois_regr/gp_pois_regr.stan, 1.0)
(stat_comp_benchmarks/benchmarks/low_dim_corr_gauss/low_dim_corr_gauss.stan, 0.99)
(stat_comp_benchmarks/benchmarks/irt_2pl/irt_2pl.stan, 1.01)
(stat_comp_benchmarks/benchmarks/pkpd/one_comp_mm_elim_abs.stan, 0.98)
(stat_comp_benchmarks/benchmarks/eight_schools/eight_schools.stan, 1.0)
(stat_comp_benchmarks/benchmarks/gp_regr/gp_regr.stan, 1.01)
(stat_comp_benchmarks/benchmarks/arK/arK.stan, 0.99)
(performance.compilation, 1.01)
(stat_comp_benchmarks/benchmarks/low_dim_gauss_mix_collapse/low_dim_gauss_mix_collapse.stan, 1.0)
(stat_comp_benchmarks/benchmarks/low_dim_gauss_mix/low_dim_gauss_mix.stan, 1.03)
(stat_comp_benchmarks/benchmarks/sir/sir.stan, 1.0)
(stat_comp_benchmarks/benchmarks/pkpd/sim_one_comp_mm_elim_abs.stan, 1.03)
(stat_comp_benchmarks/benchmarks/garch/garch.stan, 0.99)
(stat_comp_benchmarks/benchmarks/gp_regr/gen_gp_data.stan, 1.0)
(stat_comp_benchmarks/benchmarks/arma/arma.stan, 0.99)
Result: 1.00150312367
Commit hash: cbe1033

@SteveBronder SteveBronder left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Few Qs!

Comment thread stan/math/prim/mat/meta/is_eigen.hpp
Comment thread stan/math/opencl/matrix_cl.hpp

@syclik syclik left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This still needs work:

  1. the implementation is buggy. That needs to be fixed.
  2. the PR needs more careful doc. The design relies on side-effects; these aren't appropriately documented in the PR. The PR just needs to accurately describe what the side-effects are so when this PR is merged, we know how this is affecting other parts of the code.

Comment thread stan/math/opencl/matrix_cl.hpp
@syclik

syclik commented Nov 6, 2019

Copy link
Copy Markdown
Member

@t4c1, want to video chat sometime today or tomorrow? @SteveBronder, you free too? I'd like to discuss:

  1. design. Have you talk through why it should be done this way, if you've evaluated the other ways to accomplish this, if there's some way to be a little more safe about this.
  2. required things to do on the PR regardless of design. I think we've identified that this hasn't met the requirements of doxygen documentation and the PR description should be updated. I haven't even had a chance to see if there are tests that match, so we might have to do that.

Thanks for starting a new thread. I'll respond there for discussion about "side effects."

@syclik

syclik commented Nov 6, 2019

Copy link
Copy Markdown
Member

Also... mind fixing the code conflict? We can't move on this PR until that's taken care of too.

@t4c1

t4c1 commented Nov 6, 2019

Copy link
Copy Markdown
Contributor Author

That conflict is due to a refactor PR #1407 being reverted because of a bug. After that is fixed and refactor gets back into develop this conflict should go away.

We can do a chat tommorow. I have time between 8h and 15h CET.

@syclik

syclik commented Nov 7, 2019

Copy link
Copy Markdown
Member

Ah. I don't think I'm going to be able to make those times tomorrow. (I'm in eastern time zone... if I interpreted the times correctly, that's 2am-9am). Usually, I'd be able to make 14h CET, but tomorrow I have an early meeting.

Friday?

@SteveBronder

Copy link
Copy Markdown
Collaborator

I could do Friday 14-15 CET

@syclik

syclik commented Nov 7, 2019

Copy link
Copy Markdown
Member

Me too.

@t4c1

t4c1 commented Nov 7, 2019

Copy link
Copy Markdown
Contributor Author

Friday 14h CET it is!

@syclik

syclik commented Nov 7, 2019

Copy link
Copy Markdown
Member

Awesome. Talk to you tomorrow! I'm sending conference info via a Discourse pm.

@SteveBronder

Copy link
Copy Markdown
Collaborator

Ack sorry, I don't understand the concept of time zones and thought this was at 9 AM EST.

Was going to ask why we don't just use a shared pointer here instead of the callback. Since then we can keep track of reference counts and it automatically deletes when there are zero references. Little bulky but very clean

@syclik

syclik commented Nov 8, 2019

Copy link
Copy Markdown
Member

I just got off a video call with @t4c1. This is neat! Some things that happened:

  1. @t4c1 walked me through the design. This one makes sense. He was able to walk me through the common patterns of managing memory and explained how they actually don't quite work out. Specifically, he walked me through the logic of how the common pattern of having a member variable storing the location of the allocated memory isn't ideal. There are two constraints driving the existing design:

    1. this is asynchronous code. In order to handle things with different callbacks or hold onto the reference and delete in the destructor, we'd have to be threadsafe and wait for certain things to happen, which are often out of our control.
    2. early recovery of allocated memory. Using the callback allows the memory to be released back into the system when the function is called. Under most normal conditions, this will happen within the lifetime of the matrix_cl object, so it makes sense not to have it when destructed.

    That leads to the current design making sense, even though on first glance it looks like a leak. The next point addresses that.

  2. We discussed some of the required documentation. Things like initialize_buffer() assume ownership of memory under certain conditions and it's not clear what the requirements are for the function. @t4c1 is going to update some of the documentation to make things clearer.

  3. @t4c1 found a spot in the constructor that needed to be fixed; he has the details and will fix it.

Overall, the state of the code is nearly there. What is required prior to merging is an update on the documentation so it's clear why this deviates from a standard pattern. That should also include the required documentation on functions mentioning their requirements on memory persistence so it's clear to the next reader what's happening.

Thanks, @t4c1!

@t4c1

t4c1 commented Nov 8, 2019

Copy link
Copy Markdown
Contributor Author

@SteveBronder If we used shared pointer (or any other smart pointer) an store it in the matrix_cl object we could not release the memory until the matrix_cl object goes out of scope. This way we can release the memory as soon it is not needed anymore (which is often much sooner than the matrix goes out of scope).

@SteveBronder

Copy link
Copy Markdown
Collaborator

idt you even need to store it though since the shared_ptr is not deleted until it's reference count goes to zero no? You could just make one, pass it into initialize_buffer then once the last reference goes away all is well

That sounds right? I'll mess with this later to see if it works

@t4c1

t4c1 commented Nov 8, 2019

Copy link
Copy Markdown
Contributor Author

Reference count for the shared ponter is the same thing as the number of shared pointer objects that hold the same pointer. So if we create shared pointer in constructor and don't store it as a member variable that shared ponter will go out of scope when the constructor returns and the memory will be deleted. This is not what we want.

@syclik

syclik commented Nov 28, 2019

Copy link
Copy Markdown
Member

@t4c1, this has conflicts that has to be resolved. (Sorry -- I didn't realize you added the doc; adding commits alone does not notify reviewers.)

* matrices on the OpenCL device. Each matrix is flattened into one column
* of the resulting matrix_cl.
* of the resulting matrix_cl. If a lvalue is passed to this constructor the
* caller must make sure that the vector does not go out of scope before

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@t4c1, first off, thank you for adding information that there is a requirement on the caller to handle memory.

The documentation isn't quite there yet. It's not clear from reading this when "copying is complete." If I'm trying to understand the requirements on memory management, it would help to be more precise about what this means.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hopefully it is clear now.

t4c1 added 3 commits November 28, 2019 09:19
# Conflicts:
#	stan/math/opencl/copy.hpp
#	stan/math/opencl/matrix_cl.hpp
# Conflicts:
#	stan/math/opencl/copy.hpp
#	stan/math/opencl/matrix_cl.hpp
@stan-buildbot

Copy link
Copy Markdown
Contributor

(stat_comp_benchmarks/benchmarks/gp_pois_regr/gp_pois_regr.stan, 1.0)
(stat_comp_benchmarks/benchmarks/low_dim_corr_gauss/low_dim_corr_gauss.stan, 0.99)
(stat_comp_benchmarks/benchmarks/irt_2pl/irt_2pl.stan, 1.0)
(stat_comp_benchmarks/benchmarks/pkpd/one_comp_mm_elim_abs.stan, 0.98)
(stat_comp_benchmarks/benchmarks/eight_schools/eight_schools.stan, 1.0)
(stat_comp_benchmarks/benchmarks/gp_regr/gp_regr.stan, 1.0)
(stat_comp_benchmarks/benchmarks/arK/arK.stan, 1.0)
(performance.compilation, 1.02)
(stat_comp_benchmarks/benchmarks/low_dim_gauss_mix_collapse/low_dim_gauss_mix_collapse.stan, 1.0)
(stat_comp_benchmarks/benchmarks/low_dim_gauss_mix/low_dim_gauss_mix.stan, 1.01)
(stat_comp_benchmarks/benchmarks/sir/sir.stan, 1.0)
(stat_comp_benchmarks/benchmarks/pkpd/sim_one_comp_mm_elim_abs.stan, 0.97)
(stat_comp_benchmarks/benchmarks/garch/garch.stan, 1.01)
(stat_comp_benchmarks/benchmarks/gp_regr/gen_gp_data.stan, 0.97)
(stat_comp_benchmarks/benchmarks/arma/arma.stan, 1.02)
Result: 0.99683340255
Commit hash: caab623

@t4c1

t4c1 commented Dec 4, 2019

Copy link
Copy Markdown
Contributor Author

@syclik This is now ready for review.

@syclik syclik left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @t4c1. Sorry for the delay... I think it's good enough for now. The doc is still a little tough for a client to understand exactly what they're supposed to do, but I think it leaves enough hints for this to be parseable and understandable, and that's what we want.

@syclik
syclik dismissed SteveBronder’s stale review December 10, 2019 16:07

The blocking comments were resolved. Everything's good to go now.

@syclik

syclik commented Dec 10, 2019

Copy link
Copy Markdown
Member

@SteveBronder, I "dismissed" your review on the PR. @t4c1 went through and addressed all the comments and I checked it over. There was one outstanding question that was in your court, but since it went unanswered, I think it's fine.

@rok-cesnovar
rok-cesnovar merged commit 45231d1 into stan-dev:develop Dec 10, 2019
@SteveBronder

Copy link
Copy Markdown
Collaborator

Sorry, I stopped responding because I'm uncertain whether this is good or not. If your both comfortable with it then I'm fine with abstaining

@SteveBronder

Copy link
Copy Markdown
Collaborator

I've also been pretty busy at work and a lot of the stuff in this PR was unclear and I didn't have time to meaningfully look at it

@syclik

syclik commented Dec 10, 2019

Copy link
Copy Markdown
Member

It’s all good.

The important things are:

  1. It’s documented we’ll enough for someone to pick up in the future.
  2. It’s passing tests.
  3. It had been reviewed carefully.

As with most implementations, we’re not looking for the perfect solution. Things change and hopefully we know enough to fix it if it needs to change in the future.

@rok-cesnovar
rok-cesnovar deleted the matrix_cl_no_blocking branch January 8, 2020 13:26
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.

5 participants