Dear G4 maintainers, I am having an issue with G4 and accessing its G4cout streams on Mac OS X with multithreading activated. I am developing a software interfacing Geant4 for the simulation of interactions. My framework allows control of its verbosity. To keep G4 in line with this verbosity, we suppress the G4cout streams for some of our verbosity levels by setting the stream's failbit: /** * @brief Suppress an stream from writing any output * @param stream The stream to suppress */ // suppress a (logging) stream // TODO [doc] rewrite as a lowercase function in a namespace? inline void SUPPRESS_STREAM(std::ostream& stream) { stream.setstate(std::ios::failbit); } /** * @brief Release an suppressed stream so it can write again * @param stream The stream to release */ // TODO [doc] rewrite as a lowercase function in a namespace? inline void RELEASE_STREAM(std::ostream& stream) { stream.clear(); } (http://en.cppreference.com/w/cpp/io/basic_ios/setstate) and apply them to the G4cout stream: // Suppress all output from G4 SUPPRESS_STREAM(G4cout); // Get UI manager for sending commands G4UImanager* ui_g4 = G4UImanager::GetUIpointer(); // ... // Release the output stream RELEASE_STREAM(G4cout); This approach works just fine on Linux (with and without MT) and Mac OS X (without MT) but the compilation fails at the linker stage when enabling multithreading on Mac OS X: Undefined symbols for architecture x86_64: "_G4cout_p", referenced from: allpix::DepositionGeant4Module::init() in DepositionGeant4Module.cpp.o allpix::DepositionGeant4Module::run(unsigned int) in DepositionGeant4Module.cpp.o "_aCountedObjectAllocator", referenced from: allpix::SensitiveDetectorActionG4::ProcessHits(G4Step*, G4TouchableHistory*) in SensitiveDetectorActionG4.cpp.o ld: symbol(s) not found for architecture x86_64 Do you have any clue what could be the issue? Please let me know if you need additional information. Best regards, Simon
Hello, I have not seen this error before and I cannot really debug it without additional information. Similar errors were seen in the past when client code is compiled without the correct flags for MT support (G4MULTITHREADED) check that the compilation of your client code has this flag enabled. However I strongly suggest you to take a look at the functionalities of G4 message streaming, that could maybe help you in obtaining what you need. In particular subclassing G4CoutDestination could give you fine grain control on how to handle messages based on their content: http://www-geant4.kek.jp/lxr/source/global/management/src/G4coutDestination.cc Andrea
Dear Andrea, thank you very much for your response, I will certainly look into G4coutDestination to improve our implementation. Concerning the issue: I build G4 using cmake -DGEANT4_BUILD_MULTITHREADED=ON .. and use Geant4's CMake module to link to the client program via FIND_PACKAGE(Geant4) ADD_DEFINITIONS(${Geant4_DEFINITIONS}) CMake tells me, that I'm picking up the correct flags when building my client code: -DG4_STORE_TRAJECTORY;-DG4VERBOSE;-DG4UI_USE;-DG4VIS_USE;-DG4MULTITHREADED Is there any other information I could provide for you to track down the issue?
Hi, so it seems that the compiler flags are setup correctly. You mention that it works w/o MT. Naive question: are you sure the G4 libraries have been rebuilt with MT support? Could it be that you are still picking up sequential build libraries by mistake? Actually the error could also mean that the client code is MT but not the G4 libs. Andrea
Dear Andrea, This scenario is unlikely in my case, since the problem occurred on our continuous integration. We use a centrally installed and maintained version of Geant4 from CVMFS which is - as I ensured with the maintainer - built with MT enabled and also identifies itself like this via Cmake. The client code is always freshly checked out from the repository and built from scratch by the GitLab CI runner. What strikes me is, that this is not a build-time but a link-time problem, so the culprit is definitely not in the mentioned G4io headers. Best regards, Simon
We found the issue today. The problem was, that unlike other Geant4 definitions, the definition "-DG4USE_STD11" is not added as definition but as compiler flag. In principle this wouldn't break things (even though it should probably be corrected) but in addition, we had an issue with setting our CMAKE_CXX_FLAGS correctly. Adding the definition manually using ADD_DEFINITION(-DG4USE_STD11) seems to fix this issue.
To extend a bit: with this flag not set, the wrong definition was selected from here: #if defined (G4MULTITHREADED) #if ( defined(__MACH__) && defined(__clang__) && defined(__x86_64__) ) || \ ( defined(__linux__) && defined(__clang__) ) #if (defined (G4USE_STD11) && __has_feature(cxx_thread_local)) # define G4ThreadLocalStatic static thread_local # define G4ThreadLocal thread_local #else # define G4ThreadLocalStatic static __thread # define G4ThreadLocal __thread #endif from global/management/include/tls.hh and AppleClang does not support __thread but only thread_local
Hello, can you please specify which version G4, Mac OS X, clang compiler are you using? The ones we support pass all our testing and the part of the code you point out do work as expected. Thank you, Andrea
Dear Andrea, I use: * Geant4 10.3.p03 * Mac OS X High Sierra 10.13 * AppleClang 9.0.0.9000038 the problem most likely doesn't appear for your tests since the definition is passed to the compiler directly via the CXX_FLAGS. However, we had a bug in our CMake which would not set the correct CXX_FLAGS but only add the definitions. My suggestion would be, not to add -DG4USE_STD11 at cmake/Modules/Geant4LibraryBuildOptions.cmake:108 but instead make it a definition and put it into cmake/Templates/Geant4Config.cmake.in Best regards, Simon
Thank you for the report and suggestion. I've forwarded it to the cmake expert in G4. For the moment let me close this since it has been solved in the client code. Andrea