Back to home page

EIC code displayed by LXR

 
 

    


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

0001 // async_gpu_launch.cpp — Async CPU+GPU optical photon simulation example
0002 //
0003 // Demonstrates double-buffered async GPU processing where the CPU event
0004 // loop continues while the GPU processes accumulated gensteps in batches.
0005 //
0006 // Usage:
0007 //   async_gpu_launch -g apex.gdml -m run.mac [--async] [--sync]
0008 //
0009 // Default is --async.  Use --sync for the original end-of-run GPU mode.
0010 
0011 #include <string>
0012 
0013 #include <argparse/argparse.hpp>
0014 
0015 #include "FTFP_BERT.hh"
0016 #include "G4OpticalPhysics.hh"
0017 #include "G4VModularPhysicsList.hh"
0018 
0019 #include "G4UIExecutive.hh"
0020 #include "G4UImanager.hh"
0021 #include "G4VisExecutive.hh"
0022 
0023 #include "async_gpu_launch.h"
0024 #include "config.h"
0025 #include "sysrap/OPTICKS_LOG.hh"
0026 
0027 #include "G4RunManager.hh"
0028 #include "G4RunManagerFactory.hh"
0029 #include "G4VUserActionInitialization.hh"
0030 
0031 using namespace std;
0032 
0033 struct ActionInitialization : public G4VUserActionInitialization
0034 {
0035     G4App* fG4App;
0036 
0037     ActionInitialization(G4App* app) :
0038         G4VUserActionInitialization(),
0039         fG4App(app)
0040     {
0041     }
0042 
0043     void BuildForMaster() const override
0044     {
0045         SetUserAction(fG4App->run_act_);
0046     }
0047 
0048     void Build() const override
0049     {
0050         SetUserAction(fG4App->prim_gen_);
0051         SetUserAction(fG4App->run_act_);
0052         SetUserAction(fG4App->event_act_);
0053         SetUserAction(fG4App->tracking_);
0054         SetUserAction(fG4App->stepping_);
0055     }
0056 };
0057 
0058 int main(int argc, char** argv)
0059 {
0060     OPTICKS_LOG(argc, argv);
0061 
0062     argparse::ArgumentParser program("async_gpu_launch", "0.0.0");
0063 
0064     string gdml_file, macro_name;
0065     bool   interactive;
0066 
0067     program.add_argument("-g", "--gdml")
0068         .help("path to GDML file")
0069         .default_value(string("apex.gdml"))
0070         .nargs(1)
0071         .store_into(gdml_file);
0072 
0073     program.add_argument("-m", "--macro")
0074         .help("path to G4 macro")
0075         .default_value(string("run.mac"))
0076         .nargs(1)
0077         .store_into(macro_name);
0078 
0079     program.add_argument("-c", "--config")
0080         .help("config file name (without .json extension)")
0081         .default_value(string(""))
0082         .nargs(1);
0083 
0084     program.add_argument("-i", "--interactive").help("open interactive viewer").flag().store_into(interactive);
0085 
0086     program.add_argument("-s", "--seed").help("fixed random seed").scan<'i', long>();
0087 
0088     program.add_argument("--async").help("use async double-buffered GPU processing (default)").flag();
0089 
0090     program.add_argument("--sync").help("use synchronous end-of-run GPU processing").flag();
0091 
0092     try
0093     {
0094         program.parse_args(argc, argv);
0095     }
0096     catch (const exception& err)
0097     {
0098         cerr << err.what() << endl;
0099         cerr << program;
0100         return EXIT_FAILURE;
0101     }
0102 
0103     // Seed
0104     long seed;
0105     if (program.is_used("--seed"))
0106         seed = program.get<long>("--seed");
0107     else
0108         seed = static_cast<long>(time(nullptr));
0109     CLHEP::HepRandom::setTheSeed(seed);
0110     G4cout << "Random seed: " << seed << G4endl;
0111 
0112     // Mode: async by default, sync if --sync is given
0113     bool enable_async = !program.get<bool>("--sync");
0114     G4cout << "Mode: " << (enable_async ? "ASYNC" : "SYNC") << G4endl;
0115 
0116     // Physics
0117     G4VModularPhysicsList* physics = new FTFP_BERT;
0118     physics->RegisterPhysics(new G4OpticalPhysics);
0119 
0120     auto* run_mgr = G4RunManagerFactory::CreateRunManager();
0121     run_mgr->SetUserInitialization(physics);
0122 
0123     // Application
0124     G4App* g4app = new G4App(gdml_file, enable_async);
0125 
0126     ActionInitialization* actionInit = new ActionInitialization(g4app);
0127     run_mgr->SetUserInitialization(actionInit);
0128     run_mgr->SetUserInitialization(g4app->det_cons_);
0129 
0130     // UI
0131     G4UIExecutive* uix = nullptr;
0132     G4VisManager*  vis = nullptr;
0133 
0134     if (interactive)
0135     {
0136         uix = new G4UIExecutive(argc, argv);
0137         vis = new G4VisExecutive;
0138         vis->Initialize();
0139     }
0140 
0141     G4UImanager* ui = G4UImanager::GetUIpointer();
0142     ui->ApplyCommand("/control/execute " + macro_name);
0143 
0144     if (interactive)
0145         uix->SessionStart();
0146 
0147     delete uix;
0148     return EXIT_SUCCESS;
0149 }