//============================================================================ // 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_ComputeNDHistogram_h #define vtk_m_worklet_ComputeNDHistogram_h #include #include #include namespace vtkm { namespace worklet { namespace histogram { // GCC creates false positive warnings for signed/unsigned char* operations. // This occurs because the values are implicitly casted up to int's for the // operation, and than casted back down to char's when return. // This causes a false positive warning, even when the values is within // the value types range #if defined(VTKM_GCC) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wconversion" #endif // gcc template T compute_delta(T fieldMinValue, T fieldMaxValue, vtkm::Id num) { using VecType = vtkm::VecTraits; const T fieldRange = fieldMaxValue - fieldMinValue; return fieldRange / static_cast(num); } #if defined(VTKM_GCC) #pragma GCC diagnostic pop #endif // gcc // For each value set the bin it should be in template class SetHistogramBin : public vtkm::worklet::WorkletMapField { public: using ControlSignature = void(FieldIn value, FieldIn binIndexIn, FieldOut binIndexOut); using ExecutionSignature = void(_1, _2, _3); using InputDomain = _1; vtkm::Id numberOfBins; vtkm::Float64 minValue; vtkm::Float64 delta; VTKM_CONT SetHistogramBin(vtkm::Id numberOfBins0, vtkm::Float64 minValue0, vtkm::Float64 delta0) : numberOfBins(numberOfBins0) , minValue(minValue0) , delta(delta0) { } VTKM_EXEC void operator()(const FieldType& value, const vtkm::Id& binIndexIn, vtkm::Id& binIndexOut) const { const vtkm::Float64 fvalue = static_cast(value); vtkm::Id localBinIdx = static_cast((fvalue - minValue) / delta); if (localBinIdx < 0) localBinIdx = 0; else if (localBinIdx >= numberOfBins) localBinIdx = numberOfBins - 1; binIndexOut = binIndexIn * numberOfBins + localBinIdx; } }; class ComputeBins { public: VTKM_CONT ComputeBins(vtkm::cont::ArrayHandle& _bin1DIdx, vtkm::Id& _numOfBins, vtkm::Range& _minMax, vtkm::Float64& _binDelta) : Bin1DIdx(_bin1DIdx) , NumOfBins(_numOfBins) , MinMax(_minMax) , BinDelta(_binDelta) , RangeProvided(false) { } VTKM_CONT ComputeBins(vtkm::cont::ArrayHandle& _bin1DIdx, vtkm::Id& _numOfBins, vtkm::Range& _minMax, vtkm::Float64& _binDelta, bool _rangeProvided) : Bin1DIdx(_bin1DIdx) , NumOfBins(_numOfBins) , MinMax(_minMax) , BinDelta(_binDelta) , RangeProvided(_rangeProvided) { } template VTKM_CONT void operator()(const vtkm::cont::ArrayHandle& field) const { if (!RangeProvided) { const vtkm::Vec initValue(vtkm::cont::ArrayGetValue(0, field)); vtkm::Vec minMax = vtkm::cont::Algorithm::Reduce(field, initValue, vtkm::MinAndMax()); MinMax.Min = static_cast(minMax[0]); MinMax.Max = static_cast(minMax[1]); } BinDelta = compute_delta(MinMax.Min, MinMax.Max, NumOfBins); SetHistogramBin binWorklet(NumOfBins, MinMax.Min, BinDelta); vtkm::worklet::DispatcherMapField> setHistogramBinDispatcher(binWorklet); setHistogramBinDispatcher.Invoke(field, Bin1DIdx, Bin1DIdx); } private: vtkm::cont::ArrayHandle& Bin1DIdx; vtkm::Id& NumOfBins; vtkm::Range& MinMax; vtkm::Float64& BinDelta; bool RangeProvided; }; // Convert N-dims bin index into 1D index class ConvertHistBinToND : public vtkm::worklet::WorkletMapField { public: using ControlSignature = void(FieldIn bin1DIndexIn, FieldOut bin1DIndexOut, FieldOut oneVariableIndexOut); using ExecutionSignature = void(_1, _2, _3); using InputDomain = _1; vtkm::Id numberOfBins; VTKM_CONT ConvertHistBinToND(vtkm::Id numberOfBins0) : numberOfBins(numberOfBins0) { } VTKM_EXEC void operator()(const vtkm::Id& bin1DIndexIn, vtkm::Id& bin1DIndexOut, vtkm::Id& oneVariableIndexOut) const { oneVariableIndexOut = bin1DIndexIn % numberOfBins; bin1DIndexOut = (bin1DIndexIn - oneVariableIndexOut) / numberOfBins; } }; } } } // namespace vtkm::worklet #endif // vtk_m_worklet_ComputeNDHistogram_h