From 14abada5b72ab14250ba4b69ae44651912b922cc Mon Sep 17 00:00:00 2001 From: David Date: Mon, 22 Apr 2024 17:23:31 +0000 Subject: [PATCH 1/3] Switched to using new Cabana grid output --- examples/PFHub1a.cpp | 2 +- src/PFHub.hpp | 22 +++++++------ src/PFVariables.hpp | 73 +++++++++++++++++++------------------------- unit_test/test.cpp | 4 +-- 4 files changed, 46 insertions(+), 55 deletions(-) diff --git a/examples/PFHub1a.cpp b/examples/PFHub1a.cpp index 386a292..0ce7c8c 100644 --- a/examples/PFHub1a.cpp +++ b/examples/PFHub1a.cpp @@ -24,7 +24,7 @@ int main(int argc, char* argv[]) { throw std::invalid_argument(""); simulation->run_until_time(end_time); - simulation->output(); + simulation->snapshot_c(); } catch (std::invalid_argument const&) { std::cout << "Usage: ./PFHub1a
" << std::endl; } diff --git a/src/PFHub.hpp b/src/PFHub.hpp index f5c370d..2f2be30 100644 --- a/src/PFHub.hpp +++ b/src/PFHub.hpp @@ -109,7 +109,15 @@ class PFHub1aBase : public CabanaPFRunner<2> { vars.fft_inverse(0); } - virtual void output() {} + // versions of PFHub1a must override this to give themselves a name: + virtual std::string subproblem_name() const = 0; + // save a copy of the c grid to a file + void snapshot_c() { + std::stringstream s; + s << subproblem_name() << "_N" << grid_points << "_DT" << std::fixed << std::setprecision(3) << std::scientific + << dt; + vars.save(0, s.str(), 0); + } // needed to allow polymorphism: virtual ~PFHub1aBase() {} @@ -133,10 +141,8 @@ class PFHub1aBenchmark : public PFHub1aBase { }); } - void output() override { - std::stringstream s; - s << "1aBenchmark_N" << grid_points << "_DT" << std::fixed << std::setprecision(3) << std::scientific << dt; - vars.save(0, s.str()); + std::string subproblem_name() const override { + return "1aBenchmark"; } PFHub1aBenchmark(int grid_points, double dt) : PFHub1aBase{grid_points, dt} {} @@ -161,10 +167,8 @@ class PFHub1aPeriodic : public PFHub1aBase { }); } - void output() override { - std::stringstream s; - s << "1aPeriodic_N" << grid_points << "_DT" << std::fixed << std::setprecision(3) << std::scientific << dt; - vars.save(0, s.str()); + std::string subproblem_name() const override { + return "1aPeriodic"; } PFHub1aPeriodic(int grid_points, double dt) : PFHub1aBase{grid_points, dt} {} diff --git a/src/PFVariables.hpp b/src/PFVariables.hpp index 56f0ee1..1eca698 100644 --- a/src/PFVariables.hpp +++ b/src/PFVariables.hpp @@ -4,10 +4,6 @@ #include #include -#ifdef RESULTS_PATH -#include -#endif - namespace CabanaPF { template @@ -26,6 +22,16 @@ class PFVariables { Cabana::Grid::Experimental::Impl::FFTBackendDefault>> fft_calculator; + // string to be used for Cabana's BOVWriter's prefix argument + std::string save_prefix(const int index, std::string run_name) { + std::stringstream name; +#ifdef RESULTS_PATH + name << RESULTS_PATH; +#endif + name << run_name << "_" << arrays[index]->label(); + return name.str(); + } + public: std::array arrays; @@ -61,48 +67,31 @@ class PFVariables { return Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(), arrays[index]->view()); } - std::string save_name(std::string run_name, [[maybe_unused]] const int index, - [[maybe_unused]] const int timesteps_done = -1) { - std::stringstream name; -#ifdef RESULTS_PATH - name << RESULTS_PATH; -#endif - name << run_name << "_" << arrays[index]->label() << ".dat"; - return name.str(); + // Saves an array to file. + void save(const int index, std::string run_name, const int timesteps_done, const double time = 0) { + const std::string prefix = save_prefix(index, run_name); + Cabana::Grid::Experimental::BovWriter::writeTimeStep(prefix, timesteps_done, time, *arrays[index]); } - // If unfinished and just saving progress, pass in timesteps_done - void save(const int index, [[maybe_unused]] std::string run_name, [[maybe_unused]] const int timesteps_done = -1) { - Cabana::Grid::Experimental::BovWriter::writeTimeStep(999999, 0, - *arrays[index]); // use 999999 to mark it for move -#ifdef RESULTS_PATH // Comes from the CMake build; if not defined, won't have file I/O - try { - std::string old_name = "grid_" + arrays[index]->label() + "_999999.dat"; - std::filesystem::rename(old_name, save_name(run_name, index, timesteps_done)); - // TODO: Deal with the .bov file? - } catch (std::filesystem::filesystem_error& e) { - std::cerr << "Error when saving: " << e.what() << std::endl; - } -#endif - } - - void load(std::string run_name, const int timesteps_done = -1) { - for (std::size_t index = 0; index < NumVariables; index++) { - assert(NumSpaceDim == 2); // currently not supported for 3D - // open the file: - std::fstream infile(save_name(run_name, index, timesteps_done), std::fstream::in | std::fstream::binary); - // read it: - const auto view = arrays[index]->view(); - double buffer[2]; - for (int j = 0; j < array_size[1]; j++) { - for (int i = 0; i < array_size[0]; i++) { - infile.read((char*)buffer, 2 * sizeof(double)); - view(i, j, 0) = buffer[0]; - view(i, j, 1) = buffer[1]; - } - // since the grid is periodic, it writes the first value in the row again, so "burn it off": + // loads the file created by the same arguments to save + void load(const int index, std::string run_name, const int timesteps_done) { + assert(NumSpaceDim == 2); // currently not supported for 3D + // recreate Cabana's naming scheme: + std::stringstream name; + name << save_prefix(index, run_name) << "_" << std::setfill('0') << std::setw(6) << timesteps_done << ".dat"; + // open the file: + std::fstream infile(name.str(), std::fstream::in | std::fstream::binary); + // read it: + const auto view = arrays[index]->view(); + double buffer[2]; + for (int j = 0; j < array_size[1]; j++) { + for (int i = 0; i < array_size[0]; i++) { infile.read((char*)buffer, 2 * sizeof(double)); + view(i, j, 0) = buffer[0]; + view(i, j, 1) = buffer[1]; } + // since the grid is periodic, it writes the first value in the row again, so "burn it off": + infile.read((char*)buffer, 2 * sizeof(double)); } } }; diff --git a/unit_test/test.cpp b/unit_test/test.cpp index 78025df..32d63e2 100644 --- a/unit_test/test.cpp +++ b/unit_test/test.cpp @@ -75,7 +75,6 @@ TEST(PFHub1a, AllTimestep) { EXPECT_NEAR(0.6482746495041702, results(67, 7, 0), 1e-9); } -#ifdef RESULTS_PATH TEST(PFVariables, saveload) { auto global_mesh = Cabana::Grid::createUniformGlobalMesh(std::array{0, 0}, std::array{6, 6}, std::array{3, 3}); @@ -94,7 +93,7 @@ TEST(PFVariables, saveload) { vars.save(0, "Test", 0); PFVariables from_file(layout, std::array{"a"}); - from_file.load("Test", 0); + from_file.load(0, "Test", 0); for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { EXPECT_EQ(vars[0](i, j, 0), from_file[0](i, j, 0)); @@ -102,7 +101,6 @@ TEST(PFVariables, saveload) { } } } -#endif // Similar to above, the python implementation was modified to use the periodic initial conditions TEST(PFHub1aPeriodic, periodic) { From 8c116e385c016613dcf6b32885e0d54c6529d48b Mon Sep 17 00:00:00 2001 From: David Date: Mon, 22 Apr 2024 17:53:00 +0000 Subject: [PATCH 2/3] Update Cabana version in CI Co-authored-by: Sam Reeve <6740307+streeve@users.noreply.github.com> --- .github/workflows/CI.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 4f3f217..80b0ffc 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -20,7 +20,7 @@ jobs: cxx: ['g++', 'clang++'] backend: ['SERIAL', 'OPENMP'] cmake_build_type: ['Debug', 'Release'] - kokkos_ver: ['3.7.02'] + kokkos_ver: ['4.1.00'] runs-on: ubuntu-20.04 container: ghcr.io/ecp-copa/ci-containers/${{ matrix.distro }} steps: @@ -62,7 +62,7 @@ jobs: uses: actions/checkout@v3 with: repository: ECP-CoPA/Cabana - ref: 0.6.1 + ref: cd7075fd66bc346c8f28831cfb5b0ea650cf9892 path: cabana - name: Build Cabana working-directory: cabana @@ -102,7 +102,7 @@ jobs: matrix: cxx: ['nvcc'] cmake_build_type: ['Release'] - kokkos_ver: ['3.7.02'] + kokkos_ver: ['4.1.00'] runs-on: ubuntu-20.04 container: ghcr.io/ecp-copa/ci-containers/cuda:12.2.0 steps: @@ -144,7 +144,7 @@ jobs: uses: actions/checkout@v3 with: repository: ECP-CoPA/Cabana - ref: 0.6.1 + ref: cd7075fd66bc346c8f28831cfb5b0ea650cf9892 path: cabana - name: Build Cabana working-directory: cabana From 5b7dcd9951b1ccb5007cb460c8c66b19e9ccc231 Mon Sep 17 00:00:00 2001 From: David Date: Wed, 24 Apr 2024 15:04:03 +0000 Subject: [PATCH 3/3] Changes for review --- CMakeLists.txt | 4 ++-- examples/PFHub1a.cpp | 2 +- src/PFHub.hpp | 2 +- src/PFVariables.hpp | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 19b96db..fed556e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,8 +4,8 @@ project(CabanaPF CXX) include(GNUInstallDirs) set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) -if(DEFINED RESULTS_PATH) - add_compile_definitions(RESULTS_PATH="${RESULTS_PATH}") +if(DEFINED CABANAPF_RESULTS_PATH) + add_compile_definitions(CABANAPF_RESULTS_PATH="${CABANAPF_RESULTS_PATH}") endif() find_package(Cabana) diff --git a/examples/PFHub1a.cpp b/examples/PFHub1a.cpp index 0ce7c8c..2bfc24d 100644 --- a/examples/PFHub1a.cpp +++ b/examples/PFHub1a.cpp @@ -24,7 +24,7 @@ int main(int argc, char* argv[]) { throw std::invalid_argument(""); simulation->run_until_time(end_time); - simulation->snapshot_c(); + simulation->output_c(); } catch (std::invalid_argument const&) { std::cout << "Usage: ./PFHub1a
" << std::endl; } diff --git a/src/PFHub.hpp b/src/PFHub.hpp index 2f2be30..61be958 100644 --- a/src/PFHub.hpp +++ b/src/PFHub.hpp @@ -112,7 +112,7 @@ class PFHub1aBase : public CabanaPFRunner<2> { // versions of PFHub1a must override this to give themselves a name: virtual std::string subproblem_name() const = 0; // save a copy of the c grid to a file - void snapshot_c() { + void output_c() { std::stringstream s; s << subproblem_name() << "_N" << grid_points << "_DT" << std::fixed << std::setprecision(3) << std::scientific << dt; diff --git a/src/PFVariables.hpp b/src/PFVariables.hpp index 1eca698..2c02c6e 100644 --- a/src/PFVariables.hpp +++ b/src/PFVariables.hpp @@ -25,8 +25,8 @@ class PFVariables { // string to be used for Cabana's BOVWriter's prefix argument std::string save_prefix(const int index, std::string run_name) { std::stringstream name; -#ifdef RESULTS_PATH - name << RESULTS_PATH; +#ifdef CABANAPF_RESULTS_PATH + name << CABANAPF_RESULTS_PATH; #endif name << run_name << "_" << arrays[index]->label(); return name.str();