From 6ec329bd036f71d58da6a3d93a4a83868ffd10f5 Mon Sep 17 00:00:00 2001 From: Li-Ta Lo Date: Thu, 26 May 2022 12:52:08 -0600 Subject: [PATCH] migrate tutorials to New Filter interface --- tutorial/CMakeLists.txt | 50 ++++--------- tutorial/extract_edges.cxx | 143 ++++++++++++++++--------------------- tutorial/mag_grad.cxx | 21 +++--- tutorial/point_to_cell.cxx | 39 +++++----- tutorial/rendering.cxx | 1 - 5 files changed, 100 insertions(+), 154 deletions(-) diff --git a/tutorial/CMakeLists.txt b/tutorial/CMakeLists.txt index 8d3d5c46c..ac6368a88 100644 --- a/tutorial/CMakeLists.txt +++ b/tutorial/CMakeLists.txt @@ -36,11 +36,16 @@ target_link_libraries(two_filters vtkm_filter vtkm_io) add_executable(mag_grad mag_grad.cxx) target_link_libraries(mag_grad vtkm_filter vtkm_io) +# Because mag_grad.cxx creates a worklet with code that +# runs on a GPU, it needs additional information. +vtkm_add_target_information(mag_grad + DROP_UNUSED_SYMBOLS MODIFY_CUDA_FLAGS + DEVICE_SOURCES mag_grad.cxx) if (VTKm_ENABLE_RENDERING) add_executable(rendering rendering.cxx) target_link_libraries(rendering vtkm_filter vtkm_io vtkm_rendering) -endif() +endif () add_executable(error_handling error_handling.cxx) target_link_libraries(error_handling vtkm_filter vtkm_io) @@ -50,46 +55,15 @@ target_link_libraries(logging vtkm_filter vtkm_io) add_executable(point_to_cell point_to_cell.cxx) target_link_libraries(point_to_cell vtkm_cont vtkm_filter vtkm_io) +vtkm_add_target_information(point_to_cell + DROP_UNUSED_SYMBOLS MODIFY_CUDA_FLAGS + DEVICE_SOURCES point_to_cell.cxx) add_executable(extract_edges extract_edges.cxx) target_link_libraries(extract_edges vtkm_cont vtkm_filter vtkm_io) - -set(tutorial_targets -io -contour -contour_two_fields -two_filters -mag_grad -error_handling -logging -point_to_cell -extract_edges -) - -set(tutorial_sources -io.cxx -contour.cxx -contour_two_fields.cxx -two_filters.cxx -mag_grad.cxx -error_handling.cxx -logging.cxx -point_to_cell.cxx -extract_edges.cxx -) - -if (VTKm_ENABLE_RENDERING) - list(APPEND tutorial_sources rendering.cxx) - list(APPEND tutorial_targets rendering) -endif() - - -vtkm_add_target_information(${tutorial_targets} - DROP_UNUSED_SYMBOLS - MODIFY_CUDA_FLAGS - DEVICE_SOURCES - ${tutorial_sources}) - +vtkm_add_target_information(extract_edges + DROP_UNUSED_SYMBOLS MODIFY_CUDA_FLAGS + DEVICE_SOURCES extract_edges.cxx) # Copy the data file to be adjacent to the binaries file(GENERATE OUTPUT "$/data/kitchen.vtk" INPUT "${CMAKE_CURRENT_SOURCE_DIR}/data/kitchen.vtk") diff --git a/tutorial/extract_edges.cxx b/tutorial/extract_edges.cxx index 4ba0c9210..e1bef6a5e 100644 --- a/tutorial/extract_edges.cxx +++ b/tutorial/extract_edges.cxx @@ -21,6 +21,8 @@ #include #include +#include +#include #include #include @@ -117,95 +119,23 @@ struct EdgeIndicesWorklet : vtkm::worklet::WorkletReduceByKey namespace { -class ExtractEdges : public vtkm::filter::FilterDataSet -{ -public: - template - VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& inData, - vtkm::filter::PolicyBase policy); - - template - VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& input, - const vtkm::filter::FieldMetadata& fieldMeta, - const vtkm::filter::PolicyBase& policy); - -private: - vtkm::worklet::ScatterCounting::OutputToInputMapType OutputToInputCellMap; - vtkm::worklet::Keys CellToEdgeKeys; -}; - -template -inline VTKM_CONT vtkm::cont::DataSet ExtractEdges::DoExecute( - const vtkm::cont::DataSet& inData, - vtkm::filter::PolicyBase policy) -{ - auto inCellSet = vtkm::filter::ApplyPolicyCellSet(inData.GetCellSet(), policy, *this); - - // First, count the edges in each cell. - vtkm::cont::ArrayHandle edgeCounts; - this->Invoke(CountEdgesWorklet{}, inCellSet, edgeCounts); - - // Second, using these counts build a scatter that repeats a cell's visit - // for each edge in the cell. - vtkm::worklet::ScatterCounting scatter(edgeCounts); - this->OutputToInputCellMap = scatter.GetOutputToInputMap(inCellSet.GetNumberOfCells()); - vtkm::worklet::ScatterCounting::VisitArrayType outputToInputEdgeMap = - scatter.GetVisitArray(inCellSet.GetNumberOfCells()); - - // Third, for each edge, extract a canonical id. - vtkm::cont::ArrayHandle canonicalIds; - this->Invoke(EdgeIdsWorklet{}, scatter, inCellSet, canonicalIds); - - // Fourth, construct a Keys object to combine all like edge ids. - this->CellToEdgeKeys = vtkm::worklet::Keys(canonicalIds); - - // Fifth, use a reduce-by-key to extract indices for each unique edge. - vtkm::cont::ArrayHandle connectivityArray; - this->Invoke(EdgeIndicesWorklet{}, - this->CellToEdgeKeys, - inCellSet, - this->OutputToInputCellMap, - outputToInputEdgeMap, - vtkm::cont::make_ArrayHandleGroupVec<2>(connectivityArray)); - - // Sixth, use the created connectivity array to build a cell set. - vtkm::cont::CellSetSingleType<> outCellSet; - outCellSet.Fill(inCellSet.GetNumberOfPoints(), vtkm::CELL_SHAPE_LINE, 2, connectivityArray); - - vtkm::cont::DataSet outData; - - outData.SetCellSet(outCellSet); - - for (vtkm::IdComponent coordSystemIndex = 0; - coordSystemIndex < inData.GetNumberOfCoordinateSystems(); - ++coordSystemIndex) - { - outData.AddCoordinateSystem(inData.GetCoordinateSystem(coordSystemIndex)); - } - - return outData; -} - -template -inline VTKM_CONT bool ExtractEdges::DoMapField( +VTKM_CONT bool DoMapField( vtkm::cont::DataSet& result, - const vtkm::cont::ArrayHandle& inputArray, - const vtkm::filter::FieldMetadata& fieldMeta, - const vtkm::filter::PolicyBase&) + const vtkm::cont::Field& inputField, + const vtkm::worklet::ScatterCounting::OutputToInputMapType& OutputToInputCellMap, + const vtkm::worklet::Keys& CellToEdgeKeys) { vtkm::cont::Field outputField; - if (fieldMeta.IsPointField()) + if (inputField.IsFieldPoint()) { - outputField = fieldMeta.AsField(inputArray); // pass through + outputField = inputField; // pass through } - else if (fieldMeta.IsCellField()) + else if (inputField.IsFieldCell()) { - auto outputCellArray = vtkm::worklet::AverageByKey::Run( - this->CellToEdgeKeys, - vtkm::cont::make_ArrayHandlePermutation(this->OutputToInputCellMap, inputArray)); - outputField = fieldMeta.AsField(outputCellArray); + vtkm::cont::Field permuted; + vtkm::filter::MapFieldPermutation(inputField, OutputToInputCellMap, permuted); + vtkm::filter::MapFieldMergeAverage(permuted, CellToEdgeKeys, outputField); } else { @@ -217,6 +147,55 @@ inline VTKM_CONT bool ExtractEdges::DoMapField( return true; } +class ExtractEdges : public vtkm::filter::NewFilter +{ +public: + VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& inData) override; +}; + +VTKM_CONT vtkm::cont::DataSet ExtractEdges::DoExecute(const vtkm::cont::DataSet& inData) +{ + auto inCellSet = inData.GetCellSet(); + + // First, count the edges in each cell. + vtkm::cont::ArrayHandle edgeCounts; + this->Invoke(CountEdgesWorklet{}, inCellSet, edgeCounts); + + // Second, using these counts build a scatter that repeats a cell's visit + // for each edge in the cell. + vtkm::worklet::ScatterCounting scatter(edgeCounts); + vtkm::worklet::ScatterCounting::OutputToInputMapType OutputToInputCellMap; + OutputToInputCellMap = scatter.GetOutputToInputMap(inCellSet.GetNumberOfCells()); + vtkm::worklet::ScatterCounting::VisitArrayType outputToInputEdgeMap = + scatter.GetVisitArray(inCellSet.GetNumberOfCells()); + + // Third, for each edge, extract a canonical id. + vtkm::cont::ArrayHandle canonicalIds; + this->Invoke(EdgeIdsWorklet{}, scatter, inCellSet, canonicalIds); + + // Fourth, construct a Keys object to combine all like edge ids. + vtkm::worklet::Keys CellToEdgeKeys; + CellToEdgeKeys = vtkm::worklet::Keys(canonicalIds); + + // Fifth, use a reduce-by-key to extract indices for each unique edge. + vtkm::cont::ArrayHandle connectivityArray; + this->Invoke(EdgeIndicesWorklet{}, + CellToEdgeKeys, + inCellSet, + OutputToInputCellMap, + outputToInputEdgeMap, + vtkm::cont::make_ArrayHandleGroupVec<2>(connectivityArray)); + + // Sixth, use the created connectivity array to build a cell set. + vtkm::cont::CellSetSingleType<> outCellSet; + outCellSet.Fill(inCellSet.GetNumberOfPoints(), vtkm::CELL_SHAPE_LINE, 2, connectivityArray); + + auto mapper = [&](auto& outDataSet, const auto& f) { + DoMapField(outDataSet, f, OutputToInputCellMap, CellToEdgeKeys); + }; + return this->CreateResult(inData, outCellSet, inData.GetCoordinateSystems(), mapper); +} + } int main(int argc, char** argv) diff --git a/tutorial/mag_grad.cxx b/tutorial/mag_grad.cxx index 68b603768..e23254367 100644 --- a/tutorial/mag_grad.cxx +++ b/tutorial/mag_grad.cxx @@ -28,29 +28,30 @@ struct ComputeMagnitude : vtkm::worklet::WorkletMapField } }; -#include +#include -class FieldMagnitude : public vtkm::filter::FilterField +class FieldMagnitude : public vtkm::filter::NewFilterField { public: using SupportedTypes = vtkm::List; - template - VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& inDataSet, - const ArrayHandleType& inField, - const vtkm::filter::FieldMetadata& fieldMetadata, - vtkm::filter::PolicyBase) + VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& inDataSet) override { + const auto& inField = this->GetFieldFromDataSet(inDataSet); vtkm::cont::ArrayHandle outField; - this->Invoke(ComputeMagnitude{}, inField, outField); + + auto resolveType = [&](const auto& concrete) { + this->Invoke(ComputeMagnitude{}, concrete, outField); + }; + this->CastAndCallVecField<3>(inField, resolveType); std::string outFieldName = this->GetOutputFieldName(); if (outFieldName == "") { - outFieldName = fieldMetadata.GetName() + "_magnitude"; + outFieldName = inField.GetName() + "_magnitude"; } - return vtkm::filter::CreateResult(inDataSet, outField, outFieldName, fieldMetadata); + return this->CreateResultFieldCell(inDataSet, outFieldName, outField); } }; diff --git a/tutorial/point_to_cell.cxx b/tutorial/point_to_cell.cxx index 6dadccaa9..0da92c2f7 100644 --- a/tutorial/point_to_cell.cxx +++ b/tutorial/point_to_cell.cxx @@ -46,46 +46,39 @@ struct ConvertPointFieldToCells : vtkm::worklet::WorkletVisitCellsWithPoints } // namespace worklet } // namespace vtkm -#include +#include namespace vtkm { namespace filter { -struct ConvertPointFieldToCells : vtkm::filter::FilterField +struct ConvertPointFieldToCells : vtkm::filter::NewFilterField { - template - VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& inDataSet, - const ArrayHandleType& inField, - const vtkm::filter::FieldMetadata& fieldMetadata, - vtkm::filter::PolicyBase); + VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& inDataSet) override; }; -template -VTKM_CONT cont::DataSet ConvertPointFieldToCells::DoExecute( - const vtkm::cont::DataSet& inDataSet, - const ArrayHandleType& inField, - const vtkm::filter::FieldMetadata& fieldMetadata, - vtkm::filter::PolicyBase policy) +VTKM_CONT cont::DataSet ConvertPointFieldToCells::DoExecute(const vtkm::cont::DataSet& inDataSet) { - VTKM_IS_ARRAY_HANDLE(ArrayHandleType); + const auto& inField = this->GetFieldFromDataSet(inDataSet); - using ValueType = typename ArrayHandleType::ValueType; + vtkm::cont::UnknownArrayHandle outArray; + auto resolveType = [&](const auto& concrete) { + using ValueType = typename std::decay_t::ValueType; - vtkm::cont::ArrayHandle outField; - this->Invoke(vtkm::worklet::ConvertPointFieldToCells{}, - vtkm::filter::ApplyPolicyCellSet(inDataSet.GetCellSet(), policy, *this), - inField, - outField); + vtkm::cont::ArrayHandle outField; + this->Invoke( + vtkm::worklet::ConvertPointFieldToCells{}, inDataSet.GetCellSet(), concrete, outField); + outArray = outField; + }; + this->CastAndCallScalarField(inField, resolveType); std::string outFieldName = this->GetOutputFieldName(); if (outFieldName == "") { - outFieldName = fieldMetadata.GetName(); + outFieldName = inField.GetName(); } - - return vtkm::filter::CreateResultFieldCell(inDataSet, outField, outFieldName); + return this->CreateResultFieldCell(inDataSet, outFieldName, outArray); } } // namespace filter diff --git a/tutorial/rendering.cxx b/tutorial/rendering.cxx index 3fed98298..e5059eeb1 100644 --- a/tutorial/rendering.cxx +++ b/tutorial/rendering.cxx @@ -12,7 +12,6 @@ #include #include -#include #include #include #include