Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RooFit::MultiProcess & TestStatistics part 1: mathcore & Minuit2 changes #8369

Merged
merged 12 commits into from
Jul 9, 2021

Conversation

egpbos
Copy link
Contributor

@egpbos egpbos commented Jun 8, 2021

This PR is the first part of a split and clean-up of #8294, as suggested by @guitargeek.

In this PR, only the changes to mathcore and Minuit2 are taken into account. These changes will be necessary for the later RooFit parts which will come in separate PRs.

Specifically, this PR introduces the ExternalInternalGradientCalculator in Minuit2. This subclass of AnalyticalGradientCalculator enables calculation of the derivative outside of Minuit2, but in "Minuit-internal" parameter space. This allows exact replication of the gradients as calculated in Minuit2 itself, which in turn enables external optimization and parallelization of this process without having to modify Minuit2, without having to worry about differences in outcome. In other words, the resulting external gradient calculation can be easily unit tested against the existing Minuit2 gradient calculation.

Note: still working on "cherry picking" all changes and organizing them into functionally sensible commits. Will un-draft the PR once this is done. Ready for review.

Used in Minuit2 ExternalInternalGradientCalculator (introduced in a later commit) and in RooFit (also later commits) to enable calculation of all derivative and related numbers outside of Minuit2. Specifically, having second derivative and step size calculated outside of Minuit2 allows exact replication of the gradients as calculated in Minuit2 itself, which in turn enables external optimization and parallelization of this process without having to modify Minuit2.
@phsft-bot
Copy link
Collaborator

Starting build on ROOT-debian10-i386/cxx14, ROOT-performance-centos8-multicore/default, ROOT-ubuntu16/nortcxxmod, mac1014/python3, mac11.0/cxx17, windows10/cxx14
How to customize builds

…daptors

Like the changes to IFunction in the previous commit, this is also necessary for Minuit2-external gradient calculation.
@phsft-bot
Copy link
Collaborator

Starting build on ROOT-debian10-i386/cxx14, ROOT-performance-centos8-multicore/default, ROOT-ubuntu16/nortcxxmod, mac1014/python3, mac11.0/cxx17, windows10/cxx14
How to customize builds

… and increase their precision

This commit changes two (functionally speaking strictly separate, but unified in their ultimate purpose) things. First, to further accomodate the added ability of external gradient calculators to pass in second derivative and step sizes, the internal to external parameter transformers in Minuit2 need to have added D2Int2Ext and GStepInt2Ext functions that perform these transformations for those added parts. Second, we increase the precision of the transformers to long double. This is necessary  to make sure that trigonometric transformations don't lose a few bits of precision on back-and-forth parameter transformations, which they do when using the double versions. Both changes are necessary for the external gradient calculation in Minuit2 which will be introduced in a next commit in ExternalInternalGradientCalculator.
@phsft-bot
Copy link
Collaborator

Starting build on ROOT-debian10-i386/cxx14, ROOT-performance-centos8-multicore/default, ROOT-ubuntu16/nortcxxmod, mac1014/python3, mac11.0/cxx17, windows10/cxx14
How to customize builds

@phsft-bot
Copy link
Collaborator

Starting build on ROOT-debian10-i386/cxx14, ROOT-performance-centos8-multicore/default, ROOT-ubuntu16/nortcxxmod, mac1014/python3, mac11.0/cxx17, windows10/cxx14
How to customize builds

@phsft-bot
Copy link
Collaborator

Starting build on ROOT-debian10-i386/cxx14, ROOT-performance-centos8-multicore/default, ROOT-ubuntu16/nortcxxmod, mac1014/python3, mac11.0/cxx17, windows10/cxx14
How to customize builds

Derived class from AnalyticalGradientCalculator. Allows Minuit2 using
codes to calculate gradients themselves, but in Minuit2 "internal"
parameter space, in order to preserve exact value correspondence with
the Minuit2 implementation.
@phsft-bot
Copy link
Collaborator

Starting build on ROOT-debian10-i386/cxx14, ROOT-performance-centos8-multicore/default, ROOT-ubuntu16/nortcxxmod, mac1014/python3, mac11.0/cxx17, windows10/cxx14
How to customize builds

@egpbos egpbos marked this pull request as ready for review June 8, 2021 13:40
@egpbos egpbos requested review from lmoneta and oshadura as code owners June 8, 2021 13:40
@guitargeek
Copy link
Contributor

Thank you so much for investing the time to make new commits!

@lmoneta lmoneta self-assigned this Jun 8, 2021
@phsft-bot
Copy link
Collaborator

Build failed on windows10/cxx14.
Running on null:C:\build\workspace\root-pullrequests-build
See console output.

Errors:

  • [2021-06-08T17:59:04.119Z] CMake Error at C:/build/workspace/root-pullrequests-build/rootspi/jenkins/root-build.cmake:1084 (ctest_start):

@bellenot
Copy link
Member

bellenot commented Jun 8, 2021

@egpbos please fork also rootest to prevent timeouts on the Windows build nodes, thanks in advance.

@egpbos
Copy link
Contributor Author

egpbos commented Jun 9, 2021

@bellenot thanks for the tip. Should I fork to the same org where this ROOT dev branch is at (github.com/roofit-dev) or to my personal account?

@guitargeek
Copy link
Contributor

Just a fork to your personal account is sufficient. The scrips are looking for egpbos/roottest. You don't need to add any commits to this fork of roottest, just forking.

@egpbos
Copy link
Contributor Author

egpbos commented Jun 9, 2021

@phsft-bot build just on windows10/cxx14

@phsft-bot
Copy link
Collaborator

Starting build on windows10/cxx14
How to customize builds

Copy link
Member

@lmoneta lmoneta left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @egpbos for this PR.

I have some doubts about adding in the Math/IFunction interfaces the second derivatives and step sizes. I think, when supplying an external gradient to Minuit2, the G2 is used only when computing the Seed state and eventually used in NegativeG2LineSearch if G2<0.
Recently I have changed the entry point of the minimisation in ModularFunctionMinimizer, see
https://github.com/root-project/root/blob/master/math/minuit2/src/ModularFunctionMinimizer.cxx#L142
when using a FCN computing the gradient.
There the Numerical MInuit2 gradient is used for the seed, so there is really no needs to provide to Minuit G2 and step size's at the cost of using for the first iteration the Minuit2 gradient calculator. The cost of doing this I think is minimal given the fact that a large number of iteration at the end will be done ( at least 10 but often something like 100).
Furthermore the MnHesse is using still the Numerical gradient, so I would prefer if for the time being we make the smallest changes and add in a later time full support for providing second derivatives, that can be used also in MnHesse.

math/mathcore/inc/Math/IFunction.h Show resolved Hide resolved
math/mathcore/inc/Math/IFunction.h Outdated Show resolved Hide resolved
math/minuit2/src/AnalyticalGradientCalculator.cxx Outdated Show resolved Hide resolved
math/minuit2/src/AnalyticalGradientCalculator.cxx Outdated Show resolved Hide resolved
math/minuit2/inc/Minuit2/FCNGradientBase.h Outdated Show resolved Hide resolved
math/minuit2/inc/Minuit2/MnUserTransformation.h Outdated Show resolved Hide resolved
math/minuit2/src/MnSeedGenerator.cxx Outdated Show resolved Hide resolved
math/minuit2/inc/Minuit2/FCNGradientBase.h Outdated Show resolved Hide resolved
Co-authored-by: Axel Naumann <Axel.Naumann@cern.ch>
@egpbos egpbos requested a review from bellenot as a code owner June 17, 2021 13:15
@phsft-bot
Copy link
Collaborator

Starting build on ROOT-debian10-i386/cxx14, ROOT-performance-centos8-multicore/default, ROOT-ubuntu16/nortcxxmod, mac1014/python3, mac11.0/cxx17, windows10/cxx14
How to customize builds

egpbos added a commit to roofit-dev/root that referenced this pull request Jun 23, 2021
As highlighted by @lmoneta in PR review comments (root-project#8369 (review)), the second derivative and step size information is not necessary at this point. The floating point exact minuit-external (roofit-internal) derivative duplication is currently done using ExternalInternalGradientCalculator and further made possible by the long double parameter transformation functions. This is all we need for now.
As highlighted by @lmoneta in PR review comments (root-project#8369 (review)), the second derivative and step size information is not necessary at this point. The floating point exact minuit-external (roofit-internal) derivative duplication is currently done using ExternalInternalGradientCalculator and further made possible by the long double parameter transformation functions. This is all we need for now.
@phsft-bot
Copy link
Collaborator

Starting build on ROOT-debian10-i386/cxx14, ROOT-performance-centos8-multicore/default, ROOT-ubuntu16/nortcxxmod, mac1014/python3, mac11.0/cxx17, windows10/cxx14
How to customize builds

@phsft-bot
Copy link
Collaborator

Build failed on ROOT-ubuntu16/nortcxxmod.
Running on sft-ubuntu-1604-4.cern.ch:/build/workspace/root-pullrequests-build
See console output.

Errors:

  • [2021-06-23T12:37:06.205Z] FAILED: cd /mnt/build/workspace/root-pullrequests-build/build/math/mathcore && /usr/local/bin/cmake -E env LD_LIBRARY_PATH=/mnt/build/workspace/root-pullrequests-build/build/lib: ROOTIGNOREPREFIX=1 /mnt/build/workspace/root-pullrequests-build/build/bin/rootcling -rootbuild -v2 -f G__MathCore.cxx -s /mnt/build/workspace/root-pullrequests-build/build/lib/libMathCore.so -m libCore_rdict.pcm -m libImt_rdict.pcm -excludePath /mnt/build/workspace/root-pullrequests-build/root -excludePath /mnt/build/workspace/root-pullrequests-build/build/ginclude -excludePath /mnt/build/workspace/root-pullrequests-build/build/externals -excludePath /mnt/build/workspace/root-pullrequests-build/build/builtins -rml libMathCore.so -rmf /mnt/build/workspace/root-pullrequests-build/build/lib/libMathCore.rootmap -writeEmptyRootPCM -I/mnt/build/workspace/root-pullrequests-build/build/include -I/mnt/build/workspace/root-pullrequests-build/root/math/mathcore/inc -I/mnt/build/workspace/root-pullrequests-build/root/core/unix/inc -I/mnt/build/workspace/root-pullrequests-build/root/core/clingutils/inc -I/mnt/build/workspace/root-pullrequests-build/root/core/textinput/inc -I/mnt/build/workspace/root-pullrequests-build/root/core/thread/inc -I/mnt/build/workspace/root-pullrequests-build/root/core/zip/inc -I/mnt/build/workspace/root-pullrequests-build/root/core/rint/inc -I/mnt/build/workspace/root-pullrequests-build/root/core/clib/inc -I/mnt/build/workspace/root-pullrequests-build/root/core/meta/inc -I/mnt/build/workspace/root-pullrequests-build/root/core/gui/inc -I/mnt/build/workspace/root-pullrequests-build/root/core/cont/inc -I/mnt/build/workspace/root-pullrequests-build/root/core/foundation/inc -I/mnt/build/workspace/root-pullrequests-build/root/core/base/inc -I/mnt/build/workspace/root-pullrequests-build/build/ginclude -I/mnt/build/workspace/root-pullrequests-build/root/math/mathcore/v7/inc -I/mnt/build/workspace/root-pullrequests-build/root/math/mathcore/inc -I/mnt/build/workspace/root-pullrequests-build/root/core/imt/inc -I/mnt/build/workspace/root-pullrequests-build/root/core/multiproc/inc -I/mnt/build/workspace/root-pullrequests-build/build/ginclude -I/mnt/build/workspace/root-pullrequests-build/build/externals//mnt/build/workspace/root-pullrequests-build/install/include -I/mnt/build/workspace/root-pullrequests-build/build/externals//mnt/build/workspace/root-pullrequests-build/install/include -I/mnt/build/workspace/root-pullrequests-build/build/externals//mnt/build/workspace/root-pullrequests-build/install/include -I/mnt/build/workspace/root-pullrequests-build/build/externals//mnt/build/workspace/root-pullrequests-build/install/include -I/mnt/build/workspace/root-pullrequests-build/build/externals//mnt/build/workspace/root-pullrequests-build/install/include -I/mnt/build/workspace/root-pullrequests-build/build/externals//mnt/build/workspace/root-pullrequests-build/install/include -I/mnt/build/workspace/root-pullrequests-build/build/externals//mnt/build/workspace/root-pullrequests-build/install/include -I/mnt/build/workspace/root-pullrequests-build/build/externals//mnt/build/workspace/root-pullrequests-build/install/include -I/mnt/build/workspace/root-pullrequests-build/build/externals//mnt/build/workspace/root-pullrequests-build/install/include -I/mnt/build/workspace/root-pullrequests-build/build/ginclude -I/mnt/build/workspace/root-pullrequests-build/root/core/base/inc -I/mnt/build/workspace/root-pullrequests-build/root/core/foundation/inc -I/mnt/build/workspace/root-pullrequests-build/root/core/cont/inc -I/mnt/build/workspace/root-pullrequests-build/root/core/gui/inc -I/mnt/build/workspace/root-pullrequests-build/root/core/meta/inc -I/mnt/build/workspace/root-pullrequests-build/root/core/clib/inc -I/mnt/build/workspace/root-pullrequests-build/root/core/rint/inc -I/mnt/build/workspace/root-pullrequests-build/root/core/zip/inc -I/mnt/build/workspace/root-pullrequests-build/root/core/thread/inc -I/mnt/build/workspace/root-pullrequests-build/root/core/textinput/inc -I/mnt/build/workspace/root-pullrequests-build/root/core/unix/inc -I/mnt/build/workspace/root-pullrequests-build/root/core/imt/inc -I/mnt/build/workspace/root-pullrequests-build/root/core/multiproc/inc -I/mnt/build/workspace/root-pullrequests-build/root/net/net/inc -I/mnt/build/workspace/root-pullrequests-build/root/io/io/inc -I/mnt/build/workspace/root-pullrequests-build/root/core/thread/inc Fit/BasicFCN.h Fit/BinData.h Fit/Chi2FCN.h Fit/DataOptions.h Fit/DataRange.h Fit/FcnAdapter.h Fit/FitConfig.h Fit/FitData.h Fit/FitExecutionPolicy.h Fit/FitResult.h Fit/FitUtil.h Fit/Fitter.h Fit/LogLikelihoodFCN.h Fit/ParameterSettings.h Fit/PoissonLikelihoodFCN.h Fit/SparseData.h Fit/UnBinData.h Math/AdaptiveIntegratorMultiDim.h Math/AllIntegrationTypes.h Math/BasicMinimizer.h Math/BrentMethods.h Math/BrentMinimizer1D.h Math/BrentRootFinder.h Math/ChebyshevPol.h Math/Delaunay2D.h Math/DistFuncMathCore.h Math/DistSampler.h Math/DistSamplerOptions.h Math/Error.h Math/Factory.h Math/FitMethodFunction.h Math/Functor.h Math/GaussIntegrator.h Math/GaussLegendreIntegrator.h Math/GenAlgoOptions.h Math/GoFTest.h Math/IFunction.h Math/IFunctionfwd.h Math/IMinimizer1D.h Math/IOptions.h Math/IParamFunction.h Math/IParamFunctionfwd.h Math/IRootFinderMethod.h Math/Integrator.h Math/IntegratorMultiDim.h Math/IntegratorOptions.h Math/KDTree.h Math/LCGEngine.h Math/Math.h Math/MersenneTwisterEngine.h Math/MinimTransformFunction.h Math/MinimTransformVariable.h Math/Minimizer.h Math/MinimizerOptions.h Math/MinimizerVariableTransformation.h Math/MixMaxEngine.h Math/MultiDimParamFunctionAdapter.h Math/OneDimFunctionAdapter.h Math/ParamFunctor.h Math/PdfFuncMathCore.h Math/ProbFuncMathCore.h Math/QuantFuncMathCore.h Math/Random.h Math/RandomFunctions.h Math/RanluxppEngine.h Math/RichardsonDerivator.h Math/RootFinder.h Math/SpecFuncMathCore.h Math/StdEngine.h Math/TDataPoint.h Math/TDataPointN.h Math/TRandomEngine.h Math/Types.h Math/Util.h Math/VirtualIntegrator.h Math/WrappedFunction.h Math/WrappedParamFunction.h TComplex.h TKDTree.h TKDTreeBinning.h TMath.h TRandom.h TRandom1.h TRandom2.h TRandom3.h TRandomGen.h TStatistic.h VectorizedTMath.h /mnt/build/workspace/root-pullrequests-build/root/math/mathcore/inc/LinkDef.h
  • [2021-06-23T12:37:06.205Z] /mnt/build/workspace/root-pullrequests-build/build/include/Math/IFunction.h:325:30: error: unknown type name 'T'
  • [2021-06-23T12:37:06.205Z] /mnt/build/workspace/root-pullrequests-build/build/include/Math/IFunction.h:325:36: error: unknown type name 'T'
  • [2021-06-23T12:37:06.205Z] /mnt/build/workspace/root-pullrequests-build/build/include/Math/IFunction.h:325:42: error: unknown type name 'T'
  • [2021-06-23T12:37:06.205Z] /mnt/build/workspace/root-pullrequests-build/build/include/Math/IFunction.h:325:49: error: non-member function cannot have 'const' qualifier
  • [2021-06-23T12:37:06.205Z] /mnt/build/workspace/root-pullrequests-build/build/include/Math/IFunction.h:325:7: error: 'virtual' can only appear on non-static member functions
  • [2021-06-23T12:37:06.205Z] /mnt/build/workspace/root-pullrequests-build/build/include/Math/IFunction.h:327:13: error: use of undeclared identifier 'BaseFunc'
  • [2021-06-23T12:37:06.205Z] /mnt/build/workspace/root-pullrequests-build/build/include/Math/IFunction.h:331:53: error: non-member function cannot have 'const' qualifier
  • [2021-06-23T12:37:06.205Z] /mnt/build/workspace/root-pullrequests-build/build/include/Math/IFunction.h:331:7: error: 'virtual' can only appear on non-static member functions
  • [2021-06-23T12:37:06.205Z] /mnt/build/workspace/root-pullrequests-build/build/include/Math/IFunction.h:353:25: error: expected class name

And 11 more

@phsft-bot
Copy link
Collaborator

Build failed on mac1014/python3.
Running on macphsft17.dyndns.cern.ch:/build/jenkins/workspace/root-pullrequests-build
See console output.

Errors:

  • [2021-06-23T12:53:27.023Z] FAILED: math/mathcore/G__MathCore.cxx lib/MathCore.pcm
  • [2021-06-23T12:53:28.397Z] /build/jenkins/workspace/root-pullrequests-build/build/include/Math/IFunction.h:325:30: error: unknown type name 'T'
  • [2021-06-23T12:53:28.397Z] /build/jenkins/workspace/root-pullrequests-build/build/include/Math/IFunction.h:325:36: error: unknown type name 'T'
  • [2021-06-23T12:53:28.397Z] /build/jenkins/workspace/root-pullrequests-build/build/include/Math/IFunction.h:325:42: error: unknown type name 'T'
  • [2021-06-23T12:53:28.397Z] /build/jenkins/workspace/root-pullrequests-build/build/include/Math/IFunction.h:325:49: error: non-member function cannot have 'const' qualifier
  • [2021-06-23T12:53:28.397Z] /build/jenkins/workspace/root-pullrequests-build/build/include/Math/IFunction.h:325:7: error: 'virtual' can only appear on non-static member functions
  • [2021-06-23T12:53:28.397Z] /build/jenkins/workspace/root-pullrequests-build/build/include/Math/IFunction.h:327:13: error: use of undeclared identifier 'BaseFunc'
  • [2021-06-23T12:53:28.397Z] /build/jenkins/workspace/root-pullrequests-build/build/include/Math/IFunction.h:331:53: error: non-member function cannot have 'const' qualifier
  • [2021-06-23T12:53:28.398Z] /build/jenkins/workspace/root-pullrequests-build/build/include/Math/IFunction.h:331:7: error: 'virtual' can only appear on non-static member functions
  • [2021-06-23T12:53:28.398Z] /build/jenkins/workspace/root-pullrequests-build/build/include/Math/IFunction.h:353:25: error: expected class name

And 11 more

Fixes: some merge mistakes + some remaining layout diffs.

The additional reverted thing is the block from line 119 in MnSeedGenerator.cxx.
@phsft-bot
Copy link
Collaborator

Build failed on ROOT-performance-centos8-multicore/default.
Running on olbdw-01.cern.ch:/data/sftnight/workspace/root-pullrequests-build
See console output.

Errors:

  • [2021-06-23T12:58:47.974Z] /data/sftnight/workspace/root-pullrequests-build/build/include/Math/IFunction.h:325:30: error: unknown type name 'T'
  • [2021-06-23T12:58:47.974Z] /data/sftnight/workspace/root-pullrequests-build/build/include/Math/IFunction.h:325:36: error: unknown type name 'T'
  • [2021-06-23T12:58:47.974Z] /data/sftnight/workspace/root-pullrequests-build/build/include/Math/IFunction.h:325:42: error: unknown type name 'T'
  • [2021-06-23T12:58:47.974Z] /data/sftnight/workspace/root-pullrequests-build/build/include/Math/IFunction.h:325:49: error: non-member function cannot have 'const' qualifier
  • [2021-06-23T12:58:47.974Z] /data/sftnight/workspace/root-pullrequests-build/build/include/Math/IFunction.h:325:7: error: 'virtual' can only appear on non-static member functions
  • [2021-06-23T12:58:47.974Z] /data/sftnight/workspace/root-pullrequests-build/build/include/Math/IFunction.h:327:13: error: use of undeclared identifier 'BaseFunc'
  • [2021-06-23T12:58:47.974Z] /data/sftnight/workspace/root-pullrequests-build/build/include/Math/IFunction.h:331:53: error: non-member function cannot have 'const' qualifier
  • [2021-06-23T12:58:47.974Z] /data/sftnight/workspace/root-pullrequests-build/build/include/Math/IFunction.h:331:7: error: 'virtual' can only appear on non-static member functions
  • [2021-06-23T12:58:47.974Z] /data/sftnight/workspace/root-pullrequests-build/build/include/Math/IFunction.h:353:25: error: expected class name
  • [2021-06-23T12:58:47.974Z] /data/sftnight/workspace/root-pullrequests-build/build/include/Math/IFunction.h:354:17: error: expected class name

And 10 more

@phsft-bot
Copy link
Collaborator

Starting build on ROOT-debian10-i386/cxx14, ROOT-performance-centos8-multicore/default, ROOT-ubuntu16/nortcxxmod, mac1014/python3, mac11.0/cxx17, windows10/cxx14
How to customize builds

1 similar comment
@phsft-bot
Copy link
Collaborator

Starting build on ROOT-debian10-i386/cxx14, ROOT-performance-centos8-multicore/default, ROOT-ubuntu16/nortcxxmod, mac1014/python3, mac11.0/cxx17, windows10/cxx14
How to customize builds

Just trying to keep the PR diff minimal.
@egpbos egpbos force-pushed the RooFit_MultiProcess_PR_1_math branch from 5477d93 to 025f0ed Compare June 23, 2021 13:09
@phsft-bot
Copy link
Collaborator

Starting build on ROOT-debian10-i386/cxx14, ROOT-performance-centos8-multicore/default, ROOT-ubuntu16/nortcxxmod, mac1014/python3, mac11.0/cxx17, windows10/cxx14
How to customize builds

@egpbos
Copy link
Contributor Author

egpbos commented Jun 23, 2021

@lmoneta I have removed all the second derivative and step size code. As you suspected, it was all unnecessary. Looking back at my logs, it seems I just forgot to clean them up after introducing ExternalInternalGradientCalculator. This, together with the long double precision upgrade of the parameter transformation classes, allows for perfect bitwise floating point replication of the gradient calculation outside of Minuit. Thanks for the thorough review!

I also took care of the copyright lines and fixed some additional layout issues.

Ready for a final review!

@egpbos
Copy link
Contributor Author

egpbos commented Jun 24, 2021

The JupyROOT failure is a master branch failure unrelated to this PR. Other than that, CI passes now. I think it should be ready to merge if you have no further change requests @lmoneta.

Copy link
Member

@lmoneta lmoneta left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for applying the changes I requested earlier.
I have requested a change in Function, but I can do it later if you prefer.
For the ExternalInternalGradientCalculator class name, can we find a better name ?
Otherwise we can discuss it later..

@@ -360,7 +360,7 @@ namespace ROOT {
Gradient(x, df);
}


virtual bool returnsInMinuit2ParameterSpace() const { return false; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this function really needed ? It should not be at the gradient calculator level to know if the internal parameter space is used

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at the code, I would add maybe a new flag to the
ROOT::Math::Minimiser::SetFunction( gradFunc & f, bool= false)
In this way the Minuit2Minimizer can set this flag in the FCNGradientBase class when creating it from the function interface passed by the clients (e.g. RooMinimizer).
If you prefer, we can merge with this and I can do this change later, please let me know

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your suggestion makes sense, indeed it feels weird that a Minuit detail is in mathcore. In light of time constraints, I would prefer to keep it like this for now, if you don't mind too much. The problem is that returnsInMinuit2ParameterSpace is also used in other places right now, in particular in the TestStatistics::MinuitFcnGrad class that will be introduced in the next PR I will make.

/**********************************************************************
* *
* Copyright (c) 2005 LCG ROOT Math team, CERN/PH-SFT *
* Copyright (c) 2017 Patrick Bos, Netherlands eScience Center *
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you really want to keep this class name instead of calling something else ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm open to suggestions, I don't love it either.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe InternalSpaceGradientCalculator? Or MinuitSpaceGradientCalculator? Or TransformedSpaceGradientCalculator? I find it hard to make it more compact, while at the same time clearly indicating the relation to the other gradient calculators.

Perhaps as an alternative it would make sense to make a namespace GradientCalculator in which the different types could be gathered.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To at least make the use case clearer (and perhaps also the name), I added some doxygen documentation for the class. Hope this helps.

bool CheckGradient() const { return false; }
bool CheckGradient() const override { return false; }

GradientParameterSpace gradParameterSpace() const override {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned above, I would add in this class the flag to distinguish external from internal gradient parameter space

@phsft-bot
Copy link
Collaborator

Starting build on ROOT-debian10-i386/cxx14, ROOT-performance-centos8-multicore/default, ROOT-ubuntu16/nortcxxmod, mac1014/python3, mac11.0/cxx17, windows10/cxx14
How to customize builds

@phsft-bot
Copy link
Collaborator

Starting build on ROOT-debian10-i386/cxx14, ROOT-performance-centos8-multicore/default, ROOT-ubuntu16/nortcxxmod, mac1014/python3, mac11.0/cxx17, windows10/cxx14
How to customize builds

@phsft-bot
Copy link
Collaborator

Build failed on ROOT-debian10-i386/cxx14.
Running on pcepsft11.dyndns.cern.ch:/home/sftnight/build/workspace/root-pullrequests-build
See console output.

Failing tests:

Comment on lines +31 to +33
long double Int2ext(long double Value, long double Upper, long double Lower) const;
long double Ext2int(long double Value, long double Upper, long double Lower, const MnMachinePrecision &) const;
long double DInt2Ext(long double Value, long double Upper, long double Lower) const;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should these be additional overloads, leaving the perf of the double version? Or have them as templates, only offering double and long double specializations (and possibly float)?

Copy link
Contributor Author

@egpbos egpbos Jul 8, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We discussed this, and concluded that it's unlikely to cause issues. The two potential problems would be:

  1. On some more exotic platform the long doubles may not be implemented or differently and the (bit-wise exact) tests will not pass. However, it is unclear what platforms this would be. GPU computation, for instance, would not be affected, because the parameter transformations are not part of the main calculation that would be offloaded to the GPU.
  2. This also means performance is not expected to be a big issue. With big fits, the parameter transformations are a minute part of the Minuit run time. Most time by far is spent in the function calls. The only situation in which it could be an issue is if you have a very cheap function with a huge amount of parameters. This seems quite unlikely for realistic fits.

Copy link
Contributor Author

@egpbos egpbos Jul 8, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One could also argue that a pro of using long double is that it clearly signals that these trigonometric transformations can lose some bits. This happens when you use the double versions and transform back and forth. In some situations, you can then lose 1 or 2 bits, just because of the trigonometric implementations. An alternative solution would be more precise sine etc functions. Though, actually, I'm not sure if that helps, because the needed information may be in the extra bits that will not be stored for any double version...

Copy link
Member

@Axel-Naumann Axel-Naumann Jul 8, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

and the (bit-wise exact) tests will not pass

That's curious - how do you "survive" on Windows? https://docs.microsoft.com/en-us/cpp/cpp/fundamental-types-cpp?view=msvc-160#floating-point-types

Which tests, by the way?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Windows will use the double version and it will then use few bits when using the external calculator with the multiprocess. Will the multiprocess be available on Windows ? Probably not

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK - but if there's only a long double version then which "double version" are you referring to? "Bit-wise exact" still depends on implementation / architecture. I trust this is handled, just making sure you're aware. (And I still don't know where these tests are.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tests in #8596 for instance @Axel-Naumann :) Btw, they don't pass currently either, due to changes in master that I hadn't incorporated yet. On the todo list.

But good question about Windows. I haven't tested at all there yet. So probably, at least for the time being, it will have to be disabled on Windows, as @lmoneta says. In principle, ZeroMQ works on all platforms, so that is not the bottleneck. However, I have no idea how/whether forking works on Windows.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just so you don't have to dig into the code: the test compares the results of fitting with RooMinimizerFcn vs fitting the same function with RooGradMinimizerFcn. We put a lot of effort into making those two fits run exactly the same way. Small bit-wise differences quickly accumulate in the algorithm to end up with different results (past the desired precision, so e.g. in the 6th decimal if you wanted the fit to converge to 5).

Copy link
Member

@lmoneta lmoneta left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we have clarified all issues and we are ready to merge this one.
Thank you Patrick for all this !

@lmoneta lmoneta merged commit 0396d49 into root-project:master Jul 9, 2021
pzhristov pushed a commit to alisw/root that referenced this pull request Aug 27, 2021
…ges (root-project#8369)

* add virtuals to IFunction to calculate second derivative and stepsize

Used in Minuit2 ExternalInternalGradientCalculator (introduced in a later commit) and in RooFit (also later commits) to enable calculation of all derivative and related numbers outside of Minuit2. Specifically, having second derivative and step size calculated outside of Minuit2 allows exact replication of the gradients as calculated in Minuit2 itself, which in turn enables external optimization and parallelization of this process without having to modify Minuit2.

* add second derivative and step size calculation to Minuit2 function adaptors

Like the changes to IFunction in the previous commit, this is also necessary for Minuit2-external gradient calculation.

* add second derivative and step size to Minuit2 parameter transformers and increase their precision

This commit changes two (functionally speaking strictly separate, but unified in their ultimate purpose) things. First, to further accomodate the added ability of external gradient calculators to pass in second derivative and step sizes, the internal to external parameter transformers in Minuit2 need to have added D2Int2Ext and GStepInt2Ext functions that perform these transformations for those added parts. Second, we increase the precision of the transformers to long double. This is necessary  to make sure that trigonometric transformations don't lose a few bits of precision on back-and-forth parameter transformations, which they do when using the double versions. Both changes are necessary for the external gradient calculation in Minuit2 which will be introduced in a next commit in ExternalInternalGradientCalculator.

* implement optional second derivative and step size calculation in AnalyticalGradientCalculator

* remove unnecessary temporary objects

* add ExternalInternalGradientCalculator to minuit2

Derived class from AnalyticalGradientCalculator. Allows Minuit2 using
codes to calculate gradients themselves, but in Minuit2 "internal"
parameter space, in order to preserve exact value correspondence with
the Minuit2 implementation.

* Update math/mathcore/inc/Math/IFunction.h

Co-authored-by: Axel Naumann <Axel.Naumann@cern.ch>

* revert unnecessary math/minuit2 changes

As highlighted by @lmoneta in PR review comments (root-project#8369 (review)), the second derivative and step size information is not necessary at this point. The floating point exact minuit-external (roofit-internal) derivative duplication is currently done using ExternalInternalGradientCalculator and further made possible by the long double parameter transformation functions. This is all we need for now.

* fix previous revert commit + revert one additional thing

Fixes: some merge mistakes + some remaining layout diffs.

The additional reverted thing is the block from line 119 in MnSeedGenerator.cxx.

* fix additional layout

Just trying to keep the PR diff minimal.

* remove copyright line [skip ci]

* add ExternalInternalGradientCalculator doxygen

Co-authored-by: Axel Naumann <Axel.Naumann@cern.ch>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants