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

Only evaluate necessary solution components during particle property update #6051

Merged
merged 2 commits into from
Oct 14, 2024

Conversation

gassmoeller
Copy link
Member

This is one further performance improvement on top of #6020 and something I wanted to implement for a long time. The particle property interface now allows to:

  • specify which evaluation flags are required for which solution component
  • this information is transported into the solution evaluator class to only evaluate the required components
  • and into the function World::local_update_particles to only copy the requested components into the ParticlePropertyInputs object

If a model uses particle properties that only need certain solution components (like IntegratedStrain) this marks another significant speedup of the particle update cost of up to 40% (in my test model).

One aspect of the code that is not optimal yet is the number of if-conditions necessary inside SolutionEvaluator<dim>::evaluate. One would expect that if FEPointEvaluation::evaluate is called with the evaluation flags nothing that the function returns immediately without expensive work. That is however not what happens at the moment, the function call with nothing is only slightly cheaper than a call to evaluate values. I will open a separate PR against deal.II to see if we can fix that, but for now the current solution works well for ASPECT.

Copy link
Member

@tjhei tjhei left a comment

Choose a reason for hiding this comment

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

Very nice! 👍

* call to reinit().
*
* @p solution_values contains the values of the degrees of freedom.
* @p evaluation_flags controls if nothing, the solution values, or the gradients should be computed.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* @p evaluation_flags controls if nothing, the solution values, or the gradients should be computed.
* @p evaluation_flags controls if nothing, the solution values, and/or the gradients should be computed.

for (unsigned int j=0; j<gradient.size(); ++j)
gradient[j] = inputs.gradients[i][j];
if (get_update_flags(j) & update_gradients)
gradient[j] = inputs.gradients[i][j];
Copy link
Member

Choose a reason for hiding this comment

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

Can we fill these with NaNs in debug mode if not requested?

return update_values | update_gradients;
const auto &component_indices = this->introspection().component_indices;

if (component >= component_indices.velocities[0] &&
Copy link
Member

Choose a reason for hiding this comment

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

Can you do introspection.component_masks.velocities[component]==true instead?

@gassmoeller
Copy link
Member Author

Good suggestions, I addressed all comments.

* The component mask for all composition components.
* This mask selects all compositional fields.
*/
ComponentMask composition;
Copy link
Member

Choose a reason for hiding this comment

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

Should this be "compositions" to be similar to velocities?

if (get_update_flags(j) & update_values)
solution[j] = inputs.solution[i][j];
else
solution[j] = numbers::signaling_nan<double>();
Copy link
Member

Choose a reason for hiding this comment

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

Should we do this only in debug mode for performance reasons or do you think this doesn't matter?

@gassmoeller
Copy link
Member Author

Should this be "compositions" to be similar to velocities?

Yes good point. Changed.

Should we do this only in debug mode for performance reasons or do you think this doesn't matter?

The place you commented on is only the deprecated old interface, in which we allocate one Vector per particle anyway, which will be significantly more expensive than the assignment. So no, I dont think it matters. More interesting is this case which is done in the new interface. I still dont think that setting one value per particle will be a huge cost (even for the gradients where we initialize with a tensor).

@gassmoeller
Copy link
Member Author

Since this was approved and the changes are minor I am going to merge

@gassmoeller gassmoeller merged commit f537114 into geodynamics:main Oct 14, 2024
8 checks passed
@gassmoeller gassmoeller deleted the particle_component_update branch October 14, 2024 12:53
@@ -459,37 +460,41 @@ namespace aspect
++p;
}

const UpdateFlags update_flags = property_manager->get_needed_update_flags();

Copy link
Contributor

Choose a reason for hiding this comment

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

This is the part of the change that caused #6101. We used to get the update flags as UpdateFlags, but now they are EvaluationFlags obtained via a function argument.

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.

3 participants