Line data Source code
1 : // DUNE DAQ modification notice:
2 : // This file has been modified from the original ATLAS dbe source for the DUNE DAQ project.
3 : // Fork baseline commit: dbe-02-12-17 (2022-05-12).
4 : // Renamed since fork: yes (from src/graphtool/segregate.cpp to apps/graphtool/segregate.cpp).
5 :
6 : /*
7 : * segregate.cpp
8 : *
9 : * Created on: 14 Jun 2016
10 : * Author: Leonidas Georgopoulos
11 : */
12 :
13 : #include "dbe/segregate.hpp"
14 : #include "dbe/dbcontroller.hpp"
15 :
16 : #include <boost/graph/connected_components.hpp>
17 : #include <boost/graph/filtered_graph.hpp>
18 :
19 : #include <array>
20 : #include <future>
21 :
22 : #define GTOOL_MAX_THREADS 10
23 :
24 : namespace dbe {
25 : namespace tool {
26 : namespace graph {
27 :
28 0 : segregated_graph_write::segregated_graph_write(std::string const& oprfx, size_t const minc, size_t const maxc)
29 0 : : this_dest_prefix(oprfx)
30 0 : , this_min_component_size(minc)
31 0 : , this_max_component_size(maxc)
32 : {
33 0 : }
34 :
35 : int
36 0 : segregated_graph_write::operator()(gtool const& tool) const
37 : {
38 0 : typedef long unsigned int t_int;
39 0 : gtool::t_graph const& G = tool.getgraph();
40 0 : std::vector<t_int> compindices(boost::num_vertices(G));
41 0 : t_int total_connected = boost::connected_components(G, &compindices[0]);
42 :
43 0 : std::vector<gtool::t_graph> components(total_connected);
44 0 : std::vector<gtool::t_registry> component_registries(total_connected);
45 :
46 : // Build the components as seperate graphs
47 0 : for (t_int vector_i = 0; vector_i != compindices.size(); ++vector_i) {
48 0 : t_int component_j = compindices[vector_i];
49 0 : std::string oname = boost::get(>ool::vertex_label::uid, G)[vector_i];
50 0 : std::string cname = boost::get(>ool::vertex_label::cname, G)[vector_i];
51 0 : gtool::add_object_and_friends(
52 0 : components[component_j], dbe::inner::dbcontroller::get({ oname, cname }), component_registries[component_j]);
53 0 : }
54 :
55 : // from the graphs built output only those that are within the range specified
56 :
57 0 : int max_punits = GTOOL_MAX_THREADS;
58 :
59 0 : std::vector<std::future<void>> punits;
60 :
61 0 : unsigned long long int c = 0;
62 :
63 0 : for (auto const& g : components) {
64 0 : size_t const component_size = g.vertex_set().size();
65 :
66 0 : if (component_size > this_min_component_size and component_size < this_max_component_size) {
67 0 : if (--max_punits) {
68 0 : std::string output_file{ this_dest_prefix + std::string("_") + std::to_string(++c) + std::string(".dot") };
69 :
70 0 : try {
71 0 : punits.push_back(std::async(std::launch::async, graph::write, g, output_file));
72 0 : } catch (std::system_error const& e) {
73 0 : if (e.code() == std::errc::resource_unavailable_try_again) {
74 :
75 0 : ERROR("Could not launch another thread", e.what(), "for file:", output_file, "try to launch in deferred");
76 :
77 0 : punits.push_back(std::async(std::launch::deferred, graph::write, g, output_file));
78 :
79 0 : WARN("File write policy change",
80 : "Program execution correction",
81 : " for file:",
82 : output_file,
83 0 : " launched in deferred");
84 :
85 : } else {
86 0 : throw e;
87 : }
88 0 : }
89 0 : } else {
90 : // The standard dictates ( C++11 ) that wait is called on the destructor
91 : // and the futures launched are either async or defered, which puts them
92 : // always in a valid state. All that is needed to do is clear the vector
93 : // of futures to initiate calling the destructors.
94 0 : punits.clear();
95 0 : max_punits = GTOOL_MAX_THREADS;
96 : }
97 : }
98 : }
99 :
100 0 : return EXIT_SUCCESS;
101 0 : }
102 :
103 : } /* namespace graph */
104 : } /* namespace tool */
105 : } /* namespace dbe */
|