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
Break the Manifold interface for performance. #4723
Conversation
/no-longer-run-tests (I am trying out if the tester gcc-serial is running on demand now) |
Please submit the What new functionality of BOOST do you need for the current work? |
I only added the new Regardless of this patch: are people OK with adding a new conversion constructor like this one? I am a bit on the fence as to whether or not we should automatically convert The only new boost functionality that I require it |
I think we found Updating boost requirements is a different issue, of course... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm very much in favor of changing this because we really do way too many memory allocations in those places. I have a few comments regarding one of the functions and would suggest to choose larger sizes of around 200 for the small vectors.
By the way, it is not very difficult to work around the boost vector: We use a variable of size [200]
on the stack unconditionally. If it fits, we put the array view on that data type. If not, we put it into an std::vector
. That would maybe be 8x5 more lines of code. I don't know about the usage in manifold.h
, though.
include/deal.II/grid/manifold.h
Outdated
constexpr int n_default_points_per_cell<3>() | ||
{ | ||
return GeometryInfo<3>::vertices_per_cell + GeometryInfo<3>::lines_per_cell | ||
+ GeometryInfo<3>::faces_per_cell; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not simply returning 3^dim-1
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I.e., use Utilities::fixed_int_power<3,dim>::value-1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer to write it out this way so that it is clear what the number signifies.
source/grid/manifold.cc
Outdated
const std::size_t n_points = surrounding_points.size(); | ||
// TODO find a better dimension-dependent estimate for the size of this | ||
// vector | ||
boost::container::small_vector<double, 20> local_weights(n_points); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure we know that. It really depends on the degree of interpolation (or whatever comes in here). In the end, the allocation is a one-time cost that must be paid off by enough operations. I would have chosen a much larger value here, maybe 200 or 500.
// The older version used surrounding_points | ||
new_points[row] = project_to_manifold(make_array_view(surrounding_points.begin(), | ||
surrounding_points.end()), | ||
new_point); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would use surrounding_points_start
but it might be that project_to_manifold
does the necessary adjustments internally. Do we have tests that trigger on one or the other?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure; it has been long enough since I wrote this that I don't even really remember the issue. I will look at this with @luca-heltai at some point during the next few days.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe that the answer is 'yes' and our current implementation is wrong. At the same time, we do not use the surrounding points in FlatManifold::project_to_manifold
(which is another bug in itself; this function should not be the identity function for structdim != spacedim
) so this is really a separate problem.
c00334d
to
1810257
Compare
@kronbichler I have made some of the preliminary changes (and I adopted the little optimization you added in a commit to #2418). I will address things more fully once #2418 is merged. |
Just following up -- what's the status of this patch right now? |
@bangerth What we have now works but there are still some clean-ups I would like to do before merging (see the TODO list at the top of the PR). These are closely related to @kronbichler's criticisms. I haven't spent much time of this recently; I'd like to finish #4798 before returning to this. |
The first part of this patch has been moved to #5024. |
I would prefer to merge #4798 before we get to this but I will write more patches for this PR this week. |
12209b6
to
b8a8df3
Compare
I addressed most of the review comments and made a few other cosmetic changes. I believe that this is ready to be reviewed again. Here are the main points:
After reviewing this and #4798 I don't think it matters which is merged first; this one is probably easier to understand. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had a look through the patch and it looks great. I only have a minor comment. I'm looking forward to using this.
const std::vector<double> &weights) const; | ||
get_new_point (const ArrayView<const Point<spacedim>> &surrounding_points, | ||
const ArrayView<const double> &weights) const; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove one empty line (we use one line distance between function declarations).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
I think the |
/run-tests |
Are there any further comments? If nobody objects, I will merge this PR in a day or two. |
If no one feels strongly about preserving the compatibility shim then I will remove the implicit conversion constructor from |
954ff14
to
d82a525
Compare
fff95e1
to
688c50d
Compare
I have made the requested changes (including the changelog entry). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just two minor comments about the changelog. please fix and merge yourself!
Nice work!
<li>Manifold::project_to_manifold</li> | ||
</ol> | ||
have had their declarations changed in an incompatible manner: these three | ||
methods now take arguments that are ArrayViews instead of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
well, it's actually only two methods :-)
If you write it as "ArrayView objects", then doxygen will link to the class correctly.
eliminates this allocation cost. | ||
|
||
The method <code>Manifold::add_new_points</code> has been removed in favor of | ||
<code>Manifold::get_new_points</code>, which also uses ArrayViews instead of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here
you don't need to use <code>
for `Manifold::get_new_points -- doxygen will automatically print it with tt font because it knows about it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... when using Manifold::get_new_points()
(opening and closing parenthesis).
@drwells Please merge after updating the changelog. Looks good! |
Clang is not happy with the internal function: perhaps it does not like the |
Ah, what a shame. I think you can generally define the function as
Things like |
I cannot locally reproduce the clang problem; I suspect that they have since fixed this bug. I'll upload the fixed version in a moment. |
688c50d
to
d55fd91
Compare
I have made the requested changes. @bangerth's proposal is a lot nicer than the list of internal functions, so I am glad we went back and changed this. |
d55fd91
to
0431503
Compare
Blah, I screwed something up when rebasing on different machines: hold on. |
0431503
to
edb442e
Compare
This commit changes the interfaces of Manifolds::get_default_points_and_weights Manifold::project_to_manifold Manifold::get_new_point Manifold::add_new_points to use ArrayView instead of std::vector. In addition, the interface of add_new_points has been changed to populate the ArrayView argument instead of appending to the end of the array. This breaks the public interface of Manifold for the sake of improving performance by about 30%: profiling indicates that, when creating a grid with a Manifold, we spend about 30% of our time purely calling new and delete since we must create and destroy so many std::vectors.
This function no longer appends new points to a vector so a name change is in order.
edb442e
to
8bc04f9
Compare
All right; this should be good to go now. |
OK to merge once the tester is happy. |
This is the branch which I have mentioned in passing a few times: we spend nearly a third of our time allocating and freeing memory inside of the Manifold functions called when creating a grid.
I am not sure if we want to proceed with this and there are still a few things that need to be fixed:
1.581.59 (update: 1.58 is not compatible with deal.II)Manifolds::get_default_points_and_weights
function could also be improved.In addition, I included a commit that adds a new constructor to
ArrayView
which creates anArrayView
from astd::vector
: this allows all tests but one to pass in their current form.In reference to #4704.