From 2ca18a206ffb95763ef7073f50678be9cef6c987 Mon Sep 17 00:00:00 2001 From: christos <christos@cern.ch> Date: Thu, 24 Sep 2020 22:20:28 +0100 Subject: [PATCH] Since we know the maximum size of the problem we can create the Triangular array index mapping once --- .../KLGaussianMixtureReduction.h | 8 +++- .../src/KLGaussianMixtureReduction.cxx | 42 +++++++++++++------ 2 files changed, 36 insertions(+), 14 deletions(-) diff --git a/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/KLGaussianMixtureReduction.h b/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/KLGaussianMixtureReduction.h index 4719b503c6f6..2de1daca8f86 100644 --- a/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/KLGaussianMixtureReduction.h +++ b/Tracking/TrkFitter/TrkGaussianSumFilter/TrkGaussianSumFilter/KLGaussianMixtureReduction.h @@ -101,9 +101,13 @@ struct Component1D * @brief Merge the componentsIn and return * which componets got merged * - * The input component array is assumed to be - * GSFUtils::alignment aligned. + * inputSize is expected to be >0, <128 + * and reducedSize < inputsize. Invalid input + * will cause a runtime exception * + * Furthemore, the input component array is assumed to be + * GSFUtils::alignment aligned. + * Can be created via the AlignedDynArray. */ std::vector<std::pair<int16_t, int16_t>> findMerges(Component1D* componentsIn, diff --git a/Tracking/TrkFitter/TrkGaussianSumFilter/src/KLGaussianMixtureReduction.cxx b/Tracking/TrkFitter/TrkGaussianSumFilter/src/KLGaussianMixtureReduction.cxx index 414d2b888926..f45a8b0cb81e 100644 --- a/Tracking/TrkFitter/TrkGaussianSumFilter/src/KLGaussianMixtureReduction.cxx +++ b/Tracking/TrkFitter/TrkGaussianSumFilter/src/KLGaussianMixtureReduction.cxx @@ -7,6 +7,7 @@ #include "CxxUtils/vec.h" #include "TrkGaussianSumFilter/AlignedDynArray.h" #include <limits> +#include <stdexcept> #if !defined(__GNUC__) #define __builtin_assume_aligned(X, N) X @@ -39,6 +40,26 @@ struct triangularToIJ int16_t J = -1; }; +std::vector<triangularToIJ> +createToIJ128() +{ + // Create a trangular array mapping for the maximum size + // we will ever have 8 (max bethe heitle material) x16 (state components) + // =128. 128 * (128-1)/2 = 8128 + // + // The typical number we use is 6x12 = 72. + // + constexpr int16_t n = 128; + constexpr int32_t nn = n * (n - 1) / 2; + std::vector<triangularToIJ> indexMap(nn); + for (int16_t i = 1; i < n; ++i) { + const int32_t indexConst = (i - 1) * i / 2; + for (int16_t j = 0; j < i; ++j) { + indexMap[indexConst + j] = { i, j }; + } + } + return indexMap; +} /** * Based on * https://www.sciencedirect.com/science/article/pii/089812218990103X @@ -187,7 +208,7 @@ resetDistances(float* distancesIn, const int32_t minj, const int32_t n) } } -} +} // anonymous namespace namespace GSFUtils { /** @@ -201,21 +222,18 @@ findMerges(Component1D* componentsIn, { Component1D* components = static_cast<Component1D*>( __builtin_assume_aligned(componentsIn, alignment)); + + // Sanity check. Function throw on invalid inputs + if (inputSize < 0 || inputSize > 128 || reducedSize > inputSize) { + throw std::runtime_error("Invalid InputSize or reducedSize"); + } + // We need just one for the full duration of a job + const static std::vector<triangularToIJ> convert = createToIJ128(); + // Based on the inputSize allocate enough space for the pairwise distances const int16_t n = inputSize; const int32_t nn = n * (n - 1) / 2; - // Create a trianular mapping for the pairwise distances - // We now that the size is nn - std::vector<triangularToIJ> convert(nn); - for (int16_t i = 1; i < n; ++i) { - const int32_t indexConst = (i - 1) * i / 2; - for (int16_t j = 0; j < i; ++j) { - convert[indexConst + j] = { i, j }; - } - } // We work with a multiple of 8*floats (32 bytes). - // Ensures also that the size parameter passed to aligned alloc - // is an integral multiple of alignment (32 bytes). const int32_t nn2 = (nn & 7) == 0 ? nn : nn + (8 - (nn & 7)); AlignedDynArray<float, alignment> distances( nn2, std::numeric_limits<float>::max()); -- GitLab