144 строки
4.3 KiB
C++
144 строки
4.3 KiB
C++
/*!
|
|
* Copyright (c) 2018 by Contributors
|
|
* \file error.h
|
|
* \brief The set of errors raised by Relay.
|
|
*/
|
|
#ifndef TVM_RELAY_ERROR_H_
|
|
#define TVM_RELAY_ERROR_H_
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
#include <sstream>
|
|
#include "./base.h"
|
|
#include "./expr.h"
|
|
#include "./module.h"
|
|
|
|
namespace tvm {
|
|
namespace relay {
|
|
|
|
#define RELAY_ERROR(msg) (RelayErrorStream() << msg)
|
|
|
|
// Forward declaratio for RelayErrorStream.
|
|
struct Error;
|
|
|
|
/*! \brief A wrapper around std::stringstream.
|
|
*
|
|
* This is designed to avoid platform specific
|
|
* issues compiling and using std::stringstream
|
|
* for error reporting.
|
|
*/
|
|
struct RelayErrorStream {
|
|
std::stringstream ss;
|
|
|
|
template<typename T>
|
|
RelayErrorStream& operator<<(const T& t) {
|
|
ss << t;
|
|
return *this;
|
|
}
|
|
|
|
std::string str() const {
|
|
return ss.str();
|
|
}
|
|
|
|
void Raise() const;
|
|
};
|
|
|
|
struct Error : public dmlc::Error {
|
|
Span sp;
|
|
explicit Error(const std::string& msg) : dmlc::Error(msg), sp() {}
|
|
Error(const std::stringstream& msg) : dmlc::Error(msg.str()), sp() {} // NOLINT(*)
|
|
Error(const RelayErrorStream& msg) : dmlc::Error(msg.str()), sp() {} // NOLINT(*)
|
|
};
|
|
|
|
/*! \brief An abstraction around how errors are stored and reported.
|
|
* Designed to be opaque to users, so we can support a robust and simpler
|
|
* error reporting mode, as well as a more complex mode.
|
|
*
|
|
* The first mode is the most accurate: we report a Relay error at a specific
|
|
* Span, and then render the error message directly against a textual representation
|
|
* of the program, highlighting the exact lines in which it occurs. This mode is not
|
|
* implemented in this PR and will not work.
|
|
*
|
|
* The second mode is a general-purpose mode, which attempts to annotate the program's
|
|
* textual format with errors.
|
|
*
|
|
* The final mode represents the old mode, if we report an error that has no span or
|
|
* expression, we will default to throwing an exception with a textual representation
|
|
* of the error and no indication of where it occured in the original program.
|
|
*
|
|
* The latter mode is not ideal, and the goal of the new error reporting machinery is
|
|
* to avoid ever reporting errors in this style.
|
|
*/
|
|
class ErrorReporter {
|
|
public:
|
|
ErrorReporter() : errors_(), node_to_error_() {}
|
|
|
|
/*! \brief Report a tvm::relay::Error.
|
|
*
|
|
* This API is useful for reporting spanned errors.
|
|
*
|
|
* \param err The error to report.
|
|
*/
|
|
void Report(const Error& err) {
|
|
if (!err.sp.defined()) {
|
|
throw err;
|
|
}
|
|
|
|
this->errors_.push_back(err);
|
|
}
|
|
|
|
/*! \brief Report an error against a program, using the full program
|
|
* error reporting strategy.
|
|
*
|
|
* This error reporting method requires the global function in which
|
|
* to report an error, the expression to report the error on,
|
|
* and the error object.
|
|
*
|
|
* \param global The global function in which the expression is contained.
|
|
* \param node The expression or type to report the error at.
|
|
* \param err The error message to report.
|
|
*/
|
|
inline void ReportAt(const GlobalVar& global, const NodeRef& node, std::stringstream& err) {
|
|
this->ReportAt(global, node, Error(err));
|
|
}
|
|
|
|
/*! \brief Report an error against a program, using the full program
|
|
* error reporting strategy.
|
|
*
|
|
* This error reporting method requires the global function in which
|
|
* to report an error, the expression to report the error on,
|
|
* and the error object.
|
|
*
|
|
* \param global The global function in which the expression is contained.
|
|
* \param node The expression or type to report the error at.
|
|
* \param err The error to report.
|
|
*/
|
|
void ReportAt(const GlobalVar& global, const NodeRef& node, const Error& err);
|
|
|
|
/*! \brief Render all reported errors and exit the program.
|
|
*
|
|
* This function should be used after executing a pass to render reported errors.
|
|
*
|
|
* It will build an error message from the set of errors, depending on the error
|
|
* reporting strategy.
|
|
*
|
|
* \param module The module to report errors on.
|
|
* \param use_color Controls whether to colorize the output.
|
|
*/
|
|
void RenderErrors(const Module& module, bool use_color = true);
|
|
|
|
inline bool AnyErrors() {
|
|
return errors_.size() != 0;
|
|
}
|
|
|
|
private:
|
|
std::vector<Error> errors_;
|
|
std::unordered_map<NodeRef, std::vector<size_t>, NodeHash, NodeEqual> node_to_error_;
|
|
std::unordered_map<NodeRef, GlobalVar, NodeHash, NodeEqual> node_to_gv_;
|
|
};
|
|
|
|
} // namespace relay
|
|
} // namespace tvm
|
|
|
|
#endif // TVM_RELAY_ERROR_H_
|