areusch commented on a change in pull request #7153:
URL: https://github.com/apache/tvm/pull/7153#discussion_r572252014



##########
File path: include/tvm/runtime/logging.h
##########
@@ -0,0 +1,435 @@
+/*
+ * 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/runtime/logging.h
+ * \brief logging utilities
+ *
+ * We define our own CHECK and LOG macros to replace those from dmlc-core.
+ * These macros are then injected into dmlc-core via the
+ * DMLC_USE_LOGGING_LIBRARY define. dmlc-core will #include this file wherever
+ * it needs logging.
+ */
+#ifndef TVM_RUNTIME_LOGGING_H_
+#define TVM_RUNTIME_LOGGING_H_
+
+#include <dmlc/common.h>
+
+#include <ctime>
+#include <iomanip>
+#include <iostream>
+#include <sstream>
+#include <string>
+
+#include "tvm/runtime/c_runtime_api.h"
+
+// a technique that enables overriding macro names on the number of 
parameters. This is used
+// to define other macros below
+#define GET_MACRO(_1, _2, _3, _4, _5, NAME, ...) NAME
+
+/*!
+ * \brief COND_X calls COND_X_N where N is the number of parameters passed to 
COND_X
+ * X can be any of CHECK_GE, CHECK_EQ, CHECK, or LOG COND_X (but not COND_X_N)
+ * are supposed to be used outside this file.
+ * The first parameter of COND_X (and therefore, COND_X_N), which we call 
'quit_on_assert',
+ * is a boolean. The rest of the parameters of COND_X is the same as the 
parameters of X.
+ * quit_on_assert determines the overall behavior of COND_X. If it's true 
COND_X
+ * quits the program on assertion failure. If it's false, then it moves on and 
somehow reports
+ * the assertion failure back to the macro caller in an appropriate manner 
(e.g, 'return false'
+ * in a function, or 'continue' or 'break' in a loop)
+ * The default behavior when quit_on_assertion is false, is to 'return false'. 
If this is not
+ * desirable, the macro caller can pass one more last parameter to COND_X to 
tell COND_X what
+ * to do when when quit_on_assertion is false and the assertion fails.
+ *
+ * Rationale: These macros were designed to implement functions that have two 
behaviors
+ * in a concise way. Those behaviors are quitting on assertion failures, or 
trying to
+ * move on from assertion failures. Note that these macros hide lots of 
control flow in them,
+ * and therefore, makes the logic of the whole code slightly harder to 
understand. However,
+ * in pieces of code that use these macros frequently, it will significantly 
shorten the
+ * amount of code needed to be read, and we won't need to clutter the main 
logic of the
+ * function by repetitive control flow structure. The first problem
+ * mentioned will be improved over time as the developer gets used to the 
macro.
+ *
+ * Here is an example of how to use it
+ * \code
+ * bool f(..., bool quit_on_assertion) {
+ *   int a = 0, b = 0;
+ *   ...
+ *   a = ...
+ *   b = ...
+ *   // if quit_on_assertion is true, if a==b, continue, otherwise quit.
+ *   // if quit_on_assertion is false, if a==b, continue, otherwise 'return 
false' (default
+ * behaviour) COND_CHECK_EQ(quit_on_assertion, a, b) << "some error message 
when  quiting"
+ *   ...
+ *   for (int i = 0; i < N; i++) {
+ *     a = ...
+ *     b = ...
+ *     // if quit_on_assertion is true, if a==b, continue, otherwise quit.
+ *     // if quit_on_assertion is false, if a==b, continue, otherwise 'break' 
(non-default
+ *     // behaviour, therefore, has to be explicitly specified)
+ *     COND_CHECK_EQ(quit_on_assertion, a, b, break) << "some error message 
when  quiting"
+ *   }
+ * }
+ * \endcode
+ */
+#define COND_CHECK_GE(...) \
+  GET_MACRO(__VA_ARGS__, COND_CHECK_GE_5, COND_CHECK_GE_4, 
COND_CHECK_GE_3)(__VA_ARGS__)
+#define COND_CHECK_EQ(...) \
+  GET_MACRO(__VA_ARGS__, COND_CHECK_EQ_5, COND_CHECK_EQ_4, 
COND_CHECK_EQ_3)(__VA_ARGS__)
+#define COND_CHECK(...) \
+  GET_MACRO(__VA_ARGS__, COND_CHECK_5, COND_CHECK_4, COND_CHECK_3, 
COND_CHECK_2)(__VA_ARGS__)
+#define COND_LOG(...) \
+  GET_MACRO(__VA_ARGS__, COND_LOG_5, COND_LOG_4, COND_LOG_3, 
COND_LOG_2)(__VA_ARGS__)
+
+// Not supposed to be used by users directly.
+#define COND_CHECK_OP(quit_on_assert, x, y, what, op) \
+  if (!quit_on_assert) {                              \
+    if (!((x)op(y))) what;                            \
+  } else /* NOLINT(*) */                              \
+    CHECK_##op(x, y)
+
+#define COND_CHECK_EQ_4(quit_on_assert, x, y, what) 
COND_CHECK_OP(quit_on_assert, x, y, what, ==)
+#define COND_CHECK_GE_4(quit_on_assert, x, y, what) 
COND_CHECK_OP(quit_on_assert, x, y, what, >=)
+
+#define COND_CHECK_3(quit_on_assert, x, what) \
+  if (!quit_on_assert) {                      \
+    if (!(x)) what;                           \
+  } else /* NOLINT(*) */                      \
+    CHECK(x)
+
+#define COND_LOG_3(quit_on_assert, x, what) \
+  if (!quit_on_assert) {                    \
+    what;                                   \
+  } else /* NOLINT(*) */                    \
+    LOG(x)
+
+#define COND_CHECK_EQ_3(quit_on_assert, x, y) COND_CHECK_EQ_4(quit_on_assert, 
x, y, return false)
+#define COND_CHECK_GE_3(quit_on_assert, x, y) COND_CHECK_GE_4(quit_on_assert, 
x, y, return false)
+#define COND_CHECK_2(quit_on_assert, x) COND_CHECK_3(quit_on_assert, x, return 
false)
+#define COND_LOG_2(quit_on_assert, x) COND_LOG_3(quit_on_assert, x, return 
false)
+
+#define TVM_THROW_EXCEPTION noexcept(false)
+
+namespace tvm {
+namespace runtime {
+
+#ifndef TVM_BACKTRACE_DISABLED
+/* \brief Generate a backtrace when called.
+ * \return A multiline string of the backtrace. There will be either one or 
two lines per frame.
+ */
+std::string Backtrace();
+#else
+// TODO(bkimball,tkonolige) This inline function is to work around a linking 
error I am having when
+// using MSVC If the function definition is in logging.cc then the linker 
can't find it no matter
+// what kind of attributes (dllexport) I decorate it with. This is temporary 
and will be addressed
+// when we get backtrace working on Windows.
+inline std::string Backtrace() { return ""; }
+#endif
+
+/*! \brief Base error type for TVM. Wraps a string message. */
+class Error : public ::dmlc::Error {  // for backwards compatibility
+ public:
+  /*! \brief Construct an error.
+   * \param s The message to be displayed with the error.
+   */
+  explicit Error(const std::string& s) : ::dmlc::Error(s) {}
+};
+
+/*! \brief Error type for errors from CHECK, ICHECK, and LOG(FATAL). This error
+ * contains a backtrace of where it occured.
+ */
+class InternalError : public Error {
+ public:
+  /*! \brief Construct an error. Not recommended to use directly. Instead use 
LOG(FATAL).
+   *
+   * \param file The file where the error occurred.
+   * \param lineno The line number where the error occurred.
+   * \param message The error message to display.
+   * \param time The time at which the error occurred.

Review comment:
       if supplying this argument, is there guidance as to which clock should 
be used?




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to