ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
TensorMap.cpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
9 
10 #include <Logging.h>
11 #include <fmt/format.h>
12 
13 #include <sstream>
14 #include <string>
15 #include <unordered_map>
16 
17 namespace cloudViewer {
18 namespace t {
19 namespace geometry {
20 
22  const int64_t primary_size = GetPrimarySize();
23  for (auto& kv : *this) {
24  if (kv.second.GetLength() != primary_size) {
25  return false;
26  }
27  }
28  return true;
29 }
30 
31 void TensorMap::AssertPrimaryKeyInMapOrEmpty() const {
32  if (size() != 0 && count(primary_key_) == 0) {
33  utility::LogError("TensorMap does not contain primary key \"{}\".",
34  primary_key_);
35  }
36 }
37 
38 void TensorMap::AssertNoReservedKeys() const {
39  const std::unordered_set<std::string>& reserved_keys = GetReservedKeys();
40  for (const auto& kv : *this) {
41  if (reserved_keys.count(kv.first)) {
42  utility::LogError("TensorMap contains reserved key \"{}\".",
43  kv.first);
44  }
45  }
46 }
47 
49  if (!IsSizeSynchronized()) {
50  const int64_t primary_size = GetPrimarySize();
51  std::stringstream ss;
52  ss << fmt::format("Primary Tensor \"{}\" has size {}, however: \n",
53  primary_key_, primary_size);
54  for (auto& kv : *this) {
55  if (kv.first != primary_key_ &&
56  kv.second.GetLength() != primary_size) {
57  ss << fmt::format(" > Tensor \"{}\" has size {}.\n",
58  kv.first, kv.second.GetLength());
59  }
60  }
61  utility::LogError("{}", ss.str());
62  }
63 }
64 
66  for (const auto& kv : *this) {
67  if (!kv.second.IsContiguous()) {
68  return false;
69  }
70  }
71  return true;
72 }
73 
75  TensorMap tensor_map_contiguous(GetPrimaryKey());
76  for (const auto& kv : *this) {
77  // If the tensor is contiguous, the underlying memory is used.
78  tensor_map_contiguous[kv.first] = kv.second.Contiguous();
79  }
80  return tensor_map_contiguous;
81 }
82 
83 std::unordered_set<std::string> TensorMap::GetReservedKeys() {
84  const static std::unordered_set<std::string> reserved_keys = {
85  // Python reserved key.
86  "__class__",
87  "__contains__",
88  "__delattr__",
89  "__delitem__",
90  "__dir__",
91  "__doc__",
92  "__eq__",
93  "__format__",
94  "__ge__",
95  "__getattribute__",
96  "__getitem__",
97  "__gt__",
98  "__hash__",
99  "__init__",
100  "__init_subclass__",
101  "__iter__",
102  "__le__",
103  "__len__",
104  "__lt__",
105  "__ne__",
106  "__new__",
107  "__reduce__",
108  "__reduce_ex__",
109  "__repr__",
110  "__reversed__",
111  "__setattr__",
112  "__setitem__",
113  "__sizeof__",
114  "__str__",
115  "__subclasshook__",
116  "clear",
117  "copy",
118  "fromkeys",
119  "get",
120  "items",
121  "keys",
122  "pop",
123  "popitem",
124  "setdefault",
125  "update",
126  "values",
127  // Custom reserved keys.
128  "primary_key",
129  "is_size_synchronized",
130  "assert_size_synchronized",
131  };
132  return reserved_keys;
133 }
134 
135 std::string TensorMap::ToString() const {
136  const std::string primary_key = GetPrimaryKey();
137 
138  if (empty()) {
139  return fmt::format("TensorMap(primary_key=\"{}\") with no attribute",
140  primary_key);
141  }
142 
143  size_t max_key_len = 0;
144  bool has_primary_key = false;
145  std::vector<std::string> keys;
146  keys.reserve(size());
147  for (const auto& kv : *this) {
148  const std::string key = kv.first;
149  keys.push_back(key);
150  max_key_len = std::max(max_key_len, key.size());
151  if (key == primary_key) {
152  has_primary_key = true;
153  }
154  }
155  std::sort(keys.begin(), keys.end());
156 
157  const std::string tensor_format_str = fmt::format(
158  " - {{:<{}}}: shape={{}}, dtype={{}}, device={{}}", max_key_len);
159 
160  std::stringstream ss;
161  ss << fmt::format("TensorMap(primary_key=\"{}\") with {} attribute{}:",
162  primary_key, size(), size() > 1 ? "s" : "")
163  << std::endl;
164  for (const std::string& key : keys) {
165  const core::Tensor& val = at(key);
166  ss << fmt::format(tensor_format_str, key, val.GetShape().ToString(),
167  val.GetDtype().ToString(),
168  val.GetDevice().ToString());
169  if (key == primary_key) {
170  ss << " (primary)";
171  }
172  ss << std::endl;
173  }
174 
175  const std::string example_key = has_primary_key ? primary_key : keys[0];
176  ss << fmt::format(" (Use . to access attributes, e.g., tensor_map.{})",
177  example_key);
178  return ss.str();
179 }
180 
181 } // namespace geometry
182 } // namespace t
183 } // namespace cloudViewer
filament::Texture::InternalFormat format
int size
int count
std::string ToString() const
Returns string representation of device, e.g. "CPU:0", "CUDA:0".
Definition: Device.cpp:89
std::string ToString() const
Definition: Dtype.h:65
std::string ToString() const
Definition: SizeVector.cpp:132
Dtype GetDtype() const
Definition: Tensor.h:1164
Device GetDevice() const override
Definition: Tensor.cpp:1435
SizeVector GetShape() const
Definition: Tensor.h:1127
bool IsSizeSynchronized() const
Returns true if all tensors in the map have the same size.
Definition: TensorMap.cpp:21
std::string ToString() const
Print the TensorMap to string.
Definition: TensorMap.cpp:135
void AssertSizeSynchronized() const
Assert IsSizeSynchronized().
Definition: TensorMap.cpp:48
static std::unordered_set< std::string > GetReservedKeys()
Get reserved keys for the map. A map cannot contain any of these keys.
Definition: TensorMap.cpp:83
std::string GetPrimaryKey() const
Returns the primary key of the TensorMap.
Definition: TensorMap.h:159
#define LogError(...)
Definition: Logging.h:60
int max(int a, int b)
Definition: cutil_math.h:48
QTextStream & endl(QTextStream &stream)
Definition: QtCompat.h:718
Generic file read and write utility for python interface.
Rgb at(size_t color_id)