From 00b66576899b92af3b208149f1ee81e0378b5d3a Mon Sep 17 00:00:00 2001 From: Dave Pugmire Date: Fri, 26 Aug 2022 12:03:20 -0400 Subject: [PATCH] Address comments from Ken, Ollie. --- vtkm/cont/PartitionedDataSet.cxx | 2 +- vtkm/cont/PartitionedDataSet.h | 4 +- vtkm/filter/NewFilter.cxx | 4 +- vtkm/filter/NewFilter.h | 47 +++++++++++- .../UnitTestPartitionedDataSetFilters.cxx | 76 ++++++++++++++----- 5 files changed, 103 insertions(+), 30 deletions(-) diff --git a/vtkm/cont/PartitionedDataSet.cxx b/vtkm/cont/PartitionedDataSet.cxx index 9cfc9615c..8048e438f 100644 --- a/vtkm/cont/PartitionedDataSet.cxx +++ b/vtkm/cont/PartitionedDataSet.cxx @@ -144,7 +144,7 @@ void PartitionedDataSet::ReplacePartition(vtkm::Id index, const vtkm::cont::Data } VTKM_CONT -void PartitionedDataSet::CopyStructure(const vtkm::cont::PartitionedDataSet& source) +void PartitionedDataSet::CopyPartitions(const vtkm::cont::PartitionedDataSet& source) { this->Partitions = source.Partitions; } diff --git a/vtkm/cont/PartitionedDataSet.h b/vtkm/cont/PartitionedDataSet.h index 7d8ebf08d..f1f94bfd7 100644 --- a/vtkm/cont/PartitionedDataSet.h +++ b/vtkm/cont/PartitionedDataSet.h @@ -218,9 +218,9 @@ public: } //@} - /// Copies the structure i.e. partitions from the source. The fields are left unchanged. + /// Copies the partitions from the source. The fields on the PartitionedDataSet are not copied. VTKM_CONT - void CopyStructure(const vtkm::cont::PartitionedDataSet& source); + void CopyPartitions(const vtkm::cont::PartitionedDataSet& source); VTKM_CONT void PrintSummary(std::ostream& stream) const; diff --git a/vtkm/filter/NewFilter.cxx b/vtkm/filter/NewFilter.cxx index de5c74231..1b4b1ddf5 100644 --- a/vtkm/filter/NewFilter.cxx +++ b/vtkm/filter/NewFilter.cxx @@ -119,10 +119,10 @@ vtkm::cont::DataSet NewFilter::CreateResult(const vtkm::cont::DataSet& inDataSet vtkm::cont::PartitionedDataSet NewFilter::CreateResult( const vtkm::cont::PartitionedDataSet& input, - const vtkm::cont::PartitionedDataSet& output) const + const vtkm::cont::PartitionedDataSet& resultPartitions) const { vtkm::cont::PartitionedDataSet clone; - clone.CopyStructure(output); + clone.CopyPartitions(resultPartitions); this->MapFieldsOntoOutput( input, clone, [](vtkm::cont::PartitionedDataSet& out, const vtkm::cont::Field& fieldToPass) { out.AddField(fieldToPass); diff --git a/vtkm/filter/NewFilter.h b/vtkm/filter/NewFilter.h index 7e45856b3..7e784de2d 100644 --- a/vtkm/filter/NewFilter.h +++ b/vtkm/filter/NewFilter.h @@ -326,9 +326,48 @@ protected: /// fields of `inDataSet` (as selected by the `FieldsToPass` state of the filter). /// VTKM_CONT vtkm::cont::DataSet CreateResult(const vtkm::cont::DataSet& inDataSet) const; + + + /// \brief Create the output data set for `DoExecute`. + /// + /// This form of `CreateResult` will create an output PartitionedDataSet with the + /// same partitions and pass all PartitionedDataSet fields (as requested by the + /// `Filter` state). + /// + /// \param[in] input The input data set being modified (usually the one passed into + /// `DoExecute`). + /// \param[in] resultPartitions The output data created by the filter. Fields from the input are + /// passed onto the return result partition as requested by the `Filter` state. + /// VTKM_CONT vtkm::cont::PartitionedDataSet CreateResult( const vtkm::cont::PartitionedDataSet& input, - const vtkm::cont::PartitionedDataSet& output) const; + const vtkm::cont::PartitionedDataSet& resultPartitions) const; + + /// \brief Create the output data set for `DoExecute`. + /// + /// This form of `CreateResult` will create an output PartitionedDataSet with the + /// same partitions and pass all PartitionedDataSet fields (as requested by the + /// `Filter` state). + /// + /// \param[in] input The input data set being modified (usually the one passed into + /// `DoExecute`). + /// \param[in] resultPartitions The output data created by the filter. Fields from the input are + /// passed onto the return result partition as requested by the `Filter` state. + /// \param[in] fieldMapper A function or functor that takes a `PartitionedDataSet` as its first + /// argument and a `Field` as its second argument. The `PartitionedDataSet` is the data being + /// created and will eventually be returned by `CreateResult`. The `Field` comes from `input`. + /// + + template + VTKM_CONT vtkm::cont::PartitionedDataSet CreateResult( + const vtkm::cont::PartitionedDataSet& input, + const vtkm::cont::PartitionedDataSet& resultPartitions, + FieldMapper&& fieldMapper) const + { + vtkm::cont::PartitionedDataSet output(resultPartitions.GetPartitions); + this->MapFieldsOntoOutput(input, output, fieldMapper); + return output; + } /// \brief Create the output data set for `DoExecute`. /// @@ -434,9 +473,9 @@ protected: const vtkm::cont::PartitionedDataSet& inData); private: - template - VTKM_CONT void MapFieldsOntoOutput(const DataType& input, - DataType& output, + template + VTKM_CONT void MapFieldsOntoOutput(const DataSetType& input, + DataSetType& output, FieldMapper&& fieldMapper) const { for (vtkm::IdComponent cc = 0; cc < input.GetNumberOfFields(); ++cc) diff --git a/vtkm/filter/testing/UnitTestPartitionedDataSetFilters.cxx b/vtkm/filter/testing/UnitTestPartitionedDataSetFilters.cxx index 5210f7a42..b2ab3010d 100644 --- a/vtkm/filter/testing/UnitTestPartitionedDataSetFilters.cxx +++ b/vtkm/filter/testing/UnitTestPartitionedDataSetFilters.cxx @@ -116,30 +116,64 @@ void TestPartitionedDataSetFilters() Result_Verify(result, cellAverage, partitions, std::string("pointvar")); //Make sure that any Fields are propagated to the output. - partitionNum = 3; - partitions = PartitionedDataSetBuilder(partitionNum, "pointvar"); - std::vector ids = { 0, 1, 2 }; - std::vector scalar = { 10.0f }; - partitions.AddPartitionsField("ids", ids); - partitions.AddAllPartitionsField("scalar", scalar); + //Test it with and without using SetFieldsToPass + std::vector> fieldsToPass; + fieldsToPass.push_back({}); + fieldsToPass.push_back({ "ids" }); + fieldsToPass.push_back({ "scalar" }); + fieldsToPass.push_back({ "ids", "scalar" }); - result = cellAverage.Execute(partitions); + for (auto& fields : fieldsToPass) + { + partitionNum = 3; + partitions = PartitionedDataSetBuilder(partitionNum, "pointvar"); + std::vector ids = { 0, 1, 2 }; + std::vector scalar = { 10.0f }; + partitions.AddPartitionsField("ids", ids); + partitions.AddAllPartitionsField("scalar", scalar); - VTKM_TEST_ASSERT(result.HasPartitionsField("ids"), "Missing field on result"); - auto field0 = result.GetField("ids"); - auto portal0 = field0.GetData().AsArrayHandle>().ReadPortal(); - VTKM_TEST_ASSERT(portal0.GetNumberOfValues() == static_cast(ids.size()), - "Wrong number of field values."); - for (std::size_t i = 0; i < ids.size(); i++) - VTKM_TEST_ASSERT(portal0.Get(static_cast(i)) == ids[i], "Wrong field value."); + //On second iteration, only allow "ids" to pass through. + cellAverage.GetFieldsToPass().ClearFields(); + if (!fields.empty()) + { + cellAverage.GetFieldsToPass().SetMode(vtkm::filter::FieldSelection::Mode::Select); + for (auto& f : fields) + cellAverage.GetFieldsToPass().AddField(f); + } - VTKM_TEST_ASSERT(result.HasAllPartitionsField("scalar"), "Missing field on result"); - auto field1 = result.GetField("scalar"); - auto portal1 = - field1.GetData().AsArrayHandle>().ReadPortal(); - VTKM_TEST_ASSERT(portal1.GetNumberOfValues() == static_cast(scalar.size()), - "Wrong number of field values."); - VTKM_TEST_ASSERT(portal1.Get(0) == scalar[0], "Wrong field value."); + result = cellAverage.Execute(partitions); + + if (fields.empty() || std::find(fields.begin(), fields.end(), "ids") != fields.end()) + { + VTKM_TEST_ASSERT(result.HasPartitionsField("ids"), "Missing field on result"); + auto field0 = result.GetField("ids"); + auto portal0 = + field0.GetData().AsArrayHandle>().ReadPortal(); + VTKM_TEST_ASSERT(portal0.GetNumberOfValues() == static_cast(ids.size()), + "Wrong number of field values."); + for (std::size_t i = 0; i < ids.size(); i++) + VTKM_TEST_ASSERT(portal0.Get(static_cast(i)) == ids[i], "Wrong field value."); + } + else + { + VTKM_TEST_ASSERT(!result.HasPartitionsField("ids"), "Field should not be on result"); + } + + if (fields.empty() || std::find(fields.begin(), fields.end(), "scalar") != fields.end()) + { + VTKM_TEST_ASSERT(result.HasAllPartitionsField("scalar"), "Missing field on result"); + auto field1 = result.GetField("scalar"); + auto portal1 = + field1.GetData().AsArrayHandle>().ReadPortal(); + VTKM_TEST_ASSERT(portal1.GetNumberOfValues() == static_cast(scalar.size()), + "Wrong number of field values."); + VTKM_TEST_ASSERT(portal1.Get(0) == scalar[0], "Wrong field value."); + } + else + { + VTKM_TEST_ASSERT(!result.HasAllPartitionsField("scalar"), "Field should not be on result"); + } + } } int UnitTestPartitionedDataSetFilters(int argc, char* argv[])