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

WIP: Re-introducing three point coupling #2551

Merged
merged 28 commits into from
Mar 6, 2019

Conversation

KaiSzuttor
Copy link
Member

Fixes #2517

Description of changes:

  • reimplementation of three-point interpolation
  • added tests

@KaiSzuttor KaiSzuttor changed the title Re-introducing three point coupling WIP: Re-introducing three point coupling Mar 4, 2019
@codecov
Copy link

codecov bot commented Mar 4, 2019

Codecov Report

Merging #2551 into python will increase coverage by <1%.
The diff coverage is 91%.

Impacted file tree graph

@@           Coverage Diff           @@
##           python   #2551    +/-   ##
=======================================
+ Coverage      75%     75%   +<1%     
=======================================
  Files         494     494            
  Lines       28095   28124    +29     
=======================================
+ Hits        21229   21252    +23     
- Misses       6866    6872     +6
Impacted Files Coverage Δ
src/core/communication.cpp 70% <ø> (ø) ⬆️
src/core/grid_based_algorithms/lbgpu.hpp 100% <ø> (ø) ⬆️
...rc/core/grid_based_algorithms/lb_interpolation.cpp 89% <87%> (-5%) ⬇️
...ore/grid_based_algorithms/lb_particle_coupling.cpp 90% <94%> (-2%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update b453091...af1079e. Read the comment docs.


void mpi_set_interpolation_order_slave(int order, int) {
if (order == 0) {
interpolation_order = InterpolationOrder::linear;
Copy link
Contributor

Choose a reason for hiding this comment

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

You can do interpolation_order = InterpolationOrder{order} without the switch, then you don't have to hard-code the values.

Copy link
Member Author

Choose a reason for hiding this comment

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

this is c++17

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah yeah sorry, you have to do static_cast<InterpolationOrder>(order).

Copy link
Member Author

Choose a reason for hiding this comment

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

what about interpolation_order = static_cast<InterpolationOrder>(order);?

Copy link
Member Author

Choose a reason for hiding this comment

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

this is probably not such a good idea:
https://gcc.godbolt.org/z/Re_etN

Copy link
Contributor

Choose a reason for hiding this comment

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

That is fine here because the value is generated from an enum.

Copy link
Contributor

Choose a reason for hiding this comment

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

If you don't want that you can send the enum value via mpi, they can be serialized...

namespace {
void lb_lbinterpolation_set_interpolation_order(
InterpolationOrder const &interpolation_order) {
if (interpolation_order == InterpolationOrder::linear) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it is cleaner to just do

switch(interpolation_order) {
  case InterpolationOrder::linear:
  case InterpolationOrder::quadratic:
    mpi_call(interpolation_order_slave, static_cast<int>(interpolation_order));
    mpi_set_interpolation_order_slave(static_cast<int>(interpolation_order), 0);
}

or skip the switch if the value checking is not needed. This way you can avoid hard-coding the values, and a compiler warning is emitted if one of the cases is not handled.

@@ -72,12 +100,21 @@ lb_lbinterpolation_get_interpolated_velocity_global(const Vector3d &pos) {
if (lattice_switch & LATTICE_LB_GPU) {
#ifdef LB_GPU
Vector3d interpolated_u{};
lb_get_interpolated_velocity_gpu(folded_pos.data(), interpolated_u.data(),
1);
if (interpolation_order == InterpolationOrder::linear) {
Copy link
Contributor

Choose a reason for hiding this comment

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

switch(interpolation_order)

return interpolated_u;
#endif
} else if (lattice_switch & LATTICE_LB) {
#ifdef LB
if (interpolation_order == InterpolationOrder::quadratic) {
Copy link
Contributor

Choose a reason for hiding this comment

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

switch(interpolation_order)

@@ -92,6 +129,10 @@ lb_lbinterpolation_get_interpolated_velocity_global(const Vector3d &pos) {
#ifdef LB
void lb_lbinterpolation_add_force_density(const Vector3d &pos,
const Vector3d &force_density) {
if (interpolation_order == InterpolationOrder::quadratic) {
Copy link
Contributor

Choose a reason for hiding this comment

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

switch(interpolation_order)

lb_calc_particle_lattice_ia_gpu(couple_virtual,
lb_lbcoupling_get_gamma());
if (lb_particle_coupling.couple_to_md && this_node == 0) {
if (lb_lbinterpolation_get_interpolation_order() ==
Copy link
Contributor

Choose a reason for hiding this comment

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

switch(interpolation_order)

Parameters
----------
interpolation_order : :obj:`int`
0 refers to linear interpolation, 1 to quadratic interpolation.
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not directly use strings for the interpolation order?

(delta[7] * delta_j[2]));
LB_node_force_density_gpu node_f,
bool three_point_coupling) {
int max_node = 8;
Copy link
Contributor

Choose a reason for hiding this comment

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

This information should be encoded into the type of node_index and delta, this is very brittle...

@@ -2307,12 +2246,13 @@ __global__ void
calc_fluid_particle_ia(LB_nodes_gpu n_a, CUDA_particle_data *particle_data,
float *particle_force, LB_node_force_density_gpu node_f,
LB_rho_v_gpu *d_v, bool couple_virtual,
uint64_t philox_counter, float friction) {
uint64_t philox_counter, float friction,
float *lb_boundary_velocity, bool three_point_coupling) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Since there are only two coupling schemes, and this code is performance relevant, I think the coupling scheme should be selected statically and code for both schemes without the branches should be generated. E.g. make the coupling scheme a template parameter and instantiate both versions of this kernel.

@KaiSzuttor
Copy link
Member Author

@fweik

void lb_lbinterpolation_set_interpolation_order(
InterpolationOrder const &order) {
interpolation_order = order;
boost::mpi::broadcast(comm_cart, interpolation_order, 0);
Copy link
Contributor

Choose a reason for hiding this comment

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

The mpi calls need to be the other way around, this is a deadlock.

Copy link
Member Author

Choose a reason for hiding this comment

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

Could you please explain?

Copy link
Contributor

@fweik fweik Mar 6, 2019

Choose a reason for hiding this comment

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

You are blocking on boost::mpi::broadcast before the callback is invoked.

@fweik fweik merged commit b24864f into espressomd:python Mar 6, 2019
@KaiSzuttor KaiSzuttor deleted the three_point_coupling branch March 6, 2019 15:54
@RudolfWeeber
Copy link
Contributor

I think, this pr was merged prematurely, I'm afraid.

This PR decreased the performance of the 2pt coupling by a factor of 3,
I now have a time step of 1.2 sec instead of 0.4 sec for 500k particles.

If the reason for the drag cannot be removed, the changes to the 2pt coupling need to be reverted.

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