diff options
Diffstat (limited to 'ruy/check_macros.h')
-rw-r--r-- | ruy/check_macros.h | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/ruy/check_macros.h b/ruy/check_macros.h new file mode 100644 index 0000000..773f37d --- /dev/null +++ b/ruy/check_macros.h @@ -0,0 +1,138 @@ +/* Copyright 2019 Google LLC. All Rights Reserved. + +Licensed 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. +==============================================================================*/ + +#ifndef TENSORFLOW_LITE_EXPERIMENTAL_RUY_RUY_CHECK_MACROS_H_ +#define TENSORFLOW_LITE_EXPERIMENTAL_RUY_RUY_CHECK_MACROS_H_ + +#include <cstdio> +#include <cstdlib> +#include <type_traits> + +namespace ruy { +namespace check_macros { + +constexpr int kValueBufSize = 32; + +template <typename T, typename Enable = void> +struct ToString { + static void Run(const T& value, char* buf) { + snprintf(buf, kValueBufSize, "(?)"); + } +}; + +template <> +struct ToString<float, void> { + static void Run(float value, char* buf) { + snprintf(buf, kValueBufSize, "%.9g", static_cast<double>(value)); + } +}; + +template <> +struct ToString<double, void> { + static void Run(double value, char* buf) { + snprintf(buf, kValueBufSize, "%.16g", value); + } +}; + +template <typename T> +struct ToString<T, typename std::enable_if<std::is_integral<T>::value>::type> { + static void Run(const T& value, char* buf) { + snprintf(buf, kValueBufSize, "%lld", static_cast<long long>(value)); + } +}; + +template <typename T> +struct ToString<T*, void> { + static void Run(T* value, char* buf) { + snprintf(buf, kValueBufSize, "%p", value); + } +}; + +template <typename T> +struct ToString<T, typename std::enable_if<std::is_enum<T>::value>::type> { + static void Run(const T& value, char* buf) { + snprintf(buf, kValueBufSize, "(enum value %d)", static_cast<int>(value)); + } +}; + +inline void Failure(const char* file, int line, const char* macro, + const char* condition) { + fprintf(stderr, "%s:%d: %s condition not satisfied: %s\n", file, line, macro, + condition); + abort(); +} + +template <typename LhsType, typename RhsType> +inline void Failure(const char* file, int line, const char* macro, + const char* lhs, const LhsType& lhs_value, const char* op, + const char* rhs, const RhsType& rhs_value) { + char lhs_value_buf[kValueBufSize]; + ToString<LhsType>::Run(lhs_value, lhs_value_buf); + char rhs_value_buf[kValueBufSize]; + ToString<RhsType>::Run(rhs_value, rhs_value_buf); + fprintf(stderr, + "%s:%d: %s condition not satisfied: [ %s %s %s ] with values [ " + "%s %s %s ].\n", + file, line, macro, lhs, op, rhs, lhs_value_buf, op, rhs_value_buf); + abort(); +} + +#define RUY_CHECK_IMPL(macro, condition) \ + do { \ + if (!(condition)) { \ + ruy::check_macros::Failure(__FILE__, __LINE__, #macro, #condition); \ + } \ + } while (false) + +#define RUY_CHECK_OP_IMPL(macro, lhs, op, rhs) \ + do { \ + const auto& lhs_value = (lhs); \ + const auto& rhs_value = (rhs); \ + if (!(lhs_value op rhs_value)) { \ + ruy::check_macros::Failure(__FILE__, __LINE__, #macro, #lhs, lhs_value, \ + #op, #rhs, rhs_value); \ + } \ + } while (false) + +#define RUY_CHECK(condition) RUY_CHECK_IMPL(RUY_CHECK, condition) +#define RUY_CHECK_EQ(x, y) RUY_CHECK_OP_IMPL(RUY_CHECK_EQ, x, ==, y) +#define RUY_CHECK_NE(x, y) RUY_CHECK_OP_IMPL(RUY_CHECK_NE, x, !=, y) +#define RUY_CHECK_GE(x, y) RUY_CHECK_OP_IMPL(RUY_CHECK_GE, x, >=, y) +#define RUY_CHECK_GT(x, y) RUY_CHECK_OP_IMPL(RUY_CHECK_GT, x, >, y) +#define RUY_CHECK_LE(x, y) RUY_CHECK_OP_IMPL(RUY_CHECK_LE, x, <=, y) +#define RUY_CHECK_LT(x, y) RUY_CHECK_OP_IMPL(RUY_CHECK_LT, x, <, y) + +#ifdef NDEBUG +#define RUY_DCHECK(condition) +#define RUY_DCHECK_EQ(x, y) +#define RUY_DCHECK_NE(x, y) +#define RUY_DCHECK_GE(x, y) +#define RUY_DCHECK_GT(x, y) +#define RUY_DCHECK_LE(x, y) +#define RUY_DCHECK_LT(x, y) +#else +#define RUY_DCHECK(condition) RUY_CHECK(condition) +#define RUY_DCHECK_EQ(x, y) RUY_CHECK_EQ(x, y) +#define RUY_DCHECK_NE(x, y) RUY_CHECK_NE(x, y) +#define RUY_DCHECK_GE(x, y) RUY_CHECK_GE(x, y) +#define RUY_DCHECK_GT(x, y) RUY_CHECK_GT(x, y) +#define RUY_DCHECK_LE(x, y) RUY_CHECK_LE(x, y) +#define RUY_DCHECK_LT(x, y) RUY_CHECK_LT(x, y) +#endif + +} // end namespace check_macros +} // end namespace ruy + +#endif // TENSORFLOW_LITE_EXPERIMENTAL_RUY_RUY_CHECK_MACROS_H_ |