From a40f5e30fb5a98bf0443884c0a618cf290bd672c Mon Sep 17 00:00:00 2001
From: Lorenzo Moneta <moneta@olhswep08.cern.ch>
Date: Sun, 6 Aug 2017 16:48:40 +0200
Subject: [PATCH] Fix a big in the IntegralEvaluator class used for computing
 the bin integral when fitting in case of Veccore types and multi-dimensional
 functions. Fix also the padding in BinData when the number of points is a
 multiple of the vector size.

---
 math/mathcore/inc/Fit/FitUtil.h | 26 +++++++++++++++++++++-----
 math/mathcore/src/BinData.cxx   |  4 +++-
 2 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/math/mathcore/inc/Fit/FitUtil.h b/math/mathcore/inc/Fit/FitUtil.h
index 68d49efb73b..6cac32dfcd5 100644
--- a/math/mathcore/inc/Fit/FitUtil.h
+++ b/math/mathcore/inc/Fit/FitUtil.h
@@ -222,11 +222,21 @@ namespace FitUtil {
 
 #ifdef R__HAS_VECCORE
             inline double ExecFunc(const IModelFunctionTempl<ROOT::Double_v> *f, const double *x, const double *p) const{
-                ROOT::Double_v xx;
-                vecCore::Load<ROOT::Double_v>(xx, x);
-                const double *p0 = p;
-                auto res =  (*f)( &xx, (const double *)p0);
-                return vecCore::Get<ROOT::Double_v>(res, 0);
+               if (fDim == 1) { 
+                  ROOT::Double_v xx;
+                  vecCore::Load<ROOT::Double_v>(xx, x);
+                  const double *p0 = p;
+                  auto res =  (*f)( &xx, (const double *)p0);
+                  return vecCore::Get<ROOT::Double_v>(res, 0);
+               }
+               else { 
+                  std::vector<ROOT::Double_v> xx(fDim); 
+                  for (unsigned int i = 0; i  < fDim; ++i) { 
+                     vecCore::Load<ROOT::Double_v>(xx[i], x+i);
+                  }
+                  auto res =  (*f)( xx.data(), p);
+                  return vecCore::Get<ROOT::Double_v>(res, 0);
+               }
             }
 #endif
 
@@ -348,6 +358,8 @@ namespace FitUtil {
          // normal chi2 using only error on values (from fitting histogram)
          // optionally the integral of function in the bin is used
 
+         //Info("EvalChi2","Using vecorized implementation %d",(int) data.Opt().fIntegral);
+
          unsigned int n = data.Size();
 
          nPoints = 0; // count the effective non-zero points
@@ -817,6 +829,10 @@ static void EvalPoissonLogLGradient(const IModelFunctionTempl<T> &, const BinDat
          // the actual number of used points
          // normal chi2 using only error on values (from fitting histogram)
          // optionally the integral of function in the bin is used
+
+
+         //Info("EvalChi2","Using non-vecorized implementation %d",(int) data.Opt().fIntegral);
+
          return FitUtil::EvaluateChi2(func, data, p, nPoints, executionPolicy, nChunks);
       }
 
diff --git a/math/mathcore/src/BinData.cxx b/math/mathcore/src/BinData.cxx
index 9df9d76f01b..554e0d991b2 100644
--- a/math/mathcore/src/BinData.cxx
+++ b/math/mathcore/src/BinData.cxx
@@ -629,7 +629,9 @@ namespace ROOT {
     {
 #ifdef R__HAS_VECCORE
        // Add padding to be a multiple of SIMD vector size and help looping
-       auto extraP = vecCore::VectorSize<ROOT::Double_v>() - ((fMaxPoints) % vecCore::VectorSize<ROOT::Double_v>());
+       auto extraP = 0; 
+       unsigned int modP = (fMaxPoints) % vecCore::VectorSize<ROOT::Double_v>();
+       if (modP > 0) extraP = vecCore::VectorSize<ROOT::Double_v>() - modP; 
        fData.resize(fMaxPoints + extraP);
 #else
        fData.resize(fMaxPoints);
-- 
GitLab