TkN 2.1
Toolkit for Nuclei
tkn-thread-example.cpp
1#include <thread>
2#include <getopt.h>
3#include <random>
4
5#include "tkmanager.h"
6
7#ifdef HAS_ROOT
8#include "TH2F.h"
9#include "TFile.h"
10#include "TROOT.h"
11#endif
12
13#define no_argument 0
14#define required_argument 1
15#define optional_argument 2
16
17using namespace tkn;
18using namespace std;
19
20#ifdef HAS_ROOT
21TH2F *hNucChart = nullptr;
22TH2F *hNucChartBetaminus = nullptr;
23TH2F *hNucChartBetaplus = nullptr;
24TH2F *hNucChartStable = nullptr;
25TH1F *hRandExcitedState = nullptr;
26#endif
27
28void a_thread(int ithread, long NEvents);
29void print_help();
30
31// To compile this code, use: g++ tkn-thread-example.cpp -o tkn-thread `tkn-config --cflags --linklibs`
32
33void print_help() {
34 glog << blue << high_intensity << " *******************************************" << do_endl;
35 glog << blue << high_intensity << " *** tkn-thread-example user-guide ***" << do_endl;
36 glog << blue << high_intensity << " *******************************************" << do_endl;
37 glog << do_endl;
38 glog << "this utility allows to test the multi thread compatibility" << do_endl;
39 glog << do_endl;
40 glog << "supported options:" << do_endl;
41 glog << " --evts N number of random nuclei to process (default 1e6)" << do_endl;
42 glog << " --workers N number of workers to be used (default 1)" << do_endl;
43 glog << do_endl;
44}
45
46int main(int argc, char **argv) {
47
48 int option_index = 0;
49 static struct option long_options[] = {
50 {"evts", required_argument, nullptr, 'e'},
51 {"workers", required_argument, nullptr, 'w'},
52 {"help", no_argument, nullptr, 'h'},
53 {nullptr, 0, nullptr, 0}};
54
55 long NEvents=1e6;
56 int NWorkers = 1;
57
58 while (true) {
59 int c = getopt_long (argc, argv, "ewh", long_options, &option_index);
60 if (c == -1) break;
61 switch (c) {
62 case 'e':
63 NEvents = atof(optarg);
64 break;
65 case 'w':
66 NWorkers = atoi(optarg);
67 break;
68 case 'h':
69 print_help();
70 exit(EXIT_SUCCESS);
71 }
72 }
73 cout << "***********************************************************************************" << endl;
74 cout << "* Randomly produce a nucleus and extract a random excited state in multi thread *" << endl;
75 cout << "***********************************************************************************" << endl;
76 cout<<endl;
77
78#ifdef HAS_ROOT
79 ROOT::EnableImplicitMT();
80 hNucChart = new TH2F("NucChart","NucChart",90,0,180,60,0,120);
81 hNucChartBetaminus = new TH2F("NucChartBetaminus","NucChartBetaminus",90,0,180,60,0,120);
82 hNucChartBetaplus = new TH2F("NucChartBetaplus","NucChartBetaplus",90,0,180,60,0,120);
83 hNucChartStable = new TH2F("NucChartStable","NucChartStable",90,0,180,60,0,120);
84 hRandExcitedState = new TH1F("RandExcitedState","RandExcitedState",20000,0,20000);
85#endif
86
87 cout << "Nevents : " << NEvents << endl;
88 cout << "N workers: " << NWorkers << endl;
89
90 // to remove printouts due to empty level schemes
91 glog.set_warnings(false);
92
93 auto tsload = std::chrono::high_resolution_clock::now();
94
95 // preload one all level schemes for fair multi thread comparison
96 gmanager->preload_level_schemes(true);
97 cout<<endl;
98
99 auto tstart = std::chrono::high_resolution_clock::now();
100
101 vector<thread> threads;
102 threads.reserve(NWorkers);
103 for(int i=0 ; i<NWorkers ; i++) {
104 threads.emplace_back(thread(a_thread, i, NEvents/NWorkers));
105 }
106 for(int i=0 ; i<NWorkers ; i++) {
107 threads.at(i).join();
108 }
109
110#ifdef HAS_ROOT
111 auto *fout = new TFile("tkn-thread.root","recreate");
112 hNucChart->Write();
113 hNucChartBetaminus->Write();
114 hNucChartBetaplus->Write();
115 hNucChartStable->Write();
116 hRandExcitedState->Write();
117 glog << info << "tkn-thread.root created with content: " << do_endl;
118 fout->ls();
119 fout->Close();
120#endif
121
122 auto tstop = std::chrono::high_resolution_clock::now();
123 auto dtload = std::chrono::duration<double, std::milli>(tstart-tsload).count() * 0.001;
124 auto dt_process = std::chrono::duration<double, std::milli>(tstop-tstart).count() * 0.001;
125 auto dt = std::chrono::duration<double, std::milli>(tstop-tsload).count() * 0.001;
126
127 cout<<endl;
128 cout << fixed << setprecision(4) << "CPU time to load the full db : " << dtload << " s\n";
129 cout << fixed << setprecision(4) << "CPU time to process the events: " << dt_process << " s\n";
130 cout << fixed << setprecision(4) << "Total CPU time : " << dt << " s\n";
131}
132
133void a_thread(int ithread, long NEvents) {
134
135 // Create a random number generator engine
136 std::random_device rd;
137 std::mt19937 gen(rd());
138
139 // Create a uniform integer distribution on the number of nuclei
140 std::uniform_int_distribution<> dist_nuc(0, gmanager->get_nuclei().size()-1);
141
142 int Fact = NEvents/100.;
143 for(long entry=0 ; entry<NEvents ; entry++) {
144 if(ithread==0 && entry%Fact==0) {
145 cout<<"\r"<<"Analysis progress : "<<setw(3)<<setprecision(3)<<(double)entry/(double)NEvents*100<<" %"<<flush;
146 }
147 long inuc = dist_nuc(gen);
148 auto nuc = gmanager->get_nuclei().at(inuc);
149 if(nuc->get_level_scheme()->get_levels().size()>1) {
150
151 // Create a uniform integer distribution on the number of levels
152 std::uniform_int_distribution<> dist_lev(0, nuc->get_level_scheme()->get_levels().size()-1);
153
154 long ilvl = dist_lev(gen);
155 double elev = nuc->get_level_scheme()->get_levels().at(ilvl)->get_energy(tkn::tkunit_manager::keV,true);
156#ifdef HAS_ROOT
157 hNucChart->Fill(nuc->get_n(),nuc->get_z());
158 if(nuc->has_property("QbetaMinus") && nuc->get("QbetaMinus")->get_value()>0) hNucChartBetaminus->Fill(nuc->get_n(),nuc->get_z());
159 if(nuc->has_property("QpositronEmission") && nuc->get("QpositronEmission")->get_value()>0) hNucChartBetaplus->Fill(nuc->get_n(),nuc->get_z());
160 if(nuc->is_stable()) hNucChartStable->Fill(nuc->get_n(),nuc->get_z());
161 if(elev>0) hRandExcitedState->Fill(elev);
162#endif
163 }
164 }
165}
Definition: tklog.cpp:39
tklog & info(tklog &log)
Definition: tklog.h:336
tklog & do_endl(tklog &log)
Definition: tklog.h:235
tklog & blue(tklog &log)
Definition: tklog.h:270
tklog & high_intensity(tklog &log)
Colors.
Definition: tklog.h:255