From 7e04b0511f9c05d40c798f0c6eda015b84397d4a Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Wed, 31 Jul 2019 13:50:23 -0400 Subject: [PATCH] Move Invoker into vtkm/cont The Invoker is a control side object that handles the construction of the relevant worklet dispatcher. Moving it to control makes it obvious that it isn't an algorithm itself but a way to launch worklets. --- benchmarking/BenchmarkFieldAlgorithms.cxx | 12 +- docs/changelog/invoker-vtkm-cont.md | 6 + vtkm/cont/CMakeLists.txt | 1 + .../CellLocatorBoundingIntervalHierarchy.cxx | 11 +- vtkm/cont/CellLocatorUniformBins.cxx | 4 +- vtkm/cont/CellSetExtrude.h | 2 +- vtkm/cont/CellSetExtrude.hxx | 2 +- vtkm/cont/ColorTable.hxx | 8 +- vtkm/{worklet => cont}/Invoker.h | 36 +- vtkm/cont/testing/TestingBitField.h | 7 +- .../raytracing/BoundingVolumeHierarchy.cxx | 2 +- vtkm/worklet/CMakeLists.txt | 1 - vtkm/worklet/PointMerge.h | 6 +- vtkm/worklet/SplitSharpEdges.h | 4 +- vtkm/worklet/StreamLineUniformGrid.h | 4 +- .../contourtree_augmented/ActiveGraph.h | 4 +- .../contourtree_augmented/ContourTreeMaker.h | 4 +- .../contourtree_augmented/MeshExtrema.h | 4 +- .../Mesh_DEM_Triangulation.h | 4 +- vtkm/worklet/cosmotools/CosmoTools.h | 2 +- .../worklet/cosmotools/CosmoToolsHaloFinder.h | 2 +- .../UnitTestBoundingIntervalHierarchy.cxx | 2 +- .../testing/UnitTestClippingWithFunction.cxx | 354 ++++++++++++++++++ 23 files changed, 420 insertions(+), 62 deletions(-) create mode 100644 docs/changelog/invoker-vtkm-cont.md rename vtkm/{worklet => cont}/Invoker.h (80%) create mode 100644 vtkm/worklet/testing/UnitTestClippingWithFunction.cxx diff --git a/benchmarking/BenchmarkFieldAlgorithms.cxx b/benchmarking/BenchmarkFieldAlgorithms.cxx index 8a7bc4480..714975061 100644 --- a/benchmarking/BenchmarkFieldAlgorithms.cxx +++ b/benchmarking/BenchmarkFieldAlgorithms.cxx @@ -17,11 +17,9 @@ #include #include #include +#include #include -#include -#include -#include #include #include @@ -529,7 +527,7 @@ private: Timer timer{ DeviceAdapter() }; timer.Start(); - vtkm::worklet::Invoker invoke(DeviceAdapter{}); + vtkm::cont::Invoker invoke(DeviceAdapter{}); invoke(Mag{}, this->InputHandle, tempHandle1); invoke(Sin{}, tempHandle1, tempHandle2); invoke(Square{}, tempHandle2, tempHandle1); @@ -567,7 +565,7 @@ private: Timer timer{ DeviceAdapter() }; timer.Start(); - vtkm::worklet::Invoker invoke(DeviceAdapter{}); + vtkm::cont::Invoker invoke(DeviceAdapter{}); invoke(Mag{}, dinput, dtemp1); invoke(Sin{}, dtemp1, dtemp2); invoke(Square{}, dtemp2, dtemp1); @@ -595,7 +593,7 @@ private: Timer timer{ DeviceAdapter() }; timer.Start(); - vtkm::worklet::Invoker invoke(DeviceAdapter{}); + vtkm::cont::Invoker invoke(DeviceAdapter{}); invoke(Mag{}, mInput, mTemp1); invoke(Sin{}, mTemp1, mTemp2); invoke(Square{}, mTemp2, mTemp1); @@ -632,7 +630,7 @@ private: Timer timer{ DeviceAdapter() }; timer.Start(); - vtkm::worklet::Invoker invoke(DeviceAdapter{}); + vtkm::cont::Invoker invoke(DeviceAdapter{}); invoke(Mag{}, mInput, mTemp1); invoke(Sin{}, mTemp1, mTemp2); invoke(Square{}, mTemp2, mTemp1); diff --git a/docs/changelog/invoker-vtkm-cont.md b/docs/changelog/invoker-vtkm-cont.md new file mode 100644 index 000000000..d0eb406af --- /dev/null +++ b/docs/changelog/invoker-vtkm-cont.md @@ -0,0 +1,6 @@ +# Invoker moved to vtkm::cont + +Previously, `Invoker` was located in the `vtkm::worklet` namespace to convey +it was a replacement for using `vtkm::worklet::Dispatcher*`. In actuality +it should be in `vtkm::cont` as it is the proper way to launch worklets +for execution, and that shouldn't exist inside the `worklet` namespace. diff --git a/vtkm/cont/CMakeLists.txt b/vtkm/cont/CMakeLists.txt index ab3039b2e..0c2385912 100644 --- a/vtkm/cont/CMakeLists.txt +++ b/vtkm/cont/CMakeLists.txt @@ -89,6 +89,7 @@ set(headers FieldRangeGlobalCompute.h ImplicitFunctionHandle.h Initialize.h + Invoker.h Logging.h MultiBlock.h PointLocator.h diff --git a/vtkm/cont/CellLocatorBoundingIntervalHierarchy.cxx b/vtkm/cont/CellLocatorBoundingIntervalHierarchy.cxx index 22b3db775..c24353aa6 100644 --- a/vtkm/cont/CellLocatorBoundingIntervalHierarchy.cxx +++ b/vtkm/cont/CellLocatorBoundingIntervalHierarchy.cxx @@ -22,9 +22,8 @@ #include #include #include -#include -#include -#include + +#include #include #include @@ -87,7 +86,7 @@ void CalculatePlaneSplitCost(vtkm::IdComponent planeIndex, vtkm::IdComponent index, vtkm::IdComponent numTotalPlanes) { - vtkm::worklet::Invoker invoker; + vtkm::cont::Invoker invoker; // Make candidate split plane array vtkm::cont::ArrayHandle splitPlanes; @@ -182,7 +181,7 @@ IdArrayHandle CalculateSplitScatterIndices(const IdArrayHandle& cellIds, const IdArrayHandle& leqFlags, const IdArrayHandle& segmentIds) { - vtkm::worklet::Invoker invoker; + vtkm::cont::Invoker invoker; // Count total number of true flags preceding in segment IdArrayHandle trueFlagCounts; @@ -230,7 +229,7 @@ CellLocatorBoundingIntervalHierarchy::~CellLocatorBoundingIntervalHierarchy() = void CellLocatorBoundingIntervalHierarchy::Build() { - vtkm::worklet::Invoker invoker; + vtkm::cont::Invoker invoker; vtkm::cont::DynamicCellSet cellSet = this->GetCellSet(); vtkm::Id numCells = cellSet.GetNumberOfCells(); diff --git a/vtkm/cont/CellLocatorUniformBins.cxx b/vtkm/cont/CellLocatorUniformBins.cxx index 4394545a7..99b42a1e8 100644 --- a/vtkm/cont/CellLocatorUniformBins.cxx +++ b/vtkm/cont/CellLocatorUniformBins.cxx @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include @@ -346,7 +346,7 @@ namespace cont /// VTKM_CONT void CellLocatorUniformBins::Build() { - vtkm::worklet::Invoker invoke; + vtkm::cont::Invoker invoke; auto cellset = this->GetCellSet(); const auto& coords = this->GetCoordinates(); diff --git a/vtkm/cont/CellSetExtrude.h b/vtkm/cont/CellSetExtrude.h index 7c146b49e..15966aaeb 100644 --- a/vtkm/cont/CellSetExtrude.h +++ b/vtkm/cont/CellSetExtrude.h @@ -16,9 +16,9 @@ #include #include #include +#include #include #include -#include #include namespace vtkm diff --git a/vtkm/cont/CellSetExtrude.hxx b/vtkm/cont/CellSetExtrude.hxx index fdc257d98..0558e0d1c 100644 --- a/vtkm/cont/CellSetExtrude.hxx +++ b/vtkm/cont/CellSetExtrude.hxx @@ -50,7 +50,7 @@ namespace cont template VTKM_CONT void CellSetExtrude::BuildReverseConnectivity(Device) { - vtkm::worklet::Invoker invoke(Device{}); + vtkm::cont::Invoker invoke(Device{}); // create a mapping of where each key is the point id and the value // is the cell id. We diff --git a/vtkm/cont/ColorTable.hxx b/vtkm/cont/ColorTable.hxx index 61eff27e0..a38747712 100644 --- a/vtkm/cont/ColorTable.hxx +++ b/vtkm/cont/ColorTable.hxx @@ -15,7 +15,7 @@ #include #include -#include +#include #include #include #include @@ -79,7 +79,7 @@ struct map_color_table inline bool operator()(DeviceAdapter device, ColorTable&& colors, Args&&... args) const { vtkm::worklet::colorconversion::TransferFunction transfer(colors->PrepareForExecution(device)); - vtkm::worklet::Invoker invoke(device); + vtkm::cont::Invoker invoke(device); invoke(transfer, std::forward(args)...); return true; } @@ -97,7 +97,7 @@ bool ColorTable::Map(const vtkm::cont::ArrayHandle& values, return false; } vtkm::worklet::colorconversion::LookupTable lookupTable(samples); - vtkm::worklet::Invoker invoke(vtkm::cont::DeviceAdapterTagAny{}); + vtkm::cont::Invoker invoke(vtkm::cont::DeviceAdapterTagAny{}); invoke(lookupTable, values, samples.Samples, rgbaOut); return true; } @@ -112,7 +112,7 @@ bool ColorTable::Map(const vtkm::cont::ArrayHandle& values, return false; } vtkm::worklet::colorconversion::LookupTable lookupTable(samples); - vtkm::worklet::Invoker invoke(vtkm::cont::DeviceAdapterTagAny{}); + vtkm::cont::Invoker invoke(vtkm::cont::DeviceAdapterTagAny{}); invoke(lookupTable, values, samples.Samples, rgbOut); return true; } diff --git a/vtkm/worklet/Invoker.h b/vtkm/cont/Invoker.h similarity index 80% rename from vtkm/worklet/Invoker.h rename to vtkm/cont/Invoker.h index 8d97a1ec9..dfc2dfdb3 100644 --- a/vtkm/worklet/Invoker.h +++ b/vtkm/cont/Invoker.h @@ -7,8 +7,8 @@ // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notice for more information. //============================================================================ -#ifndef vtk_m_worklet_Invoker_h -#define vtk_m_worklet_Invoker_h +#ifndef vtk_m_cont_Invoker_h +#define vtk_m_cont_Invoker_h #include #include @@ -19,7 +19,7 @@ namespace vtkm { -namespace worklet +namespace cont { @@ -56,15 +56,16 @@ struct Invoker /// Optional second parameter is the scatter type associated with the worklet. /// Any additional parameters are the ControlSignature arguments for the worklet. /// - template >::value, - int>::type* = nullptr> + template < + typename Worklet, + typename T, + typename... Args, + typename std::enable_if>::value, + int>::type* = nullptr> inline void operator()(Worklet&& worklet, T&& scatter, Args&&... args) const { - using WorkletType = internal::detail::remove_cvref; + using WorkletType = worklet::internal::detail::remove_cvref; using DispatcherType = typename WorkletType::template Dispatcher; DispatcherType dispatcher(worklet, scatter); @@ -76,15 +77,16 @@ struct Invoker /// Optional second parameter is the scatter type associated with the worklet. /// Any additional parameters are the ControlSignature arguments for the worklet. /// - template >::value, - int>::type* = nullptr> + template < + typename Worklet, + typename T, + typename... Args, + typename std::enable_if>::value, + int>::type* = nullptr> inline void operator()(Worklet&& worklet, T&& t, Args&&... args) const { - using WorkletType = internal::detail::remove_cvref; + using WorkletType = worklet::internal::detail::remove_cvref; using DispatcherType = typename WorkletType::template Dispatcher; DispatcherType dispatcher(worklet); diff --git a/vtkm/cont/testing/TestingBitField.h b/vtkm/cont/testing/TestingBitField.h index ead8d290a..78f1d9abc 100644 --- a/vtkm/cont/testing/TestingBitField.h +++ b/vtkm/cont/testing/TestingBitField.h @@ -14,14 +14,13 @@ #include #include #include +#include #include #include #include -#include - #include #define DEVICE_ASSERT_MSG(cond, message) \ @@ -599,7 +598,7 @@ struct TestingBitField auto falseArray = vtkm::cont::make_ArrayHandleCounting(13, 2, NUM_BITS); vtkm::cont::ArrayHandle output; - vtkm::worklet::Invoker invoke; + vtkm::cont::Invoker invoke; invoke(ConditionalMergeWorklet{}, condArray, trueArray, falseArray, output); auto condVals = condArray.GetPortalConstControl(); @@ -625,7 +624,7 @@ struct TestingBitField auto falseArray = vtkm::cont::make_ArrayHandleCounting(13, 2, NUM_BITS); vtkm::cont::ArrayHandle output; - vtkm::worklet::Invoker invoke; + vtkm::cont::Invoker invoke; invoke(ConditionalMergeWorklet2{}, condBits, trueArray, falseArray, output); auto condVals = condBits.GetPortalConstControl(); diff --git a/vtkm/rendering/raytracing/BoundingVolumeHierarchy.cxx b/vtkm/rendering/raytracing/BoundingVolumeHierarchy.cxx index 31648cdcf..26448160b 100644 --- a/vtkm/rendering/raytracing/BoundingVolumeHierarchy.cxx +++ b/vtkm/rendering/raytracing/BoundingVolumeHierarchy.cxx @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -27,7 +28,6 @@ #include #include -#include #include #define AABB_EPSILON 0.00001f diff --git a/vtkm/worklet/CMakeLists.txt b/vtkm/worklet/CMakeLists.txt index 500252a03..68e63582c 100644 --- a/vtkm/worklet/CMakeLists.txt +++ b/vtkm/worklet/CMakeLists.txt @@ -33,7 +33,6 @@ set(headers FieldHistogram.h FieldStatistics.h Gradient.h - Invoker.h KdTree3D.h KernelSplatter.h Keys.h diff --git a/vtkm/worklet/PointMerge.h b/vtkm/worklet/PointMerge.h index a269b92b5..9a3632219 100644 --- a/vtkm/worklet/PointMerge.h +++ b/vtkm/worklet/PointMerge.h @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -25,6 +24,7 @@ #include #include #include +#include #include #include @@ -336,7 +336,7 @@ private: vtkm::cont::ArrayHandle>& points, // coordinates, modified to merge close vtkm::cont::ArrayHandle indexNeighborMap) // identifies each neighbor group, updated { - Invoker invoker; + vtkm::cont::Invoker invoker; vtkm::cont::ArrayHandle hashes; invoker(CoordsToHash(), points, binLocator, hashes); @@ -358,7 +358,7 @@ public: const vtkm::Bounds& bounds, // Bounds of points vtkm::cont::ArrayHandle>& points) // coordinates, modified to merge close { - Invoker invoker; + vtkm::cont::Invoker invoker; BinLocator binLocator(bounds, delta); diff --git a/vtkm/worklet/SplitSharpEdges.h b/vtkm/worklet/SplitSharpEdges.h index 81dbbde64..ded85a8ba 100644 --- a/vtkm/worklet/SplitSharpEdges.h +++ b/vtkm/worklet/SplitSharpEdges.h @@ -11,12 +11,12 @@ #define vtk_m_worklet_SplitSharpEdges_h #include -#include #include #include #include #include +#include #include #include @@ -401,7 +401,7 @@ public: vtkm::cont::ArrayHandle, CoordsOutStorageType>& newCoords, NewCellSetType& newCellset) { - vtkm::worklet::Invoker invoke; + vtkm::cont::Invoker invoke; const vtkm::FloatDefault featureAngleR = featureAngle / static_cast(180.0) * vtkm::Pi(); diff --git a/vtkm/worklet/StreamLineUniformGrid.h b/vtkm/worklet/StreamLineUniformGrid.h index ee06cb634..c91002472 100644 --- a/vtkm/worklet/StreamLineUniformGrid.h +++ b/vtkm/worklet/StreamLineUniformGrid.h @@ -19,8 +19,8 @@ #include #include #include +#include -#include #include #include @@ -375,7 +375,7 @@ public: // Worklet to make the streamlines streamline::MakeStreamLines makeStreamLines(timeStep, streamMode, maxSteps, vdims); - vtkm::worklet::Invoker{}( + vtkm::cont::Invoker{}( makeStreamLines, fieldArray, seedIdArray, seedPosArray, numIndices, validPoint, streamArray); // Size of connectivity based on size of returned streamlines diff --git a/vtkm/worklet/contourtree_augmented/ActiveGraph.h b/vtkm/worklet/contourtree_augmented/ActiveGraph.h index 5bcdf19e1..a11c714a0 100644 --- a/vtkm/worklet/contourtree_augmented/ActiveGraph.h +++ b/vtkm/worklet/contourtree_augmented/ActiveGraph.h @@ -97,7 +97,7 @@ #include #include #include -#include +#include namespace active_graph_inc_ns = vtkm::worklet::contourtree_augmented::active_graph_inc; @@ -114,7 +114,7 @@ namespace contourtree_augmented class ActiveGraph { // class ActiveGraph public: - vtkm::worklet::Invoker Invoke; + vtkm::cont::Invoker Invoke; // we also need the orientation of the edges (i.e. is it join or split) bool isJoinGraph; diff --git a/vtkm/worklet/contourtree_augmented/ContourTreeMaker.h b/vtkm/worklet/contourtree_augmented/ContourTreeMaker.h index db0f4b33a..11a8e09b5 100644 --- a/vtkm/worklet/contourtree_augmented/ContourTreeMaker.h +++ b/vtkm/worklet/contourtree_augmented/ContourTreeMaker.h @@ -95,7 +95,7 @@ #include #include #include -#include +#include @@ -113,7 +113,7 @@ namespace contourtree_augmented class ContourTreeMaker { // class MergeTree public: - vtkm::worklet::Invoker Invoke; + vtkm::cont::Invoker Invoke; // the contour tree, join tree & split tree to use ContourTree& contourTree; diff --git a/vtkm/worklet/contourtree_augmented/MeshExtrema.h b/vtkm/worklet/contourtree_augmented/MeshExtrema.h index f05cdb939..0a483330d 100644 --- a/vtkm/worklet/contourtree_augmented/MeshExtrema.h +++ b/vtkm/worklet/contourtree_augmented/MeshExtrema.h @@ -58,7 +58,7 @@ // local includes #include #include -#include +#include #include #include #include @@ -79,7 +79,7 @@ namespace contourtree_augmented class MeshExtrema { // MeshExtrema public: - vtkm::worklet::Invoker Invoke; + vtkm::cont::Invoker Invoke; // arrays for peaks & pits IdArrayType peaks; IdArrayType pits; diff --git a/vtkm/worklet/contourtree_augmented/Mesh_DEM_Triangulation.h b/vtkm/worklet/contourtree_augmented/Mesh_DEM_Triangulation.h index 6548cbccd..c3f4e157c 100644 --- a/vtkm/worklet/contourtree_augmented/Mesh_DEM_Triangulation.h +++ b/vtkm/worklet/contourtree_augmented/Mesh_DEM_Triangulation.h @@ -78,7 +78,7 @@ #include #include #include -#include +#include #include #include @@ -244,7 +244,7 @@ void Mesh_DEM_Triangulation::SortData( // for (indexType vertex = 0; vertex < nVertices; vertex++) // sortIndices[sortOrder[vertex]] = vertex; mesh_dem_worklets::SortIndices sortIndicesWorklet; - vtkm::worklet::Invoker invoke; + vtkm::cont::Invoker invoke; invoke(sortIndicesWorklet, sortOrder, sortIndices); // Debug print statement diff --git a/vtkm/worklet/cosmotools/CosmoTools.h b/vtkm/worklet/cosmotools/CosmoTools.h index 3167acabf..d86ff4d2e 100644 --- a/vtkm/worklet/cosmotools/CosmoTools.h +++ b/vtkm/worklet/cosmotools/CosmoTools.h @@ -76,7 +76,7 @@ #include #include #include -#include +#include #include #include diff --git a/vtkm/worklet/cosmotools/CosmoToolsHaloFinder.h b/vtkm/worklet/cosmotools/CosmoToolsHaloFinder.h index 0bb57a98a..173ce5163 100644 --- a/vtkm/worklet/cosmotools/CosmoToolsHaloFinder.h +++ b/vtkm/worklet/cosmotools/CosmoToolsHaloFinder.h @@ -316,7 +316,7 @@ void CosmoTools::MBPCenterFindingByHalo(vtkm::cont::ArrayHandle< // Setup the ScatterCounting worklets needed to expand the ReduceByKeyResults vtkm::worklet::ScatterCounting scatter(particlesPerHalo); - vtkm::worklet::Invoker invoke; + vtkm::cont::Invoker invoke; // Calculate the minimum particle index per halo id and scatter DeviceAlgorithm::ScanExclusive(particlesPerHalo, tempI); diff --git a/vtkm/worklet/testing/UnitTestBoundingIntervalHierarchy.cxx b/vtkm/worklet/testing/UnitTestBoundingIntervalHierarchy.cxx index 50ba66555..17791dba1 100644 --- a/vtkm/worklet/testing/UnitTestBoundingIntervalHierarchy.cxx +++ b/vtkm/worklet/testing/UnitTestBoundingIntervalHierarchy.cxx @@ -12,12 +12,12 @@ #include #include #include +#include #include #include #include #include #include -#include namespace { diff --git a/vtkm/worklet/testing/UnitTestClippingWithFunction.cxx b/vtkm/worklet/testing/UnitTestClippingWithFunction.cxx new file mode 100644 index 000000000..f5da28000 --- /dev/null +++ b/vtkm/worklet/testing/UnitTestClippingWithFunction.cxx @@ -0,0 +1,354 @@ +//============================================================================ +// Copyright (c) Kitware, Inc. +// All rights reserved. +// See LICENSE.txt for details. +// +// This software is distributed WITHOUT ANY WARRANTY; without even +// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. See the above copyright notice for more information. +//============================================================================ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include + +using Coord3D = vtkm::Vec; + +const vtkm::Float32 clipValue = 0.5; + +template +bool TestArrayHandle(const vtkm::cont::ArrayHandle& ah, + const T* expected, + vtkm::Id size) +{ + if (size != ah.GetNumberOfValues()) + { + return false; + } + + for (vtkm::Id i = 0; i < size; ++i) + { + if (ah.GetPortalConstControl().Get(i) != expected[i]) + { + return false; + } + } + + return true; +} + +vtkm::cont::DataSet MakeTestDatasetExplicit() +{ + std::vector coords; + coords.push_back(Coord3D(0.0f, 0.0f, 0.0f)); + coords.push_back(Coord3D(1.0f, 0.0f, 0.0f)); + coords.push_back(Coord3D(1.0f, 1.0f, 0.0f)); + coords.push_back(Coord3D(0.0f, 1.0f, 0.0f)); + + std::vector connectivity; + connectivity.push_back(0); + connectivity.push_back(1); + connectivity.push_back(3); + connectivity.push_back(3); + connectivity.push_back(1); + connectivity.push_back(2); + + vtkm::cont::DataSet ds; + vtkm::cont::DataSetBuilderExplicit builder; + ds = builder.Create(coords, vtkm::CellShapeTagTriangle(), 3, connectivity, "coords"); + + vtkm::cont::DataSetFieldAdd fieldAdder; + + std::vector values; + values.push_back(1.0); + values.push_back(2.0); + values.push_back(1.0); + values.push_back(0.0); + fieldAdder.AddPointField(ds, "scalars", values); + + values.clear(); + values.push_back(100.f); + values.push_back(-100.f); + fieldAdder.AddCellField(ds, "cellvar", values); + + return ds; +} + +vtkm::cont::DataSet MakeTestDatasetStructured() +{ + static constexpr vtkm::Id xdim = 3, ydim = 3; + static const vtkm::Id2 dim(xdim, ydim); + static constexpr vtkm::Id numVerts = xdim * ydim; + + vtkm::Float32 scalars[numVerts]; + for (vtkm::Id i = 0; i < numVerts; ++i) + { + scalars[i] = 1.0f; + } + scalars[4] = 0.0f; + + vtkm::cont::DataSet ds; + vtkm::cont::DataSetBuilderUniform builder; + ds = builder.Create(dim); + + vtkm::cont::DataSetFieldAdd fieldAdder; + fieldAdder.AddPointField(ds, "scalars", scalars, numVerts); + + std::vector cellvar = { -100.f, 100.f, 30.f, -30.f }; + fieldAdder.AddCellField(ds, "cellvar", cellvar); + + return ds; +} + +void TestClippingExplicit() +{ + vtkm::cont::DataSet ds = MakeTestDatasetExplicit(); + vtkm::worklet::Clip clip; + bool invertClip = false; + vtkm::cont::CellSetExplicit<> outputCellSet = + clip.Run(ds.GetCellSet(0), + ds.GetField("scalars").GetData().ResetTypes(vtkm::TypeListTagFieldScalar()), + clipValue, + invertClip); + + auto coordsIn = ds.GetCoordinateSystem("coords").GetData(); + vtkm::cont::ArrayHandle coords = clip.ProcessPointField(coordsIn); + + vtkm::cont::ArrayHandle scalarsIn; + ds.GetField("scalars").GetData().CopyTo(scalarsIn); + vtkm::cont::ArrayHandle scalars = clip.ProcessPointField(scalarsIn); + + vtkm::cont::ArrayHandle cellvarIn; + ds.GetField("cellvar").GetData().CopyTo(cellvarIn); + vtkm::cont::ArrayHandle cellvar = clip.ProcessCellField(cellvarIn); + + vtkm::Id connectivitySize = 8; + vtkm::Id fieldSize = 7; + vtkm::Id expectedConnectivity[] = { 0, 1, 5, 4, 1, 2, 6, 5 }; + const Coord3D expectedCoords[] = { + Coord3D(0.00f, 0.00f, 0.0f), Coord3D(1.00f, 0.00f, 0.0f), Coord3D(1.00f, 1.00f, 0.0f), + Coord3D(0.00f, 1.00f, 0.0f), Coord3D(0.00f, 0.50f, 0.0f), Coord3D(0.25f, 0.75f, 0.0f), + Coord3D(0.50f, 1.00f, 0.0f), + }; + const vtkm::Float32 expectedScalars[] = { 1, 2, 1, 0, 0.5, 0.5, 0.5 }; + std::vector expectedCellvar = { 100.f, -100.f }; + + VTKM_TEST_ASSERT(outputCellSet.GetNumberOfPoints() == fieldSize, + "Wrong number of points in cell set."); + + VTKM_TEST_ASSERT( + TestArrayHandle(outputCellSet.GetConnectivityArray(vtkm::TopologyElementTagPoint(), + vtkm::TopologyElementTagCell()), + expectedConnectivity, + connectivitySize), + "Got incorrect conectivity"); + + VTKM_TEST_ASSERT(TestArrayHandle(coords, expectedCoords, fieldSize), "Got incorrect coordinates"); + + VTKM_TEST_ASSERT(TestArrayHandle(scalars, expectedScalars, fieldSize), "Got incorrect scalars"); + + VTKM_TEST_ASSERT( + TestArrayHandle(cellvar, expectedCellvar.data(), static_cast(expectedCellvar.size())), + "Got incorrect cellvar"); +} + +void TestClippingStructured() +{ + using CoordsValueType = vtkm::cont::ArrayHandleUniformPointCoordinates::ValueType; + using CoordsOutType = vtkm::cont::ArrayHandle; + + vtkm::cont::DataSet ds = MakeTestDatasetStructured(); + + bool invertClip = false; + vtkm::worklet::Clip clip; + vtkm::cont::CellSetExplicit<> outputCellSet = + clip.Run(ds.GetCellSet(0), + ds.GetField("scalars").GetData().ResetTypes(vtkm::TypeListTagFieldScalar()), + clipValue, + invertClip); + + auto coordsIn = ds.GetCoordinateSystem("coords").GetData(); + CoordsOutType coords = clip.ProcessPointField(coordsIn); + + vtkm::cont::ArrayHandle scalarsIn; + ds.GetField("scalars").GetData().CopyTo(scalarsIn); + vtkm::cont::ArrayHandle scalars = clip.ProcessPointField(scalarsIn); + + vtkm::cont::ArrayHandle cellvarIn; + ds.GetField("cellvar").GetData().CopyTo(cellvarIn); + vtkm::cont::ArrayHandle cellvar = clip.ProcessCellField(cellvarIn); + + + vtkm::Id connectivitySize = 28; + vtkm::Id fieldSize = 13; + const vtkm::Id expectedConnectivity[] = { 9, 10, 3, 1, 1, 3, 0, 11, 9, 1, 5, 5, 1, 2, + 10, 12, 7, 3, 3, 7, 6, 12, 11, 5, 7, 7, 5, 8 }; + + const Coord3D expectedCoords[] = { + Coord3D(0.0f, 0.0f, 0.0f), Coord3D(1.0f, 0.0f, 0.0f), Coord3D(2.0f, 0.0f, 0.0f), + Coord3D(0.0f, 1.0f, 0.0f), Coord3D(1.0f, 1.0f, 0.0f), Coord3D(2.0f, 1.0f, 0.0f), + Coord3D(0.0f, 2.0f, 0.0f), Coord3D(1.0f, 2.0f, 0.0f), Coord3D(2.0f, 2.0f, 0.0f), + Coord3D(1.0f, 0.5f, 0.0f), Coord3D(0.5f, 1.0f, 0.0f), Coord3D(1.5f, 1.0f, 0.0f), + Coord3D(1.0f, 1.5f, 0.0f), + }; + const vtkm::Float32 expectedScalars[] = { 1, 1, 1, 1, 0, 1, 1, 1, 1, 0.5, 0.5, 0.5, 0.5 }; + std::vector expectedCellvar = { -100.f, -100.f, 100.f, 100.f, + 30.f, 30.f, -30.f, -30.f }; + + VTKM_TEST_ASSERT(outputCellSet.GetNumberOfPoints() == fieldSize, + "Wrong number of points in cell set."); + + VTKM_TEST_ASSERT( + TestArrayHandle(outputCellSet.GetConnectivityArray(vtkm::TopologyElementTagPoint(), + vtkm::TopologyElementTagCell()), + expectedConnectivity, + connectivitySize), + "Got incorrect conectivity"); + + VTKM_TEST_ASSERT(TestArrayHandle(coords, expectedCoords, fieldSize), "Got incorrect coordinates"); + + VTKM_TEST_ASSERT(TestArrayHandle(scalars, expectedScalars, fieldSize), "Got incorrect scalars"); + + VTKM_TEST_ASSERT( + TestArrayHandle(cellvar, expectedCellvar.data(), static_cast(expectedCellvar.size())), + "Got incorrect cellvar"); +} + +void TestClippingWithImplicitFunction() +{ + vtkm::Vec center(1, 1, 0); + vtkm::FloatDefault radius(0.5); + + vtkm::cont::DataSet ds = MakeTestDatasetStructured(); + + bool invertClip = false; + vtkm::worklet::Clip clip; + vtkm::cont::CellSetExplicit<> outputCellSet = + clip.Run(ds.GetCellSet(0), + vtkm::cont::make_ImplicitFunctionHandle(center, radius), + ds.GetCoordinateSystem("coords"), + invertClip); + + auto coordsIn = ds.GetCoordinateSystem("coords").GetData(); + vtkm::cont::ArrayHandle coords = clip.ProcessPointField(coordsIn); + + vtkm::cont::ArrayHandle scalarsIn; + ds.GetField("scalars").GetData().CopyTo(scalarsIn); + vtkm::cont::ArrayHandle scalars = clip.ProcessPointField(scalarsIn); + + vtkm::cont::ArrayHandle cellvarIn; + ds.GetField("cellvar").GetData().CopyTo(cellvarIn); + vtkm::cont::ArrayHandle cellvar = clip.ProcessCellField(cellvarIn); + + vtkm::Id connectivitySize = 28; + vtkm::Id fieldSize = 13; + + const vtkm::Id expectedConnectivity[] = { 9, 10, 3, 1, 1, 3, 0, 11, 9, 1, 5, 5, 1, 2, + 10, 12, 7, 3, 3, 7, 6, 12, 11, 5, 7, 7, 5, 8 }; + + const Coord3D expectedCoords[] = { + Coord3D(0.0f, 0.0f, 0.0f), Coord3D(1.0f, 0.0f, 0.0f), Coord3D(2.0f, 0.0f, 0.0f), + Coord3D(0.0f, 1.0f, 0.0f), Coord3D(1.0f, 1.0f, 0.0f), Coord3D(2.0f, 1.0f, 0.0f), + Coord3D(0.0f, 2.0f, 0.0f), Coord3D(1.0f, 2.0f, 0.0f), Coord3D(2.0f, 2.0f, 0.0f), + Coord3D(1.0f, 0.75f, 0.0f), Coord3D(0.75f, 1.0f, 0.0f), Coord3D(1.25f, 1.0f, 0.0f), + Coord3D(1.0f, 1.25f, 0.0f), + }; + const vtkm::Float32 expectedScalars[] = { 1, 1, 1, 1, 0, 1, 1, 1, 1, 0.25, 0.25, 0.25, 0.25 }; + std::vector expectedCellvar = { -100.f, -100.f, 100.f, 100.f, + 30.f, 30.f, -30.f, -30.f }; + + VTKM_TEST_ASSERT( + TestArrayHandle(outputCellSet.GetConnectivityArray(vtkm::TopologyElementTagPoint(), + vtkm::TopologyElementTagCell()), + expectedConnectivity, + connectivitySize), + "Got incorrect conectivity"); + + VTKM_TEST_ASSERT(TestArrayHandle(coords, expectedCoords, fieldSize), "Got incorrect coordinates"); + + VTKM_TEST_ASSERT(TestArrayHandle(scalars, expectedScalars, fieldSize), "Got incorrect scalars"); + + VTKM_TEST_ASSERT( + TestArrayHandle(cellvar, expectedCellvar.data(), static_cast(expectedCellvar.size())), + "Got incorrect cellvar"); +} + +void TestClippingWithImplicitFunctionInverted() +{ + vtkm::Vec center(1, 1, 0); + vtkm::FloatDefault radius(0.5); + + vtkm::cont::DataSet ds = MakeTestDatasetStructured(); + + bool invertClip = true; + vtkm::worklet::Clip clip; + vtkm::cont::CellSetExplicit<> outputCellSet = + clip.Run(ds.GetCellSet(0), + vtkm::cont::make_ImplicitFunctionHandle(center, radius), + ds.GetCoordinateSystem("coords"), + invertClip); + + auto coordsIn = ds.GetCoordinateSystem("coords").GetData(); + vtkm::cont::ArrayHandle coords = clip.ProcessPointField(coordsIn); + + vtkm::cont::ArrayHandle scalarsIn; + ds.GetField("scalars").GetData().CopyTo(scalarsIn); + vtkm::cont::ArrayHandle scalars = clip.ProcessPointField(scalarsIn); + + vtkm::cont::ArrayHandle cellvarIn; + ds.GetField("cellvar").GetData().CopyTo(cellvarIn); + vtkm::cont::ArrayHandle cellvar = clip.ProcessCellField(cellvarIn); + + vtkm::Id connectivitySize = 12; + vtkm::Id fieldSize = 13; + vtkm::Id expectedConnectivity[] = { 10, 9, 4, 9, 11, 4, 12, 10, 4, 11, 12, 4 }; + const Coord3D expectedCoords[] = { + Coord3D(0.0f, 0.0f, 0.0f), Coord3D(1.0f, 0.0f, 0.0f), Coord3D(2.0f, 0.0f, 0.0f), + Coord3D(0.0f, 1.0f, 0.0f), Coord3D(1.0f, 1.0f, 0.0f), Coord3D(2.0f, 1.0f, 0.0f), + Coord3D(0.0f, 2.0f, 0.0f), Coord3D(1.0f, 2.0f, 0.0f), Coord3D(2.0f, 2.0f, 0.0f), + Coord3D(1.0f, 0.75f, 0.0f), Coord3D(0.75f, 1.0f, 0.0f), Coord3D(1.25f, 1.0f, 0.0f), + Coord3D(1.0f, 1.25f, 0.0f), + }; + vtkm::Float32 expectedScalars[] = { 1, 1, 1, 1, 0, 1, 1, 1, 1, 0.25, 0.25, 0.25, 0.25 }; + std::vector expectedCellvar = { -100.f, 100.f, 30.f, -30.f }; + + VTKM_TEST_ASSERT( + TestArrayHandle(outputCellSet.GetConnectivityArray(vtkm::TopologyElementTagPoint(), + vtkm::TopologyElementTagCell()), + expectedConnectivity, + connectivitySize), + "Got incorrect conectivity"); + + VTKM_TEST_ASSERT(TestArrayHandle(coords, expectedCoords, fieldSize), "Got incorrect coordinates"); + + VTKM_TEST_ASSERT(TestArrayHandle(scalars, expectedScalars, fieldSize), "Got incorrect scalars"); + + VTKM_TEST_ASSERT( + TestArrayHandle(cellvar, expectedCellvar.data(), static_cast(expectedCellvar.size())), + "Got incorrect cellvar"); +} + +void TestClippingWithFunction() +{ + std::cout << "Testing clipping with implicit function (sphere):" << std::endl; + TestClippingWithImplicitFunction(); + TestClippingWithImplicitFunctionInverted(); +} + +int UnitTestClippingWithFunction(int argc, char* argv[]) +{ + return vtkm::cont::testing::Testing::Run(TestClippingWithFunction, argc, argv); +}