Minuit2 - PrintLevel in multi-threading

Dear all,

I am using the C++11 std::thread library to minimise a functor with different parameters in each thread. I am tracking the “v6-02-00-patches” git branch. The minimiser is instantiated and used in each thread as

chiSquared functor defined...
ROOT::Math::Functor f(chiSquared, chiSquared.getNumberOfFreeParameters());
minuit(ROOT::Minuit2::kMigrad);
minuit.SetFunction(f);
for(unsigned k = 0; k<f.NDim(); ++k) minuit.SetVariable(k,"x_"+to_string(k),variable[k], step[k]);
miniuit.Minimize();

The minisation works fine using either one ore many more threads at the same time (the results are always the same on top of this, and the ones that are expected). There is only point that bugs me (and a post about the PrintLevel being fixed here didn’t help in my case) : I get most Info messages when using more than one thread. For instance

Info in <Minuit2>: DavidonErrorUpdator: delgam < 0 : first derivatives increasing along search line Info in <Minuit2>: VariableMetricBuilder: matrix not pos.def, gdel > 0 Info in <Minuit2>: gdel = 4238.16 Info in <Minuit2>: negative or zero diagonal element in covariance matrix : i = 0 Info in <Minuit2>: negative or zero diagonal element in covariance matrix : i = 1 Info in <Minuit2>: added to diagonal of Error matrix a value : dg = 0.507048 Info in <Minuit2>: gdel = -1.00438e+06

I have tried looking at the source code of MnPrint.h, the pre-processor instructions for MN_INFO_MSG, the MnPrint::Level method, with little success. I have printed the “minuit.PrintLevel()” value in each thread, before starting the minimisation and it always outputs to “0”. According to the source code, it would mean that no such messages are to be displayed, and yet I see them… Any ideas ?

Many thanks in advance,
Valérian

I believe the issue lies in the “ErrorHandler” function call in the “Info” function of the “TError.cxx” file inasmuch as commenting this call out (i.e. “ErrorHandler(kInfo, location, va_(fmt), ap);
”) in the “TError.cxx” file removes the annoying messages in multi-threaded applications.

I have tried adding “R__LOCKGUARD2” to the ROOT source code without much success yet… Probably someone with better knowledge of the ROOT source code would know how to efficiently handle the mutexes…

Best regards,
Valérian

Hello,
These info messages are controlled by the ROOT error handler and not by Minuit2::MnPrint::PrintLevel().
If you want to switch them off you need to change the global variable gErrorIgnoreLevel.
You can do this globally for every thread, by setting for example to 1001. In this way the Info message will be ignored.

If you are using the ROOT::Math::Minuit2Minimizer class (via the Minimizer interface), you can switch them off by calling minimizer.SetPrintLevel(0).

Best Regards

Lorenzo

Dear Lorenzo,

Thank you for your reply! When instantiating the minimiser in each thread, setting “gErrorIgnoreLevel = 1001” does remove the info messages!

However, writing “minimiser.SetPrintLevel(0)” does not change anything (and as I noticed, minmiser.PrintLevel() already and always outputs “0” in each thread).

I am not sure why using “PrintLevel” does not work, but the “gErrorIgnoreLevel = 1001” is at least a nicer fix than commenting the call to the error handler in the ROOT source files!

Many thanks for your help,
Valérian

Hello,

It is strange that minimiser.SetPrintLevel(0) does not work for you, because it should set gErrorIgnoreLevel=1001.
Is it at least working in single-thread mode ?

Best Regards

Lorenzo

Hello Lorenzo,

Sorry for the late reply. Yes, as I wrote in my original post, it does work perfectly with a single-thread without any need to call anything! When using more than one std::thread, only “gErrorIgnoreLevel=1001” prevents the messages from being printed.

Best regards,
Valérian