Usage of TMinuit SetFCN in multi-threading environment?

Hi all,

in ATLAS we make use of TMinuit for a minimisation problem. We pass a function to TMinuit::SetFCN here: https://gitlab.cern.ch/atlas/athena/-/blob/master/MuonSpectrometer/MuonReconstruction/MuonSegmentMakers/MuonSegmentMakerTools/MdtSegmentT0Fitter/src/MdtSegmentT0Fitter.cxx#L626
However, this function depends itself on values changing dynamically during runtime (cf. https://gitlab.cern.ch/atlas/athena/-/blob/master/MuonSpectrometer/MuonReconstruction/MuonSegmentMakers/MuonSegmentMakerTools/MdtSegmentT0Fitter/src/MdtSegmentT0Fitter.cxx#L243). Thus, in the past, people implemented this via a public object accessed inside the function which is passed to TMinuit::SetFCN (since the data cannot be passed as function arguments since the function arguments are predefined by TMinuit).
Obviously this causes problems when trying to execute TMinuit from different threads at the same time. We were wondering, if TMinuit in general supports multi-threaded execution and if yes, if there is some receipt for the case where a function needs to be passed to TMinuit which has dynamically changing parameters?

Thanks, Nicolas


ROOT Version: 6.22.00
Platform: centos7
Compiler: gcc8


Hi,
I would not use TMinuit in a multi-thread environment, but MInuit2. There you can define a function class that you pass for the minimization and if you want to use it in a multi-thread environment is enough to implement the function to be minimized to be thread-safe.

Best regards
Lorenzo

Hi @moneta,

I had a look and I guess you are referring to something similar as this: https://root.cern/doc/v610/demoMinimizer_8cxx_source.html ?
There, the problem seems to be the same as the one we currently encounter: The function which shall be minimised cannot depend on input that dynamically changes during runtime? I.e. in the example, the function is set via min->SetFunction(f) but we cannot pass any arguments to it explicitly which are then needed inside the function to calculate the return value. Or do I miss something?

Thanks, Nicolas

Hi,

In that case you have a class representing the function, so you can cache in the class some state values that can be used to evaluate the function .To be thread safe, you need to be sure to deal correctly with that state. Either keep constants during the multi-thread execution or look its writing access or make it as a thread local variable. All depends on how will you implement that function.

Best regards

Lorenzo

Hi @moneta,

thanks for your reply. We now solved it by a helper class inheriting from ROOT::Math::IMultiGenFunction (https://gitlab.cern.ch/atlas/athena/-/blob/master/MuonSpectrometer/MuonReconstruction/MuonSegmentMakers/MuonSegmentMakerTools/MdtSegmentT0Fitter/src/MdtSegmentT0Fitter.cxx#L47) and we create one instance of this class per thread and pass this to the SetFunction() of Minuit2. This works fine.

Thanks again,
Nicolas

I think this solution makes sense. Thank you for letting us know
Best regards

Lorenzo

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.