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

Add unit tests for BoutMesh::load #2245

Merged
merged 54 commits into from
May 10, 2021
Merged

Add unit tests for BoutMesh::load #2245

merged 54 commits into from
May 10, 2021

Conversation

ZedThree
Copy link
Member

@ZedThree ZedThree commented Mar 1, 2021

Adds various unit tests for BoutMesh::load by splitting it into smaller helper methods and testing those, plus unit tests for some other BoutMesh methods. This enables parameterised tests, for instance, checking a double-null configuration can be split across various processor combinations. Each of these tests takes less than 3ms, and it's very easy to add a new combination to test, so it would be interesting to get some more variations in.

There's still some more bits left to pull out into helper functions and test, so this is WIP till then.

It should also be possible to test the communication routines to some extent as well, as we've got MpiWrapper that allows us to use GoogleMock to test routines that use MPI.

Helps clarify which numbers are the grid sizes and which are the
decomposition indices
Wrong value when called with `yind == ny`: this should be
out-of-range. Never called with this value, so should not be a
problem
This test is really not very clever, but it's difficult to see how to
write a better one
Clean up the existing tests with helper functions, expand to more configurations
@ZedThree
Copy link
Member Author

Now also fixes a whole host of clang-tidy warnings

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

clang-tidy made some suggestions

src/mesh/impls/bout/boutmesh.cxx Show resolved Hide resolved
src/mesh/impls/bout/boutmesh.cxx Show resolved Hide resolved
@@ -1181,7 +1257,7 @@ int BoutMesh::wait(comm_handle handle) {
int ind, len;
MPI_Status status;

if (ch->var_list.size() == 0) {
if (ch->var_list.empty()) {

// Just waiting for a single MPI request
mpi->MPI_Wait(ch->request, &status);
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: Request has no matching nonblocking call. [clang-analyzer-optin.mpi.MPI-Checker]

mpi->MPI_Wait(ch->request, &status);
    ^
src/mesh/impls/bout/boutmesh.cxx:1242:7: note: Assuming the condition is false
  if (handle == nullptr) {
      ^
src/mesh/impls/bout/boutmesh.cxx:1242:3: note: Taking false branch
  if (handle == nullptr) {
  ^
src/mesh/impls/bout/boutmesh.cxx:1248:7: note: Assuming field 'in_progress' is true
  if (!ch->in_progress) {
      ^
src/mesh/impls/bout/boutmesh.cxx:1248:3: note: Taking false branch
  if (!ch->in_progress) {
  ^
src/mesh/impls/bout/boutmesh.cxx:1260:7: note: Assuming the condition is true
  if (ch->var_list.empty()) {
      ^
src/mesh/impls/bout/boutmesh.cxx:1260:3: note: Taking true branch
  if (ch->var_list.empty()) {
  ^
src/mesh/impls/bout/boutmesh.cxx:1263:5: note: Request  has no matching nonblocking call. 
    mpi->MPI_Wait(ch->request, &status);
    ^

} while (ind != MPI_UNDEFINED);

if (async_send) {
/// Asyncronous sending: Need to check if sends have completed (frees MPI memory)
MPI_Status async_status;

if (UDATA_INDEST != -1)
if (UDATA_INDEST != -1) {
mpi->MPI_Wait(ch->sendreq, &async_status);
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: Request has no matching nonblocking call. [clang-analyzer-optin.mpi.MPI-Checker]

mpi->MPI_Wait(ch->sendreq, &async_status);
      ^
src/mesh/impls/bout/boutmesh.cxx:1242:7: note: Assuming the condition is false
  if (handle == nullptr) {
      ^
src/mesh/impls/bout/boutmesh.cxx:1242:3: note: Taking false branch
  if (handle == nullptr) {
  ^
src/mesh/impls/bout/boutmesh.cxx:1248:7: note: Assuming field 'in_progress' is true
  if (!ch->in_progress) {
      ^
src/mesh/impls/bout/boutmesh.cxx:1248:3: note: Taking false branch
  if (!ch->in_progress) {
  ^
src/mesh/impls/bout/boutmesh.cxx:1260:7: note: Assuming the condition is false
  if (ch->var_list.empty()) {
      ^
src/mesh/impls/bout/boutmesh.cxx:1260:3: note: Taking false branch
  if (ch->var_list.empty()) {
  ^
src/mesh/impls/bout/boutmesh.cxx:1271:5: note: 'Default' branch taken. Execution continues on line 1308
    switch (ind) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1308:9: note: Assuming the condition is false
    if (ind != MPI_UNDEFINED) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1308:5: note: Taking false branch
    if (ind != MPI_UNDEFINED) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1269:3: note: Loop condition is false.  Exiting loop
  do {
  ^
src/mesh/impls/bout/boutmesh.cxx:1313:7: note: Assuming field 'async_send' is true
  if (async_send) {
      ^
src/mesh/impls/bout/boutmesh.cxx:1313:3: note: Taking true branch
  if (async_send) {
  ^
src/mesh/impls/bout/boutmesh.cxx:1317:9: note: Assuming the condition is true
    if (UDATA_INDEST != -1) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1317:5: note: Taking true branch
    if (UDATA_INDEST != -1) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1318:7: note: Request  has no matching nonblocking call. 
      mpi->MPI_Wait(ch->sendreq, &async_status);
      ^

mpi->MPI_Wait(ch->sendreq, &async_status);
if (UDATA_OUTDEST != -1)
}
if (UDATA_OUTDEST != -1) {
mpi->MPI_Wait(ch->sendreq + 1, &async_status);
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: Request has no matching nonblocking call. [clang-analyzer-optin.mpi.MPI-Checker]

mpi->MPI_Wait(ch->sendreq + 1, &async_status);
      ^
src/mesh/impls/bout/boutmesh.cxx:1242:7: note: Assuming the condition is false
  if (handle == nullptr) {
      ^
src/mesh/impls/bout/boutmesh.cxx:1242:3: note: Taking false branch
  if (handle == nullptr) {
  ^
src/mesh/impls/bout/boutmesh.cxx:1248:7: note: Assuming field 'in_progress' is true
  if (!ch->in_progress) {
      ^
src/mesh/impls/bout/boutmesh.cxx:1248:3: note: Taking false branch
  if (!ch->in_progress) {
  ^
src/mesh/impls/bout/boutmesh.cxx:1260:7: note: Assuming the condition is false
  if (ch->var_list.empty()) {
      ^
src/mesh/impls/bout/boutmesh.cxx:1260:3: note: Taking false branch
  if (ch->var_list.empty()) {
  ^
src/mesh/impls/bout/boutmesh.cxx:1271:5: note: 'Default' branch taken. Execution continues on line 1308
    switch (ind) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1308:9: note: Assuming the condition is false
    if (ind != MPI_UNDEFINED) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1308:5: note: Taking false branch
    if (ind != MPI_UNDEFINED) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1269:3: note: Loop condition is false.  Exiting loop
  do {
  ^
src/mesh/impls/bout/boutmesh.cxx:1313:7: note: Assuming field 'async_send' is true
  if (async_send) {
      ^
src/mesh/impls/bout/boutmesh.cxx:1313:3: note: Taking true branch
  if (async_send) {
  ^
src/mesh/impls/bout/boutmesh.cxx:1317:9: note: Assuming the condition is false
    if (UDATA_INDEST != -1) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1317:5: note: Taking false branch
    if (UDATA_INDEST != -1) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1320:9: note: Assuming the condition is true
    if (UDATA_OUTDEST != -1) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1320:5: note: Taking true branch
    if (UDATA_OUTDEST != -1) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1321:7: note: Request  has no matching nonblocking call. 
      mpi->MPI_Wait(ch->sendreq + 1, &async_status);
      ^

mpi->MPI_Wait(ch->sendreq + 2, &async_status);
if (DDATA_OUTDEST != -1)
}
if (DDATA_OUTDEST != -1) {
mpi->MPI_Wait(ch->sendreq + 3, &async_status);
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: Request has no matching nonblocking call. [clang-analyzer-optin.mpi.MPI-Checker]

mpi->MPI_Wait(ch->sendreq + 3, &async_status);
      ^
src/mesh/impls/bout/boutmesh.cxx:1242:7: note: Assuming the condition is false
  if (handle == nullptr) {
      ^
src/mesh/impls/bout/boutmesh.cxx:1242:3: note: Taking false branch
  if (handle == nullptr) {
  ^
src/mesh/impls/bout/boutmesh.cxx:1248:7: note: Assuming field 'in_progress' is true
  if (!ch->in_progress) {
      ^
src/mesh/impls/bout/boutmesh.cxx:1248:3: note: Taking false branch
  if (!ch->in_progress) {
  ^
src/mesh/impls/bout/boutmesh.cxx:1260:7: note: Assuming the condition is false
  if (ch->var_list.empty()) {
      ^
src/mesh/impls/bout/boutmesh.cxx:1260:3: note: Taking false branch
  if (ch->var_list.empty()) {
  ^
src/mesh/impls/bout/boutmesh.cxx:1271:5: note: 'Default' branch taken. Execution continues on line 1308
    switch (ind) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1308:9: note: Assuming the condition is false
    if (ind != MPI_UNDEFINED) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1308:5: note: Taking false branch
    if (ind != MPI_UNDEFINED) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1269:3: note: Loop condition is false.  Exiting loop
  do {
  ^
src/mesh/impls/bout/boutmesh.cxx:1313:7: note: Assuming field 'async_send' is true
  if (async_send) {
      ^
src/mesh/impls/bout/boutmesh.cxx:1313:3: note: Taking true branch
  if (async_send) {
  ^
src/mesh/impls/bout/boutmesh.cxx:1317:9: note: Assuming the condition is false
    if (UDATA_INDEST != -1) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1317:5: note: Taking false branch
    if (UDATA_INDEST != -1) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1320:9: note: Assuming the condition is false
    if (UDATA_OUTDEST != -1) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1320:5: note: Taking false branch
    if (UDATA_OUTDEST != -1) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1323:9: note: Assuming the condition is false
    if (DDATA_INDEST != -1) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1323:5: note: Taking false branch
    if (DDATA_INDEST != -1) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1326:9: note: Assuming the condition is true
    if (DDATA_OUTDEST != -1) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1326:5: note: Taking true branch
    if (DDATA_OUTDEST != -1) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1327:7: note: Request  has no matching nonblocking call. 
      mpi->MPI_Wait(ch->sendreq + 3, &async_status);
      ^

mpi->MPI_Wait(ch->sendreq + 3, &async_status);
if (IDATA_DEST != -1)
}
if (IDATA_DEST != -1) {
mpi->MPI_Wait(ch->sendreq + 4, &async_status);
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: Request has no matching nonblocking call. [clang-analyzer-optin.mpi.MPI-Checker]

mpi->MPI_Wait(ch->sendreq + 4, &async_status);
      ^
src/mesh/impls/bout/boutmesh.cxx:1242:7: note: Assuming the condition is false
  if (handle == nullptr) {
      ^
src/mesh/impls/bout/boutmesh.cxx:1242:3: note: Taking false branch
  if (handle == nullptr) {
  ^
src/mesh/impls/bout/boutmesh.cxx:1248:7: note: Assuming field 'in_progress' is true
  if (!ch->in_progress) {
      ^
src/mesh/impls/bout/boutmesh.cxx:1248:3: note: Taking false branch
  if (!ch->in_progress) {
  ^
src/mesh/impls/bout/boutmesh.cxx:1260:7: note: Assuming the condition is false
  if (ch->var_list.empty()) {
      ^
src/mesh/impls/bout/boutmesh.cxx:1260:3: note: Taking false branch
  if (ch->var_list.empty()) {
  ^
src/mesh/impls/bout/boutmesh.cxx:1271:5: note: 'Default' branch taken. Execution continues on line 1308
    switch (ind) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1308:9: note: Assuming the condition is false
    if (ind != MPI_UNDEFINED) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1308:5: note: Taking false branch
    if (ind != MPI_UNDEFINED) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1269:3: note: Loop condition is false.  Exiting loop
  do {
  ^
src/mesh/impls/bout/boutmesh.cxx:1313:7: note: Assuming field 'async_send' is true
  if (async_send) {
      ^
src/mesh/impls/bout/boutmesh.cxx:1313:3: note: Taking true branch
  if (async_send) {
  ^
src/mesh/impls/bout/boutmesh.cxx:1317:9: note: Assuming the condition is false
    if (UDATA_INDEST != -1) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1317:5: note: Taking false branch
    if (UDATA_INDEST != -1) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1320:9: note: Assuming the condition is false
    if (UDATA_OUTDEST != -1) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1320:5: note: Taking false branch
    if (UDATA_OUTDEST != -1) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1323:9: note: Assuming the condition is false
    if (DDATA_INDEST != -1) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1323:5: note: Taking false branch
    if (DDATA_INDEST != -1) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1326:9: note: Assuming the condition is false
    if (DDATA_OUTDEST != -1) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1326:5: note: Taking false branch
    if (DDATA_OUTDEST != -1) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1329:9: note: Assuming the condition is true
    if (IDATA_DEST != -1) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1329:5: note: Taking true branch
    if (IDATA_DEST != -1) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1330:7: note: Request  has no matching nonblocking call. 
      mpi->MPI_Wait(ch->sendreq + 4, &async_status);
      ^

mpi->MPI_Wait(ch->sendreq + 4, &async_status);
if (ODATA_DEST != -1)
}
if (ODATA_DEST != -1) {
mpi->MPI_Wait(ch->sendreq + 5, &async_status);
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: Request has no matching nonblocking call. [clang-analyzer-optin.mpi.MPI-Checker]

mpi->MPI_Wait(ch->sendreq + 5, &async_status);
      ^
src/mesh/impls/bout/boutmesh.cxx:1242:7: note: Assuming the condition is false
  if (handle == nullptr) {
      ^
src/mesh/impls/bout/boutmesh.cxx:1242:3: note: Taking false branch
  if (handle == nullptr) {
  ^
src/mesh/impls/bout/boutmesh.cxx:1248:7: note: Assuming field 'in_progress' is true
  if (!ch->in_progress) {
      ^
src/mesh/impls/bout/boutmesh.cxx:1248:3: note: Taking false branch
  if (!ch->in_progress) {
  ^
src/mesh/impls/bout/boutmesh.cxx:1260:7: note: Assuming the condition is false
  if (ch->var_list.empty()) {
      ^
src/mesh/impls/bout/boutmesh.cxx:1260:3: note: Taking false branch
  if (ch->var_list.empty()) {
  ^
src/mesh/impls/bout/boutmesh.cxx:1271:5: note: 'Default' branch taken. Execution continues on line 1308
    switch (ind) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1308:9: note: Assuming the condition is false
    if (ind != MPI_UNDEFINED) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1308:5: note: Taking false branch
    if (ind != MPI_UNDEFINED) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1269:3: note: Loop condition is false.  Exiting loop
  do {
  ^
src/mesh/impls/bout/boutmesh.cxx:1313:7: note: Assuming field 'async_send' is true
  if (async_send) {
      ^
src/mesh/impls/bout/boutmesh.cxx:1313:3: note: Taking true branch
  if (async_send) {
  ^
src/mesh/impls/bout/boutmesh.cxx:1317:9: note: Assuming the condition is false
    if (UDATA_INDEST != -1) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1317:5: note: Taking false branch
    if (UDATA_INDEST != -1) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1320:9: note: Assuming the condition is false
    if (UDATA_OUTDEST != -1) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1320:5: note: Taking false branch
    if (UDATA_OUTDEST != -1) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1323:9: note: Assuming the condition is false
    if (DDATA_INDEST != -1) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1323:5: note: Taking false branch
    if (DDATA_INDEST != -1) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1326:9: note: Assuming the condition is false
    if (DDATA_OUTDEST != -1) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1326:5: note: Taking false branch
    if (DDATA_OUTDEST != -1) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1329:9: note: Assuming the condition is false
    if (IDATA_DEST != -1) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1329:5: note: Taking false branch
    if (IDATA_DEST != -1) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1332:9: note: Assuming the condition is true
    if (ODATA_DEST != -1) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1332:5: note: Taking true branch
    if (ODATA_DEST != -1) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1333:7: note: Request  has no matching nonblocking call. 
      mpi->MPI_Wait(ch->sendreq + 5, &async_status);
      ^

src/mesh/impls/bout/boutmesh.cxx Show resolved Hide resolved
src/mesh/impls/bout/boutmesh.hxx Show resolved Hide resolved
MPI types are `int_t` in MPICH, not opaque pointers like in OpenMPI
@ZedThree
Copy link
Member Author

clang-tidy is worried about a few MPI calls, mostly when async_send is true. I've not managed to follow the logic through myself yet, but could be something we need to look at.

@ZedThree
Copy link
Member Author

Not really related to this PR, but I think we can now squash BoutMesh::load into the constructor and remove Mesh::load entirely. It looks like we need to remove the call to Mesh::getCoordinates at the end of load to initialise the Coordinates, and rely on fields creating them as needed. All the tests pass, but maybe there's still some cases that this would break.

@johnomotani
Copy link
Contributor

maybe there's still some cases that this would break.

I can't think of any immediately. Anything that uses Coordinates members will need to get a pointer to some Coordinates using Mesh::getCoordinates() (either directly or through Field*::getCoordinates()), so I think Coordinates should always be created when they are needed.

@ZedThree
Copy link
Member Author

I guess I was thinking of if we create a staggered field before anything else -- but that issue is sorted now, right?

I'll make another PR for that change, this one is already way, way bigger than I was expecting/hoping!

@johnomotani
Copy link
Contributor

I guess I was thinking of if we create a staggered field before anything else -- but that issue is sorted now, right?

Good point, I hadn't thought about that! But I think it's OK, when we create staggered Coordinates, they'll just get/create the CELL_CENTRE ones first - I think we fixed the problem with initialising things in the coords_map.

BOUT-dev/src/mesh/mesh.cxx

Lines 433 to 444 in e7920b7

std::shared_ptr<Coordinates> Mesh::createDefaultCoordinates(const CELL_LOC location,
bool force_interpolate_from_centre) {
if (location == CELL_CENTRE || location == CELL_DEFAULT) {
// Initialize coordinates from input
return std::make_shared<Coordinates>(this, options);
} else {
// Interpolate coordinates from CELL_CENTRE version
return std::make_shared<Coordinates>(this, options, location,
getCoordinates(CELL_CENTRE), force_interpolate_from_centre);
}
}

…aries

Add Mesh method to get all possible boundary regions
Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

clang-tidy made some suggestions

@@ -942,7 +948,7 @@ class Mesh {
// The maxregionblocksize to use when creating the default regions.
// Can be set in the input file and the global default is set by,
// MAXREGIONBLOCKSIZE in include/bout/region.hxx
int maxregionblocksize;
int maxregionblocksize{MAXREGIONBLOCKSIZE};
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: member variable maxregionblocksize has public visibility [cppcoreguidelines-non-private-member-variables-in-classes]

int maxregionblocksize{MAXREGIONBLOCKSIZE};
    ^

@@ -73,113 +77,42 @@ BoutMesh::~BoutMesh() {
clear_handles();

// Delete the boundary regions
for (const auto &bndry : boundary)
for (const auto& bndry : boundary) {
delete bndry;
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: deleting a pointer through a type that is not marked gsl::owner<>; consider using a smart pointer instead [cppcoreguidelines-owning-memory]

delete bndry;
    ^
src/mesh/impls/bout/boutmesh.cxx:80:8: note: variable declared here
  for (const auto& bndry : boundary) {
       ^

delete bndry;
for (const auto &bndry : par_boundary)
}
for (const auto& bndry : par_boundary) {
delete bndry;
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: deleting a pointer through a type that is not marked gsl::owner<>; consider using a smart pointer instead [cppcoreguidelines-owning-memory]

delete bndry;
    ^
src/mesh/impls/bout/boutmesh.cxx:83:8: note: variable declared here
  for (const auto& bndry : par_boundary) {
       ^

@@ -1181,7 +1318,7 @@ int BoutMesh::wait(comm_handle handle) {
int ind, len;
MPI_Status status;

if (ch->var_list.size() == 0) {
if (ch->var_list.empty()) {

// Just waiting for a single MPI request
mpi->MPI_Wait(ch->request, &status);
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: Request has no matching nonblocking call. [clang-analyzer-optin.mpi.MPI-Checker]

mpi->MPI_Wait(ch->request, &status);
    ^
src/mesh/impls/bout/boutmesh.cxx:1303:7: note: Assuming the condition is false
  if (handle == nullptr) {
      ^
src/mesh/impls/bout/boutmesh.cxx:1303:3: note: Taking false branch
  if (handle == nullptr) {
  ^
src/mesh/impls/bout/boutmesh.cxx:1309:7: note: Assuming field 'in_progress' is true
  if (!ch->in_progress) {
      ^
src/mesh/impls/bout/boutmesh.cxx:1309:3: note: Taking false branch
  if (!ch->in_progress) {
  ^
src/mesh/impls/bout/boutmesh.cxx:1321:7: note: Assuming the condition is true
  if (ch->var_list.empty()) {
      ^
src/mesh/impls/bout/boutmesh.cxx:1321:3: note: Taking true branch
  if (ch->var_list.empty()) {
  ^
src/mesh/impls/bout/boutmesh.cxx:1324:5: note: Request  has no matching nonblocking call. 
    mpi->MPI_Wait(ch->request, &status);
    ^

} while (ind != MPI_UNDEFINED);

if (async_send) {
/// Asyncronous sending: Need to check if sends have completed (frees MPI memory)
MPI_Status async_status;

if (UDATA_INDEST != -1)
if (UDATA_INDEST != -1) {
mpi->MPI_Wait(ch->sendreq, &async_status);
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: Request has no matching nonblocking call. [clang-analyzer-optin.mpi.MPI-Checker]

mpi->MPI_Wait(ch->sendreq, &async_status);
      ^
src/mesh/impls/bout/boutmesh.cxx:1303:7: note: Assuming the condition is false
  if (handle == nullptr) {
      ^
src/mesh/impls/bout/boutmesh.cxx:1303:3: note: Taking false branch
  if (handle == nullptr) {
  ^
src/mesh/impls/bout/boutmesh.cxx:1309:7: note: Assuming field 'in_progress' is true
  if (!ch->in_progress) {
      ^
src/mesh/impls/bout/boutmesh.cxx:1309:3: note: Taking false branch
  if (!ch->in_progress) {
  ^
src/mesh/impls/bout/boutmesh.cxx:1321:7: note: Assuming the condition is false
  if (ch->var_list.empty()) {
      ^
src/mesh/impls/bout/boutmesh.cxx:1321:3: note: Taking false branch
  if (ch->var_list.empty()) {
  ^
src/mesh/impls/bout/boutmesh.cxx:1332:5: note: 'Default' branch taken. Execution continues on line 1369
    switch (ind) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1369:9: note: Assuming the condition is false
    if (ind != MPI_UNDEFINED) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1369:5: note: Taking false branch
    if (ind != MPI_UNDEFINED) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1330:3: note: Loop condition is false.  Exiting loop
  do {
  ^
src/mesh/impls/bout/boutmesh.cxx:1374:7: note: Assuming field 'async_send' is true
  if (async_send) {
      ^
src/mesh/impls/bout/boutmesh.cxx:1374:3: note: Taking true branch
  if (async_send) {
  ^
src/mesh/impls/bout/boutmesh.cxx:1378:9: note: Assuming the condition is true
    if (UDATA_INDEST != -1) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1378:5: note: Taking true branch
    if (UDATA_INDEST != -1) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1379:7: note: Request  has no matching nonblocking call. 
      mpi->MPI_Wait(ch->sendreq, &async_status);
      ^

mpi->MPI_Wait(ch->sendreq + 2, &async_status);
if (DDATA_OUTDEST != -1)
}
if (DDATA_OUTDEST != -1) {
mpi->MPI_Wait(ch->sendreq + 3, &async_status);
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: Request has no matching nonblocking call. [clang-analyzer-optin.mpi.MPI-Checker]

mpi->MPI_Wait(ch->sendreq + 3, &async_status);
      ^
src/mesh/impls/bout/boutmesh.cxx:1303:7: note: Assuming the condition is false
  if (handle == nullptr) {
      ^
src/mesh/impls/bout/boutmesh.cxx:1303:3: note: Taking false branch
  if (handle == nullptr) {
  ^
src/mesh/impls/bout/boutmesh.cxx:1309:7: note: Assuming field 'in_progress' is true
  if (!ch->in_progress) {
      ^
src/mesh/impls/bout/boutmesh.cxx:1309:3: note: Taking false branch
  if (!ch->in_progress) {
  ^
src/mesh/impls/bout/boutmesh.cxx:1321:7: note: Assuming the condition is false
  if (ch->var_list.empty()) {
      ^
src/mesh/impls/bout/boutmesh.cxx:1321:3: note: Taking false branch
  if (ch->var_list.empty()) {
  ^
src/mesh/impls/bout/boutmesh.cxx:1332:5: note: 'Default' branch taken. Execution continues on line 1369
    switch (ind) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1369:9: note: Assuming the condition is false
    if (ind != MPI_UNDEFINED) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1369:5: note: Taking false branch
    if (ind != MPI_UNDEFINED) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1330:3: note: Loop condition is false.  Exiting loop
  do {
  ^
src/mesh/impls/bout/boutmesh.cxx:1374:7: note: Assuming field 'async_send' is true
  if (async_send) {
      ^
src/mesh/impls/bout/boutmesh.cxx:1374:3: note: Taking true branch
  if (async_send) {
  ^
src/mesh/impls/bout/boutmesh.cxx:1378:9: note: Assuming the condition is false
    if (UDATA_INDEST != -1) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1378:5: note: Taking false branch
    if (UDATA_INDEST != -1) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1381:9: note: Assuming the condition is false
    if (UDATA_OUTDEST != -1) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1381:5: note: Taking false branch
    if (UDATA_OUTDEST != -1) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1384:9: note: Assuming the condition is false
    if (DDATA_INDEST != -1) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1384:5: note: Taking false branch
    if (DDATA_INDEST != -1) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1387:9: note: Assuming the condition is true
    if (DDATA_OUTDEST != -1) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1387:5: note: Taking true branch
    if (DDATA_OUTDEST != -1) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1388:7: note: Request  has no matching nonblocking call. 
      mpi->MPI_Wait(ch->sendreq + 3, &async_status);
      ^

mpi->MPI_Wait(ch->sendreq + 3, &async_status);
if (IDATA_DEST != -1)
}
if (IDATA_DEST != -1) {
mpi->MPI_Wait(ch->sendreq + 4, &async_status);
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: Request has no matching nonblocking call. [clang-analyzer-optin.mpi.MPI-Checker]

mpi->MPI_Wait(ch->sendreq + 4, &async_status);
      ^
src/mesh/impls/bout/boutmesh.cxx:1303:7: note: Assuming the condition is false
  if (handle == nullptr) {
      ^
src/mesh/impls/bout/boutmesh.cxx:1303:3: note: Taking false branch
  if (handle == nullptr) {
  ^
src/mesh/impls/bout/boutmesh.cxx:1309:7: note: Assuming field 'in_progress' is true
  if (!ch->in_progress) {
      ^
src/mesh/impls/bout/boutmesh.cxx:1309:3: note: Taking false branch
  if (!ch->in_progress) {
  ^
src/mesh/impls/bout/boutmesh.cxx:1321:7: note: Assuming the condition is false
  if (ch->var_list.empty()) {
      ^
src/mesh/impls/bout/boutmesh.cxx:1321:3: note: Taking false branch
  if (ch->var_list.empty()) {
  ^
src/mesh/impls/bout/boutmesh.cxx:1332:5: note: 'Default' branch taken. Execution continues on line 1369
    switch (ind) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1369:9: note: Assuming the condition is false
    if (ind != MPI_UNDEFINED) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1369:5: note: Taking false branch
    if (ind != MPI_UNDEFINED) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1330:3: note: Loop condition is false.  Exiting loop
  do {
  ^
src/mesh/impls/bout/boutmesh.cxx:1374:7: note: Assuming field 'async_send' is true
  if (async_send) {
      ^
src/mesh/impls/bout/boutmesh.cxx:1374:3: note: Taking true branch
  if (async_send) {
  ^
src/mesh/impls/bout/boutmesh.cxx:1378:9: note: Assuming the condition is false
    if (UDATA_INDEST != -1) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1378:5: note: Taking false branch
    if (UDATA_INDEST != -1) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1381:9: note: Assuming the condition is false
    if (UDATA_OUTDEST != -1) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1381:5: note: Taking false branch
    if (UDATA_OUTDEST != -1) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1384:9: note: Assuming the condition is false
    if (DDATA_INDEST != -1) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1384:5: note: Taking false branch
    if (DDATA_INDEST != -1) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1387:9: note: Assuming the condition is false
    if (DDATA_OUTDEST != -1) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1387:5: note: Taking false branch
    if (DDATA_OUTDEST != -1) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1390:9: note: Assuming the condition is true
    if (IDATA_DEST != -1) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1390:5: note: Taking true branch
    if (IDATA_DEST != -1) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1391:7: note: Request  has no matching nonblocking call. 
      mpi->MPI_Wait(ch->sendreq + 4, &async_status);
      ^

mpi->MPI_Wait(ch->sendreq + 4, &async_status);
if (ODATA_DEST != -1)
}
if (ODATA_DEST != -1) {
mpi->MPI_Wait(ch->sendreq + 5, &async_status);
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: Request has no matching nonblocking call. [clang-analyzer-optin.mpi.MPI-Checker]

mpi->MPI_Wait(ch->sendreq + 5, &async_status);
      ^
src/mesh/impls/bout/boutmesh.cxx:1303:7: note: Assuming the condition is false
  if (handle == nullptr) {
      ^
src/mesh/impls/bout/boutmesh.cxx:1303:3: note: Taking false branch
  if (handle == nullptr) {
  ^
src/mesh/impls/bout/boutmesh.cxx:1309:7: note: Assuming field 'in_progress' is true
  if (!ch->in_progress) {
      ^
src/mesh/impls/bout/boutmesh.cxx:1309:3: note: Taking false branch
  if (!ch->in_progress) {
  ^
src/mesh/impls/bout/boutmesh.cxx:1321:7: note: Assuming the condition is false
  if (ch->var_list.empty()) {
      ^
src/mesh/impls/bout/boutmesh.cxx:1321:3: note: Taking false branch
  if (ch->var_list.empty()) {
  ^
src/mesh/impls/bout/boutmesh.cxx:1332:5: note: 'Default' branch taken. Execution continues on line 1369
    switch (ind) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1369:9: note: Assuming the condition is false
    if (ind != MPI_UNDEFINED) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1369:5: note: Taking false branch
    if (ind != MPI_UNDEFINED) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1330:3: note: Loop condition is false.  Exiting loop
  do {
  ^
src/mesh/impls/bout/boutmesh.cxx:1374:7: note: Assuming field 'async_send' is true
  if (async_send) {
      ^
src/mesh/impls/bout/boutmesh.cxx:1374:3: note: Taking true branch
  if (async_send) {
  ^
src/mesh/impls/bout/boutmesh.cxx:1378:9: note: Assuming the condition is false
    if (UDATA_INDEST != -1) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1378:5: note: Taking false branch
    if (UDATA_INDEST != -1) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1381:9: note: Assuming the condition is false
    if (UDATA_OUTDEST != -1) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1381:5: note: Taking false branch
    if (UDATA_OUTDEST != -1) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1384:9: note: Assuming the condition is false
    if (DDATA_INDEST != -1) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1384:5: note: Taking false branch
    if (DDATA_INDEST != -1) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1387:9: note: Assuming the condition is false
    if (DDATA_OUTDEST != -1) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1387:5: note: Taking false branch
    if (DDATA_OUTDEST != -1) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1390:9: note: Assuming the condition is false
    if (IDATA_DEST != -1) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1390:5: note: Taking false branch
    if (IDATA_DEST != -1) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1393:9: note: Assuming the condition is true
    if (ODATA_DEST != -1) {
        ^
src/mesh/impls/bout/boutmesh.cxx:1393:5: note: Taking true branch
    if (ODATA_DEST != -1) {
    ^
src/mesh/impls/bout/boutmesh.cxx:1394:7: note: Request  has no matching nonblocking call. 
      mpi->MPI_Wait(ch->sendreq + 5, &async_status);
      ^

@@ -1806,11 +1907,27 @@ BoutMesh::BoutMesh(int input_nx, int input_ny, int input_nz, int mxg, int myg, i
addBoundaryRegions();
}

BoutMesh::BoutMesh(int input_nx, int input_ny, int input_nz, int mxg, int myg, int nxpe,
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: constructor does not initialize these fields: MX, MY, MZ, MYSUB, MXSUB, MZSUB, jyseps1_1, jyseps2_1, jyseps1_2, jyseps2_2, ixseps_inner, ixseps_outer, ixseps_upper, ixseps_lower, ny_inner, TS_up_in, TS_up_out, TS_down_in, TS_down_out, UDATA_INDEST, UDATA_OUTDEST, UDATA_XSPLIT, DDATA_INDEST, DDATA_OUTDEST, DDATA_XSPLIT, IDATA_DEST, ODATA_DEST, TwistShift, zperiod, ZMIN, ZMAX [cppcoreguidelines-pro-type-member-init]

BoutMesh::BoutMesh(int input_nx, int input_ny, int input_nz, int mxg, int myg, int nxpe,
^

int pe_xind, int pe_yind);
int pe_xind, int pe_yind, bool create_topology = true, bool symmetric_X = true,
bool symmetric_Y = true);
BoutMesh(int input_nx, int input_ny, int input_nz, int mxg, int myg, int nxpe, int nype,
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: function BoutMesh::BoutMesh has a definition with different parameter names [readability-inconsistent-declaration-parameter-name]

BoutMesh(int input_nx, int input_ny, int input_nz, int mxg, int myg, int nxpe, int nype,
  ^
/github/workspace/src/mesh/impls/bout/boutmesh.cxx:1910:11: note: the definition seen here
BoutMesh::BoutMesh(int input_nx, int input_ny, int input_nz, int mxg, int myg, int nxpe,
          ^
src/mesh/impls/bout/boutmesh.hxx:214:3: note: differing parameters are named here: ('periodic_X'), in definition: ('periodicX_')
  BoutMesh(int input_nx, int input_ny, int input_nz, int mxg, int myg, int nxpe, int nype,
  ^

johnomotani
johnomotani previously approved these changes May 9, 2021
Copy link
Contributor

@johnomotani johnomotani left a comment

Choose a reason for hiding this comment

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

Looks good to me, although I only skimmed over the unit test files very quickly.

Having test coverage of BoutMesh is awesome, thanks @ZedThree! 🎉

src/mesh/impls/bout/boutmesh.cxx Outdated Show resolved Hide resolved
src/mesh/impls/bout/boutmesh.cxx Outdated Show resolved Hide resolved
tests/unit/mesh/test_boutmesh.cxx Outdated Show resolved Hide resolved
tests/unit/mesh/test_mesh.cxx Outdated Show resolved Hide resolved
* next: (102 commits)
  Docs: Fix sphinx conf.py for breathe 4.30
  CMake: Print link to generated docs after completion
  CMake: Fix typo in docs comment
  Move constraint creation to utility method
  CMake: Default to not building the docs
  CMake: Be explicit that docs aren't built in `all`
  CMake: Fix typo
  Make method parameter names consistent (clang-tidy fix)
  Check version of SUNDIALS is new enough for constraints
  Option to set positivity constraints in CVODE
  Option to change max nonlinear iterations in CVODE
  GHA: Don't build the docs for other Github actions either
  GHA: Don't build docs on github
  CMake: Build documentation
  [skip ci] Apply black changes
  Update installation suggestions for Marconi/gnu
  fix order of date and time
  Fix compilation
  Faster recompile
  Remove checks for old behaviour of bool conversion
  ...
@ZedThree
Copy link
Member Author

Thanks @johnomotani , sorted your comments

Copy link
Contributor

@johnomotani johnomotani left a comment

Choose a reason for hiding this comment

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

Looks good to me 👍

@ZedThree
Copy link
Member Author

Failing test is just readthedocs, should be fixed in #2310

@ZedThree ZedThree merged commit 5800806 into next May 10, 2021
@ZedThree ZedThree deleted the split-boutmesh-load branch May 10, 2021 15:04
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.

None yet

2 participants