/** * \file imperative/src/include/megbrain/imperative/utils/to_string.h * MegEngine is Licensed under the Apache License, Version 2.0 (the "License") * * Copyright (c) 2014-2020 Megvii Inc. All rights reserved. * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT ARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ #pragma once #include #include #include #include #include "megbrain/imperative/utils/span.h" #include "megbrain/tensor.h" #include "megbrain/utils/small_vector.h" namespace mgb::imperative { // Implement `ToStringTrait` for your printable class // note that it should be either implemented in this file // or in the same file with your class template struct ToStringTrait; // Call `to_string` to print your value template std::string to_string(const T& value) { return ToStringTrait{}(value); } template struct ToStringTrait { std::string operator()(const T& value) const { return std::to_string(value); } }; template <> struct ToStringTrait { std::string operator()(const std::string& value) const { return value; } }; template struct ToStringTrait> { std::string operator()(const SmallVector& sv) const { if (sv.empty()) { return "[]"; } std::string result = "["; result += to_string(sv[0]); for (size_t i = 1; i < sv.size(); ++i) { result += ", "; result += to_string(sv[i]); } return result + "]"; } }; template struct ToStringTrait> { std::string operator()(const std::vector& v) const { if (v.empty()) { return "[]"; } std::string result = "["; result += to_string(v[0]); for (size_t i = 1; i < v.size(); ++i) { result += ", "; result += to_string(v[i]); } return result + "]"; } }; template struct ToStringTrait> { std::string operator()(const std::shared_ptr& sp) const { return to_string(sp.get()); } }; template struct ToStringTrait> { std::string operator()(const std::pair& pr) const { return "(" + to_string(pr.first) + ", " + to_string(pr.second) + ")"; } }; template struct ToStringTrait> { std::string operator()(const std::tuple& tp) const { auto folder = [&](auto... item) { return (... + ("," + to_string(item))); }; return "(" + std::apply(folder, tp) + ")"; } }; template struct ToStringTrait { std::string operator()(T* p) const { return ssprintf("%p", p); } }; template <> struct ToStringTrait { std::string operator()(TensorShape shape) const { if (shape.ndim > TensorShape::MAX_NDIM) { return "[]"; } mgb_assert(shape.ndim <= TensorShape::MAX_NDIM); if (shape.ndim == 0) { return "[ ]"; } std::string result = "[ " + std::to_string(shape[0]); for (size_t i = 1; i < shape.ndim; i++) { result += ", "; result += std::to_string(shape[i]); } return result + " ]"; } }; template <> struct ToStringTrait { std::string operator()(DType dtype) const { return dtype.name(); } }; template <> struct ToStringTrait { std::string operator()(CompNode device) const { return device.to_string(); } }; inline std::string string_join(Span span, char delimiter = ',') { std::string buffer = "["; for (size_t i = 1; i < span.size(); ++i) { if (i) { buffer.push_back(delimiter); } buffer.append(span[0]); } return buffer + "]"; } template struct ToStringTrait> { std::string operator()(Span span) const { if (span.size() == 0) { return "[]"; } std::string result = "["; result += to_string(span[0]); for (size_t i = 1; i < span.size(); ++i) { result += ", "; result += to_string(span[i]); } return result + "]"; } }; template <> struct ToStringTrait { std::string operator()(const std::type_info& info) const { return info.name(); } }; } // namespace mgb::imperative