Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-15 07:41:49

0001 // async_gpu_std.cpp — async CPU+GPU optical photon simulation, std-only.
0002 //
0003 // Same architecture as examples/async_gpu_launch but the GPU worker is a
0004 // plain std::thread driven by std::mutex + std::condition_variable +
0005 // std::queue, with no G4TaskGroup or G4Mutex.
0006 //
0007 // Usage:
0008 //   async_gpu_std -g apex.gdml -m run.mac [--async] [--sync] [-s SEED]
0009 
0010 #include <cstdlib>
0011 #include <cstring>
0012 #include <ctime>
0013 #include <iostream>
0014 #include <string>
0015 
0016 #include "FTFP_BERT.hh"
0017 #include "G4OpticalPhysics.hh"
0018 #include "G4VModularPhysicsList.hh"
0019 
0020 #include "G4UIExecutive.hh"
0021 #include "G4UImanager.hh"
0022 #include "G4VisExecutive.hh"
0023 
0024 #include "G4RunManager.hh"
0025 #include "G4RunManagerFactory.hh"
0026 #include "G4VUserActionInitialization.hh"
0027 
0028 #include "async_gpu_std.h"
0029 #include "sysrap/OPTICKS_LOG.hh"
0030 
0031 struct ActionInitialization : public G4VUserActionInitialization
0032 {
0033     G4App* fG4App;
0034     ActionInitialization(G4App* app) :
0035         fG4App(app)
0036     {
0037     }
0038 
0039     void BuildForMaster() const override
0040     {
0041         SetUserAction(fG4App->run_act_);
0042     }
0043 
0044     void Build() const override
0045     {
0046         SetUserAction(fG4App->prim_gen_);
0047         SetUserAction(fG4App->run_act_);
0048         SetUserAction(fG4App->event_act_);
0049         SetUserAction(fG4App->tracking_);
0050         SetUserAction(fG4App->stepping_);
0051     }
0052 };
0053 
0054 static void usage(const char* prog)
0055 {
0056     std::cerr << "Usage: " << prog
0057               << " [options]\n"
0058                  "  -g, --gdml PATH      GDML file (default: apex.gdml)\n"
0059                  "  -m, --macro PATH     Geant4 macro (default: run.mac)\n"
0060                  "  -s, --seed N         random seed (default: time())\n"
0061                  "  -i, --interactive    open interactive viewer\n"
0062                  "      --async          double-buffered async GPU (default)\n"
0063                  "      --sync           end-of-run GPU simulation\n"
0064                  "  -h, --help           show this message\n";
0065 }
0066 
0067 int main(int argc, char** argv)
0068 {
0069     OPTICKS_LOG(argc, argv);
0070 
0071     std::string gdml_file = "apex.gdml";
0072     std::string macro_name = "run.mac";
0073     long        seed = static_cast<long>(std::time(nullptr));
0074     bool        seed_set = false;
0075     bool        interactive = false;
0076     bool        sync_mode = false;
0077 
0078     for (int i = 1; i < argc; i++)
0079     {
0080         std::string a = argv[i];
0081         auto        next = [&](const char* flag) -> const char* {
0082             if (i + 1 >= argc)
0083             {
0084                 std::cerr << flag << " requires an argument\n";
0085                 std::exit(EXIT_FAILURE);
0086             }
0087             return argv[++i];
0088         };
0089 
0090         if (a == "-g" || a == "--gdml")
0091             gdml_file = next("--gdml");
0092         else if (a == "-m" || a == "--macro")
0093             macro_name = next("--macro");
0094         else if (a == "-s" || a == "--seed")
0095         {
0096             seed = std::atol(next("--seed"));
0097             seed_set = true;
0098         }
0099         else if (a == "-i" || a == "--interactive")
0100             interactive = true;
0101         else if (a == "--sync")
0102             sync_mode = true;
0103         else if (a == "--async")
0104             sync_mode = false;
0105         else if (a == "-h" || a == "--help")
0106         {
0107             usage(argv[0]);
0108             return EXIT_SUCCESS;
0109         }
0110         else
0111         {
0112             std::cerr << "unknown option: " << a << "\n";
0113             usage(argv[0]);
0114             return EXIT_FAILURE;
0115         }
0116     }
0117 
0118     CLHEP::HepRandom::setTheSeed(seed);
0119     G4cout << "Random seed: " << seed << (seed_set ? " (user)" : " (time)")
0120            << G4endl;
0121 
0122     bool enable_async = !sync_mode;
0123     G4cout << "Mode: " << (enable_async ? "ASYNC (std)" : "SYNC") << G4endl;
0124 
0125     G4VModularPhysicsList* physics = new FTFP_BERT;
0126     physics->RegisterPhysics(new G4OpticalPhysics);
0127 
0128     auto* run_mgr = G4RunManagerFactory::CreateRunManager();
0129     run_mgr->SetUserInitialization(physics);
0130 
0131     G4App* g4app = new G4App(gdml_file, enable_async);
0132 
0133     auto* actionInit = new ActionInitialization(g4app);
0134     run_mgr->SetUserInitialization(actionInit);
0135     run_mgr->SetUserInitialization(g4app->det_cons_);
0136 
0137     G4UIExecutive* uix = nullptr;
0138     G4VisManager*  vis = nullptr;
0139     if (interactive)
0140     {
0141         uix = new G4UIExecutive(argc, argv);
0142         vis = new G4VisExecutive;
0143         vis->Initialize();
0144     }
0145 
0146     G4UImanager* ui = G4UImanager::GetUIpointer();
0147     ui->ApplyCommand("/control/execute " + macro_name);
0148 
0149     if (interactive)
0150         uix->SessionStart();
0151 
0152     delete uix;
0153     return EXIT_SUCCESS;
0154 }