]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/math/reporting/performance/table_helper.cpp
1 // Copyright John Maddock 2015.
2 // Use, modification and distribution are subject to the
3 // Boost Software License, Version 1.0. (See accompanying file
4 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 # pragma warning (disable : 4224)
10 #include <boost/regex.hpp>
11 #include <boost/lexical_cast.hpp>
12 #include <boost/filesystem.hpp>
13 #include <boost/filesystem/fstream.hpp>
14 #include <boost/interprocess/sync/named_mutex.hpp>
15 #include <boost/interprocess/sync/scoped_lock.hpp>
21 #include "table_helper.hpp"
23 void add_cell(boost::intmax_t val
, const std::string
& table_name
, const std::string
& row_name
, const std::string
& column_heading
);
24 void add_to_all_sections(const std::string
& id
, std::string list_name
= "performance_all_sections");
26 std::vector
<std::vector
<double> > data
;
27 std::vector
<std::tuple
<double, std::string
, std::string
, std::string
> > items_to_add
;
29 inline std::string
sanitize_string(const std::string
& s
)
31 static const boost::regex
e("[^a-zA-Z0-9]+");
32 std::string result
= boost::regex_replace(s
, e
, "_");
33 while(result
[0] == '_')
38 std::string
format_precision(double val
, int digits
)
41 ss
<< std::setprecision(digits
);
47 static std::string content
;
48 boost::filesystem::path path_to_content
;
55 boost::interprocess::named_mutex
mu(boost::interprocess::open_or_create
, "handle_test_result");
56 boost::interprocess::scoped_lock
<boost::interprocess::named_mutex
> lock(mu
);
57 boost::filesystem::path
p(__FILE__
);
60 p
/= "performance_tables.qbk";
62 if(boost::filesystem::exists(p
))
64 boost::filesystem::ifstream
is(p
);
69 char c
= static_cast<char>(is
.get());
76 // Now iterate through results and add them one at a time:
78 for(auto i
= items_to_add
.begin(); i
!= items_to_add
.end(); ++i
)
80 add_cell(static_cast<boost::uintmax_t>(std::get
<0>(*i
) / 1e-9), std::get
<1>(*i
), std::get
<2>(*i
), std::get
<3>(*i
));
83 // Write out the results:
85 boost::filesystem::ofstream
os(path_to_content
);
88 void instantiate()const
93 static const content_loader loader
;
95 void load_table(std::vector
<std::vector
<std::string
> >& table
, std::string::const_iterator begin
, std::string::const_iterator end
)
97 static const boost::regex
item_e(
103 boost::regex_token_iterator
<std::string::const_iterator
> i(begin
, end
, item_e
), j
;
108 table
.push_back(std::vector
<std::string
>());
109 boost::regex_token_iterator
<std::string::const_iterator
> k(i
->first
+ 1, i
->second
- 1, item_e
);
113 table
.back().push_back(std::string(k
->first
+ 1, k
->second
- 1));
120 std::string
save_table(std::vector
<std::vector
<std::string
> >& table
)
124 for(std::vector
<std::vector
<std::string
> >::const_iterator i
= table
.begin(), j
= table
.end(); i
!= j
; ++i
)
127 for(std::vector
<std::string
>::const_iterator k
= i
->begin(), l
= i
->end(); k
!= l
; ++k
)
138 void add_to_all_sections(const std::string
& id
, std::string list_name
)
140 std::string::size_type pos
= content
.find("[template " + list_name
+ "[]"), end_pos
;
141 if(pos
== std::string::npos
)
144 // Just append to the end:
146 content
.append("\n[template ").append(list_name
).append("[]\n[").append(id
).append("]\n]\n");
151 // Read in the all list of sections, add our new one (in alphabetical order),
152 // and then rewrite the whole thing:
154 static const boost::regex
item_e(
156 "((?=[^\\]])[^\\[\\]]*+(?0)?+)*+"
159 boost::regex_token_iterator
<std::string::const_iterator
> i(content
.begin() + pos
+ 12 + list_name
.size(), content
.end(), item_e
), j
;
160 std::set
<std::string
> sections
;
165 end_pos
= i
->first
- content
.begin();
168 sections
.insert(std::string(i
->first
+ 1, i
->second
- 1));
172 std::string new_list
= "\n";
173 for(std::set
<std::string
>::const_iterator sec
= sections
.begin(); sec
!= sections
.end(); ++sec
)
175 new_list
+= "[" + *sec
+ "]\n";
177 content
.replace(pos
+ 12 + list_name
.size(), end_pos
- pos
- 12 - list_name
.size(), new_list
);
181 std::string
get_colour(boost::uintmax_t val
, boost::uintmax_t best
)
183 if(val
<= best
* 1.2)
190 boost::intmax_t get_value_from_cell(const std::string
& cell
)
192 static const boost::regex
time_e("(\\d+)ns");
194 if(regex_search(cell
, what
, time_e
))
196 return boost::lexical_cast
<boost::uintmax_t>(what
.str(1));
201 void add_cell(boost::intmax_t val
, const std::string
& table_name
, const std::string
& row_name
, const std::string
& column_heading
)
204 // Load the table, add our data, and re-write:
206 std::string table_id
= "table_" + sanitize_string(table_name
);
207 boost::regex
table_e("\\[table:" + table_id
210 "([^\\[\\]]*+(?2)?+)*+"
215 boost::smatch table_location
;
216 if(regex_search(content
, table_location
, table_e
))
218 std::vector
<std::vector
<std::string
> > table_data
;
219 load_table(table_data
, table_location
[1].first
, table_location
[1].second
);
221 // Figure out which column we're on:
223 unsigned column_id
= 1001u;
224 for(unsigned i
= 0; i
< table_data
[0].size(); ++i
)
226 if(table_data
[0][i
] == column_heading
)
235 // Need a new column, must be adding a new compiler to the table!
237 table_data
[0].push_back(column_heading
);
238 for(unsigned i
= 1; i
< table_data
.size(); ++i
)
239 table_data
[i
].push_back(std::string());
240 column_id
= table_data
[0].size() - 1;
243 // Figure out the row:
245 unsigned row_id
= 1001;
246 for(unsigned i
= 1; i
< table_data
.size(); ++i
)
248 if(table_data
[i
][0] == row_name
)
257 // Need a new row, add it now:
259 table_data
.push_back(std::vector
<std::string
>());
260 table_data
.back().push_back(row_name
);
261 for(unsigned i
= 1; i
< table_data
[0].size(); ++i
)
262 table_data
.back().push_back(std::string());
263 row_id
= table_data
.size() - 1;
266 // Find the best result in this row:
268 boost::uintmax_t best
= (std::numeric_limits
<boost::uintmax_t>::max
)();
269 std::vector
<boost::intmax_t> values
;
270 for(unsigned i
= 1; i
< table_data
[row_id
].size(); ++i
)
276 values
.push_back(val
);
280 std::cout
<< "Existing cell value was " << table_data
[row_id
][i
] << std::endl
;
281 boost::uintmax_t cell_val
= get_value_from_cell(table_data
[row_id
][i
]);
282 std::cout
<< "Extracted value: " << cell_val
<< std::endl
;
285 values
.push_back(cell_val
);
291 for(unsigned i
= 1; i
< table_data
[row_id
].size(); ++i
)
293 std::string
& s
= table_data
[row_id
][i
];
295 if(values
[i
- 1] < 0)
301 s
+= get_colour(values
[i
- 1], best
);
303 s
+= format_precision(static_cast<double>(values
[i
- 1]) / best
, 2);
305 s
+= boost::lexical_cast
<std::string
>(values
[i
- 1]) + "ns)]";
309 // Convert back to a string and insert into content:
310 std::sort(table_data
.begin() + 1, table_data
.end(), [](std::vector
<std::string
> const& a
, std::vector
<std::string
> const& b
) { return a
[0] < b
[0]; } );
311 std::string c
= save_table(table_data
);
312 content
.replace(table_location
.position(1), table_location
.length(1), c
);
317 // Create a new table and try again:
319 std::string new_table
= "\n[template " + table_id
;
320 new_table
+= "[]\n[table:" + table_id
;
322 new_table
+= table_name
;
323 new_table
+= "\n[[Function][";
324 new_table
+= column_heading
;
327 new_table
+= row_name
;
328 new_table
+= "][[role blue 1.00[br](";
329 new_table
+= boost::lexical_cast
<std::string
>(val
);
330 new_table
+= "ns)]]]\n]\n]\n";
332 std::string::size_type pos
= content
.find("[/tables:]");
333 if(pos
!= std::string::npos
)
334 content
.insert(pos
+ 10, new_table
);
336 content
+= "\n\n[/tables:]\n" + new_table
;
338 // Add a section for this table as well:
340 std::string section_id
= "section_" + sanitize_string(table_name
);
341 if(content
.find(section_id
+ "[]") == std::string::npos
)
343 std::string new_section
= "\n[template " + section_id
+ "[]\n[section:" + section_id
+ " " + table_name
+ "]\n[" + table_id
+ "]\n[endsect]\n]\n";
344 pos
= content
.find("[/sections:]");
345 if(pos
!= std::string::npos
)
346 content
.insert(pos
+ 12, new_section
);
348 content
+= "\n\n[/sections:]\n" + new_section
;
349 add_to_all_sections(section_id
);
352 // Add to list of all tables (not in sections):
354 add_to_all_sections(table_id
, "performance_all_tables");
358 void report_execution_time(double t
, std::string table
, std::string row
, std::string heading
)
360 items_to_add
.push_back(std::make_tuple(t
, table
, row
, heading
));
361 //add_cell(static_cast<boost::uintmax_t>(t / 1e-9), table, row, heading);
364 std::string
get_compiler_options_name()
366 #if defined(BOOST_MSVC) || defined(__ICL)
375 result
+= "/arch:AVX /Ox";
379 result
+= " (x64 build)";
383 #elif defined(__AVX2__)
384 result
+= "/arch:AVX2 /Ox";
385 #elif defined(__AVX__)
386 result
+= "/arch:AVX /Ox";
387 #elif _M_IX86_FP == 2
388 result
+= "/arch:sse2 /Ox";
390 result
+= "/arch:ia32 /Ox";
392 result
+= " (x86 build)";
394 std::cout
<< "Compiler options are found as: " << result
<< std::endl
;