From b1554b34ec74f06007a68ccabd8ff6620d2eb292 Mon Sep 17 00:00:00 2001 From: Jacob Merson Date: Mon, 17 Aug 2026 03:01:56 -0400 Subject: [PATCH 1/2] Use Field with serializer Rather than pass data and layouts separately, we update the serializer to directly take the Field&. This does a better job of maintaining consistency with what data we are operating with. Also, it reduces the number of places we expose FieldData, which is really an internal implementation detail that we don't want readily exposed. --- src/pcms/coupler/field_communicator.hpp | 6 +- src/pcms/coupler/field_serializer.h | 8 +- src/pcms/coupler/serializer/xgc.h | 13 +- test/CMakeLists.txt | 3 +- test/field_test_utils.h | 34 --- test/test_field_serializer.cpp | 239 ++++++++++++++++++ test/test_omega_h_lagrange_field.cpp | 57 ----- ...lynomial_reconstruction_function_space.cpp | 18 -- test/test_uniform_grid_field.cpp | 24 -- test/test_xgc_field_data.cpp | 60 ----- 10 files changed, 254 insertions(+), 208 deletions(-) create mode 100644 test/test_field_serializer.cpp diff --git a/src/pcms/coupler/field_communicator.hpp b/src/pcms/coupler/field_communicator.hpp index fa731487..2ff250b5 100644 --- a/src/pcms/coupler/field_communicator.hpp +++ b/src/pcms/coupler/field_communicator.hpp @@ -51,8 +51,7 @@ class FieldCommunicator PCMS_FUNCTION_TIMER; PCMS_ALWAYS_ASSERT(layout_comm_.GetChannel().InSendCommunicationPhase()); auto buffer = make_array_view(comm_buffer_); - serializer_->Serialize(field_.GetData(), field_.GetLayout(), buffer, - layout_comm_.GetPermutationArray()); + serializer_->Serialize(field_, buffer, layout_comm_.GetPermutationArray()); comm_.Send(buffer.data_handle(), mode); } @@ -64,8 +63,7 @@ class FieldCommunicator // mode because we make an immediate call to deserialize after a call to // receive. auto data = comm_.Recv(redev::Mode::Synchronous); - serializer_->Deserialize(field_.GetData(), field_.GetLayout(), - make_const_array_view(data), + serializer_->Deserialize(field_, make_const_array_view(data), layout_comm_.GetPermutationArray()); } diff --git a/src/pcms/coupler/field_serializer.h b/src/pcms/coupler/field_serializer.h index 723929cf..f619aa5a 100644 --- a/src/pcms/coupler/field_serializer.h +++ b/src/pcms/coupler/field_serializer.h @@ -14,12 +14,12 @@ template class FieldSerializer { public: - virtual int Serialize(const FieldData& field, const FieldLayout& layout, + virtual int Serialize(const Field& field, Rank1View buffer, Rank1View permutation) const { auto data = field.GetDOFHolderDataHost(); - auto owned = layout.GetOwnedHost(); + auto owned = field.GetLayout().GetOwnedHost(); // The exchange plan is per DOF holder: owned[i] and permutation[i] are // indexed by holder. All num_components components of a holder share its // location, so they occupy one contiguous block permutation[i]*num_comp in @@ -41,10 +41,10 @@ class FieldSerializer } virtual void Deserialize( - FieldData& field, const FieldLayout& layout, - Rank1View buffer, + Field& field, Rank1View buffer, Rank1View permutation) const { + const auto& layout = field.GetLayout(); const LO num_dof = layout.GetNumOwnedDofHolder(); const LO num_comp = layout.GetNumComponents(); Kokkos::View sorted("sorted", layout.OwnedSize()); diff --git a/src/pcms/coupler/serializer/xgc.h b/src/pcms/coupler/serializer/xgc.h index e2658377..72169368 100644 --- a/src/pcms/coupler/serializer/xgc.h +++ b/src/pcms/coupler/serializer/xgc.h @@ -20,20 +20,21 @@ class XGCFieldSerializer : public FieldSerializer { } - int Serialize(const FieldData& field, const FieldLayout& layout, - Rank1View buffer, + int Serialize(const Field& field, Rank1View buffer, Rank1View permutation) const override { if (!rank_participates_) { return 0; } - auto const* xgc_field = dynamic_cast*>(&field); + auto const* xgc_field = + dynamic_cast*>(&field.GetData()); if (!xgc_field) { throw pcms_error("XGCFieldSerializer::Serialize: incompatible FieldData"); } auto data = xgc_field->GetDOFHolderDataHost(); + const auto& layout = field.GetLayout(); auto owned = layout.GetOwnedHost(); // Per-holder plan: owned[i]/permutation[i] index holders; a holder's // num_components values form one contiguous block in the wire buffer. @@ -54,17 +55,17 @@ class XGCFieldSerializer : public FieldSerializer } void Deserialize( - FieldData& field, const FieldLayout& layout, - Rank1View buffer, + Field& field, Rank1View buffer, Rank1View permutation) const override { - auto* xgc_field = dynamic_cast*>(&field); + auto* xgc_field = dynamic_cast*>(&field.GetData()); if (!xgc_field) { throw pcms_error( "XGCFieldSerializer::Deserialize: incompatible FieldData"); } auto current = xgc_field->GetDOFHolderDataHost(); + const auto& layout = field.GetLayout(); const LO num_dof = static_cast(current.extent(0)); const LO num_comp = static_cast(current.extent(1)); std::vector full_data(current.size()); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 9a7eb845..93e68a33 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -400,7 +400,8 @@ if(Catch2_FOUND) message( STATUS "Found Catch2: ${Catch2_DIR} (found version ${Catch2_VERSION})") set(PCMS_UNIT_TEST_SOURCES unit_test_main.cpp test_coordinate_transform.cpp - test_coordinate.cpp test_bounding_box.cpp) + test_coordinate.cpp test_bounding_box.cpp + test_field_serializer.cpp) if(PCMS_ENABLE_XGC) list(APPEND PCMS_UNIT_TEST_SOURCES test_xgc_reverse_classification.cpp test_xgc_field_data.cpp) diff --git a/test/field_test_utils.h b/test/field_test_utils.h index 2ddd2f45..60b488fe 100644 --- a/test/field_test_utils.h +++ b/test/field_test_utils.h @@ -10,7 +10,6 @@ #include "pcms/field/evaluation_request.h" #include "pcms/field/point_evaluator.h" #include "pcms/field/out_of_bounds_policy.h" -#include "pcms/coupler/field_serializer.h" #include "pcms/field/coordinate_system.h" #include "pcms/utility/arrays.h" #include "pcms/utility/memory_spaces.h" @@ -282,39 +281,6 @@ inline void SetField(FieldData& field, const FieldLayout& layout, SetField(layout, field, func); } -// Check that serialize followed by deserialize round-trips the data. -// Uses an identity permutation so permutation[i] = i. -inline void CheckSerializeDeserialize(const FieldLayout& layout, - FieldData& field) -{ - auto data_before = FlattenToRank1View(field.GetDOFHolderDataHost()); - int n = static_cast(data_before.size()); - - std::vector buffer(n); - std::vector perm(n); - for (int i = 0; i < n; ++i) - perm[i] = i; - - Rank1View buf_view(buffer.data(), n); - Rank1View perm_view(perm.data(), n); - - FieldSerializer serializer; - serializer.Serialize(field, layout, buf_view, perm_view); - serializer.Deserialize( - field, layout, Rank1View(buf_view), perm_view); - - auto data_after = FlattenToRank1View(field.GetDOFHolderDataHost()); - REQUIRE(data_after.size() == data_before.size()); - for (int i = 0; i < n; ++i) { - REQUIRE(data_after[i] == Catch::Approx(data_before[i])); - } -} - -inline void CheckSerializeDeserialize(Field& field) -{ - CheckSerializeDeserialize(field.GetLayout(), field.GetData()); -} - // Helper structure to hold device coordinates with proper lifetime management struct DeviceCoordinates { diff --git a/test/test_field_serializer.cpp b/test/test_field_serializer.cpp new file mode 100644 index 00000000..10a29e74 --- /dev/null +++ b/test/test_field_serializer.cpp @@ -0,0 +1,239 @@ +#include +#include + +#include "pcms/configuration.h" +#include "pcms/coupler/field_serializer.h" +#include "pcms/utility/arrays.h" + +#include +#include +#include + +#ifdef PCMS_ENABLE_OMEGA_H +#include "field_test_utils.h" +#include "pcms/field/function_space/lagrange.h" +#include "pcms/field/function_space/polynomial_reconstruction.hpp" +#include "pcms/utility/uniform_grid.h" +#include +#endif + +#ifdef PCMS_ENABLE_XGC +#include "pcms/coupler/serializer/xgc.h" +#include "pcms/field/data/xgc.h" +#include "pcms/field/function_space/xgc.h" +#endif + +namespace +{ + +#ifdef PCMS_ENABLE_OMEGA_H +void CheckSerializeDeserialize(pcms::Field& field) +{ + auto data_before = field.GetDOFHolderDataHost(); + const auto num_dof = static_cast(data_before.extent(0)); + const auto num_components = static_cast(data_before.extent(1)); + const auto num_values = static_cast(data_before.size()); + + std::vector expected(num_values); + for (pcms::LO i = 0; i < num_dof; ++i) { + for (pcms::LO c = 0; c < num_components; ++c) { + expected[static_cast(i) * num_components + c] = data_before(i, c); + } + } + + std::vector buffer(num_values); + std::vector permutation(num_dof); + std::iota(permutation.begin(), permutation.end(), pcms::LO{0}); + + pcms::FieldSerializer serializer; + REQUIRE(serializer.Serialize(field, pcms::make_array_view(buffer), + pcms::make_const_array_view(permutation)) == + static_cast(num_values)); + + std::vector cleared(num_values, -1.0); + field.SetDOFHolderDataHost( + pcms::Rank2View( + cleared.data(), num_dof, num_components)); + serializer.Deserialize(field, pcms::make_const_array_view(buffer), + pcms::make_const_array_view(permutation)); + + auto data_after = field.GetDOFHolderDataHost(); + REQUIRE(data_after.size() == expected.size()); + for (pcms::LO i = 0; i < num_dof; ++i) { + for (pcms::LO c = 0; c < num_components; ++c) { + REQUIRE( + data_after(i, c) == + Catch::Approx(expected[static_cast(i) * num_components + c])); + } + } +} +#endif + +#ifdef PCMS_ENABLE_XGC +pcms::ReverseClassificationVertex CreateDummyReverseClassification(int size) +{ + pcms::ReverseClassificationVertex rc; + for (int i = 0; i < size; ++i) { + rc.Insert(i % 4 == 0 ? pcms::DimID{0, 0} : pcms::DimID{0, 1}, i); + } + return rc; +} + +bool InXGCOverlap(int, int id) +{ + return id == 0; +} +#endif + +} // namespace + +#ifdef PCMS_ENABLE_XGC +TEST_CASE("XGCFieldSerializer preserves inactive field entries") +{ + static constexpr int data_size = 16; + auto rc = CreateDummyReverseClassification(data_size); + pcms::XGCFieldFactory factory(rc, InXGCOverlap, data_size); + + std::vector data(data_size); + std::iota(data.begin(), data.end(), 0.0); + const auto original = data; + auto field = factory.CreateField( + "", std::make_unique>( + factory.GetXGCLayout(), pcms::FieldMetadata{}, + pcms::make_array_view(data))); + pcms::XGCFieldSerializer serializer(MPI_COMM_SELF); + + auto owned = field.GetLayout().GetOwnedHost(); + std::vector permutation(data_size, -1); + int entry = 0; + for (int i = 0; i < data_size; ++i) { + if (owned[i]) { + permutation[i] = entry++; + } + } + const int num_owned = entry; + REQUIRE(num_owned == 4); + + std::vector buffer(num_owned, -1.0); + REQUIRE(serializer.Serialize(field, pcms::make_array_view(buffer), + pcms::make_const_array_view(permutation)) == + num_owned); + + for (int i = 0; i < data_size; ++i) { + if (owned[i]) { + REQUIRE(buffer[permutation[i]] == data[i]); + buffer[permutation[i]] += 100.0; + } else { + REQUIRE(permutation[i] == -1); + } + } + + serializer.Deserialize(field, pcms::make_const_array_view(buffer), + pcms::make_const_array_view(permutation)); + + auto after = pcms::FlattenToRank1View(field.GetDOFHolderDataHost()); + for (int i = 0; i < data_size; ++i) { + if (owned[i]) { + REQUIRE(after[i] == Catch::Approx(original[i] + 100.0)); + } else { + REQUIRE(after[i] == Catch::Approx(original[i])); + } + } +} +#endif + +#ifdef PCMS_ENABLE_OMEGA_H +TEST_CASE("FieldSerializer round-trips a polynomial-reconstruction field") +{ + std::vector coords{0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0}; + pcms::Rank2View coords_view(coords.data(), + 4, 2); + auto space = pcms::PolynomialReconstructionFunctionSpace::Create( + coords_view, pcms::CoordinateSystem::Cartesian); + auto field = space->CreateFunction(); + + std::vector data{5.0, 6.0, 7.0, 8.0}; + field.SetDOFHolderDataHost( + pcms::Rank2View(data.data(), 4, + 1)); + + CheckSerializeDeserialize(field); +} + +TEST_CASE("FieldSerializer round-trips a uniform-grid field") +{ + pcms::UniformGrid<2> grid; + grid.bot_left = {0.0, 0.0}; + grid.edge_length = {10.0, 10.0}; + grid.divisions = {3, 3}; + auto space = pcms::LagrangeFunctionSpace::FromUniformGrid( + grid, 1, pcms::CoordinateSystem::Cartesian); + auto field = space->CreateFunction(); + + std::vector data(16); + for (size_t i = 0; i < data.size(); ++i) { + data[i] = static_cast(i * 10); + } + field.SetDOFHolderDataHost( + pcms::Rank2View(data.data(), 16, + 1)); + + CheckSerializeDeserialize(field); +} + +TEST_CASE("FieldSerializer round-trips an order-1 Omega_h field") +{ + auto lib = Omega_h::Library{}; + auto mesh = pcms::test::BuildUnitSquare(lib, 0); + auto space = pcms::test::MakeP1Space(mesh); + auto field = space->CreateFunction(); + + pcms::test::SetField( + field, OMEGA_H_LAMBDA(pcms::Real x, pcms::Real y) { + return pcms::test::linear_f(x, y); + }); + + CheckSerializeDeserialize(field); +} + +TEST_CASE("FieldSerializer round-trips a multi-component Omega_h field") +{ + auto lib = Omega_h::Library{}; + auto mesh = pcms::test::BuildUnitSquare(lib, 0); + constexpr int num_components = 3; + auto space = pcms::LagrangeFunctionSpace::FromMesh( + mesh, 1, num_components, pcms::CoordinateSystem::Cartesian, "global", + pcms::LagrangeFunctionSpace::Backend::OmegaH); + auto field = space->CreateFunction(); + + const int num_dof = field.GetLayout().GetNumOwnedDofHolder(); + std::vector data(static_cast(num_dof) * num_components); + for (int i = 0; i < num_dof; ++i) { + for (int c = 0; c < num_components; ++c) { + data[static_cast(i) * num_components + c] = i + 0.25 * c; + } + } + field.SetDOFHolderDataHost( + pcms::Rank2View( + data.data(), num_dof, num_components)); + + CheckSerializeDeserialize(field); +} + +TEST_CASE("FieldSerializer round-trips an order-0 Omega_h field") +{ + auto lib = Omega_h::Library{}; + auto mesh = pcms::test::BuildUnitSquare(lib, 0); + auto space = pcms::test::MakeP0Space(mesh); + auto field = space->CreateFunction(); + + const int num_dof = mesh.nelems(); + std::vector data(num_dof); + std::iota(data.begin(), data.end(), pcms::Real{0}); + field.SetDOFHolderDataHost( + pcms::Rank2View(data.data(), + num_dof, 1)); + + CheckSerializeDeserialize(field); +} +#endif diff --git a/test/test_omega_h_lagrange_field.cpp b/test/test_omega_h_lagrange_field.cpp index 0dd5ffc7..4345fce2 100644 --- a/test/test_omega_h_lagrange_field.cpp +++ b/test/test_omega_h_lagrange_field.cpp @@ -196,44 +196,6 @@ TEST_CASE("OmegaHLagrangeField order-1: out-of-bounds FILL mode") pcms::test::CheckFillMode(factory, field, fill_value, outside); } -TEST_CASE("OmegaHLagrangeField order-1: serialize / deserialize round-trip") -{ - auto lib = Omega_h::Library{}; - auto mesh = MakeBox2D(lib.world()); - auto factory = pcms::LagrangeFunctionSpace::FromMesh( - mesh, 1, 1, pcms::CoordinateSystem::Cartesian); - auto field = factory->CreateFunction(); - - pcms::test::SetField( - field.GetData(), *factory->GetLayout(), - OMEGA_H_LAMBDA(Real x, Real y) { return pcms::test::linear_f(x, y); }); - pcms::test::CheckSerializeDeserialize(*factory->GetLayout(), field.GetData()); -} - -TEST_CASE( - "OmegaHLagrangeField order-1: multi-component serialize / deserialize " - "round-trip") -{ - auto lib = Omega_h::Library{}; - auto mesh = MakeBox2D(lib.world()); - const int nc = 3; - // The MeshFields backend is scalar-only; multi-component needs OmegaH. - auto factory = pcms::LagrangeFunctionSpace::FromMesh( - mesh, 1, nc, pcms::CoordinateSystem::Cartesian, "global", - pcms::LagrangeFunctionSpace::Backend::OmegaH); - auto field = factory->CreateFunction(); - - const int n = factory->GetLayout()->GetNumOwnedDofHolder(); - std::vector data(static_cast(n) * nc); - for (int i = 0; i < n; ++i) - for (int c = 0; c < nc; ++c) - data[static_cast(i) * nc + c] = i + 0.25 * c; - field.GetData().SetDOFHolderDataHost( - pcms::Rank2View(data.data(), n, nc)); - - pcms::test::CheckSerializeDeserialize(*factory->GetLayout(), field.GetData()); -} - // ---- Order-0 field tests ---------------------------------------------------- TEST_CASE("OmegaHLagrangeField order-0: set/get DOF data round-trip") @@ -294,25 +256,6 @@ TEST_CASE("OmegaHLagrangeField order-0: out-of-bounds FILL mode") pcms::test::CheckFillMode(factory, field, fill_value, outside); } -TEST_CASE("OmegaHLagrangeField order-0: serialize / deserialize round-trip") -{ - auto lib = Omega_h::Library{}; - auto mesh = MakeBox2D(lib.world()); - auto factory = pcms::LagrangeFunctionSpace::FromMesh( - mesh, 0, 1, pcms::CoordinateSystem::Cartesian); - auto field = factory->CreateFunction(); - - int nelems = mesh.nelems(); - std::vector data(nelems); - for (int i = 0; i < nelems; ++i) - data[i] = static_cast(i); - pcms::Rank2View view(data.data(), nelems, - 1); - field.GetData().SetDOFHolderDataHost(view); - - pcms::test::CheckSerializeDeserialize(*factory->GetLayout(), field.GetData()); -} - // ---- Layout sharing communicator contract ----------------------------------- // // BEHAVIORAL CONTRACT (requires MPI/redev — exercised by diff --git a/test/test_polynomial_reconstruction_function_space.cpp b/test/test_polynomial_reconstruction_function_space.cpp index 0281c13f..2c836af9 100644 --- a/test/test_polynomial_reconstruction_function_space.cpp +++ b/test/test_polynomial_reconstruction_function_space.cpp @@ -92,24 +92,6 @@ TEST_CASE("PolynomialReconstructionFunctionSpace point-cloud field set/get DOF " } } -TEST_CASE("PolynomialReconstructionFunctionSpace point-cloud field serialize / " - "deserialize round-trip") -{ - auto coords = MakeCoords2D(); - Rank2View coords_view(coords.data(), 4, 2); - - auto factory = pcms::PolynomialReconstructionFunctionSpace::Create( - coords_view, CoordinateSystem::Cartesian); - auto field = factory->CreateFunction(); - - std::vector data{5.0, 6.0, 7.0, 8.0}; - Rank2View data_view( - data.data(), static_cast(data.size()), 1); - field.GetData().SetDOFHolderDataHost(data_view); - - pcms::test::CheckSerializeDeserialize(*factory->GetLayout(), field.GetData()); -} - TEST_CASE("PolynomialReconstructionFunctionSpace field keeps layout alive " "after temporary factory destruction") { diff --git a/test/test_uniform_grid_field.cpp b/test/test_uniform_grid_field.cpp index 699ec26a..56cd2b0a 100644 --- a/test/test_uniform_grid_field.cpp +++ b/test/test_uniform_grid_field.cpp @@ -248,30 +248,6 @@ TEST_CASE("UniformGrid field evaluation - piecewise constant") REQUIRE(std::abs(results_host(3, 0) - 3.25) < 1e-10); } -TEST_CASE("UniformGrid field serialization") -{ - pcms::UniformGrid<2> grid; - grid.bot_left = {0.0, 0.0}; - grid.edge_length = {10.0, 10.0}; - grid.divisions = {3, 3}; - - auto layout = std::make_shared>( - grid, 1, pcms::CoordinateSystem::Cartesian); - auto field_space = pcms::LagrangeFunctionSpace::FromUniformGrid( - grid, 1, pcms::CoordinateSystem::Cartesian); - auto field = field_space->CreateFunction(); - - std::vector data(16); - for (size_t i = 0; i < 16; ++i) - data[i] = static_cast(i * 10); - - field.SetDOFHolderDataHost( - pcms::Rank2View( - data.data(), static_cast(data.size()), 1)); - - pcms::test::CheckSerializeDeserialize(field); -} - TEST_CASE("UniformGrid field copy") { pcms::UniformGrid<2> grid; diff --git a/test/test_xgc_field_data.cpp b/test/test_xgc_field_data.cpp index b487b1e1..498d855a 100644 --- a/test/test_xgc_field_data.cpp +++ b/test/test_xgc_field_data.cpp @@ -1,9 +1,6 @@ #include -#include #include "pcms/field/data/xgc.h" #include "pcms/field/function_space/xgc.h" -#include "pcms/coupler/serializer/xgc.h" -#include #include namespace @@ -54,63 +51,6 @@ TEST_CASE("XGC FieldLayout marks overlap entries and gids") } } -TEST_CASE("XGC FieldData serializer preserves inactive entries") -{ - static constexpr int data_size = 16; - auto rc = create_dummy_rc(data_size); - auto layout = - std::make_shared(rc, in_overlap, data_size); - - std::vector data(data_size); - std::iota(data.begin(), data.end(), 0.0); - auto original = data; - pcms::XGCFieldData field(layout, pcms::FieldMetadata{}, - pcms::make_array_view(data)); - pcms::XGCFieldSerializer serializer(MPI_COMM_SELF); - - auto owned = layout->GetOwnedHost(); - - // Non-owned / non-participating holders must have negative permutation - // entries (matching the real FieldExchangePlanner output). Only the 4 - // owned holders get compacted non-negative indices. - std::vector permutation(data_size, -1); - int entry = 0; - for (int i = 0; i < data_size; ++i) { - if (owned[i]) { - permutation[i] = entry++; - } - } - const int num_owned = entry; - REQUIRE(num_owned == 4); - - std::vector buffer(num_owned, -1.0); - - REQUIRE(serializer.Serialize(field, *layout, pcms::make_array_view(buffer), - pcms::make_const_array_view(permutation)) == - num_owned); - - for (int i = 0; i < data_size; ++i) { - if (owned[i]) { - REQUIRE(buffer[permutation[i]] == data[i]); - buffer[permutation[i]] += 100.0; - } else { - REQUIRE(permutation[i] == -1); - } - } - - serializer.Deserialize(field, *layout, pcms::make_const_array_view(buffer), - pcms::make_const_array_view(permutation)); - - auto after = pcms::FlattenToRank1View(field.GetDOFHolderDataHost()); - for (int i = 0; i < data_size; ++i) { - if (owned[i]) { - REQUIRE(after[i] == Catch::Approx(original[i] + 100.0)); - } else { - REQUIRE(after[i] == Catch::Approx(original[i])); - } - } -} - TEST_CASE("XGCFieldFactory creates fields and rejects evaluator access") { static constexpr int data_size = 16; From 213fb1e7a87837ae51224e34760366bb1f323808 Mon Sep 17 00:00:00 2001 From: Jacob Merson Date: Thu, 20 Aug 2026 00:53:55 -0400 Subject: [PATCH 2/2] Apply suggestions from code review Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- src/pcms/coupler/serializer/xgc.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/pcms/coupler/serializer/xgc.h b/src/pcms/coupler/serializer/xgc.h index 72169368..b5c62a12 100644 --- a/src/pcms/coupler/serializer/xgc.h +++ b/src/pcms/coupler/serializer/xgc.h @@ -34,10 +34,8 @@ class XGCFieldSerializer : public FieldSerializer } auto data = xgc_field->GetDOFHolderDataHost(); - const auto& layout = field.GetLayout(); - auto owned = layout.GetOwnedHost(); - // Per-holder plan: owned[i]/permutation[i] index holders; a holder's - // num_components values form one contiguous block in the wire buffer. + // Per-holder plan: permutation[i] indexes holders; a holder's num_components + // values form one contiguous block in the wire buffer. if (buffer.size() > 0) { const LO num_dof = static_cast(data.extent(0)); const LO num_comp = static_cast(data.extent(1));