From a91e9fe04a14d194b3dc97940d6be02f45ae0d7f Mon Sep 17 00:00:00 2001 From: Zhang Qinghua Date: Thu, 27 Aug 2020 10:58:36 +0800 Subject: [PATCH] Add comma seperator for __repr__(). --- mindspore/ccsrc/utils/tensorprint_utils.cc | 2 +- mindspore/core/ir/tensor.cc | 83 ++++++++++++++-------- mindspore/core/ir/tensor.h | 6 +- 3 files changed, 61 insertions(+), 30 deletions(-) diff --git a/mindspore/ccsrc/utils/tensorprint_utils.cc b/mindspore/ccsrc/utils/tensorprint_utils.cc index 7a926337625..bdb06d7fb34 100644 --- a/mindspore/ccsrc/utils/tensorprint_utils.cc +++ b/mindspore/ccsrc/utils/tensorprint_utils.cc @@ -210,7 +210,7 @@ bool ConvertDataItem2Tensor(const std::vector &items) { mindspore::tensor::Tensor print_tensor(type_id, tensor_shape); auto memory_size = totaldims * type_size_map[item.tensorType_]; if (PrintTensorToString(str_data_ptr->data(), &print_tensor, memory_size)) { - buf << print_tensor.ToStringRepr() << std::endl; + buf << print_tensor.ToStringNoLimit() << std::endl; } } } diff --git a/mindspore/core/ir/tensor.cc b/mindspore/core/ir/tensor.cc index 660148688ec..eaedf5302da 100644 --- a/mindspore/core/ir/tensor.cc +++ b/mindspore/core/ir/tensor.cc @@ -213,7 +213,7 @@ class TensorDataImpl : public TensorData { std::equal(data_.get(), data_.get() + data_size_, ptr->data_.get()); } - std::string ToString(const TypeId type, const ShapeVector &shape) const override { + std::string ToString(const TypeId type, const ShapeVector &shape, bool use_comma) const override { constexpr auto valid = std::is_same::value || std::is_same::value || std::is_same::value || std::is_same::value || std::is_same::value || std::is_same::value || @@ -229,16 +229,16 @@ class TensorDataImpl : public TensorData { std::ostringstream ss; if (data_size_ == 1 && ndim_ == 0) { // Scalar - OutputDataString(ss, 0, 0, 1); + OutputDataString(ss, 0, 0, 1, false); return ss.str(); } ssize_t cursor = 0; - SummaryStringRecursive(ss, shape, &cursor, 0); + SummaryStringRecursive(ss, shape, &cursor, 0, use_comma); return ss.str(); } private: - void OutputDataString(std::ostringstream &ss, ssize_t cursor, ssize_t start, ssize_t end) const { + void OutputDataString(std::ostringstream &ss, ssize_t cursor, ssize_t start, ssize_t end, bool use_comma) const { const bool isScalar = ndim_ == 0 && end - start == 1; constexpr auto isFloat = std::is_same::value || std::is_same::value || std::is_same::value; @@ -265,33 +265,43 @@ class TensorDataImpl : public TensorData { ss << std::setw(5) << std::setiosflags(std::ios::right) << (value ? "True" : "False"); } } else { - constexpr auto isSigned = std::is_same::value || std::is_same::value || - std::is_same::value || std::is_same::value; + constexpr auto isSigned = std::is_same::value; if constexpr (isSigned) { if (!isScalar && static_cast(value) >= 0) { ss << ' '; } } - // Set width and indent for different int type. + // Set width and indent for different int type with signed position. // - // int8/uint8 width: 3 - // int16/uint16 width: 5 - // int32/uint32 width: 10 - // int64/uint64 width: NOT SET - if constexpr (std::is_same::value) { - ss << std::setw(3) << std::setiosflags(std::ios::right) << static_cast(value); - } else if constexpr (std::is_same::value) { + // uint8 width: 3, [0, 255] + // int8 width: 4, [-128, 127] + // uint16 width: 5, [0, 65535] + // int16 width: 6, [-32768, 32767] + // uint32 width: 10, [0, 4294967295] + // int32 width: 11, [-2147483648, 2147483647] + // uint64 width: NOT SET (20, [0, 18446744073709551615]) + // int64 width: NOT SET (20, [-9223372036854775808, 9223372036854775807]) + if constexpr (std::is_same::value) { ss << std::setw(3) << std::setiosflags(std::ios::right) << static_cast(value); - } else if constexpr (std::is_same::value || std::is_same::value) { + } else if constexpr (std::is_same::value) { + ss << std::setw(4) << std::setiosflags(std::ios::right) << static_cast(value); + } else if constexpr (std::is_same::value) { ss << std::setw(5) << std::setiosflags(std::ios::right) << value; - } else if constexpr (std::is_same::value || std::is_same::value) { + } else if constexpr (std::is_same::value) { + ss << std::setw(6) << std::setiosflags(std::ios::right) << value; + } else if constexpr (std::is_same::value) { ss << std::setw(10) << std::setiosflags(std::ios::right) << value; + } else if constexpr (std::is_same::value) { + ss << std::setw(11) << std::setiosflags(std::ios::right) << value; } else { ss << value; } } if (!isScalar && i != end - 1) { + if (use_comma) { + ss << ','; + } ss << ' '; } if (!isScalar && ndim_ == 1 && (i + 1) % linefeedThreshold == 0) { @@ -301,7 +311,8 @@ class TensorDataImpl : public TensorData { } } - void SummaryStringRecursive(std::ostringstream &ss, const ShapeVector &shape, ssize_t *cursor, ssize_t depth) const { + void SummaryStringRecursive(std::ostringstream &ss, const ShapeVector &shape, ssize_t *cursor, ssize_t depth, + bool use_comma) const { if (depth >= static_cast(ndim_)) { return; } @@ -309,11 +320,11 @@ class TensorDataImpl : public TensorData { if (depth == static_cast(ndim_) - 1) { // Bottom dimension ssize_t num = shape[depth]; if (num > kThreshold && ndim_ > 1) { - OutputDataString(ss, *cursor, 0, kThreshold / 2); + OutputDataString(ss, *cursor, 0, kThreshold / 2, use_comma); ss << ' ' << kEllipsis << ' '; - OutputDataString(ss, *cursor, num - kThreshold / 2, num); + OutputDataString(ss, *cursor, num - kThreshold / 2, num, use_comma); } else { - OutputDataString(ss, *cursor, 0, num); + OutputDataString(ss, *cursor, 0, num, use_comma); } *cursor += num; } else { // Middle dimension @@ -321,13 +332,19 @@ class TensorDataImpl : public TensorData { // Handle the first half. for (ssize_t i = 0; i < std::min(static_cast(kThreshold / 2), num); i++) { if (i > 0) { + if (use_comma) { + ss << ','; + } ss << '\n'; ss << std::setw(depth + 1) << ' '; // Add the indent. } - SummaryStringRecursive(ss, shape, cursor, depth + 1); + SummaryStringRecursive(ss, shape, cursor, depth + 1, use_comma); } // Handle the ignored part. if (num > kThreshold) { + if (use_comma) { + ss << ','; + } ss << '\n'; ss << std::setw(depth + 1) << ' '; // Add the indent. ss << kEllipsis; @@ -343,10 +360,14 @@ class TensorDataImpl : public TensorData { } // Handle the second half. if (num > kThreshold / 2) { - for (ssize_t i = num - kThreshold / 2; i < num; i++) { + auto continue_pos = num - kThreshold / 2; + for (ssize_t i = continue_pos; i < num; i++) { + if (use_comma && i != continue_pos) { + ss << ','; + } ss << '\n'; ss << std::setw(depth + 1) << ' '; // Add the indent. - SummaryStringRecursive(ss, shape, cursor, depth + 1); + SummaryStringRecursive(ss, shape, cursor, depth + 1, use_comma); } } } @@ -487,29 +508,35 @@ std::string Tensor::GetShapeAndDataTypeInfo() const { return buf.str(); } -std::string Tensor::ToString() const { - constexpr int small_tensor_size = 30; +std::string Tensor::ToStringInternal(int limit_size) const { std::ostringstream buf; auto dtype = Dtype(); MS_EXCEPTION_IF_NULL(dtype); data_sync(); buf << "Tensor(shape=" << ShapeToString(shape_) << ", dtype=" << dtype->ToString() << ','; - if (DataSize() < small_tensor_size) { + if (limit_size <= 0 || DataSize() < limit_size) { // Only print data for small tensor. - buf << ((data().ndim() > 1) ? '\n' : ' ') << data().ToString(data_type_, shape_) << ')'; + buf << ((data().ndim() > 1) ? '\n' : ' ') << data().ToString(data_type_, shape_, false) << ')'; } else { buf << " [...])"; } return buf.str(); } +std::string Tensor::ToString() const { + constexpr int small_tensor_size = 30; + return ToStringInternal(small_tensor_size); +} + +std::string Tensor::ToStringNoLimit() const { return ToStringInternal(0); } + std::string Tensor::ToStringRepr() const { std::ostringstream buf; auto dtype = Dtype(); MS_EXCEPTION_IF_NULL(dtype); data_sync(); buf << "Tensor(shape=" << ShapeToString(shape_) << ", dtype=" << dtype->ToString() << ',' - << ((data().ndim() > 1) ? '\n' : ' ') << data().ToString(data_type_, shape_) << ')'; + << ((data().ndim() > 1) ? '\n' : ' ') << data().ToString(data_type_, shape_, true) << ')'; return buf.str(); } diff --git a/mindspore/core/ir/tensor.h b/mindspore/core/ir/tensor.h index 8bf499a9b4a..315fb1c97f2 100644 --- a/mindspore/core/ir/tensor.h +++ b/mindspore/core/ir/tensor.h @@ -53,7 +53,7 @@ class TensorData { /// Is data equals. virtual bool equals(const TensorData &other) const = 0; /// To string. - virtual std::string ToString(const TypeId type, const ShapeVector &shape) const = 0; + virtual std::string ToString(const TypeId type, const ShapeVector &shape, bool use_comma) const = 0; }; using TensorDataPtr = std::shared_ptr; @@ -208,6 +208,10 @@ class Tensor : public MetaTensor { std::string GetShapeAndDataTypeInfo() const; + std::string ToStringInternal(int limit_size) const; + + std::string ToStringNoLimit() const; + std::string ToString() const override; std::string ToStringRepr() const;