From 63e6f776e67c8c4f9329aaa9c66abbb728a7b77a Mon Sep 17 00:00:00 2001 From: melt Date: Fri, 23 Aug 2024 14:53:02 +0200 Subject: [PATCH] feat: added metadata info on neighbours add metadata info for periodic and non-periodic neighbours i.e., halo sizes, starting indices etc. add an associated unit test to check values are read correctly from file. --- core/src/ModelMetadata.cpp | 86 ++++++++++++++- core/src/include/ModelMetadata.hpp | 26 ++++- core/test/CMakeLists.txt | 30 +++++- core/test/ModelMetadata_test.cpp | 149 ++++++++++++++++++++++++++ core/test/partition_metadata_3_cb.cdl | 108 +++++++++++++++++++ core/test/partition_metadata_3_pb.cdl | 132 +++++++++++++++++++++++ 6 files changed, 524 insertions(+), 7 deletions(-) create mode 100644 core/test/ModelMetadata_test.cpp create mode 100644 core/test/partition_metadata_3_cb.cdl create mode 100644 core/test/partition_metadata_3_pb.cdl diff --git a/core/src/ModelMetadata.cpp b/core/src/ModelMetadata.cpp index 65fbbb23f..5d0be43bb 100644 --- a/core/src/ModelMetadata.cpp +++ b/core/src/ModelMetadata.cpp @@ -10,6 +10,9 @@ #include "include/IStructure.hpp" #include "include/NextsimModule.hpp" #include "include/gridNames.hpp" +#include "mpi.h" +#include +#include #ifdef USE_MPI #include @@ -39,6 +42,75 @@ void ModelMetadata::setMpiMetadata(MPI_Comm comm) MPI_Comm_rank(mpiComm, &mpiMyRank); } +void ModelMetadata::readNeighbourData(netCDF::NcFile& ncFile) +{ + netCDF::NcGroup neighbourGroup(ncFile.getGroup(neighbourName)); + std::string varName {}; + for (auto edge : edges) { + size_t nStart {}; // start point in metadata arrays + size_t count {}; // number of elements to read from metadata arrays + std::vector numNeighbours = std::vector(mpiSize, 0); + std::vector offsets = std::vector(mpiSize, 0); + + // non-periodic neighbours + varName = edgeNames[edge] + "_neighbours"; + neighbourGroup.getVar(varName).getVar( + { 0 }, { static_cast(mpiSize) }, &numNeighbours[0]); + + // compute start index for each process + MPI_Exscan(&numNeighbours[mpiMyRank], &nStart, 1, MPI_INT, MPI_SUM, mpiComm); + // how many elements to read for each process + count = numNeighbours[mpiMyRank]; + + if (count) { + // initialize neighbour info to zero and correct size + neighbourRanks[edge].resize(count, 0); + neighbourExtents[edge].resize(count, 0); + neighbourHaloStarts[edge].resize(count, 0); + + varName = edgeNames[edge] + "_neighbour_ids"; + neighbourGroup.getVar(varName).getVar({ nStart }, { count }, &neighbourRanks[edge][0]); + + varName = edgeNames[edge] + "_neighbour_halos"; + neighbourGroup.getVar(varName).getVar( + { nStart }, { count }, &neighbourExtents[edge][0]); + + varName = edgeNames[edge] + "_neighbour_halo_starts"; + neighbourGroup.getVar(varName).getVar( + { nStart }, { count }, &neighbourHaloStarts[edge][0]); + } + + // periodic neighbours + varName = edgeNames[edge] + "_neighbours_periodic"; + neighbourGroup.getVar(varName).getVar( + { 0 }, { static_cast(mpiSize) }, &numNeighbours[0]); + + // compute start index for each process + MPI_Exscan(&numNeighbours[mpiMyRank], &nStart, 1, MPI_INT, MPI_SUM, mpiComm); + // how many elements to read for each process + count = numNeighbours[mpiMyRank]; + + if (count) { + // initialize neighbour info to zero and correct size + neighbourRanksPeriodic[edge].resize(count, 0); + neighbourExtentsPeriodic[edge].resize(count, 0); + neighbourHaloStartsPeriodic[edge].resize(count, 0); + + varName = edgeNames[edge] + "_neighbour_ids_periodic"; + neighbourGroup.getVar(varName).getVar( + { nStart }, { count }, &neighbourRanksPeriodic[edge][0]); + + varName = edgeNames[edge] + "_neighbour_halos_periodic"; + neighbourGroup.getVar(varName).getVar( + { nStart }, { count }, &neighbourExtentsPeriodic[edge][0]); + + varName = edgeNames[edge] + "_neighbour_halo_starts_periodic"; + neighbourGroup.getVar(varName).getVar( + { nStart }, { count }, &neighbourHaloStartsPeriodic[edge][0]); + } + } +} + void ModelMetadata::getPartitionMetadata(std::string partitionFile) { // TODO: Move the reading of the partition file to its own class @@ -53,11 +125,15 @@ void ModelMetadata::getPartitionMetadata(std::string partitionFile) globalExtentX = ncFile.getDim("NX").getSize(); globalExtentY = ncFile.getDim("NY").getSize(); netCDF::NcGroup bboxGroup(ncFile.getGroup(bboxName)); - std::vector index(1, mpiMyRank); - bboxGroup.getVar("domain_x").getVar(index, &localCornerX); - bboxGroup.getVar("domain_y").getVar(index, &localCornerY); - bboxGroup.getVar("domain_extent_x").getVar(index, &localExtentX); - bboxGroup.getVar("domain_extent_y").getVar(index, &localExtentY); + + std::vector rank(1, mpiMyRank); + bboxGroup.getVar("domain_x").getVar(rank, &localCornerX); + bboxGroup.getVar("domain_y").getVar(rank, &localCornerY); + bboxGroup.getVar("domain_extent_x").getVar(rank, &localExtentX); + bboxGroup.getVar("domain_extent_y").getVar(rank, &localExtentY); + + readNeighbourData(ncFile); + ncFile.close(); } diff --git a/core/src/include/ModelMetadata.hpp b/core/src/include/ModelMetadata.hpp index ad4956c7a..8f06cdabd 100644 --- a/core/src/include/ModelMetadata.hpp +++ b/core/src/include/ModelMetadata.hpp @@ -13,7 +13,9 @@ #include "include/ModelState.hpp" #include "include/Time.hpp" +#include #include +#include #ifdef USE_MPI #include @@ -93,13 +95,34 @@ class ModelMetadata { */ void getPartitionMetadata(std::string partitionFile); + enum Edge { BOTTOM, RIGHT, TOP, LEFT, N_EDGE }; + // An array to allow the edges to be accessed in the correct order. + static constexpr std::array edges = { BOTTOM, RIGHT, TOP, LEFT }; + std::array edgeNames = { "bottom", "right", "top", "left" }; + MPI_Comm mpiComm; int mpiSize = 0; int mpiMyRank = -1; - int localCornerX, localCornerY, localExtentX, localExtentY, globalExtentX, globalExtentY; + int localCornerX, localCornerY; + int localExtentX, localExtentY; + int globalExtentX, globalExtentY; + // mpi rank ID and extent for each edge direction + std::array, N_EDGE> neighbourRanks; + std::array, N_EDGE> neighbourExtents; + std::array, N_EDGE> neighbourHaloStarts; + std::array, N_EDGE> neighbourRanksPeriodic; + std::array, N_EDGE> neighbourExtentsPeriodic; + std::array, N_EDGE> neighbourHaloStartsPeriodic; #endif private: + /*! + * @brief Read neighbour metadata from netCDF file + * + * @param netCDF file with partition metadata + */ + void readNeighbourData(netCDF::NcFile& ncFile); + TimePoint m_time; ConfigMap m_config; @@ -116,6 +139,7 @@ class ModelMetadata { bool hasParameters; #ifdef USE_MPI const std::string bboxName = "bounding_boxes"; + const std::string neighbourName = "connectivity"; #endif }; diff --git a/core/test/CMakeLists.txt b/core/test/CMakeLists.txt index 6c353289a..65b72c514 100644 --- a/core/test/CMakeLists.txt +++ b/core/test/CMakeLists.txt @@ -32,10 +32,24 @@ if(ENABLE_MPI) ncgen -b -o partition_metadata_2.nc ${CMAKE_CURRENT_SOURCE_DIR}/partition_metadata_2.cdl DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/partition_metadata_2.cdl ) + add_custom_command( + OUTPUT partition_metadata_3_cb.nc partition_metadata_3_pb.nc + COMMAND + ncgen -b -o partition_metadata_3_cb.nc ${CMAKE_CURRENT_SOURCE_DIR}/partition_metadata_3_cb.cdl + COMMAND + ncgen -b -o partition_metadata_3_pb.nc ${CMAKE_CURRENT_SOURCE_DIR}/partition_metadata_3_pb.cdl + DEPENDS + ${CMAKE_CURRENT_SOURCE_DIR}/partition_metadata_3_cb.cdl + ${CMAKE_CURRENT_SOURCE_DIR}/partition_metadata_3_pb.cdl + ) add_custom_target( generate_partition_files ALL - DEPENDS partition_metadata_3.nc partition_metadata_2.nc + DEPENDS + partition_metadata_3.nc + partition_metadata_2.nc + partition_metadata_3_cb.nc + partition_metadata_3_pb.nc ) add_executable(testRectGrid_MPI3 "RectGrid_test.cpp" "MainMPI.cpp") @@ -49,6 +63,20 @@ if(ENABLE_MPI) ) target_link_libraries(testRectGrid_MPI3 PRIVATE nextsimlib doctest::doctest) + add_executable(testModelMetadata_MPI3 "ModelMetadata_test.cpp" "MainMPI.cpp") + target_compile_definitions( + testModelMetadata_MPI3 + PRIVATE + USE_MPI + TEST_FILES_DIR=\"${CMAKE_CURRENT_BINARY_DIR}\" + TEST_FILE_SOURCE=\"${CMAKE_CURRENT_SOURCE_DIR}\" + ) + target_include_directories( + testModelMetadata_MPI3 + PRIVATE ${MODEL_INCLUDE_DIR} "${ModulesRoot}/StructureModule" + ) + target_link_libraries(testModelMetadata_MPI3 PRIVATE nextsimlib doctest::doctest) + add_executable(testParaGrid_MPI2 "ParaGrid_test.cpp" "MainMPI.cpp") target_compile_definitions( testParaGrid_MPI2 diff --git a/core/test/ModelMetadata_test.cpp b/core/test/ModelMetadata_test.cpp new file mode 100644 index 000000000..2da43c959 --- /dev/null +++ b/core/test/ModelMetadata_test.cpp @@ -0,0 +1,149 @@ +/*! + * @file ModelMetadata_test.cpp + * + * @date 18 Nov 2024 + * @author Tom Meltzer + */ + +#include +#include + +#include "ModelMetadata.hpp" + +const std::string testFilesDir = TEST_FILES_DIR; +const std::string filename = testFilesDir + "/paraGrid_test.nc"; +const std::string diagFile = "paraGrid_diag.nc"; +const std::string dateString = "2000-01-01T00:00:00Z"; +const std::string partitionFilenameCB = testFilesDir + "/partition_metadata_3_cb.nc"; +const std::string partitionFilenamePB = testFilesDir + "/partition_metadata_3_pb.nc"; + +namespace Nextsim { + +TEST_SUITE_BEGIN("ModelMetadata"); +MPI_TEST_CASE("Test getPartitionMetadata closed boundary", 3) +{ + ModelMetadata metadata(partitionFilenameCB, test_comm); + REQUIRE(metadata.mpiComm == test_comm); + // this metadata is specific to the non-periodic boundary conditions + if (test_rank == 0) { + REQUIRE(metadata.neighbourRanks[ModelMetadata::LEFT].size() == 0); + REQUIRE(metadata.neighbourRanks[ModelMetadata::RIGHT] == std::vector { 2 }); + REQUIRE(metadata.neighbourExtents[ModelMetadata::RIGHT] == std::vector { 4 }); + REQUIRE(metadata.neighbourHaloStarts[ModelMetadata::RIGHT] == std::vector { 0 }); + REQUIRE(metadata.neighbourRanks[ModelMetadata::BOTTOM].size() == 0); + REQUIRE(metadata.neighbourRanks[ModelMetadata::TOP] == std::vector { 1 }); + REQUIRE(metadata.neighbourExtents[ModelMetadata::TOP] == std::vector { 7 }); + REQUIRE(metadata.neighbourHaloStarts[ModelMetadata::TOP] == std::vector { 0 }); + } else if (test_rank == 1) { + REQUIRE(metadata.neighbourRanks[ModelMetadata::LEFT].size() == 0); + REQUIRE(metadata.neighbourRanks[ModelMetadata::RIGHT] == std::vector { 2 }); + REQUIRE(metadata.neighbourExtents[ModelMetadata::RIGHT] == std::vector { 5 }); + REQUIRE(metadata.neighbourHaloStarts[ModelMetadata::RIGHT] == std::vector { 12 }); + REQUIRE(metadata.neighbourRanks[ModelMetadata::BOTTOM] == std::vector { 0 }); + REQUIRE(metadata.neighbourExtents[ModelMetadata::BOTTOM] == std::vector { 7 }); + REQUIRE(metadata.neighbourHaloStarts[ModelMetadata::BOTTOM] == std::vector { 21 }); + REQUIRE(metadata.neighbourRanks[ModelMetadata::TOP].size() == 0); + } else if (test_rank == 2) { + REQUIRE(metadata.neighbourRanks[ModelMetadata::LEFT] == std::vector { 0, 1 }); + REQUIRE(metadata.neighbourExtents[ModelMetadata::LEFT] == std::vector { 4, 5 }); + REQUIRE(metadata.neighbourHaloStarts[ModelMetadata::LEFT] == std::vector { 6, 6 }); + REQUIRE(metadata.neighbourRanks[ModelMetadata::RIGHT].size() == 0); + REQUIRE(metadata.neighbourRanks[ModelMetadata::BOTTOM].size() == 0); + REQUIRE(metadata.neighbourRanks[ModelMetadata::TOP].size() == 0); + } else { + std::cerr << "only valid for 3 ranks" << std::endl; + exit(1); + } + + // This metadata is specific to the periodic boundary conditions. + // They are all zero because the input metadata file `partitionFilenameCB` does not use periodic + // boundary conditions. + REQUIRE(metadata.neighbourRanksPeriodic[ModelMetadata::LEFT].size() == 0); + REQUIRE(metadata.neighbourRanksPeriodic[ModelMetadata::RIGHT].size() == 0); + REQUIRE(metadata.neighbourRanksPeriodic[ModelMetadata::BOTTOM].size() == 0); + REQUIRE(metadata.neighbourRanksPeriodic[ModelMetadata::TOP].size() == 0); +} + +MPI_TEST_CASE("Test getPartitionMetadata periodic boundary", 3) +{ + ModelMetadata metadata(partitionFilenamePB, test_comm); + REQUIRE(metadata.mpiComm == test_comm); + // this metadata should be identical to the Closed Boundary version so we check it again + if (test_rank == 0) { + REQUIRE(metadata.neighbourRanks[ModelMetadata::LEFT].size() == 0); + REQUIRE(metadata.neighbourRanks[ModelMetadata::RIGHT] == std::vector { 2 }); + REQUIRE(metadata.neighbourExtents[ModelMetadata::RIGHT] == std::vector { 4 }); + REQUIRE(metadata.neighbourHaloStarts[ModelMetadata::RIGHT] == std::vector { 0 }); + REQUIRE(metadata.neighbourRanks[ModelMetadata::BOTTOM].size() == 0); + REQUIRE(metadata.neighbourRanks[ModelMetadata::TOP] == std::vector { 1 }); + REQUIRE(metadata.neighbourExtents[ModelMetadata::TOP] == std::vector { 7 }); + REQUIRE(metadata.neighbourHaloStarts[ModelMetadata::TOP] == std::vector { 0 }); + } else if (test_rank == 1) { + REQUIRE(metadata.neighbourRanks[ModelMetadata::LEFT].size() == 0); + REQUIRE(metadata.neighbourRanks[ModelMetadata::RIGHT] == std::vector { 2 }); + REQUIRE(metadata.neighbourExtents[ModelMetadata::RIGHT] == std::vector { 5 }); + REQUIRE(metadata.neighbourHaloStarts[ModelMetadata::RIGHT] == std::vector { 12 }); + REQUIRE(metadata.neighbourRanks[ModelMetadata::BOTTOM] == std::vector { 0 }); + REQUIRE(metadata.neighbourExtents[ModelMetadata::BOTTOM] == std::vector { 7 }); + REQUIRE(metadata.neighbourHaloStarts[ModelMetadata::BOTTOM] == std::vector { 21 }); + REQUIRE(metadata.neighbourRanks[ModelMetadata::TOP].size() == 0); + } else if (test_rank == 2) { + REQUIRE(metadata.neighbourRanks[ModelMetadata::LEFT] == std::vector { 0, 1 }); + REQUIRE(metadata.neighbourExtents[ModelMetadata::LEFT] == std::vector { 4, 5 }); + REQUIRE(metadata.neighbourHaloStarts[ModelMetadata::LEFT] == std::vector { 6, 6 }); + REQUIRE(metadata.neighbourRanks[ModelMetadata::RIGHT].size() == 0); + REQUIRE(metadata.neighbourRanks[ModelMetadata::BOTTOM].size() == 0); + REQUIRE(metadata.neighbourRanks[ModelMetadata::TOP].size() == 0); + } else { + std::cerr << "only valid for 3 ranks" << std::endl; + exit(1); + } + + // this metadata is specific to the periodic boundary conditions + if (test_rank == 0) { + // clang-format off + REQUIRE(metadata.neighbourRanksPeriodic[ModelMetadata::LEFT] == std::vector { 2 }); + REQUIRE(metadata.neighbourExtentsPeriodic[ModelMetadata::LEFT] == std::vector { 4 }); + REQUIRE(metadata.neighbourHaloStartsPeriodic[ModelMetadata::LEFT] == std::vector { 2 }); + + REQUIRE(metadata.neighbourRanksPeriodic[ModelMetadata::RIGHT].size() == 0); + + REQUIRE(metadata.neighbourRanksPeriodic[ModelMetadata::BOTTOM] == std::vector { 1 }); + REQUIRE(metadata.neighbourExtentsPeriodic[ModelMetadata::BOTTOM] == std::vector { 7 }); + REQUIRE(metadata.neighbourHaloStartsPeriodic[ModelMetadata::BOTTOM] == std::vector { 28 }); + + REQUIRE(metadata.neighbourRanksPeriodic[ModelMetadata::TOP].size() == 0); + } else if (test_rank == 1) { + REQUIRE(metadata.neighbourRanksPeriodic[ModelMetadata::LEFT] == std::vector { 2 }); + REQUIRE(metadata.neighbourExtentsPeriodic[ModelMetadata::LEFT] == std::vector { 5 }); + REQUIRE(metadata.neighbourHaloStartsPeriodic[ModelMetadata::LEFT] == std::vector { 14 }); + + REQUIRE(metadata.neighbourRanksPeriodic[ModelMetadata::RIGHT].size() == 0); + + REQUIRE(metadata.neighbourRanksPeriodic[ModelMetadata::BOTTOM].size() == 0); + + REQUIRE(metadata.neighbourRanksPeriodic[ModelMetadata::TOP] == std::vector { 0 }); + REQUIRE(metadata.neighbourExtentsPeriodic[ModelMetadata::TOP] == std::vector { 7 }); + REQUIRE(metadata.neighbourHaloStartsPeriodic[ModelMetadata::TOP] == std::vector { 0 }); + } else if (test_rank == 2) { + REQUIRE(metadata.neighbourRanksPeriodic[ModelMetadata::LEFT].size() == 0); + + REQUIRE(metadata.neighbourRanksPeriodic[ModelMetadata::RIGHT] == std::vector { 0, 1 }); + REQUIRE(metadata.neighbourExtentsPeriodic[ModelMetadata::RIGHT] == std::vector { 4, 5 }); + REQUIRE(metadata.neighbourHaloStartsPeriodic[ModelMetadata::RIGHT] == std::vector { 0, 0 }); + + REQUIRE(metadata.neighbourRanksPeriodic[ModelMetadata::BOTTOM] == std::vector { 2 }); + REQUIRE(metadata.neighbourExtentsPeriodic[ModelMetadata::BOTTOM] == std::vector { 3 }); + REQUIRE(metadata.neighbourHaloStartsPeriodic[ModelMetadata::BOTTOM] == std::vector { 24 }); + + REQUIRE(metadata.neighbourRanksPeriodic[ModelMetadata::TOP] == std::vector { 2 }); + REQUIRE(metadata.neighbourExtentsPeriodic[ModelMetadata::TOP] == std::vector { 3 }); + REQUIRE(metadata.neighbourHaloStartsPeriodic[ModelMetadata::TOP] == std::vector { 0 }); + // clang-format on + } else { + std::cerr << "only valid for 3 ranks" << std::endl; + exit(1); + } +} + +} diff --git a/core/test/partition_metadata_3_cb.cdl b/core/test/partition_metadata_3_cb.cdl new file mode 100644 index 000000000..f08c26cf9 --- /dev/null +++ b/core/test/partition_metadata_3_cb.cdl @@ -0,0 +1,108 @@ +netcdf partition_metadata_3 { +dimensions: + NX = 10 ; + NY = 9 ; + P = 3 ; + L = 2 ; + R = 2 ; + B = 1 ; + T = 1 ; + L_periodic = UNLIMITED ; // (0 currently) + R_periodic = UNLIMITED ; // (0 currently) + B_periodic = UNLIMITED ; // (0 currently) + T_periodic = UNLIMITED ; // (0 currently) + +group: bounding_boxes { + variables: + int domain_x(P) ; + int domain_extent_x(P) ; + int domain_y(P) ; + int domain_extent_y(P) ; + data: + + domain_x = 0, 0, 7 ; + + domain_extent_x = 7, 7, 3 ; + + domain_y = 0, 4, 0 ; + + domain_extent_y = 4, 5, 9 ; + } // group bounding_boxes + +group: connectivity { + variables: + int left_neighbours(P) ; + int left_neighbour_ids(L) ; + int left_neighbour_halos(L) ; + int left_neighbour_halo_starts(L) ; + int right_neighbours(P) ; + int right_neighbour_ids(R) ; + int right_neighbour_halos(R) ; + int right_neighbour_halo_starts(R) ; + int bottom_neighbours(P) ; + int bottom_neighbour_ids(B) ; + int bottom_neighbour_halos(B) ; + int bottom_neighbour_halo_starts(B) ; + int top_neighbours(P) ; + int top_neighbour_ids(T) ; + int top_neighbour_halos(T) ; + int top_neighbour_halo_starts(T) ; + int left_neighbours_periodic(P) ; + int left_neighbour_ids_periodic(L_periodic) ; + int left_neighbour_halos_periodic(L_periodic) ; + int left_neighbour_halo_starts_periodic(L_periodic) ; + int right_neighbours_periodic(P) ; + int right_neighbour_ids_periodic(R_periodic) ; + int right_neighbour_halos_periodic(R_periodic) ; + int right_neighbour_halo_starts_periodic(R_periodic) ; + int bottom_neighbours_periodic(P) ; + int bottom_neighbour_ids_periodic(B_periodic) ; + int bottom_neighbour_halos_periodic(B_periodic) ; + int bottom_neighbour_halo_starts_periodic(B_periodic) ; + int top_neighbours_periodic(P) ; + int top_neighbour_ids_periodic(T_periodic) ; + int top_neighbour_halos_periodic(T_periodic) ; + int top_neighbour_halo_starts_periodic(T_periodic) ; + data: + + left_neighbours = 0, 0, 2 ; + + left_neighbour_ids = 0, 1 ; + + left_neighbour_halos = 4, 5 ; + + left_neighbour_halo_starts = 6, 6 ; + + right_neighbours = 1, 1, 0 ; + + right_neighbour_ids = 2, 2 ; + + right_neighbour_halos = 4, 5 ; + + right_neighbour_halo_starts = 0, 12 ; + + bottom_neighbours = 0, 1, 0 ; + + bottom_neighbour_ids = 0 ; + + bottom_neighbour_halos = 7 ; + + bottom_neighbour_halo_starts = 21 ; + + top_neighbours = 1, 0, 0 ; + + top_neighbour_ids = 1 ; + + top_neighbour_halos = 7 ; + + top_neighbour_halo_starts = 0 ; + + left_neighbours_periodic = 0, 0, 0 ; + + right_neighbours_periodic = 0, 0, 0 ; + + bottom_neighbours_periodic = 0, 0, 0 ; + + top_neighbours_periodic = 0, 0, 0 ; + } // group connectivity +} diff --git a/core/test/partition_metadata_3_pb.cdl b/core/test/partition_metadata_3_pb.cdl new file mode 100644 index 000000000..6d71d7ed5 --- /dev/null +++ b/core/test/partition_metadata_3_pb.cdl @@ -0,0 +1,132 @@ +netcdf partition_metadata_3 { +dimensions: + NX = 10 ; + NY = 9 ; + P = 3 ; + L = 2 ; + R = 2 ; + B = 1 ; + T = 1 ; + L_periodic = 2 ; + R_periodic = 2 ; + B_periodic = 2 ; + T_periodic = 2 ; + +group: bounding_boxes { + variables: + int domain_x(P) ; + int domain_extent_x(P) ; + int domain_y(P) ; + int domain_extent_y(P) ; + data: + + domain_x = 0, 0, 7 ; + + domain_extent_x = 7, 7, 3 ; + + domain_y = 0, 4, 0 ; + + domain_extent_y = 4, 5, 9 ; + } // group bounding_boxes + +group: connectivity { + variables: + int left_neighbours(P) ; + int left_neighbour_ids(L) ; + int left_neighbour_halos(L) ; + int left_neighbour_halo_starts(L) ; + int right_neighbours(P) ; + int right_neighbour_ids(R) ; + int right_neighbour_halos(R) ; + int right_neighbour_halo_starts(R) ; + int bottom_neighbours(P) ; + int bottom_neighbour_ids(B) ; + int bottom_neighbour_halos(B) ; + int bottom_neighbour_halo_starts(B) ; + int top_neighbours(P) ; + int top_neighbour_ids(T) ; + int top_neighbour_halos(T) ; + int top_neighbour_halo_starts(T) ; + int left_neighbours_periodic(P) ; + int left_neighbour_ids_periodic(L_periodic) ; + int left_neighbour_halos_periodic(L_periodic) ; + int left_neighbour_halo_starts_periodic(L_periodic) ; + int right_neighbours_periodic(P) ; + int right_neighbour_ids_periodic(R_periodic) ; + int right_neighbour_halos_periodic(R_periodic) ; + int right_neighbour_halo_starts_periodic(R_periodic) ; + int bottom_neighbours_periodic(P) ; + int bottom_neighbour_ids_periodic(B_periodic) ; + int bottom_neighbour_halos_periodic(B_periodic) ; + int bottom_neighbour_halo_starts_periodic(B_periodic) ; + int top_neighbours_periodic(P) ; + int top_neighbour_ids_periodic(T_periodic) ; + int top_neighbour_halos_periodic(T_periodic) ; + int top_neighbour_halo_starts_periodic(T_periodic) ; + data: + + left_neighbours = 0, 0, 2 ; + + left_neighbour_ids = 0, 1 ; + + left_neighbour_halos = 4, 5 ; + + left_neighbour_halo_starts = 6, 6 ; + + right_neighbours = 1, 1, 0 ; + + right_neighbour_ids = 2, 2 ; + + right_neighbour_halos = 4, 5 ; + + right_neighbour_halo_starts = 0, 12 ; + + bottom_neighbours = 0, 1, 0 ; + + bottom_neighbour_ids = 0 ; + + bottom_neighbour_halos = 7 ; + + bottom_neighbour_halo_starts = 21 ; + + top_neighbours = 1, 0, 0 ; + + top_neighbour_ids = 1 ; + + top_neighbour_halos = 7 ; + + top_neighbour_halo_starts = 0 ; + + left_neighbours_periodic = 1, 1, 0 ; + + left_neighbour_ids_periodic = 2, 2 ; + + left_neighbour_halos_periodic = 4, 5 ; + + left_neighbour_halo_starts_periodic = 2, 14 ; + + right_neighbours_periodic = 0, 0, 2 ; + + right_neighbour_ids_periodic = 0, 1 ; + + right_neighbour_halos_periodic = 4, 5 ; + + right_neighbour_halo_starts_periodic = 0, 0 ; + + bottom_neighbours_periodic = 1, 0, 1 ; + + bottom_neighbour_ids_periodic = 1, 2 ; + + bottom_neighbour_halos_periodic = 7, 3 ; + + bottom_neighbour_halo_starts_periodic = 28, 24 ; + + top_neighbours_periodic = 0, 1, 1 ; + + top_neighbour_ids_periodic = 0, 2 ; + + top_neighbour_halos_periodic = 7, 3 ; + + top_neighbour_halo_starts_periodic = 0, 0 ; + } // group connectivity +}