diff --git a/vtkm/worklet/Mask.h b/vtkm/worklet/Mask.h new file mode 100644 index 000000000..6fdd7e26e --- /dev/null +++ b/vtkm/worklet/Mask.h @@ -0,0 +1,103 @@ +//============================================================================ +// 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. +// +// Copyright 2015 Sandia Corporation. +// Copyright 2015 UT-Battelle, LLC. +// Copyright 2015 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National +// Laboratory (LANL), the U.S. Government retains certain rights in +// this software. +//============================================================================ +#ifndef vtkm_m_worklet_Mask_h +#define vtkm_m_worklet_Mask_h + +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace vtkm { +namespace worklet { + +// Subselect points using stride for now, creating new cellset of vertices +class Mask +{ +public: + struct BoolType : vtkm::ListTagBase {}; + + template + vtkm::cont::CellSetPermutation Run( + const CellSetType &cellSet, + const vtkm::Id stride, + DeviceAdapter device) + { + typedef typename vtkm::cont::DeviceAdapterAlgorithm DeviceAlgorithm; + typedef vtkm::cont::CellSetPermutation OutputType; + + vtkm::Id numberOfInputCells = cellSet.GetNumberOfCells(); + vtkm::Id numberOfSampledCells = numberOfInputCells / stride; + vtkm::cont::ArrayHandleCounting strideArray(0, stride, numberOfSampledCells); + + DeviceAlgorithm::Copy(strideArray, this->ValidCellIds); + + return OutputType(this->ValidCellIds, cellSet, cellSet.GetName()); + } + + // Permute cell data to match permuted cells + class PermuteCellData + { + public: + PermuteCellData(const vtkm::cont::ArrayHandle validCellIds, + vtkm::cont::DynamicArrayHandle &data) + : ValidCellIds(validCellIds), Data(&data) + { } + + template + void operator()(const ArrayHandleType &input) const + { + *(this->Data) = vtkm::cont::DynamicArrayHandle( + vtkm::cont::make_ArrayHandlePermutation(this->ValidCellIds, input)); + } + + private: + vtkm::cont::ArrayHandle ValidCellIds; + vtkm::cont::DynamicArrayHandle *Data; + }; + + vtkm::cont::Field ProcessCellField(const vtkm::cont::Field field) const + { + if (field.GetAssociation() != vtkm::cont::Field::ASSOC_CELL_SET) + { + throw vtkm::cont::ErrorBadValue("Expecting cell field."); + } + + vtkm::cont::DynamicArrayHandle data; + CastAndCall(field, PermuteCellData(this->ValidCellIds, data)); + + return vtkm::cont::Field(field.GetName(), field.GetAssociation(), + field.GetAssocCellSet(), data); + } + +private: + vtkm::cont::ArrayHandle ValidCellIds; +}; + +} +} // namespace vtkm::worklet + +#endif // vtkm_m_worklet_Mask_h diff --git a/vtkm/worklet/testing/UnitTestMask.cxx b/vtkm/worklet/testing/UnitTestMask.cxx new file mode 100644 index 000000000..718ebd5f9 --- /dev/null +++ b/vtkm/worklet/testing/UnitTestMask.cxx @@ -0,0 +1,155 @@ +//============================================================================ +// 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. +// +// Copyright 2014 Sandia Corporation. +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National +// Laboratory (LANL), the U.S. Government retains certain rights in +// this software. +//============================================================================ + +#include + +#include +#include + +#include +#include + +#include +#include +#include + +using vtkm::cont::testing::MakeTestDataSet; + +template +class TestingMask +{ +public: + + ///////////////////////////////////////////////////////////////////////////////////////////////// + void TestUniform2D() const + { + std::cout << "Testing mask cells structured:" << std::endl; + + typedef vtkm::cont::CellSetStructured<2> CellSetType; + typedef vtkm::cont::CellSetPermutation OutCellSetType; + typedef vtkm::cont::ArrayHandlePermutation< + vtkm::cont::ArrayHandle, + vtkm::cont::ArrayHandle > OutCellFieldArrayHandleType; + + // Input data set created + vtkm::cont::DataSet dataset = MakeTestDataSet().Make2DUniformDataSet1(); + CellSetType cellSet; + dataset.GetCellSet(0).CopyTo(cellSet); + + // Output data set permutation + vtkm::worklet::Mask maskCells; + OutCellSetType outCellSet = + maskCells.Run(cellSet, + 2, + DeviceAdapter()); + + vtkm::cont::Field cellField = + maskCells.ProcessCellField(dataset.GetField("cellvar")); + OutCellFieldArrayHandleType cellFieldArray; + cellField.GetData().CopyTo(cellFieldArray); + + VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfCells(), 8), "Wrong result for Mask"); + VTKM_TEST_ASSERT(cellFieldArray.GetNumberOfValues() == 8 && + cellFieldArray.GetPortalConstControl().Get(7) == 14.f, + "Wrong cell field data"); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////// + void TestUniform3D() const + { + std::cout << "Testing mask cells structured:" << std::endl; + + typedef vtkm::cont::CellSetStructured<3> CellSetType; + typedef vtkm::cont::CellSetPermutation OutCellSetType; + typedef vtkm::cont::ArrayHandlePermutation< + vtkm::cont::ArrayHandle, + vtkm::cont::ArrayHandle > OutCellFieldArrayHandleType; + + // Input data set created + vtkm::cont::DataSet dataset = MakeTestDataSet().Make3DUniformDataSet1(); + CellSetType cellSet; + dataset.GetCellSet(0).CopyTo(cellSet); + + // Output data set with cell set permuted + vtkm::worklet::Mask maskCells; + OutCellSetType outCellSet = + maskCells.Run(cellSet, + 9, + DeviceAdapter()); + + vtkm::cont::Field cellField = + maskCells.ProcessCellField(dataset.GetField("cellvar")); + OutCellFieldArrayHandleType cellFieldArray; + cellField.GetData().CopyTo(cellFieldArray); + + VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfCells(), 7), "Wrong result for ExtractCells"); + VTKM_TEST_ASSERT(cellFieldArray.GetNumberOfValues() == 7 && + cellFieldArray.GetPortalConstControl().Get(2) == 18.f, + "Wrong cell field data"); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////// + void TestExplicit() const + { + std::cout << "Testing mask cells explicit:" << std::endl; + + typedef vtkm::cont::CellSetExplicit<> CellSetType; + typedef vtkm::cont::CellSetPermutation OutCellSetType; + typedef vtkm::cont::ArrayHandlePermutation< + vtkm::cont::ArrayHandle, + vtkm::cont::ArrayHandle > OutCellFieldArrayHandleType; + + // Input data set created + vtkm::cont::DataSet dataset = MakeTestDataSet().Make3DExplicitDataSet5(); + CellSetType cellSet; + dataset.GetCellSet(0).CopyTo(cellSet); + + // Output data set with cell set permuted + vtkm::worklet::Mask maskCells; + OutCellSetType outCellSet = + maskCells.Run(cellSet, + 2, + DeviceAdapter()); + + + vtkm::cont::Field cellField = + maskCells.ProcessCellField(dataset.GetField("cellvar")); + OutCellFieldArrayHandleType cellFieldArray; + cellField.GetData().CopyTo(cellFieldArray); + + VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfCells(), 2), "Wrong result for ExtractCells"); + VTKM_TEST_ASSERT(cellFieldArray.GetNumberOfValues() == 2 && + cellFieldArray.GetPortalConstControl().Get(1) == 120.2f, + "Wrong cell field data"); + } + + void operator()() const + { + this->TestUniform2D(); + this->TestUniform3D(); + this->TestExplicit(); + } +}; + +int UnitTestMask(int, char *[]) +{ + return vtkm::cont::testing::Testing::Run( + TestingMask()); +}