Multithreading UI manager issue

Hello everyone,

In my application I am trying to build a bundle of scintillating fibers with SiPM matrices at each end. The simulation works fine when run in singlethreaded mode, but I wanted to adapt it to run it multithreaded to save time on simulation runs. I adapted the run manager and action initialization classes for multithreaded, but when running the simulation I get the following error:

**************************************************************
 Geant4 version Name: geant4-11-02-patch-01 [MT]   (16-February-2024)
                       Copyright : Geant4 Collaboration
                      References : NIM A 506 (2003), 250-303
                                 : IEEE-TNS 53 (2006), 270-278
                                 : NIM A 835 (2016), 186-225
                             WWW : http://geant4.org/
**************************************************************

Visualization Manager instantiating with verbosity "warnings (3)"...
Visualization Manager initialising...
Registering graphics systems...
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
[1]    30149 IOT instruction (core dumped)  ./sim gpsSr.mac

while trying to run it using the following macro:

/run/numberOfThreads 16
/run/initialize

/process/had/rdm/thresholdForVeryLongDecayTime 1.0e+60 year

/gps/particle ion
/gps/ion 38 90 0 0

/gps/pos/type Volume 
/gps/pos/shape Cylinder
/gps/pos/centre 0. 0. 12. cm
/gps/pos/radius 0.8 cm
/gps/pos/halfz 6. cm

/gps/ang/type iso

/run/beamOn 100

I am new to multithreading, so I do not know if this is caused by faulty construction of the geometry, or if it’s something caused in the main simulation file. I will attach the sim.cc and the construction.cc responsible for the geometry.

#include <iostream>

#include "G4RunManager.hh"
#include "G4UIExecutive.hh"
#include "G4VisManager.hh"
#include "G4VisExecutive.hh"
#include "G4UImanager.hh"
#include "G4MTRunManager.hh"

#include "construction.hh"
#include "physics.hh"
#include "action.hh"

int main(int argc, char** argv) {
    #ifdef G4MULTITHREADED
        G4MTRunManager *runManager = new G4MTRunManager();
    #else
        G4RunManager *runManager = new G4RunManager();
    #endif

    runManager->SetUserInitialization(new myDetectorConstruction());
    runManager->SetUserInitialization(new myPhysicsList());
    runManager->SetUserInitialization(new myActionInitialization());
    
    G4UIExecutive *uiExec = 0;

    if(argc == 1) {
        uiExec = new G4UIExecutive(argc, argv);
    }

    G4VisManager *visManager = new G4VisExecutive();
    visManager->Initialise();

    G4UImanager *uiManager = G4UImanager::GetUIpointer();

    if(uiExec) {
        uiManager->ApplyCommand("/control/execute vis.mac");
        uiExec->SessionStart();
    }
    else {
        G4String command = "/control/execute ";
        G4String fileName = argv[1];
        uiManager->ApplyCommand(command+fileName);
    }

    return 0;
}
#include "construction.hh"

myDetectorConstruction::myDetectorConstruction() {
    xWorld = 0.5*m;
    yWorld = 0.5*m;
    zWorld = 0.5*m;

    nCols = 8;
    nRows = 8;

    DefineMaterial();
}

myDetectorConstruction::~myDetectorConstruction() {

}

G4LogicalVolume *myDetectorConstruction::GetScoringVolume() const {
    return fScoringVolume;
}

void myDetectorConstruction::DefineMaterial() {
    G4NistManager *nist = G4NistManager::Instance();
    std::vector<G4double> energy = {1.239841939*eV/0.9, 1.239841939*eV/0.2};


    // Defining the world material
    worldMat = nist->FindOrBuildMaterial("G4_AIR");

    G4MaterialPropertiesTable *mptWorld = new G4MaterialPropertiesTable();
    std::vector<G4double> rindexAir = {1.0, 1.0};
    mptWorld->AddProperty("RINDEX", energy, rindexAir);
    worldMat->SetMaterialPropertiesTable(mptWorld);


    // Defining the scintillator material
    detMat = new G4Material("detMat", 1.06*g/cm3, 2);

    detMat->AddElement(nist->FindOrBuildElement("C"), 50.00*perCent);
    detMat->AddElement(nist->FindOrBuildElement("H"), 50.00*perCent);

    std::vector<G4double> scintEnergydetMat = {1.239841939*eV/0.9, 1.239841939*eV/0.425, 1.239841939*eV/0.2};
    std::vector<G4double> rindexdetMat = {1.60, 1.60, 1.60};
    std::vector<G4double> scintFracdetMat = {0.01, 1.0, 0.01};

    G4MaterialPropertiesTable *mptdetMat = new G4MaterialPropertiesTable();
    mptdetMat->AddProperty("RINDEX", scintEnergydetMat, rindexdetMat);
    mptdetMat->AddProperty("SCINTILLATIONCOMPONENT1", scintEnergydetMat, scintFracdetMat);
    mptdetMat->AddConstProperty("SCINTILLATIONYIELD", 10.44/keV);
    mptdetMat->AddConstProperty("RESOLUTIONSCALE", 1.0);
    mptdetMat->AddConstProperty("SCINTILLATIONTIMECONSTANT1", 3.3*ns);
    mptdetMat->AddConstProperty("SCINTILLATIONYIELD1", 1.);

    detMat->SetMaterialPropertiesTable(mptdetMat);


    // Defining the case material
    caseMat = new G4Material("caseMat", 0.855*g/cm3, 2);

    caseMat->AddElement(nist->FindOrBuildElement("C"), 33.33*perCent);
    caseMat->AddElement(nist->FindOrBuildElement("H"), 66.67*perCent);


    Si = nist->FindOrBuildMaterial("G4_Si");
}

void myDetectorConstruction::ConstructScintillator() {
    G4double radScint = 0.5*mm, lenScint = 10.*cm, posScint = 12.*cm, sideSIPM = 0.5*mm, lenSIPM = 0.1*mm, widthCase = 0.25*cm;

    // Constructing the scintillating fibers
    solidScintillator = new G4Tubs("solidScintillator", 0.*cm, radScint, lenScint, 0.*deg, 360.*deg);
    logicScintillator = new G4LogicalVolume(solidScintillator, detMat, "logicalScintillator");
    for(G4int i = 0; i < nRows; i++) {
        for(G4int j = 0; j < nCols; j++) {
            physScintillator = new G4PVPlacement(0, G4ThreeVector(-radScint*nRows+(i+0.5)*mm, -radScint*nCols+(j+0.5)*mm, posScint), logicScintillator, "physScintillator", logicWorld, false, j+i*nCols, true);
        }
    }
    

    // Constructing the SIPM matrices
    solidSIPM = new G4Box("solidSIPM", sideSIPM, sideSIPM, lenSIPM);
    logicSIPM = new G4LogicalVolume(solidSIPM, Si, "logicSIPM");
    for(G4int i = 0; i < nRows; i++) {
        for(G4int j = 0; j < nCols; j++) {
            physSIPM1 = new G4PVPlacement(0, G4ThreeVector(-sideSIPM*nRows+(i+0.5)*mm, -sideSIPM*nCols+(j+0.5)*mm, posScint+lenScint+lenSIPM), logicSIPM, "physSIPM1", logicWorld, false, j+i*nCols, true);
            physSIPM2 = new G4PVPlacement(0, G4ThreeVector(-sideSIPM*nRows+(i+0.5)*mm, -sideSIPM*nCols+(j+0.5)*mm, posScint-lenScint-lenSIPM), logicSIPM, "physSIPM2", logicWorld, false, j+i*nCols, true);
        }
    }


    // Constructing the casing of the detector
    auto              *solidCase1  = new G4Box("solidCase1", nRows*radScint, widthCase, lenScint+2*lenSIPM); 
    G4LogicalVolume   *logicCase1  = new G4LogicalVolume(solidCase1, caseMat, "logicalCase1");
    G4VPhysicalVolume *physCase11  = new G4PVPlacement(0, G4ThreeVector(0., nCols*radScint+widthCase, posScint), logicCase1, "physCase11", logicWorld, false, 0, true);
    G4VPhysicalVolume *physCase12  = new G4PVPlacement(0, G4ThreeVector(0., -nCols*radScint-widthCase, posScint), logicCase1, "physCase12", logicWorld, false, 0, true);
    auto              *solidCase2  = new G4Box("solidCase2", widthCase, nCols*radScint+2*widthCase, lenScint+2*lenSIPM); 
    G4LogicalVolume   *logicCase2  = new G4LogicalVolume(solidCase2, caseMat, "logicalCase2");
    G4VPhysicalVolume *physCase21  = new G4PVPlacement(0, G4ThreeVector(nRows*radScint+widthCase, 0., posScint), logicCase2, "physCase21", logicWorld, false, 0, true);
    G4VPhysicalVolume *physCase22  = new G4PVPlacement(0, G4ThreeVector(-nRows*radScint-widthCase, 0., posScint), logicCase2, "physCase22", logicWorld, false, 0, true);
    auto              *solidCase3  = new G4Box("solidCase3", nRows*radScint+2*widthCase, nCols*radScint+2*widthCase, widthCase); 
    G4LogicalVolume   *logicCase3  = new G4LogicalVolume(solidCase3, caseMat, "logicalCase3");
    G4VPhysicalVolume *physCase31  = new G4PVPlacement(0, G4ThreeVector(0., 0., posScint-lenScint-2*lenSIPM-widthCase), logicCase3, "physCase31", logicWorld, false, 0, true);
    G4VPhysicalVolume *physCase32  = new G4PVPlacement(0, G4ThreeVector(0., 0., posScint+lenScint+2*lenSIPM+widthCase), logicCase3, "physCase32", logicWorld, false, 0, true);
    
    fScoringVolume = logicScintillator;
}

G4VPhysicalVolume *myDetectorConstruction::Construct() {
    // Defining the world
    solidWorld = new G4Box("solidWorld", xWorld, yWorld, zWorld);
    logicWorld = new G4LogicalVolume(solidWorld, worldMat, "logicWorld");
    physWorld = new G4PVPlacement(0, G4ThreeVector(0., 0., 0.), logicWorld, "physWorld", 0, false, 0, true);

    ConstructScintillator();

    return physWorld;
}

void myDetectorConstruction::ConstructSDandField() {
    mySensitiveDetector *sensDet = new mySensitiveDetector("SensitiveDetector");

    logicScintillator->SetSensitiveDetector(sensDet);
}

I am running GEANT4 MT version 11.2.1 on Ubuntu. The singlethreaded version is 11.2.0 and works fine, as mentioned above. Thank you in advance!

Difficult to say what could be going wrong here, so I’d suggest running this through the gdb debugger so you can get a backtrace of exactly where the bad_alloc exception is coming from. It should be sufficient to do

$ gdb --args ./sim gpsSr.mac
... loads ...
(gdb) run
... runs, fails ...
(gdb) bt
... backtrace prints ...

Hi and thank you for replying! I have used the debugger to see where the exception is thrown and running the backtrace, I get the following:

(gdb) run
Starting program: /home/daniel/Work/GEANT4/scintillating-tile/build/sim gpsSr.mac
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

**************************************************************
 Geant4 version Name: geant4-11-02-patch-01 [MT]   (16-February-2024)
                       Copyright : Geant4 Collaboration
                      References : NIM A 506 (2003), 250-303
                                 : IEEE-TNS 53 (2006), 270-278
                                 : NIM A 835 (2016), 186-225
                             WWW : http://geant4.org/
**************************************************************

Visualization Manager instantiating with verbosity "warnings (3)"...
Visualization Manager initialising...
Registering graphics systems...
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc

Program received signal SIGABRT, Aborted.
__pthread_kill_implementation (no_tid=0, signo=6, threadid=140737226202240) at ./nptl/pthread_kill.c:44
44	./nptl/pthread_kill.c: No such file or directory.
(gdb) bt
#0  __pthread_kill_implementation (no_tid=0, signo=6, 
    threadid=140737226202240) at ./nptl/pthread_kill.c:44
#1  __pthread_kill_internal (signo=6, threadid=140737226202240)
    at ./nptl/pthread_kill.c:78
#2  __GI___pthread_kill (threadid=140737226202240, signo=signo@entry=6)
    at ./nptl/pthread_kill.c:89
#3  0x00007ffff5a42476 in __GI_raise (sig=sig@entry=6)
    at ../sysdeps/posix/raise.c:26
#4  0x00007ffff5a287f3 in __GI_abort () at ./stdlib/abort.c:79
#5  0x00007ffff5ea2b9e in ?? ()
   from /lib/x86_64-linux-gnu/libstdc++.so.6
#6  0x00007ffff5eae20c in ?? ()
   from /lib/x86_64-linux-gnu/libstdc++.so.6
#7  0x00007ffff5eae277 in std::terminate() ()
   from /lib/x86_64-linux-gnu/libstdc++.so.6
#8  0x00007ffff5eae4d8 in __cxa_throw ()
   from /lib/x86_64-linux-gnu/libstdc++.so.6
#9  0x00007ffff5ea27ac in ?? ()
   from /lib/x86_64-linux-gnu/libstdc++.so.6
#10 0x00007ffff7b088ae in void std::vector<G4VModelFactory<G4VFilter<G4VDigi> >*, std::allocator<G4VModelFactory<G4VFilter<G4VDigi> >*> >::_M_realloc_insert<G4VModelFactory<G4VFilter<G4VDigi> >* const&>(__gnu_cxx::__normal_iterator<G4VModelFactory<G4VFilter<G4VDigi> >**, std::vector<G4VModelFactory<G4VFilter<G4VDigi> >*, std::allocator<G4VModelFactory<G4VFilter<G4VDigi> >*> > >, G4VModelFactory<G4VFilter<G4VDigi> >* const&) ()
   from /home/daniel/Software/geant4/geant4-v11.2.1-install-mt/lib/libG4vis_management.so
#11 0x00007ffff7afdb9e in G4VisManager::RegisterModelFactory(G4VModelFactory<G4VFilter<G4VDigi> >*) ()
   from /home/daniel/Software/geant4/geant4-v11.2.1-install-mt/lib/libG4vis_management.so
#12 0x0000555555563a60 in G4VisExecutive::RegisterModelFactories() ()
#13 0x00007ffff7b00ef4 in G4VisManager::Initialise() ()
   from /home/daniel/Software/geant4/geant4-v11.2.1-install-mt/lib/libG4vis_management.so
#14 0x0000555555562412 in main ()

From what I can understand, there is an issue with the G4 visualization manager/executive class and that might lead to some weird action that ends the process before the threads are killed. If I can provide more info about the issue let me know, thank you!

Thanks! As this appears to be something in the vis system, I’ve moved it to the relevant category so more of the experts here (@Allison, @gybarran) can take a look.

Works in Serial/sequential mode with 11.2.0. Doesn’t work with MT with 11.2.1.

What has changed? Certainly not the code where it crashes. Have you changed compiler? Perhaps your system libraries are not compatible with the new compiler? Make sure your system is up to date and your compiler is consistent with it.

If that’s not it, then I’m stumped!

Hi Daniel. Any progress on this?
John

Hi, sorry for not replying, have been caught up with stuff. As a last resort, this week I have reinstalled my Ubuntu distribution, I reinstalled GEANT4 and also re-did the project, modifying the stuff associated to CMake and somehow that solved the issue and the simulation runs now. Thank you for supporting me and giving me ideas on what to do!

OK, Daniel. Glad it’s working for you now. Good to know. Helps us understand users’ issues.

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