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 : {
26 : namespace tool
27 : {
28 : namespace graph
29 : {
30 :
31 0 : segregated_graph_write::segregated_graph_write ( std::string const & oprfx,
32 : size_t const minc,
33 0 : size_t const maxc )
34 : :
35 0 : this_dest_prefix ( oprfx ),
36 0 : this_min_component_size ( minc ),
37 0 : this_max_component_size ( maxc )
38 : {
39 0 : }
40 :
41 0 : int segregated_graph_write::operator () ( gtool const & tool ) const
42 : {
43 0 : typedef long unsigned int t_int;
44 0 : gtool::t_graph const & G = tool.getgraph();
45 0 : std::vector<t_int> compindices ( boost::num_vertices ( G ) );
46 0 : t_int total_connected = boost::connected_components ( G, &compindices[0] );
47 :
48 0 : std::vector<gtool::t_graph> components ( total_connected );
49 0 : std::vector<gtool::t_registry> component_registries ( total_connected );
50 :
51 : // Build the components as seperate graphs
52 0 : for ( t_int vector_i = 0; vector_i != compindices.size(); ++vector_i )
53 : {
54 0 : t_int component_j = compindices[vector_i];
55 0 : std::string oname = boost::get ( >ool::vertex_label::uid, G ) [vector_i];
56 0 : std::string cname = boost::get ( >ool::vertex_label::cname, G ) [vector_i];
57 0 : gtool::add_object_and_friends (
58 0 : components[component_j],
59 0 : dbe::inner::dbcontroller::get (
60 : { oname, cname } ),
61 0 : component_registries[component_j] );
62 0 : }
63 :
64 : // from the graphs built output only those that are within the range specified
65 :
66 0 : int max_punits = GTOOL_MAX_THREADS;
67 :
68 0 : std::vector<std::future<void>> punits;
69 :
70 0 : unsigned long long int c = 0;
71 :
72 0 : for ( auto const & g : components )
73 : {
74 0 : size_t const component_size = g.vertex_set().size();
75 :
76 0 : if ( component_size > this_min_component_size
77 0 : and component_size < this_max_component_size )
78 : {
79 0 : if ( --max_punits )
80 : {
81 0 : std::string output_file
82 0 : { this_dest_prefix + std::string ( "_" ) + std::to_string ( ++c ) + std::string ( ".dot" ) };
83 :
84 0 : try
85 : {
86 0 : punits.push_back ( std::async ( std::launch::async, graph::write, g, output_file ) );
87 : }
88 0 : catch ( std::system_error const & e )
89 : {
90 0 : if ( e.code() == std::errc::resource_unavailable_try_again )
91 : {
92 :
93 0 : ERROR (
94 : "Could not launch another thread", e.what(), "for file:", output_file,
95 0 : "try to launch in deferred" );
96 :
97 0 : punits.push_back (
98 0 : std::async ( std::launch::deferred, graph::write, g, output_file ) );
99 :
100 0 : WARN (
101 : "File write policy change", "Program execution correction", " for file:",
102 0 : output_file, " launched in deferred" );
103 :
104 : }
105 : else
106 : {
107 0 : throw e;
108 : }
109 0 : }
110 0 : }
111 : else
112 : {
113 : // The standard dictates ( C++11 ) that wait is called on the destructor
114 : // and the futures launched are either async or defered, which puts them
115 : // always in a valid state. All that is needed to do is clear the vector
116 : // of futures to initiate calling the destructors.
117 0 : punits.clear();
118 0 : max_punits = GTOOL_MAX_THREADS;
119 : }
120 : }
121 : }
122 :
123 0 : return EXIT_SUCCESS;
124 0 : }
125 :
126 : } /* namespace graph */
127 : } /* namespace tool */
128 : } /* namespace dbe */
|