Parallelism in QC task

Dear @bvonhall, @pkonopka, @shahoian, all,

in the CPV pedestal QC task I try to perform a parallel fitting of set of histograms.
Let’s say I have 23040 TH1 histos to 1) search peaks and 2) fit with gauss.
In the PedestalTask.h I have:

class PedestalTask:
...
private:
  std::array<TH1F*, kNChannels> mHistAmplitudes;

In the PedestalTask.cxx I try to do following:

void PedestalTask::fillHistograms() 
{
...
  auto lambdaHistoFitter = [this] (int iStartChannel, int nChannels) {
    TSpectrum* peakSearcher = new TSpectrum(5);
    int numberOfPeaks;
    double *xPeaks, yPeaks[5]; 
    ...
    for (int channel = iStartChannel; 
        (channel < iStartChannel + nChannels) && (channel < kNChannels); 
        channel++) {
      numberOfPeaks = peakSearcher->Search(mHistAmplitudes[channel], 10., "nobackground", 0.2);
      xPeaks = peakSearcher->GetPositionX();
      if (numberOfPeaks == 1) {
        TF1* functionGaus = new TF1(Form("functionGaus%d",channel), "gaus", 0., 4095.);
        yPeaks[0] = mHistAmplitudes[channel]
                      ->GetBinContent(mHistAmplitudes[channel]->GetXaxis()->FindBin(xPeaks[0]));
        functionGaus->SetParameters(yPeaks[0], xPeaks[0], 2.);
        mHistAmplitudes[channel]->Fit(functionGaus, "WWQ0", "", xPeaks[0] - 20., xPeaks[0] + 20.);
      }
      ...
  };
  //create fitting threads
  std::vector<std::thread> fitThreads;
  for (int iTh = 0; iTh < 3; iTh++) {
    fitThreads.push_back(std::thread(lambdaHistoFitter, iTh * 7680, 7680));
  }
  //wait until all threads finished
  for (auto& t : fitThreads) {
      t.join();
  } 
}

and this code fails always with different errors like
*** Break *** segmentation violation
or like some other errors saying problems in TFormula or in fortran’s minuit or whatever you want.
If I run everything in 1 thread then all is fine. I assume that the program is not thread-safe and every time I obtain random error due to incorrect access of common memory by the threads.
Any tips how to prepare thread-safe code are very welcome.

The problem is not supercritical for me, and there are ways to overcome this problem without threading. It’s more for my curiosity.

Thank you!

Hi Sergey,

Minuit is not thread safe. Ruben implemented a fitGaus that is thread safe, which is used by TOF, see AliceO2/fit.h at dev · AliceO2Group/AliceO2 · GitHub, AliceO2/fit.h at 0aff69c1be28239558c3024fde30e3985d962cbd · AliceO2Group/AliceO2 · GitHub. This works very well used with openMP to parallelize, but I guess that also your way should work.
See Use openMP to parallelize TOF calibration by chiarazampolli · Pull Request #6568 · AliceO2Group/AliceO2 · GitHub for the application.

Cheers,

Chiara

Dear @zampolli,

thank you very much for your answer. Unfortunately I figured out that not only minuit is not thread-safe but TSpectrum as well. But I’ll use the fitGaus for CPV calibration where is no need to search for peaks in spectrum.

Thank you & regards,
Sergey