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

refactor sync_chunk_connections to remove barrier during fields::step #1635

Merged
merged 1 commit into from
Jun 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions src/boundaries.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ namespace meep {
void fields::set_boundary(boundary_side b, direction d, boundary_condition cond) {
if (boundaries[b][d] != cond) {
boundaries[b][d] = cond;
// we don't need to call sync_chunk_connections() since set_boundary()
// should always be called on every process
chunk_connections_valid = false;
}
}
Expand Down Expand Up @@ -120,11 +122,19 @@ void fields::disconnect_chunks() {
}
}

void fields::connect_chunks() {
/* make sure all processes agree on chunk_connections_valid to avoid deadlocks */
// this should be called by any code that might set chunk_connections_valid = false,
// with the caveat that we need to be careful that we call it on all processes
void fields::sync_chunk_connections() {
/* make sure all processes agree on chunk_connections_valid to avoid deadlocks
when we eventually call connect_chunks */
am_now_working_on(MpiAllTime);
chunk_connections_valid = and_to_all(chunk_connections_valid);
finished_working();
}

void fields::connect_chunks() {
// might have invalidated connections in step_db, update_eh, or update_pols:
if (changed_materials) sync_chunk_connections();

if (!chunk_connections_valid) {
am_now_working_on(Connecting);
Expand Down
12 changes: 11 additions & 1 deletion src/fields.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ fields::fields(structure *s, double m, double beta, bool zero_fields_near_cylori
boundaries[b][d] = None;
}
chunk_connections_valid = false;
changed_materials = true;

// unit directions are periodic by default:
FOR_DIRECTIONS(d) {
Expand Down Expand Up @@ -126,6 +127,7 @@ fields::fields(const fields &thef)
for (int b = 0; b < 2; b++)
FOR_DIRECTIONS(d) { boundaries[b][d] = thef.boundaries[b][d]; }
chunk_connections_valid = false;
changed_materials = true;
}

fields::~fields() {
Expand All @@ -152,6 +154,9 @@ void fields::use_real_fields() {
is_real = 1;
for (int i = 0; i < num_chunks; i++)
chunks[i]->use_real_fields();

// don't need to call sync_chunk_connections() since use_real_fields()
// should always be called on every process
chunk_connections_valid = false;
}

Expand Down Expand Up @@ -492,6 +497,7 @@ void fields::require_source_components() {
for (int c = 0; c < NUM_FIELD_COMPONENTS; ++c)
if (allneeded[c])
_require_component(component(c), aniso2d);
sync_chunk_connections();
}

// check if we are in 2d but anisotropy couples xy with z
Expand Down Expand Up @@ -532,7 +538,9 @@ void fields::_require_component(component c, bool aniso2d) {

if (need_to_reconnect) {
figure_out_step_plan();
chunk_connections_valid = false; // connect_chunks() will synchronize this for us
// we will eventually call sync_chunk_connections(), in either require_component(c)
// or require_components(), to synchronize this across processes:
chunk_connections_valid = false;
}
}

Expand Down Expand Up @@ -566,6 +574,7 @@ void fields_chunk::remove_susceptibilities(bool shared_chunks) {
}

void fields::remove_susceptibilities() {
changed_materials = true;
for (int i = 0; i < num_chunks; i++)
chunks[i]->remove_susceptibilities(shared_chunks);
}
Expand Down Expand Up @@ -635,6 +644,7 @@ int fields::phase_in_material(const structure *snew, double time) {
for (int i = 0; i < num_chunks; i++)
if (chunks[i]->is_mine()) chunks[i]->phase_in_material(snew->chunks[i]);
phasein_time = (int)(time / dt);
changed_materials = true;
// FIXME: how to handle changes in susceptibilities?
return phasein_time;
}
Expand Down
4 changes: 3 additions & 1 deletion src/meep.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1743,7 +1743,7 @@ class fields {
bool is_aniso2d();
void require_source_components();
void _require_component(component c, bool aniso2d);
void require_component(component c) { _require_component(c, is_aniso2d()); }
void require_component(component c) { _require_component(c, is_aniso2d()); sync_chunk_connections(); }
void add_srcdata(struct sourcedata cur_data, src_time *src, size_t n, std::complex<double>* amp_arr);

// mpb.cpp
Expand Down Expand Up @@ -2040,9 +2040,11 @@ class fields {
void figure_out_step_plan();
// boundaries.cpp
bool chunk_connections_valid;
bool changed_materials; // keep track of whether materials have changed (in case field chunk connections need sync'ing)
void find_metals();
void disconnect_chunks();
void connect_chunks();
void sync_chunk_connections();
void connect_the_chunks(); // Intended to be ultra-private...
bool on_metal_boundary(const ivec &);
ivec ilattice_vector(direction) const;
Expand Down
2 changes: 2 additions & 0 deletions src/step.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ void fields::step() {
synchronized_magnetic_fields = save_synchronized_magnetic_fields;
}

changed_materials = false; // any material changes were handled in connect_chunks()

if (!std::isfinite(get_field(D_EnergyDensity, gv.center(), false)))
meep::abort("simulation fields are NaN or Inf");
}
Expand Down
6 changes: 5 additions & 1 deletion src/step_db.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <assert.h>

#include "meep.hpp"
#include "meep_internals.hpp"
Expand All @@ -32,7 +33,10 @@ namespace meep {
void fields::step_db(field_type ft) {
for (int i = 0; i < num_chunks; i++)
if (chunks[i]->is_mine())
if (chunks[i]->step_db(ft)) chunk_connections_valid = false;
if (chunks[i]->step_db(ft)) {
chunk_connections_valid = false;
assert(changed_materials);
}
}

bool fields_chunk::step_db(field_type ft) {
Expand Down
5 changes: 4 additions & 1 deletion src/update_eh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/

#include <string.h>
#include <assert.h>

#include "meep.hpp"
#include "meep_internals.hpp"
Expand All @@ -28,8 +29,10 @@ void fields::update_eh(field_type ft, bool skip_w_components) {
if (ft != E_stuff && ft != H_stuff) meep::abort("update_eh only works with E/H");
for (int i = 0; i < num_chunks; i++)
if (chunks[i]->is_mine())
if (chunks[i]->update_eh(ft, skip_w_components))
if (chunks[i]->update_eh(ft, skip_w_components)) {
chunk_connections_valid = false; // E/H allocated - reconnect chunks
assert(changed_materials);
}
}

bool fields_chunk::needs_W_prev(component c) const {
Expand Down
6 changes: 5 additions & 1 deletion src/update_pols.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <assert.h>

#include "meep.hpp"
#include "meep_internals.hpp"
Expand All @@ -30,7 +31,10 @@ namespace meep {
void fields::update_pols(field_type ft) {
for (int i = 0; i < num_chunks; i++)
if (chunks[i]->is_mine())
if (chunks[i]->update_pols(ft)) chunk_connections_valid = false;
if (chunks[i]->update_pols(ft)) {
chunk_connections_valid = false;
assert(changed_materials);
}
}

bool fields_chunk::update_pols(field_type ft) {
Expand Down