LDMX-Software / ldmx-sw

The Light Dark Matter eXperiment simulation and reconstruction framework.
https://ldmx-software.github.io
GNU General Public License v3.0
21 stars 20 forks source link

LTO prevents SimCore Factory from creating objects #1465

Open tomeichlersmith opened 1 week ago

tomeichlersmith commented 1 week ago

Describe the bug The SimCore plugin factory is found unaware of declared plugins when LTO is enabled.

To Reproduce Steps to reproduce the behavior:

just configure-clang-lto
just build
just fire SimCore/test/basic.py

and then you see

[ fire ] 0 fatal: [SimFactory] : An object named simcore::TrackerSD has not been declared.
  at /home/tom/code/ldmx/ldmx-sw/SimCore/include/SimCore/Factory.h:274 in make

Desired behavior It'd be cool to be able to enable LTO.

Additional context So, there are actually two different plugin factories in ldmx-sw.

The Framework/PluginFactory appears to be working when LTO is enabled since we get to attempting to create the TrackerSD. This implies that the Framework/PluginFactory was already used to declare and create the simulation processor. This causes me to focus attention on SimCore/Factory which works out since I originally designed it. I placed some printouts including the address of the Factory so we can observe the separate Factories being created for the different types. This is what I see.

denv fire SimCore/test/basic.py 
---- LDMXSW: Loading configuration --------
Factory(0x7ff2238562b8)
Factory(0x7ff2238562b8): declare simcore::BertiniAtLeastNProductsModel
Factory(0x7ff2238562b8): declare simcore::BertiniModel
Factory(0x7ff2238562b8): declare simcore::BertiniNothingHardModel
Factory(0x7ff2238562b8): declare simcore::BertiniSingleNeutronModel
Factory(0x7ff2238562b8): declare simcore::NoPhotoNuclearModel
Factory(0x7ff22383d4b0)
Factory(0x7ff22383d4b0): declare simcore::EcalSD
Factory(0x7ff22383d4b0): declare simcore::HcalSD
Factory(0x7ff22383d4b0): declare simcore::ScoringPlaneSD
Factory(0x7ff22383d4b0): declare simcore::TrackerSD
Factory(0x7ff22383d4b0): declare simcore::TrigScintSD
Factory(0x7ff223816538)
Factory(0x7ff223816538): declare simcore::generators::GeneralParticleSource
Factory(0x7ff223816538): declare simcore::generators::LHEPrimaryGenerator
Factory(0x7ff223816538): declare simcore::generators::MultiParticleGunPrimaryGenerator
Factory(0x7ff223816538): declare simcore::generators::ParticleGun
---- LDMXSW: Configuration load complete  --------
---- LDMXSW: Starting event processing --------
[ RunManager ]: Parallel worlds physics list has been registered.
[ RunManager ]: Parallel worlds have been enabled.
Factory(0x7ff2270bcfe0)
Factory(0x7ff2270bcfe0): make simcore::TrackerSD
[ fire ] 0 fatal: [SimFactory] : An object named simcore::TrackerSD has not been declared.
  at /home/tom/code/ldmx/ldmx-sw/SimCore/include/SimCore/Factory.h:274 in make
~Factory(0x7ff2270bcfe0)
~Factory(0x7ff223816538)
~Factory(0x7ff22383d4b0)
~Factory(0x7ff2238562b8)

So LTO does not prevent the declaration process from happening (which is what I assumed was going wrong), but - for some reason - a new Factory is created when attempting to create the TrackerSD instead of using the one that was already created during library-load for declaration. My guess is that I'll need to read-up on the actual meaning of static variable in the context of a static class member function. Oofdah.

I'll probably try to create a separate testing area since it takes so long to recompile after changing the templated Factory.h header. See my gist about this Factory for more links and probably where I'll put results.

EinarElen commented 1 week ago

I think you will see a similar effect if you build with clang instead of GCC

tvami commented 1 week ago

I think you will see a similar effect if you build with clang instead of GCC

Yes, I can confirm that. But takes similarly long time.

tomeichlersmith commented 1 week ago

I was able to create a very small repo reproducing the error: https://github.com/tomeichlersmith/ldmx-factory-test-bench much faster to compiler and play around with :smile: