The program was terminated when running in multi-thread mode

Please fill out the following information to help in answering your question, and also see tips for posting code snippets. If you don’t provide this information it will take more time to help with your problem!

Geant4 Version: geant-v11.4.0
Operating System: Ubuntu 24.04
Compiler/Version: gcc (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0
CMake Version: cmake version 3.28.3


Dear experts,
I am a beginner with the Geant4 toolkit. I have developed a multithreaded computing program for counting the neutrons emitted after heavy ion bombardment of a lead target. Here are the codes for MySensitiveDetector.cc and RunAction.cc that I wrote.

G4bool MySensitiveDetector::ProcessHits(G4Step* step, G4TouchableHistory* history){
G4AnalysisManager* analysisManager = G4AnalysisManager::Instance();

if(step->GetTrack()->GetDefinition() != G4Neutron::Neutron()) return false;
if(!step->IsFirstStepInVolume()) return false;

G4double energy = step->GetPreStepPoint()->GetKineticEnergy() / MeV;
G4ThreeVector direction = step->GetPreStepPoint()->GetMomentumDirection();
G4double theta = direction.theta() / deg;

if(theta >= 0.0 && theta < 2.4) analysisManager->FillH1(0, energy);
else if(theta >= 2.5 && theta < 7.5) analysisManager->FillH1(1, energy);
else if(theta >= 12.5 && theta < 17.5) analysisManager->FillH1(2, energy);
else if(theta >= 28.5 && theta < 32.5) analysisManager->FillH1(3, energy);
else if(theta >= 42.5 && theta < 47.5) analysisManager->FillH1(4, energy);
else if(theta >= 58.5 && theta < 62.5) analysisManager->FillH1(5, energy);
else if(theta >= 72.5 && theta < 77.5) analysisManager->FillH1(6, energy);  
return true;

}
RunAction::RunAction()
{
    G4AnalysisManager* analysisManager = G4AnalysisManager::Instance();
    #ifdef G4MULTITHREADED
        analysisManager->SetNtupleMerging(true);
    #endif
    analysisManager->SetVerboseLevel(1);
    analysisManager->OpenFile("yield.root");
    for (size_t i = 0; i < 7; ++i) 
    {
        std::ostringstream nameStream;
        nameStream << "h" << i+1;
        G4String hname = nameStream.str();        
        G4String htitle = "Neutron double differential yield;Neutron Energy [MeV];d^{2}N/(dE d#Omega) [MeV^{-1} sr^{-1}]";       
        analysisManager->CreateH1(hname, htitle, 2000, 0.0, 2000.0);     
    }
}

RunAction::~RunAction()
{}

void RunAction::BeginOfRunAction(const G4Run* run)
{
    std::vector<G4HadronicInteraction *> interactions = G4HadronicInteractionRegistry::Instance()
    ->FindAllModels(G4INCLXXInterfaceStore::GetInstance()->getINCLXXVersionName());
    for(std::vector<G4HadronicInteraction *>::const_iterator iInter=interactions.begin(), e=interactions.end();
      iInter!=e; ++iInter) 
    {
        G4INCLXXInterface *theINCLInterface = static_cast<G4INCLXXInterface*>(*iInter);
        if(theINCLInterface) 
        {
            // Instantiate the ABLA model
            G4HadronicInteraction *interaction = G4HadronicInteractionRegistry::Instance()->FindModel("ABLA");
            G4AblaInterface *theAblaInterface = static_cast<G4AblaInterface*>(interaction);
            if(!theAblaInterface)
            theAblaInterface = new G4AblaInterface;
            // Couple INCL++ to ABLA
            G4cout << "---------------------------------------------" << G4endl
            << "-----------------Coupling INCLXX to ABLA-----------" << G4endl
            << "---------------------------------------------" << G4endl;
            theINCLInterface->SetDeExcitation(theAblaInterface);
        }
    }   
}

void RunAction::EndOfRunAction(const G4Run* run)
{
    G4AnalysisManager* analysisManager = G4AnalysisManager::Instance();
    G4long nEvents = run->GetNumberOfEventToBeProcessed();
    if (nEvents == 0) return;
    if(IsMaster())
    {
        incidentParticles = run->GetNumberOfEventToBeProcessed();
        G4cout << "incident particles: " << incidentParticles << G4endl;
        G4double dE = 1.0;  // MeV
        for (int i = 0; i < 7; ++i) 
        {
            double theta1 = angleMin[i] * M_PI / 180.0;
            double theta2 = angleMax[i] * M_PI / 180.0;
            double dOmega = 2.0 * M_PI * std::abs(std::cos(theta1) - std::cos(theta2));
            double scale = 1.0 / (incidentParticles * dE * dOmega);
            analysisManager->ScaleH1(i, scale);
        }
    }
    analysisManager->Write();
    analysisManager->CloseFile(); 
}

When I was running the program, I encountered the following problems:
(1) If I use 100 threads and the number of incident particles is 1e7, the program can run normally and produce the correct results. However, if I increase the number of incident particles to 1e8, the program will be terminated. I checked the memory usage during runtime, and the memory would exceed the computer’s memory (521G) when the number of incident particles reached 5e7. I wonder if there is an error in my code that caused this situation.
(2) If I use 300 threads, the program will not run and will display the following error:

*** Fatal Exception *** core dump ***
G4WT294 > **** Track information is not available at this moment
G4WT148 >
-------- EEEE ------- G4Exception-START -------- EEEE -------
*** G4Exception : ABLA
issued by : G4AblaDataFile::readData()
Data missing: could not find ABLA data file in /mnt/1c05098b-4371-462d-bda4-30f438a4ea53/liqin/software/geant4/geant4-v11.4.0-install/share/Geant4/data/G4ABLA3.3defined by environment variable G4ABLADATA

*** Fatal Exception *** core dump ***
G4WT294 > **** Step information is not available at this moment
G4WT294 >
-------- EEEE -------- G4Exception-END --------- EEEE -------

G4WT294 >
G4WT294 > *** G4Exception: Aborting execution ***
srun: error: compute1: task 0: Aborted (core dumped)

Could you please tell me what caused this?

If you could help me solve the aforementioned problems, I would be extremely grateful.
Best wishes.

I’d first take care of the following:

  1. Physics lists should not be defined in Run or RunAction

There are ways to do it but not for a simple simulation like this. You want to pass the physics list to the run manager instance instead. See, for example, B1.cc

  1. Move analysisManager->OpenFile("yield.root"); to BeginOfRunAction

See B5 for what this looks like (as well as CloseFIle)

  1. ScaleH1 timing

analysisManager->ScaleH1(i, scale); in your EndOfRunAction needs to happen after analysisManager->Write(); or it will attempt to scale an empty histogram. Also Geant handles ntuple merging for you as is so you don’t need to check if you are the master.

I’d start with those 3 things first. But more generally is this for learning or working with? In either case, the Activation example might be good to look at for ideas.