← Documentation
ADS-IDAC Engine 5.0.0
BranchCluster.cpp
Go to the documentation of this file.
1// BranchCluster.cpp: implementation of the BranchCluster class.
2//
4#if defined(_WIN32)
5#include <direct.h>
6#include <boost/serialization/export.hpp>
7#else
8#include <sys/stat.h>
9#include <sys/types.h>
10#endif
11
12#include "BranchCluster.h"
13#include "BranchRecord.h"
14#include "../Scheduler/Scheduler.h"
15#include <filesystem>
16#include <functional>
17#include <sstream>
18#include "../Global/SimulationContext.h"
19#include <boost/archive/binary_oarchive.hpp>
20#include <boost/archive/binary_iarchive.hpp>
21#include "../Global/PEOutput.h"
22BOOST_CLASS_EXPORT_IMPLEMENT(BranchCluster)
23using namespace std;
24
25namespace fs = std::filesystem;
26
27
29// Construction/Destruction
31
33{
34// ID_of_the_mother_branch = -1;
36 Current_branch_num = -1; //the current branch in the run time
39// ID_of_the_mother_cluster = -1;
41}
42
44{
45 this->clearBranchCluster();
46}
48 all_branch.clear();
49}
52
54{
55 for(auto &p : all_branch){
56 p->calculateProbability();
57 }
58}
59
60// Writes one PE node per branch of this cluster under the PE directory strDirName.
61void BranchCluster::savePENodeToFile(string strDirName)
62{
63 int num_subfolder, branch_no, branch_no1, num_of_child;
64 string full_file_name, branch_name;
65 BranchProbability *current_branch_pt;
66//
67 //do the following for all branches within this branch cluster
68 //Note: each branchProbability within a branchCluster is a PE node
69 for(branch_no = 0; branch_no < this->all_branch.size(); branch_no++){
70 current_branch_pt = this->all_branch.at(branch_no).get();//each element within all_branch is a PE Node
71
72 // The node's content is built in memory first. MPI clients re-save the
73 // whole lineage after every sequence, so nearly every file is a
74 // byte-identical rewrite. The write is skipped when this process has
75 // already put identical bytes on disk for this PE id; the final disk
76 // state is the same because any content change (new child link, type
77 // flip) changes the signature.
78 std::ostringstream oss;
79 //
80 branch_name = "PE_";
81 branch_name += to_string(current_branch_pt->getIDOfThisBranch());
82 //TNode
83 oss << branch_name << ' ' //Name
84 << this->getTimeAtWhichThisEventHappen() << ' ' //Time
85 << current_branch_pt->getIDOfThisBranch() << ' '//ID
86 << this->getIDOfTheMotherBranch() << " 0 " //Mother ID & level
87 << sim::Branch::Branch << ' ' << current_branch_pt->getIDOfThisBranch() << ' ' //Type & Type Sequence
88 << this->getProbability() << "\n PE_BRANCH " //node probability & node type
89 << this->all_branch.size() << ' ' //total branch no
90 << branch_no << ' ' << this->getIDOfTheMotherBranch() << " 0 " //current branch no, mother branch no & Child Info ID
91 << this->all_branch.at(0)->getIDOfThisBranch() << '\n'; //First Sibling sequence
92
93 if(current_branch_pt->getTypeOfChild() == sim::Branch::Branch){
94 //info of children
95 num_of_child = current_branch_pt->child_IDs.size();
96 oss << num_of_child << ' ';
97
98 for(branch_no1 = 0; branch_no1 < num_of_child; branch_no1++){
99 oss << sim::Branch::Branch << ' ';
100 }
101 oss << '\n';
102 oss << num_of_child << ' ';
103 for(branch_no1 = 0; branch_no1 < num_of_child; branch_no1++){
104 oss << current_branch_pt->child_IDs.at(branch_no1) << ' ';
105 }
106 oss << '\n';
107 //info of current branch cluster
108 if (branch_no == 0){
109 oss << this->all_branch.size() << ' ';
110 for(branch_no1 = 0; branch_no1 < this->all_branch.size(); branch_no1++){
111 oss << this->all_branch.at(branch_no1)->getProbability() << ' ';
112 }
113 oss << '\n' << this->all_branch.size() << '\n';
114 for(branch_no1 = 0; branch_no1 < this->all_branch.size(); branch_no1++){
115 this->all_branch.at(branch_no1)->saveInfoToFile(oss);
116 oss << '\n';
117 }
118 }
119 else{
120 oss << "0\n0\n";
121 }
122 }
123 else{//sim::Branch::EndState
124 //info of children
125 oss << "1 " << sim::Branch::EndState << '\n';
126 oss << "1 " << current_branch_pt->getIDOfTheChildBranchCluster() << '\n';
127 if (branch_no == 0){
128 oss << this->all_branch.size() << ' ';
129 for(branch_no1 = 0; branch_no1 < this->all_branch.size(); branch_no1++){
130 oss << this->all_branch.at(branch_no1)->getProbability() << ' ';
131 }
132 oss << '\n' << this->all_branch.size() << '\n';
133 for(branch_no1 = 0; branch_no1 < this->all_branch.size(); branch_no1++){
134 this->all_branch.at(branch_no1)->saveInfoToFile(oss);
135 oss << '\n';
136 }
137 }
138 else{
139 oss << "0\n0\n";
140 }
141 }
142
143 const std::string content = oss.str();
144 const std::pair<size_t, size_t> sig{content.size(), std::hash<std::string>{}(content)};
145 auto [state_it, first_write] = g_sim.pe_file_state.try_emplace(current_branch_pt->getIDOfThisBranch(), sig);
146 if (!first_write) {
147 if (state_it->second == sig) continue; // identical bytes already on disk
148 state_it->second = sig;
149 }
150
151 // Aggregate layout: one record appended to one file per rank, instead
152 // of one file per node. Opt-in; see Global/PEOutput.h for why (file
153 // COUNT quota, not capacity, is what bounds a long-mission DET).
156 current_branch_pt->getIDOfThisBranch(), content);
157 continue;
158 }
159
160 full_file_name = strDirName;
161 full_file_name += "PEFolder_";
162 num_subfolder = (int) current_branch_pt->getIDOfThisBranch() / g_sim.Branch_center.getSizeOfSubFolder();
163 full_file_name += to_string(num_subfolder);
164#if defined(_WIN32)
165 _mkdir(full_file_name.c_str());
166#else
167 // Creating a directory
168 if (fs::create_directories(full_file_name.c_str()) == -1)
169 cerr << "Error : " << strerror(errno) << endl;
170
171#endif
172 full_file_name += "//ZPENode_";
173 full_file_name += to_string(current_branch_pt->getIDOfThisBranch());
174 full_file_name += ".txt";
175 ofstream fout(full_file_name.c_str(), ios::out);
176 fout << content;
177 fout.close();
178 }
179}
180
181
183 string full_file_name;
184 full_file_name = g_sim.SScheduler.getPEDirectory();
185
186 savePENodeToFile(full_file_name);
187}
188
189/*void BranchCluster::saveInfoToFile(){
190 ofstream *fout;
191 bool first_branch = true;
192 int num_subfolder, branch_no;
193 char numtext[20];
194 string full_file_name, branch_name;
195 vector<BranchProbability *>::iterator all_branch_itr, all_branch_itr1;
196 for(all_branch_itr = this->all_branch.begin(); all_branch_itr != this->all_branch.end(); all_branch_itr++){
197 itoa((*all_branch_itr)->getIDOfThisBranch(), numtext, 10);
198//
199 full_file_name = g_sim.SScheduler.getPEDirectory();
200 full_file_name += "PEFolder_";
201 num_subfolder = (int) (*all_branch_itr)->getIDOfThisBranch() / g_sim.Branch_center.getSizeOfSubFolder();
202 itoa(num_subfolder, numtext, 10);
203 full_file_name += numtext;
204 _mkdir(full_file_name.c_str());
205 full_file_name += "//PE_";
206 itoa((*all_branch_itr)->getIDOfThisBranch(), numtext, 10);
207 full_file_name += numtext;
208 full_file_name += ".txt";
209 fout = new ofstream();
210 fout->open(full_file_name.c_str(), ios::out);
211 //
212 branch_name = "PE_";
213 branch_name += numtext;
214 branch_no = 0;
215 //TNode
216 *fout << branch_name << ' ' //Name
217 << this->getTimeAtWhichThisEventHappen() << ' ' //Time
218 << (*all_branch_itr)->getIDOfThisBranch() << ' ' //ID
219 << this->getIDOfThisBranchCluster() << " 0 " //Mother ID and Level
220 << sim::Branch::Branch << ' ' //Type
221 << (*all_branch_itr)->getIDOfThisBranch() //Type Sequence
222 << ' ' << this->getProbability() //Node probability
223 << " PE_BRANCH " << this->all_branch.size() //Node Type and Total branch num
224 << " 0 " << branch_no << " 0 " //current branch num, mother branch num, child info ID
225 << (*all_branch_itr)->getIDOfThisBranch() << ' '
226 << this->all_branch.size() << '\n';
227
228
229 for(all_branch_itr1 = this->all_branch.begin(); all_branch_itr1 != this->all_branch.end(); all_branch_itr1++){
230 *fout << (*all_branch_itr1)->getTypeOfChild << ' ';
231 }
232 *fout << '\n' << this->all_branch.size() << '\n';
233 for(all_branch_itr1 = this->all_branch.begin(); all_branch_itr1 != this->all_branch.end(); all_branch_itr1++){
234 *fout << (*all_branch_itr1)->getIDOfThisBranch() << ' ';
235 }
236 *fout << '\n' << this->all_branch.size() << '\n';
237 for(all_branch_itr1 = this->all_branch.begin(); all_branch_itr1 != this->all_branch.end(); all_branch_itr1++){
238 *fout << (*all_branch_itr1)->getProbability() << ' ';
239 }
240 *fout << this->all_branch.size() << '\n';
241 for(all_branch_itr1 = this->all_branch.begin(); all_branch_itr1 != this->all_branch.end(); all_branch_itr1++){
242
243 *fout << (*all_branch_itr1)->getProbability() << ' ';
244 }
245 (*all_branch_itr)->saveInfoToFile(*fout);
246 //
247 branch_no++;
248 fout->close();
249 delete fout;
250 }
251}*/
252
254}
262 bool found = false;
263 BranchProbability *branch_pt = 0;
264 auto all_branch_ritr = all_branch.rbegin();
265 while(all_branch_ritr != all_branch.rend() && !found){
266 if((*all_branch_ritr)->getIDOfThisBranch() == _id){
267 found = true;
268 branch_pt = all_branch_ritr->get();
269 }
270 all_branch_ritr++;
271 }
272 if(!found){
273 ofstream fout("err messages.txt", ios::app);
274 cout << r5pars_.timesno << "\tBranchProbability* BranchCluster::findBranch Branch_ID:" << _id
275 << " could not be found in the BranchCluster: " << this->getIDOfThisBranchCluster() << endl;
276 fout << r5pars_.timesno << "\tBranchProbability* BranchCluster::findBranch Branch_ID:" << _id
277 << " could not be found in the BranchCluster: " << this->getIDOfThisBranchCluster() << '\n';
278 fout.close();
279 }
280 return branch_pt;
281}
283 int i, num;
284 num = this->all_branch.size();
285 fout << ID_of_the_mother_branch << ' '
287 << Current_branch_num << ' '
290 << num << '\n';
291 for(i = 0; i < num; i++){
292 this->all_branch.at(i)->saveBranchProbabilityToFile(fout);
293 }
294 this->saveTimeToFile(fout);
295 this->saveProbabilityToFile(fout);
296}
298 int i, num;
304 >> num;
305 for(i = 0; i < num; i++){
306 auto all_branch_pt = make_unique<BranchProbability>();
307 all_branch_pt->retrieveBranchProbabilityFromFile(fin);
308 this->all_branch.push_back(std::move(all_branch_pt));
309 }
310 this->retrieveTimeFromFile(fin);
312}
314 for(auto &src : _bc.all_branch){
315 auto ab_pt = make_unique<BranchProbability>();
316 ab_pt->copyBranchProbability(*src);
317 this->all_branch.push_back(std::move(ab_pt));
318 }
321 Current_branch_num = _bc.getCurrentBranchNum(); //the current branch in the run time
324 this->copyProbability(_bc);
325 this->copyTime(_bc);
326}
A branching point in the DET, holding its branch alternatives.
Central dynamic event tree data structure: the branch clusters, the end states and the forks that are...
SimulationContext g_sim
Global simulation context: the single instance, defined in SimulationContext.cpp.
int getNCountForRestartRELAP5()
void setIDOfTheMotherBranch(int)
Sets the ID of the branch (PE node) this cluster hangs from.
int getIDOfMotherCluster()
void copyBranchCluster(BranchCluster &)
Deep-copies the alternatives and all scalar fields of another cluster. The copies are appended to all...
BranchProbability * findBranch(int)
Finds the alternative with the given branch ID, searching from the last alternative.
int getIDOfThisBranchCluster()
void setNCountForRestartRELAP5(long)
Stores the RELAP5 restart count (r5pars_.cncount) recorded at this branching point.
BranchCluster()
Constructs an empty cluster: mother branch and mother cluster IDs 0, cluster ID, current branch numbe...
void clearBranchCluster()
Destroys all alternatives held in all_branch.
int ID_of_the_mother_branch
void calBranchProbability()
Recomputes the conditional probability of every alternative (BranchProbability::calculateProbability ...
int ID_of_the_mother_cluster
void saveBranchClusterToFile(std::ofstream &)
Writes the cluster as text: the five ID fields, the alternative count, every alternative,...
void setIDOfThisBranchCluster(int)
void retrieveInfoFromFile(std::ifstream &)
Does nothing; the stream is not read.
void setIDOfMotherCluster(int)
Sets the ID of the cluster that contains the mother branch.
int getCurrentBranchNum()
int ID_of_this_branch_cluster
void setCurrentBranchNum(int)
Sets the index (within all_branch) of the most recently started alternative. Alternatives with a larg...
long n_count_for_restart_RELAP5
void savePENodeToFile()
Writes the PE nodes of this cluster under the scheduler's PE directory (Scheduler::getPEDirectory()).
virtual ~BranchCluster()
int getIDOfTheMotherBranch()
void retrieveBranchClusterFromFile(std::ifstream &)
Reads the text layout written by saveBranchClusterToFile and appends the alternatives it reads to all...
std::vector< std::unique_ptr< BranchProbability > > all_branch
The alternatives of this branching point; index 0 is the one the generating sequence continues on.
One alternative of a BranchCluster, i.e. one PE node of the DET.
std::vector< int > child_IDs
int getSizeOfSubFolder()
double getProbability()
Definition: Probability.cpp:27
void copyProbability(Probability &)
Definition: Probability.cpp:28
void saveProbabilityToFile(std::ofstream &)
Definition: Probability.cpp:34
void retrieveProbabilityFromFile(std::ifstream &)
Definition: Probability.cpp:39
std::string getPEDirectory()
Definition: Scheduler.cpp:604
double getTimeAtWhichThisEventHappen() const
Definition: Timp.cpp:26
void saveTimeToFile(std::ofstream &)
Definition: Timp.cpp:32
void copyTime(Time &)
Definition: Timp.cpp:30
void retrieveTimeFromFile(std::ifstream &)
Definition: Timp.cpp:36
struct @0 r5pars_
void append_record(const std::string &pe_dir, int branch_id, const std::string &content)
Append one node record to <pe_dir>ZPENodes_agg.txt.
Definition: PEOutput.h:70
constexpr int EndState
Definition: SimConstants.h:258
constexpr int Branch
Definition: SimConstants.h:257
bool aggregate_pe_output
Definition: SimConfig.h:23
Scheduler SScheduler
Simulation scheduling, parses CLI options.
std::map< int, std::pair< size_t, size_t > > pe_file_state
PE id -> (size, hash) last written by this process; an unchanged node is not rewritten.
BranchRecord Branch_center
Dynamic event tree state.