| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| /*! |
| * \file tvm/ir/error.h |
| * \brief Utilities for error tracking and reporting. |
| */ |
| #ifndef TVM_IR_ERROR_H_ |
| #define TVM_IR_ERROR_H_ |
| |
| #include <tvm/ir/module.h> |
| #include <tvm/ir/span.h> |
| |
| #include <sstream> |
| #include <string> |
| #include <unordered_map> |
| #include <vector> |
| |
| namespace tvm { |
| /*! |
| * \brief A wrapper around std::stringstream to build error. |
| * |
| * Can be consumed by Error to construct an error. |
| * |
| * \code |
| * |
| * void ReportError(const Error& err); |
| * |
| * void Test(int number) { |
| * // Use error reporter to construct an error. |
| * ReportError(ErrorBuilder() << "This is an error number=" << number); |
| * } |
| * |
| * \endcode |
| */ |
| struct ErrorBuilder { |
| public: |
| template <typename T> |
| ErrorBuilder& operator<<(const T& val) { // NOLINT(*) |
| stream_ << val; |
| return *this; |
| } |
| |
| private: |
| std::stringstream stream_; |
| friend class Error; |
| }; |
| |
| /*! |
| * \brief Custom Error class to be thrown during compilation. |
| */ |
| class Error : public dmlc::Error { |
| public: |
| /*! \brief Location of the error */ |
| Span span; |
| /*! |
| * \brief construct error from message. |
| * \param msg The message |
| */ |
| explicit Error(const std::string& msg) : dmlc::Error(msg), span(nullptr) {} |
| /*! |
| * \brief construct error from error builder. |
| * \param err The error builder |
| */ |
| Error(const ErrorBuilder& err) : dmlc::Error(err.stream_.str()), span(nullptr) {} // NOLINT(*) |
| /*! |
| * \brief copy constructor. |
| * \param other The other ereor. |
| */ |
| Error(const Error& other) : dmlc::Error(other.what()), span(other.span) {} // NOLINT(*) |
| /*! |
| * \brief default constructor. */ |
| Error() : dmlc::Error(""), span(nullptr) {} |
| }; |
| |
| /*! |
| * \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 occurred 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: |
| /*! \brief default constructor. */ |
| ErrorReporter() : errors_(), node_to_error_() {} |
| |
| /*! |
| * \brief Report a tvm::Error. |
| * |
| * This API is useful for reporting spanned errors. |
| * |
| * \param err The error to report. |
| */ |
| void Report(const Error& err) { |
| if (!err.span.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. |
| */ |
| void ReportAt(const GlobalVar& global, const ObjectRef& node, std::stringstream& err) { |
| std::string err_msg = err.str(); |
| this->ReportAt(global, node, Error(err_msg)); |
| } |
| |
| /*! |
| * \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 ObjectRef& 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 IRModule& module, bool use_color = true); |
| |
| inline bool AnyErrors() { return errors_.size() != 0; } |
| |
| private: |
| std::vector<Error> errors_; |
| std::unordered_map<ObjectRef, std::vector<size_t>, ObjectPtrHash, ObjectPtrEqual> node_to_error_; |
| std::unordered_map<ObjectRef, GlobalVar, ObjectPtrHash, ObjectPtrEqual> node_to_gv_; |
| }; |
| |
| } // namespace tvm |
| #endif // TVM_IR_ERROR_H_ |