//============================================================================ // 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. //============================================================================ #ifndef vtk_m_worklet_connectivity_InnerJoin_h #define vtk_m_worklet_connectivity_InnerJoin_h #include #include #include #include namespace vtkm { namespace worklet { namespace connectivity { class InnerJoin { public: struct Merge : vtkm::worklet::WorkletMapField { using ControlSignature = void(FieldIn, FieldIn, FieldIn, WholeArrayIn, FieldOut, FieldOut, FieldOut); using ExecutionSignature = void(_1, _2, _3, VisitIndex, _4, _5, _6, _7); using InputDomain = _1; using ScatterType = vtkm::worklet::ScatterCounting; // TODO: type trait for array portal? template VTKM_EXEC void operator()(KeyType key, ValueType1 value1, vtkm::Id lowerBounds, vtkm::Id visitIndex, const InPortalType& value2, vtkm::Id& keyOut, ValueType1& value1Out, ValueType2& value2Out) const { auto v2 = value2.Get(lowerBounds + visitIndex); keyOut = key; value1Out = value1; value2Out = v2; } }; using Algorithm = vtkm::cont::Algorithm; // TODO: not mutating input keys and values? template void Run(vtkm::cont::ArrayHandle& key1, vtkm::cont::ArrayHandle& value1, vtkm::cont::ArrayHandle& key2, vtkm::cont::ArrayHandle& value2, vtkm::cont::ArrayHandle& keyOut, vtkm::cont::ArrayHandle& value1Out, vtkm::cont::ArrayHandle& value2Out) const { Algorithm::SortByKey(key1, value1); Algorithm::SortByKey(key2, value2); vtkm::cont::ArrayHandle lbs; vtkm::cont::ArrayHandle ubs; Algorithm::LowerBounds(key2, key1, lbs); Algorithm::UpperBounds(key2, key1, ubs); vtkm::cont::ArrayHandle counts; Algorithm::Transform(ubs, lbs, counts, vtkm::Subtract()); vtkm::worklet::ScatterCounting scatter{ counts }; vtkm::worklet::DispatcherMapField mergeDisp(scatter); mergeDisp.Invoke(key1, value1, lbs, value2, keyOut, value1Out, value2Out); } }; } } } // vtkm::worklet::connectivity #endif //vtk_m_worklet_connectivity_InnerJoin_h