Skip to content

Commit

Permalink
Various bug fixes test repairs in progress [broken]
Browse files Browse the repository at this point in the history
  • Loading branch information
nyoungbq committed Sep 18, 2024
1 parent 4e1bb40 commit d9c1888
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class ComputeArrayStatisticsByIndexImpl
int32 numBins, bool modalBinRanges, const std::unique_ptr<MaskCompare>& mask, const Int32Array* featureIds, const DataArray<T>& source,
BoolArray* featureHasDataArray, UInt64Array* lengthArray, DataArray<T>* minArray, DataArray<T>* maxArray, Float32Array* meanArray, NeighborList<T>* modeArray,
Float32Array* stdDevArray, Float32Array* summationArray, UInt64Array* histBinCountsArray, DataArray<T>* histBinRangesArray, UInt64Array* mostPopulatedBinArray,
NeighborList<float32>* modalBinRangesArray, ComputeArrayStatistics* filter)
NeighborList<T>* modalBinRangesArray, ComputeArrayStatistics* filter)
: m_Length(length)
, m_Min(min)
, m_Max(max)
Expand Down Expand Up @@ -240,18 +240,18 @@ class ComputeArrayStatisticsByIndexImpl
std::vector<uint64> histogram(m_NumBins, 0);
if(length[localFeatureIndex] > 0)
{
float32 histMin = m_HistMin;
float32 histMax = m_HistMax;
T histMin = static_cast<T>(m_HistMin);
T histMax = static_cast<T>(m_HistMax);

if(m_HistFullRange)
{
histMin = static_cast<float32>(min[localFeatureIndex]);
histMax = static_cast<float32>(max[localFeatureIndex]);
histMin = min[localFeatureIndex];
histMax = max[localFeatureIndex];
}

HistogramUtilities::serial::FillBinRanges(ranges, std::make_pair(static_cast<T>(histMin), static_cast<T>(histMax)), m_NumBins);
HistogramUtilities::serial::FillBinRanges(ranges, std::make_pair(histMin, histMax), m_NumBins);

const float32 increment = (histMax - histMin) / (m_NumBins);
const T increment = (histMax - histMin) / (m_NumBins);
if(std::fabs(increment) < 1E-10)
{
histogram[0] = length[localFeatureIndex];
Expand All @@ -272,7 +272,7 @@ class ComputeArrayStatisticsByIndexImpl
{
continue;
}
const auto value = static_cast<float32>(m_Source[i]);
const T value = m_Source[i];
const auto bin = static_cast<int32>(HistogramUtilities::serial::CalculateBin(value, histMin, increment)); // find bin for this input array value
if((bin >= 0) && (bin < m_NumBins)) // make certain bin is in range
{
Expand All @@ -287,29 +287,46 @@ class ComputeArrayStatisticsByIndexImpl

if(m_ModalBinRanges)
{
if(std::fabs(increment) < 1E-10)
bool skip = false;
if constexpr(std::is_floating_point_v<T>)
{
m_ModalBinRangesArray->addEntry(j, histMin);
m_ModalBinRangesArray->addEntry(j, histMax);
if(m_HistFullRange && std::fabs(increment) < 1E-10)
{
m_ModalBinRangesArray->addEntry(j, histMin);
m_ModalBinRangesArray->addEntry(j, histMax);

skip = true;
}
}
else
{
if(m_HistFullRange && increment == 0)
{
m_ModalBinRangesArray->addEntry(j, histMin);
m_ModalBinRangesArray->addEntry(j, histMax);

skip = true;
}
}

if(!skip)
{
auto modeList = m_ModeArray->getList(j);
for(int i = 0; i < modeList->size(); i++)
{
const float32 mode = modeList->at(i);
const auto modalBin = static_cast<int32>(HistogramUtilities::serial::CalculateBin(mode, histMin, increment));
float32 minBinValue = 0.0f;
float32 maxBinValue = 0.0f;
const T mode = modeList->at(i);
const auto modalBin = HistogramUtilities::serial::CalculateBin(mode, histMin, increment);
T minBinValue;
T maxBinValue;
if((modalBin >= 0) && (modalBin < m_NumBins)) // make certain bin is in range
{
minBinValue = static_cast<float32>(histMin + (modalBin * increment));
maxBinValue = static_cast<float32>(histMin + ((modalBin + 1) * increment));
minBinValue = static_cast<T>(histMin + (modalBin * increment));
maxBinValue = static_cast<T>(histMin + ((modalBin + 1) * increment));
}
else if(mode == histMax)
{
minBinValue = static_cast<float32>(histMin + ((modalBin - 1) * increment));
maxBinValue = static_cast<float32>(histMin + (modalBin * increment));
minBinValue = static_cast<T>(histMin + ((modalBin - 1) * increment));
maxBinValue = static_cast<T>(histMin + (modalBin * increment));
}
m_ModalBinRangesArray->addEntry(j, minBinValue);
m_ModalBinRangesArray->addEntry(j, maxBinValue);
Expand Down Expand Up @@ -419,7 +436,7 @@ class ComputeArrayStatisticsByIndexImpl
UInt64Array* m_HistBinCountsArray = nullptr;
DataArray<T>* m_HistBinRangesArray = nullptr;
UInt64Array* m_MostPopulatedBinArray = nullptr;
NeighborList<float32>* m_ModalBinRangesArray = nullptr;
NeighborList<T>* m_ModalBinRangesArray = nullptr;
ComputeArrayStatistics* m_Filter = nullptr;
};

Expand Down Expand Up @@ -701,7 +718,7 @@ void FindStatistics(const DataArray<T>& source, const Int32Array* featureIds, co
auto* summationArrayPtr = dynamic_cast<Float32Array*>(arrays[7]);
auto* histBinCountsArrayPtr = dynamic_cast<UInt64Array*>(arrays[8]);
auto* mostPopulatedBinPtr = dynamic_cast<UInt64Array*>(arrays[10]);
auto* modalBinsArrayPtr = dynamic_cast<NeighborList<float32>*>(arrays[11]);
auto* modalBinsArrayPtr = dynamic_cast<NeighborList<T>*>(arrays[11]);
auto* histBinRangesArrayPtr = dynamic_cast<DataArray<T>*>(arrays[12]);
auto* featureHasDataPtr = dynamic_cast<BoolArray*>(arrays[13]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ OutputActions CreateCompatibleArrays(const DataStructure& dataStructure, const A
if(findModalBinRanges)
{
auto arrayPath = args.value<std::string>(ComputeArrayStatisticsFilter::k_ModalBinArrayName_Key);
auto action = std::make_unique<CreateNeighborListAction>(DataType::float32, tupleSize, destinationAttributeMatrixValue.createChildPath(arrayPath));
auto action = std::make_unique<CreateNeighborListAction>(dataType, tupleSize, destinationAttributeMatrixValue.createChildPath(arrayPath));
actions.appendAction(std::move(action));
}
}
Expand Down
83 changes: 83 additions & 0 deletions src/simplnx/Utilities/HistogramUtilities.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,89 @@ Result<> GenerateHistogram(const InputContainer<Type>& inputStore, OutputContain
return {};
}

/**
* @function GenerateHistogram
* @brief [Runs over specific component] This function creates a uniform histogram (logarithmic possible, but not currently implemented) it fills two arrays,
* one with the ranges for each bin and one for bin counts
* See FillBinRanges function for details on the high level structuring of the bin ranges array
* @tparam Type this the end type of the function in that it is the scalar type of the input and by extension range data
* @tparam SizeType this is the scalar type of the bin counts container
* * @tparam OutputContainer this is the type of object the values are stored/written to:
* !!! In current implementation it is expected that this class is either AbstractDataStore or std::vector !!!
* @param inputStore this is the container holding the data that will be binned
* @param binRangesStore this is the object that the ranges will be loaded into.
* @param rangeMinMax this is assumed to be the inclusive minimum value and exclusive maximum value for the overall histogram bins. FORMAT: [minimum, maximum)
* @param shouldCancel this is an atomic value that will determine whether execution ends early; `true` cancels algorithm
* @param numBins this is the total number of bin ranges being calculated and by extension the indexing value for the ranges
* @param histogramCountsStore this is the container that will hold the counts for each bin (variable type sizing)
* @param overflow this is an atomic counter for the number of values that fall outside the bin range
*/
template <typename Type, std::integral SizeType, template <typename> class OutputContainer>
Result<> GenerateHistogramAtComponent(const AbstractDataStore<Type>& inputStore, OutputContainer<Type>& binRangesStore, const std::pair<Type, Type>& rangeMinMax, const std::atomic_bool& shouldCancel,
const int32 numBins, OutputContainer<SizeType>& histogramCountsStore, std::atomic<usize>& overflow, usize componentIndex)
{
usize numComp = inputStore.getNumberOfComponents();
if(componentIndex > numComp)
{
return MakeErrorResult(-23765, fmt::format("HistogramUtilities::{}: supplied component index is larger than component size of input array. Needed: x < {} | Currently: {}. {}:{}", __func__,
numComp, componentIndex, __FILE__, __LINE__));
}

if constexpr(std::is_same_v<std::vector<Type>, OutputContainer<Type>>)
{
// just resize outputs to ensure no wasted space and won't be out of bounds
binRangesStore.resize(numBins + 1);
histogramCountsStore.resize(numBins);
}
if constexpr(std::is_same_v<AbstractDataStore<Type>, OutputContainer<Type>>)
{
if(binRangesStore.getSize() < numBins + 1)
{
return MakeErrorResult(-23761, fmt::format("HistogramUtilities::{}: binRangesStore is too small to hold ranges. Needed: {} | Current Size: {}. {}:{}", __func__, numBins + 1,
binRangesStore.getSize(), __FILE__, __LINE__));
}
if(histogramCountsStore.getSize() < numBins)
{
return MakeErrorResult(-23762, fmt::format("HistogramUtilities::{}: histogramCountsStore is too small to hold counts. Needed: {} | Current Size: {}. {}:{}", __func__, numBins,
histogramCountsStore.getSize(), __FILE__, __LINE__));
}
}

const Type increment = (rangeMinMax.second - rangeMinMax.first) / static_cast<Type>(numBins);

// Fill Bins
FillBinRanges(binRangesStore, rangeMinMax, numBins, increment);

if(shouldCancel)
{
return MakeErrorResult(-23762, fmt::format("HistogramUtilities::{}: Signal Interrupt Received. {}:{}", __func__, __FILE__, __LINE__));
}

for(usize i = 0; i < inputStore.getNumberOfTuples(); i++)
{
if(shouldCancel)
{
return MakeErrorResult(-23763, fmt::format("HistogramUtilities::{}: Signal Interrupt Received. {}:{}", __func__, __FILE__, __LINE__));
}
const auto bin = CalculateBin(inputStore[i * numComp + componentIndex], rangeMinMax.first, increment);
if((bin >= 0) && (bin < numBins))
{
histogramCountsStore[bin]++;
}
else
{
overflow++;
}
}

if(overflow > 0)
{
return MakeWarningVoidResult(-23762, fmt::format("HistogramUtilities::{}: Overflow detected: overflow count {}. {}:{}", __func__, overflow.load(), __FILE__, __LINE__));
}

return {};
}

/**
* @class GenerateHistogramFunctor
* @brief This is a compatibility functor that leverages existing typecasting functions to execute GenerateHistogram() cleanly. In it there are two
Expand Down

0 comments on commit d9c1888

Please sign in to comment.