Skip to content

Commit 264e954

Browse files
acomodivaughnbetz
authored andcommitted
vpr: added optional disable errors and suppress warnings
The errors can be disabled for entire functions. From the command line option, the developers can select which functions should not treat errors as warnings. The noisy warnings can be suppressed and redirected to a custom file. This can help to have a clearer output. Signed-off-by: Alessandro Comodi <[email protected]>
1 parent b812b4e commit 264e954

File tree

12 files changed

+174
-21
lines changed

12 files changed

+174
-21
lines changed

libs/libvtrutil/src/vtr_log.cpp

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1-
#include "vtr_log.h"
1+
#include <string>
2+
#include <fstream>
3+
#include <cstdarg>
24

5+
#include "vtr_util.h"
6+
#include "vtr_log.h"
37
#include "log.h"
48

59
namespace vtr {
@@ -14,3 +18,33 @@ void set_log_file(const char* filename) {
1418
}
1519

1620
} // namespace vtr
21+
22+
void add_warnings_to_suppress(std::string function_name) {
23+
warnings_to_suppress.insert(function_name);
24+
}
25+
26+
void set_noisy_warn_log_file(const char* log_file_name) {
27+
std::ofstream log;
28+
log.open(log_file_name, std::ifstream::out | std::ifstream::trunc);
29+
log.close();
30+
noisy_warn_log_file = std::string(log_file_name);
31+
}
32+
33+
void print_or_suppress_warning(const char* pszFileName, unsigned int lineNum, const char* pszFuncName, const char* pszMessage, ...) {
34+
std::string function_name(pszFuncName);
35+
36+
va_list va_args;
37+
va_start(va_args, pszMessage);
38+
std::string msg = vtr::vstring_fmt(pszMessage, va_args);
39+
va_end(va_args);
40+
41+
auto result = warnings_to_suppress.find(function_name);
42+
if (result == warnings_to_suppress.end()) {
43+
vtr::printf_warning(pszFileName, lineNum, msg.data());
44+
} else {
45+
std::ofstream log;
46+
log.open(noisy_warn_log_file.data(), std::ios_base::app);
47+
log << "Warning:\n\tfile: " << pszFileName << "\n\tline: " << lineNum << "\n\tmessage: " << msg << std::endl;
48+
log.close();
49+
}
50+
}

libs/libvtrutil/src/vtr_log.h

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#ifndef VTR_LOG_H
22
#define VTR_LOG_H
33
#include <tuple>
4+
#include <unordered_set>
5+
#include <string>
46

57
/*
68
* This header defines useful logging macros for VTR projects.
@@ -71,22 +73,31 @@
7173
#define VTR_LOGF_ERROR(file, line, ...) VTR_LOGVF_ERROR(true, file, line, __VA_ARGS__)
7274
#define VTR_LOGF_NOP(file, line, ...) VTR_LOGVF_NOP(true, file, line, __VA_ARGS__)
7375

76+
//Custom file-line-func location logging macros
77+
#define VTR_LOGFF_WARN(file, line, func, ...) VTR_LOGVFF_WARN(true, file, line, func, __VA_ARGS__)
78+
7479
//Conditional logging and custom file-line location macros
7580
#define VTR_LOGVF(expr, file, line, ...) \
7681
do { \
7782
if (expr) vtr::printf(__VA_ARGS__); \
7883
} while (false)
7984

80-
#define VTR_LOGVF_WARN(expr, file, line, ...) \
81-
do { \
82-
if (expr) vtr::printf_warning(file, line, __VA_ARGS__); \
85+
#define VTR_LOGVF_WARN(expr, file, line, ...) \
86+
do { \
87+
if (expr) print_or_suppress_warning(file, line, __func__, __VA_ARGS__); \
8388
} while (false)
8489

8590
#define VTR_LOGVF_ERROR(expr, file, line, ...) \
8691
do { \
8792
if (expr) vtr::printf_error(file, line, __VA_ARGS__); \
8893
} while (false)
8994

95+
// Conditional logging and custom file-line-func location macros
96+
#define VTR_LOGVFF_WARN(expr, file, line, func, ...) \
97+
do { \
98+
if (expr) print_or_suppress_warning(file, line, func, __VA_ARGS__); \
99+
} while (false)
100+
90101
//No-op version of logging macro which avoids unused parameter warnings.
91102
//
92103
//Note that to avoid unused parameter warnings we call sizeof() and cast
@@ -129,4 +140,20 @@ void set_log_file(const char* filename);
129140

130141
} // namespace vtr
131142

143+
// The following data structure and functions allow to suppress noisy warnings
144+
// and direct them into an external file.
145+
static std::unordered_set<std::string> warnings_to_suppress;
146+
static std::string noisy_warn_log_file;
147+
148+
void add_warnings_to_suppress(std::string function_name);
149+
150+
// This function creates a new log file to hold the suppressed warnings.
151+
// If the file already exists, it is cleared out first.
152+
void set_noisy_warn_log_file(const char* log_file_name);
153+
154+
// This function checks whether the function from which the warning has been called
155+
// is in the set of warnings_to_suppress. If so, the warning is printed on the
156+
// noisy_warn_log_file, otherwise it is printed on stdout (or the regular log file)
157+
void print_or_suppress_warning(const char* pszFileName, unsigned int lineNum, const char* pszFuncName, const char* pszMessage, ...);
158+
132159
#endif

vpr/src/base/read_options.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -931,6 +931,22 @@ static argparse::ArgumentParser create_arg_parser(std::string prog_name, t_optio
931931
.default_value("on")
932932
.show_in(argparse::ShowIn::HELP_ONLY);
933933

934+
gen_grp.add_argument<std::string>(args.disable_errors, "--disable_errors")
935+
.help(
936+
"Parses a list of functions for which the errors are going to be treated as warnings.\n"
937+
"Each function in the list is delimited by `:`\n"
938+
"This option should be only used for development purposes.")
939+
.default_value("");
940+
941+
gen_grp.add_argument<std::string>(args.suppress_warnings, "--suppress_warnings")
942+
.help(
943+
"Parses a list of functions for which the warnings will be suppressed on stdout.\n"
944+
"The first element of the list is the name of the output log file with the suppressed warnings.\n"
945+
"The file name and the list of functions is separated by `,`\n"
946+
"Each function in the list is delimited by `:`\n"
947+
"This option should be only used for development purposes.")
948+
.default_value("");
949+
934950
auto& file_grp = parser.add_argument_group("file options");
935951

936952
file_grp.add_argument(args.BlifFile, "--circuit_file")

vpr/src/base/read_options.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ struct t_options {
5050
argparse::ArgValue<e_clock_modeling> clock_modeling;
5151
argparse::ArgValue<bool> exit_before_pack;
5252
argparse::ArgValue<bool> strict_checks;
53+
argparse::ArgValue<std::string> disable_errors;
54+
argparse::ArgValue<std::string> suppress_warnings;
5355

5456
/* Atom netlist options */
5557
argparse::ArgValue<bool> absorb_buffer_luts;

vpr/src/base/vpr_api.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,29 @@ void vpr_init(const int argc, const char** argv, t_options* options, t_vpr_setup
214214
/* Determine whether echo is on or off */
215215
setEchoEnabled(options->CreateEchoFile);
216216

217+
/*
218+
* Initialize the functions names for which VPR_THROWs
219+
* are demoted to VTR_LOG_WARNs
220+
*/
221+
for (std::string func_name : vtr::split(options->disable_errors, std::string(":"))) {
222+
map_error_activation_status(func_name);
223+
}
224+
225+
/*
226+
* Initialize the functions names for which
227+
* warnings are being suppressed
228+
*/
229+
std::vector<std::string> split_warning_option = vtr::split(options->suppress_warnings, std::string(","));
230+
231+
// If the file or the list of functions is not provided
232+
// no warning is suppressed
233+
if (split_warning_option.size() == 2) {
234+
set_noisy_warn_log_file(split_warning_option[0].data());
235+
for (std::string func_name : vtr::split(split_warning_option[1], std::string(":"))) {
236+
add_warnings_to_suppress(func_name);
237+
}
238+
}
239+
217240
/* Read in arch and circuit */
218241
SetupVPR(options,
219242
vpr_setup->TimingEnabled,

vpr/src/place/place.cpp

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -963,11 +963,7 @@ static void recompute_costs_from_scratch(const t_placer_opts& placer_opts, const
963963
if (fabs(new_bb_cost - costs->bb_cost) > costs->bb_cost * ERROR_TOL) {
964964
std::string msg = vtr::string_fmt("in recompute_costs_from_scratch: new_bb_cost = %g, old bb_cost = %g\n",
965965
new_bb_cost, costs->bb_cost);
966-
if (placer_opts.strict_checks) {
967-
vpr_throw(VPR_ERROR_PLACE, __FILE__, __LINE__, msg.c_str());
968-
} else {
969-
VTR_LOG_WARN(msg.c_str());
970-
}
966+
VPR_THROW(VPR_ERROR_PLACE, msg.c_str());
971967
}
972968
costs->bb_cost = new_bb_cost;
973969

@@ -977,11 +973,7 @@ static void recompute_costs_from_scratch(const t_placer_opts& placer_opts, const
977973
if (fabs(new_timing_cost - costs->timing_cost) > costs->timing_cost * ERROR_TOL) {
978974
std::string msg = vtr::string_fmt("in recompute_costs_from_scratch: new_timing_cost = %g, old timing_cost = %g, ERROR_TOL = %g\n",
979975
new_timing_cost, costs->timing_cost, ERROR_TOL);
980-
if (placer_opts.strict_checks) {
981-
vpr_throw(VPR_ERROR_PLACE, __FILE__, __LINE__, msg.c_str());
982-
} else {
983-
VTR_LOG_WARN(msg.c_str());
984-
}
976+
VPR_THROW(VPR_ERROR_PLACE, msg.c_str());
985977
}
986978
costs->timing_cost = new_timing_cost;
987979
} else {

vpr/src/route/check_route.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ void check_route(enum e_route_type route_type) {
118118
} else { //Continuing along existing branch
119119
connects = check_adjacent(prev_node, inode);
120120
if (!connects) {
121-
vpr_throw(VPR_ERROR_ROUTE, __FILE__, __LINE__,
121+
VPR_THROW(VPR_ERROR_ROUTE,
122122
"in check_route: found non-adjacent segments in traceback while checking net %d:\n"
123123
" %s\n"
124124
" %s\n",

vpr/src/route/check_rr_graph.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ static void check_unbuffered_edges(int from_node) {
502502
}
503503

504504
if (trans_matched == false) {
505-
vpr_throw(VPR_ERROR_ROUTE, __FILE__, __LINE__,
505+
VPR_THROW(VPR_ERROR_ROUTE,
506506
"in check_unbuffered_edges:\n"
507507
"connection from node %d to node %d uses an unbuffered switch (switch type %d '%s')\n"
508508
"but there is no corresponding unbuffered switch edge in the other direction.\n",

vpr/src/util/vpr_error.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#include <cstdarg>
2+
#include <string>
23

34
#include "vtr_util.h"
5+
#include "vtr_log.h"
46
#include "vpr_error.h"
57

68
/* Date:June 15th, 2013
@@ -11,6 +13,10 @@
1113
* anything but throw an exception which will be caught
1214
* main.c.
1315
*/
16+
void map_error_activation_status(std::string function_name) {
17+
functions_to_demote.insert(function_name);
18+
}
19+
1420
void vpr_throw(enum e_vpr_error type,
1521
const char* psz_file_name,
1622
unsigned int line_num,
@@ -41,3 +47,38 @@ void vvpr_throw(enum e_vpr_error type,
4147

4248
throw VprError(type, msg, psz_file_name, line_num);
4349
}
50+
51+
void vpr_throw_msg(enum e_vpr_error type,
52+
const char* psz_file_name,
53+
unsigned int line_num,
54+
std::string msg) {
55+
throw VprError(type, msg, psz_file_name, line_num);
56+
}
57+
58+
void vpr_throw_opt(enum e_vpr_error type,
59+
const char* psz_func_name,
60+
const char* psz_file_name,
61+
unsigned int line_num,
62+
const char* psz_message,
63+
...) {
64+
std::string func_name(psz_func_name);
65+
66+
// Make a variable argument list
67+
va_list va_args;
68+
69+
// Initialize variable argument list
70+
va_start(va_args, psz_message);
71+
72+
//Format the message
73+
std::string msg = vtr::vstring_fmt(psz_message, va_args);
74+
75+
auto result = functions_to_demote.find(func_name);
76+
if (result != functions_to_demote.end()) {
77+
VTR_LOGFF_WARN(psz_file_name, line_num, psz_func_name, msg.data());
78+
} else {
79+
vpr_throw_msg(type, psz_file_name, line_num, msg);
80+
}
81+
82+
// Reset variable argument list
83+
va_end(va_args);
84+
}

vpr/src/util/vpr_error.h

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
#ifndef VPR_ERROR_H
22
#define VPR_ERROR_H
33

4-
#include "vtr_error.h"
54
#include <cstdarg>
5+
#include <string>
6+
#include <unordered_set>
7+
8+
#include "vtr_error.h"
69

710
enum e_vpr_error {
811
VPR_ERROR_UNKNOWN = 0,
@@ -45,21 +48,33 @@ class VprError : public vtr::VtrError {
4548
t_vpr_error_type type_;
4649
};
4750

51+
// Set of function names for which the VPR_THROW errors are treated
52+
// as VTR_LOG_WARN
53+
static std::unordered_set<std::string> functions_to_demote;
54+
55+
// This function is used to save into the functions_to_demote set
56+
// all the function names which contain VPR_THROW errors that are
57+
// going to be demoted to be VTR_LOG_WARN
58+
void map_error_activation_status(std::string function_name);
59+
4860
//VPR error reporting routines
4961
//
5062
//Note that we mark these functions with the C++11 attribute 'noreturn'
5163
//as they will throw exceptions and not return normally. This can help
5264
//reduce false-positive compiler warnings
5365
[[noreturn]] void vpr_throw(enum e_vpr_error type, const char* psz_file_name, unsigned int line_num, const char* psz_message, ...);
5466
[[noreturn]] void vvpr_throw(enum e_vpr_error type, const char* psz_file_name, unsigned int line_num, const char* psz_message, va_list args);
67+
[[noreturn]] void vpr_throw_msg(enum e_vpr_error type, const char* psz_file_name, unsigned int line_num, std::string msg);
68+
69+
void vpr_throw_opt(enum e_vpr_error type, const char* psz_func_name, const char* psz_file_name, unsigned int line_num, const char* psz_message, ...);
5570

5671
/*
5772
* Macro wrapper around vpr_throw() which automatically
5873
* specifies file and line number of call site.
5974
*/
60-
#define VPR_THROW(type, ...) \
61-
do { \
62-
vpr_throw(type, __FILE__, __LINE__, __VA_ARGS__); \
75+
#define VPR_THROW(type, ...) \
76+
do { \
77+
vpr_throw_opt(type, __func__, __FILE__, __LINE__, __VA_ARGS__); \
6378
} while (false)
6479

6580
#endif

vpr/src/util/vpr_utils.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#include <cstring>
22
#include <unordered_set>
33
#include <regex>
4+
#include <algorithm>
5+
46
using namespace std;
57

68
#include "vtr_assert.h"
@@ -18,7 +20,6 @@ using namespace std;
1820
#include "string.h"
1921
#include "pack_types.h"
2022
#include "device_grid.h"
21-
#include <algorithm>
2223

2324
/* This module contains subroutines that are used in several unrelated parts *
2425
* of VPR. They are VPR-specific utility routines. */

vpr/src/util/vpr_utils.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
#define VPR_UTILS_H
33

44
#include <vector>
5+
#include <string>
56
#include <regex>
7+
68
#include "vpr_types.h"
79
#include "atom_netlist.h"
810
#include "clustered_netlist.h"

0 commit comments

Comments
 (0)