Open3D (C++ API)
AdvancedIndexing.h
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - Open3D: www.open3d.org -
3 // ----------------------------------------------------------------------------
4 // The MIT License (MIT)
5 //
6 // Copyright (c) 2018 www.open3d.org
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files (the "Software"), to deal
10 // in the Software without restriction, including without limitation the rights
11 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 // copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
14 //
15 // The above copyright notice and this permission notice shall be included in
16 // all copies or substantial portions of the Software.
17 //
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24 // IN THE SOFTWARE.
25 // ----------------------------------------------------------------------------
26 
27 #pragma once
28 
29 #include <vector>
30 
31 #include "Open3D/Core/Indexer.h"
32 #include "Open3D/Core/SizeVector.h"
33 #include "Open3D/Core/Tensor.h"
34 
35 namespace open3d {
36 
39 public:
41  const std::vector<Tensor>& index_tensors)
42  : tensor_(tensor), index_tensors_(ExpandBoolTensors(index_tensors)) {
43  RunPreprocess();
44  }
45 
46  inline Tensor GetTensor() const { return tensor_; }
47 
48  inline std::vector<Tensor> GetIndexTensors() const {
49  return index_tensors_;
50  }
51 
52  inline SizeVector GetOutputShape() const { return output_shape_; }
53 
54  inline SizeVector GetIndexedShape() const { return indexed_shape_; }
55 
56  inline SizeVector GetIndexedStrides() const { return indexed_strides_; }
57 
61  static bool IsIndexSplittedBySlice(
62  const std::vector<Tensor>& index_tensors);
63 
66  static std::pair<Tensor, std::vector<Tensor>> ShuffleIndexedDimsToFront(
67  const Tensor& tensor, const std::vector<Tensor>& index_tensors);
68 
71  static std::pair<std::vector<Tensor>, SizeVector>
72  ExpandToCommonShapeExceptZeroDim(const std::vector<Tensor>& index_tensors);
73 
74  // Replace indexed dimensions with stride 0 and the size of the result
75  // tensor.
76  //
77  // The offset in these dimensions is computed by the kernel using
78  // the index tensor's values and the stride of the tensor. The new shape is
79  // not meaningful. It's used to make the shape compatible with the result
80  // tensor.
81  //
82  // Effectively, we throw away the tensor's shape and strides for the sole
83  // purpose of element-wise iteration for the Indexer. The tensor's original
84  // strides are stored in indexed_shape_ and indexed_strides_,
85  // which are passed to fancy indexing kernels.
86  static Tensor RestrideTensor(const Tensor& tensor,
87  int64_t dims_before,
88  int64_t dims_indexed,
89  SizeVector replacement_shape);
90 
91  // Add dimensions of size 1 to an index tensor so that it can be broadcast
92  // to the result shape and iterated over element-wise like the result tensor
93  // and the restrided src.
94  static Tensor RestrideIndexTensor(const Tensor& index_tensor,
95  int64_t dims_before,
96  int64_t dims_after);
97 
98 protected:
100  void RunPreprocess();
101 
103  static std::vector<Tensor> ExpandBoolTensors(
104  const std::vector<Tensor>& index_tensors);
105 
109 
111  std::vector<Tensor> index_tensors_;
112 
115 
119 
123 };
124 
135 public:
136  enum class AdvancedIndexerMode { SET, GET };
137 
139  const Tensor& dst,
140  const std::vector<Tensor>& index_tensors,
141  const SizeVector& indexed_shape,
142  const SizeVector& indexed_strides,
144  : mode_(mode) {
145  if (indexed_shape.size() != indexed_strides.size()) {
147  "Internal error: indexed_shape's ndim {} does not equal to "
148  "indexd_strides' ndim {}",
149  indexed_shape.size(), indexed_strides.size());
150  }
151  num_indices_ = indexed_shape.size();
152 
153  // Initialize Indexer
154  std::vector<Tensor> inputs;
155  inputs.push_back(src);
156  for (const Tensor& index_tensor : index_tensors) {
157  if (index_tensor.NumDims() != 0) {
158  inputs.push_back(index_tensor);
159  }
160  }
161  indexer_ = Indexer({inputs}, dst, DtypePolicy::NONE);
162 
163  // Fill shape and strides
164  if (num_indices_ != static_cast<int64_t>(indexed_strides.size())) {
166  "Internal error: indexed_shape's ndim {} does not equal to "
167  "indexd_strides' ndim {}",
168  num_indices_, indexed_strides.size());
169  }
170  for (int64_t i = 0; i < num_indices_; ++i) {
171  indexed_shape_[i] = indexed_shape[i];
172  indexed_strides_[i] = indexed_strides[i];
173  }
174 
175  // Check dtypes
176  if (src.GetDtype() != dst.GetDtype()) {
178  "src's dtype {} is not the same as dst's dtype {}.",
180  DtypeUtil::ToString(dst.GetDtype()));
181  }
182  element_byte_size_ = DtypeUtil::ByteSize(src.GetDtype());
183  }
184 
185  inline OPEN3D_HOST_DEVICE char* GetInputPtr(int64_t workload_idx) const {
186  char* ptr = indexer_.GetInputPtr(0, workload_idx);
187  ptr += GetIndexedOffset(workload_idx) * element_byte_size_ *
188  (mode_ == AdvancedIndexerMode::GET);
189  return ptr;
190  }
191 
192  inline OPEN3D_HOST_DEVICE char* GetOutputPtr(int64_t workload_idx) const {
193  char* ptr = indexer_.GetOutputPtr(workload_idx);
194  ptr += GetIndexedOffset(workload_idx) * element_byte_size_ *
195  (mode_ == AdvancedIndexerMode::SET);
196  return ptr;
197  }
198 
199  inline OPEN3D_HOST_DEVICE int64_t
200  GetIndexedOffset(int64_t workload_idx) const {
201  int64_t offset = 0;
202  for (int64_t i = 0; i < num_indices_; ++i) {
203  int64_t index = *(reinterpret_cast<int64_t*>(
204  indexer_.GetInputPtr(i + 1, workload_idx)));
205  assert(index >= -indexed_shape_[i] && index < indexed_shape_[i] &&
206  "Index out of bounds");
207  index += indexed_shape_[i] * (index < 0);
208  offset += index * indexed_strides_[i];
209  }
210  return offset;
211  }
212 
213  int64_t NumWorkloads() const { return indexer_.NumWorkloads(); }
214 
215 protected:
218  int64_t num_indices_;
220  int64_t indexed_shape_[MAX_DIMS];
221  int64_t indexed_strides_[MAX_DIMS];
222 };
223 
224 } // namespace open3d
SizeVector output_shape_
Output shape.
Definition: AdvancedIndexing.h:114
const char const char value recording_handle imu_sample recording_handle uint8_t size_t data_size k4a_record_configuration_t config target_format k4a_capture_t capture_handle k4a_imu_sample_t imu_sample playback_handle k4a_logging_message_cb_t void min_level device_handle k4a_imu_sample_t timeout_in_ms capture_handle capture_handle capture_handle image_handle temperature_c k4a_image_t image_handle uint8_t image_handle image_handle image_handle image_handle image_handle timestamp_usec white_balance image_handle k4a_device_configuration_t config device_handle char size_t serial_number_size bool int32_t int32_t int32_t int32_t k4a_color_control_mode_t default_mode mode
Definition: K4aPlugin.cpp:676
Dtype GetDtype() const
Definition: Tensor.h:742
std::vector< Tensor > index_tensors_
The processed index tensors.
Definition: AdvancedIndexing.h:111
int64_t num_indices_
Definition: AdvancedIndexing.h:218
OPEN3D_HOST_DEVICE int64_t GetIndexedOffset(int64_t workload_idx) const
Definition: AdvancedIndexing.h:200
Tensor GetTensor() const
Definition: AdvancedIndexing.h:46
AdvancedIndexerMode mode_
Definition: AdvancedIndexing.h:217
SizeVector GetIndexedShape() const
Definition: AdvancedIndexing.h:54
int offset
Definition: FilePCD.cpp:62
void LogError(const char *format, const Args &... args)
Definition: Console.h:174
Indexer indexer_
Definition: AdvancedIndexing.h:216
void RunPreprocess()
Preprocess tensor and index tensors.
Definition: AdvancedIndexing.cpp:128
static std::pair< Tensor, std::vector< Tensor > > ShuffleIndexedDimsToFront(const Tensor &tensor, const std::vector< Tensor > &index_tensors)
Definition: AdvancedIndexing.cpp:59
static std::vector< Tensor > ExpandBoolTensors(const std::vector< Tensor > &index_tensors)
Expand boolean tensor to integer index.
Definition: AdvancedIndexing.cpp:248
static Tensor RestrideIndexTensor(const Tensor &index_tensor, int64_t dims_before, int64_t dims_after)
Definition: AdvancedIndexing.cpp:118
int64_t NumWorkloads() const
Definition: AdvancedIndexing.h:213
Definition: AdvancedIndexing.h:134
SizeVector indexed_strides_
Definition: AdvancedIndexing.h:122
#define OPEN3D_HOST_DEVICE
Definition: CUDAUtils.h:54
Definition: SizeVector.h:40
static int64_t ByteSize(const Dtype &dtype)
Definition: Dtype.h:61
SizeVector indexed_shape_
Definition: AdvancedIndexing.h:118
static bool IsIndexSplittedBySlice(const std::vector< Tensor > &index_tensors)
Definition: AdvancedIndexing.cpp:35
static Tensor RestrideTensor(const Tensor &tensor, int64_t dims_before, int64_t dims_indexed, SizeVector replacement_shape)
Definition: AdvancedIndexing.cpp:103
Tensor tensor_
Definition: AdvancedIndexing.h:108
SizeVector GetIndexedStrides() const
Definition: AdvancedIndexing.h:56
SizeVector GetOutputShape() const
Definition: AdvancedIndexing.h:52
OPEN3D_HOST_DEVICE char * GetInputPtr(int64_t workload_idx) const
Definition: AdvancedIndexing.h:185
Definition: Open3DViewer.h:29
Definition: Indexer.h:260
static std::pair< std::vector< Tensor >, SizeVector > ExpandToCommonShapeExceptZeroDim(const std::vector< Tensor > &index_tensors)
Definition: AdvancedIndexing.cpp:81
std::vector< Tensor > GetIndexTensors() const
Definition: AdvancedIndexing.h:48
AdvancedIndexerMode
Definition: AdvancedIndexing.h:136
This class is based on PyTorch&#39;s aten/src/ATen/native/Indexing.cpp.
Definition: AdvancedIndexing.h:38
OPEN3D_HOST_DEVICE char * GetOutputPtr(int64_t workload_idx) const
Definition: AdvancedIndexing.h:192
AdvancedIndexPreprocessor(const Tensor &tensor, const std::vector< Tensor > &index_tensors)
Definition: AdvancedIndexing.h:40
static std::string ToString(const Dtype &dtype)
Definition: Dtype.h:97
Definition: Tensor.h:46
AdvancedIndexer(const Tensor &src, const Tensor &dst, const std::vector< Tensor > &index_tensors, const SizeVector &indexed_shape, const SizeVector &indexed_strides, AdvancedIndexerMode mode)
Definition: AdvancedIndexing.h:138
int64_t element_byte_size_
Definition: AdvancedIndexing.h:219