Multithreading with standalone_cpp output

Asked by Rob Verheyen on 2017-07-27

Dear Madgraph team,

I'm trying to use the standalone c++ output in a multithreaded program, but I'm running into issues. I managed to condense the problem down to some code that's very similar to the check_sa.cc that comes with the c++ output (compiled with -std=c++11):

#include <iostream>
#include <iomanip>
#include <thread>

#include "CPPProcess.h"
#include "rambo.h"

struct MEC
{
  MEC(){process.initProc("../../Cards/param_card.dat");}

  void run()
  {
    double energy = 1500;
    double weight;

    for (int i=0; i<3; i++)
    {
      // Get phase space point
      vector<double*> p = get_momenta(process.ninitial, energy,
             process.getMasses(), weight);

      // Set momenta for this event
      process.setMomenta(p);

      // Evaluate matrix element
      process.sigmaKin();
      cout << process.getMatrixElements()[0] << endl;
    }
  }

  CPPProcess process;
};

int main()
{
  thread t1(&MEC::run, MEC());
  thread t2(&MEC::run, MEC());
  t1.join();
  t2.join();
}

The code is supposed to generate 3 sets of rambo momenta and calculate the matrix element. However, the output is
0.000000e+00
0.000000e+00
0.000000e+00
0.000000e+00
0.000000e+00
0.000000e+00

If I remove one of the threads, the output is something like
3.624505e-15
2.599132e-13
2.264434e-14

as I would expect. I'm hoping anyone knows what's going on here, since as far as I know, this is how you're supposed to multithread this kind of c++ code.

Thanks,
Rob Verheyen

Question information

Language:
English Edit question
Status:
Answered
For:
MadGraph5_aMC@NLO Edit question
Assignee:
No assignee Edit question
Last query:
2017-07-27
Last reply:
2017-07-31

Hi,

I have simply no idea on this....

Cheers,

Olivier

Rob Verheyen (robverheyen) said : #2

Hey Olivier,

I guess that makes two of us :) Do you happen to have any idea if there's anyone I could ask about this?

Cheers

The defaultMG5aMC C++ standalone tree matrix element output uses a "global" static pointer to store the model instance.
This is a rather bad programming style that is, among other problems, not thread-safe and I suspect that this could be the origin of the issue you are facing. This is however just a wild guess, so it could have nothing to do with this.

I have a private MG5aMC plugin for a more advanced and thread-safe C++ output for tree-level matrix elements that could play nicer for your application. Contact me by email directly (<email address hidden>) if you want to discuss more about that.

Rob confirmed that the C++ output from my (still) private MG5aMC plugin is indeed thread-safe and could be used for his purpose (contact me if someone else needs it).
The thread-unsafety of the default C++ output is probably related to the global Model static pointer and the RAMBO C++ implementation (for which Rob has written an alternative implementation himself, again available upon request).

Rob Verheyen (robverheyen) said : #5

For anyone that happens to encounter the same issue as I did, it turns out you can pretty easily modify the regular code to be thread-safe by doing the following:

- Remove every instance of the keyword 'static' from the CPPProcess.cc file
- Remove the static pointer functionality from the Parameter_sm class and change it in such a way that every instance of the CPPProcess object just has a copy of the Paramter_sm class.

Rob Verheyen (robverheyen) said : #6

Actually only the first step is necessary as long as the CPPProcess objects are not created simultaneously. The singleton pattern design of the Parameter_sm class is thread-safe as long as the instance cannot be created by multiple threads.

Can you help with this problem?

Provide an answer of your own, or ask Rob Verheyen for more information if necessary.

To post a message you must log in.