Open3D (C++ API)  0.20.0
Loading...
Searching...
No Matches
Indexer.h
Go to the documentation of this file.
1// ----------------------------------------------------------------------------
2// - Open3D: www.open3d.org -
3// ----------------------------------------------------------------------------
4// Copyright (c) 2018-2026 www.open3d.org
5// SPDX-License-Identifier: MIT
6// ----------------------------------------------------------------------------
7
8#pragma once
9
10#include <sstream>
11
13#include "open3d/core/Dtype.h"
16#include "open3d/core/Tensor.h"
19
20// The generated "Indexer_ispc.h" header will not be available outside the
21// library. Therefore, forward declare all exported ISPC classes.
22#ifdef BUILD_ISPC_MODULE
23namespace ispc {
24struct TensorRef;
25struct Indexer;
26} // namespace ispc
27#endif
28
29namespace open3d {
30namespace core {
31
32class Indexer;
33
34class IndexerIterator;
35
36// Maximum number of dimensions of TensorRef.
37static constexpr int64_t MAX_DIMS = 5;
38
39// Maximum number of inputs of an op.
40// MAX_INPUTS shall be >= MAX_DIMS to support advanced indexing.
41static constexpr int64_t MAX_INPUTS = 5;
42
43// Maximum number of outputs of an op. This number can be increased when
44// necessary.
45static constexpr int64_t MAX_OUTPUTS = 2;
46
47template <int NARGS, typename index_t = uint32_t>
50 const int64_t* sizes,
51 const int64_t* const* strides)
52 : dims_(dims) {
53 if (dims_ > MAX_DIMS) {
54 utility::LogError("tensor has too many (>{}) dims_", MAX_DIMS);
55 }
56
57 for (int i = 0; i < MAX_DIMS; ++i) {
58 if (i < dims_) {
59 sizes_[i] = sizes[i];
60 } else {
61 sizes_[i] = 1;
62 }
63 for (int arg = 0; arg < NARGS; arg++) {
64 strides_[i][arg] = i < dims_ ? strides[arg][i] : 0;
65 }
66 }
67 }
68
70 index_t linear_idx) const {
72#if defined(__CUDA_ARCH__)
73#pragma unroll
74#endif
75 for (int arg = 0; arg < NARGS; arg++) {
76 offsets[arg] = 0;
77 }
78
79#if defined(__CUDA_ARCH__)
80#pragma unroll
81#endif
82 for (int dim = 0; dim < MAX_DIMS; ++dim) {
83 if (dim == dims_) {
84 break;
85 }
86 index_t mod = linear_idx % sizes_[dim];
87 linear_idx = linear_idx / sizes_[dim];
88
89#if defined(__CUDA_ARCH__)
90#pragma unroll
91#endif
92 for (int arg = 0; arg < NARGS; arg++) {
93 offsets[arg] += mod * strides_[dim][arg];
94 }
95 }
96 return offsets;
97 }
98
99 int dims_;
100 index_t sizes_[MAX_DIMS];
101 index_t strides_[MAX_DIMS][NARGS];
102};
103
105struct TensorRef {
106 // The default copy constructor works on __device__ as well so we don't
107 // define it explicitly. shape_[MAX_DIMS] and strides[MAX_DIMS] will be
108 // copied fully.
109 TensorRef() : data_ptr_(nullptr) {}
110
111 TensorRef(const Tensor& t) {
112 if (t.NumDims() > MAX_DIMS) {
113 utility::LogError("Tensor has too many dimensions {} > {}.",
114 t.NumDims(), MAX_DIMS);
115 }
116 data_ptr_ = const_cast<void*>(t.GetDataPtr());
117 ndims_ = t.NumDims();
118 dtype_byte_size_ = t.GetDtype().ByteSize();
119 for (int64_t i = 0; i < ndims_; ++i) {
120 shape_[i] = t.GetShape(i);
121 byte_strides_[i] = t.GetStride(i) * dtype_byte_size_;
122 }
124 }
125
131 int64_t num_elements = 1;
132 for (int64_t i = 0; i < ndims_; ++i) {
133 num_elements *= shape_[i];
134 }
137 if (num_elements == 0) {
138 return;
139 }
140 int64_t min_o = 0;
141 int64_t max_o = 0;
142 for (int64_t d = 0; d < ndims_; ++d) {
143 const int64_t max_coord = shape_[d] - 1;
144 const int64_t stride = byte_strides_[d];
145 const int64_t dim_min = stride >= 0 ? 0 : max_coord * stride;
146 const int64_t dim_max = stride >= 0 ? max_coord * stride : 0;
147 min_o += dim_min;
148 max_o += dim_max;
149 }
150 min_byte_offset_ = min_o;
151 total_byte_size_ = max_o - min_o + dtype_byte_size_;
152 }
153
155 if (total_byte_size_ == 0) {
156 return offset == min_byte_offset_;
157 }
158 return offset >= min_byte_offset_ &&
160 }
161
168 void Permute(const SizeVector& dims) {
169 // Check dims are permuntation of [0, 1, 2, ..., n-1]
170 if (static_cast<int64_t>(dims.size()) != ndims_) {
171 utility::LogError("Number of dimensions mismatch {} != {}.",
172 dims.size(), ndims_);
173 }
174 std::vector<bool> seen_dims(ndims_, false);
175 for (const int64_t& dim : dims) {
176 seen_dims[dim] = true;
177 }
178 if (!std::all_of(seen_dims.begin(), seen_dims.end(),
179 [](bool seen) { return seen; })) {
180 utility::LogError(
181 "Permute dims must be a permuntation from 0 to {}.",
182 dims.size() - 1);
183 }
184
185 // Map to new shape and strides
186 SizeVector new_shape(ndims_);
187 SizeVector new_byte_strides(ndims_);
188 for (int64_t i = 0; i < ndims_; ++i) {
189 int64_t old_dim = shape_util::WrapDim(dims[i], ndims_);
190 new_shape[i] = shape_[old_dim];
191 new_byte_strides[i] = byte_strides_[old_dim];
192 }
193 for (int64_t i = 0; i < ndims_; ++i) {
194 shape_[i] = new_shape[i];
195 byte_strides_[i] = new_byte_strides[i];
196 }
197 }
198
201 inline bool IsContiguous() const {
202 SizeVector shape(ndims_);
203 SizeVector strides(ndims_);
204 for (int64_t i = 0; i < ndims_; ++i) {
205 shape[i] = shape_[i];
206 strides[i] = byte_strides_[i] / dtype_byte_size_;
207 }
208 return shape_util::DefaultStrides(shape) == strides;
209 }
210
211 bool operator==(const TensorRef& other) const {
212 bool rc = true;
213 rc = rc && (data_ptr_ == other.data_ptr_);
214 rc = rc && (ndims_ == other.ndims_);
215 rc = rc && (dtype_byte_size_ == other.dtype_byte_size_);
216 rc = rc && (min_byte_offset_ == other.min_byte_offset_);
217 rc = rc && (total_byte_size_ == other.total_byte_size_);
218 for (int64_t i = 0; i < ndims_; ++i) {
219 rc = rc && (shape_[i] == other.shape_[i]);
220 rc = rc && (byte_strides_[i] == other.byte_strides_[i]);
221 }
222 return rc;
223 }
224
225 bool operator!=(const TensorRef& other) const { return !(*this == other); }
226
227#ifdef BUILD_ISPC_MODULE
229 ispc::TensorRef ToISPC() const;
230#endif
231
233 int64_t ndims_ = 0;
234 int64_t dtype_byte_size_ = 0;
235 int64_t min_byte_offset_ = 0;
236 int64_t total_byte_size_ = 0;
237 int64_t shape_[MAX_DIMS];
238 int64_t byte_strides_[MAX_DIMS];
239};
240
241enum class DtypePolicy {
242 NONE, // Do not check. Expects the kernel to handle the conversion.
243 // E.g. in Copy kernel with type casting.
244 ALL_SAME, // All inputs and outputs to to have the same dtype.
245 INPUT_SAME, // All inputs have the same dtype.
246 INPUT_SAME_OUTPUT_BOOL // All inputs have the same dtype. Outputs
247 // have bool dtype.
248};
249
268public:
269 TensorIterator(const Tensor& tensor)
270 : input_(TensorRef(tensor)), ndims_(tensor.NumDims()) {
271 is_contiguous_ = true;
272 int64_t expected_byte_stride = input_.dtype_byte_size_;
273 for (int64_t d = ndims_ - 1; d >= 0; --d) {
274 if (input_.byte_strides_[d] != expected_byte_stride) {
275 is_contiguous_ = false;
276 break;
277 }
278 expected_byte_stride *= input_.shape_[d];
279 }
280 }
281
283 int64_t num_workloads = 1;
284 for (int64_t i = 0; i < ndims_; ++i) {
285 num_workloads *= input_.shape_[i];
286 }
287 return num_workloads;
288 }
289
291 OPEN3D_HOST_DEVICE void* GetPtr(int64_t workload_idx) const {
292 if (workload_idx < 0 || workload_idx >= NumWorkloads()) {
293 return nullptr;
294 }
295 int64_t offset;
296 if (is_contiguous_) {
297 offset = workload_idx * input_.dtype_byte_size_;
298 } else {
299 offset = 0;
300 int64_t remaining = workload_idx;
301 for (int64_t d = ndims_ - 1; d >= 0; --d) {
302 const int64_t coord = remaining % input_.shape_[d];
303 remaining /= input_.shape_[d];
304 offset += coord * input_.byte_strides_[d];
305 }
306 }
308 "Index operation data pointer is out of range.");
309 return static_cast<void*>(static_cast<char*>(input_.data_ptr_) +
310 offset);
311 }
312
313protected:
315 int64_t ndims_;
317};
318
326class Indexer {
327public:
329 Indexer(const Indexer&) = default;
330 Indexer& operator=(const Indexer&) = default;
331
335 Indexer(const std::vector<Tensor>& input_tensors,
336 const Tensor& output_tensor,
337 DtypePolicy dtype_policy = DtypePolicy::ALL_SAME,
338 const SizeVector& reduction_dims = {});
339
340 Indexer(const std::vector<Tensor>& input_tensors,
341 const std::vector<Tensor>& output_tensors,
342 DtypePolicy dtype_policy = DtypePolicy::ALL_SAME,
343 const SizeVector& reduction_dims = {});
344
346 bool CanUse32BitIndexing() const;
347
350 IndexerIterator SplitTo32BitIndexing() const;
351
355 std::unique_ptr<Indexer> SplitLargestDim();
356
359 Indexer GetPerOutputIndexer(int64_t output_idx) const;
360
361 bool ShouldAccumulate() const { return accumulate_; }
362
363 bool IsFinalOutput() const { return final_output_; }
364
370 void ShrinkDim(int64_t dim, int64_t start, int64_t size);
371
373 int64_t NumReductionDims() const;
374
376 int64_t NumDims() const { return ndims_; }
377
380 const int64_t* GetPrimaryShape() const { return primary_shape_; }
381 int64_t* GetPrimaryShape() { return primary_shape_; }
382
385 const int64_t* GetPrimaryStrides() const { return primary_strides_; }
386
397 int64_t NumWorkloads() const;
398
400 int64_t NumOutputElements() const;
401
403 int64_t NumInputs() const { return num_inputs_; }
404
406 int64_t NumOutputs() const { return num_outputs_; }
407
409 TensorRef& GetInput(int64_t i) {
410 if (i >= num_inputs_ || i < 0) {
411 utility::LogError("0 <= i < {} required, however, i = {}.",
412 num_inputs_, i);
413 }
414 return inputs_[i];
415 }
416 const TensorRef& GetInput(int64_t i) const {
417 if (i >= num_inputs_ || i < 0) {
418 utility::LogError("0 <= i < {} required, however, i = {}.",
419 num_inputs_, i);
420 }
421 return inputs_[i];
422 }
423
425 TensorRef& GetOutput(int64_t i) {
426 if (i >= num_outputs_ || i < 0) {
427 utility::LogError("0 <= i < {} required, however, i = {}.",
428 num_outputs_, i);
429 }
430 return outputs_[i];
431 }
432 const TensorRef& GetOutput(int64_t i) const {
433 if (i >= num_outputs_ || i < 0) {
434 utility::LogError("0 <= i < {} required, however, i = {}.",
435 num_outputs_, i);
436 }
437 return outputs_[i];
438 }
439
443 if (num_outputs_ > 1) {
444 utility::LogError("num_outputs_ == {} > 0, use GetOutput(i)",
446 }
447 return GetOutput(0);
448 }
449 const TensorRef& GetOutput() const {
450 if (num_outputs_ > 1) {
451 utility::LogError("num_outputs_ == {} > 0, use GetOutput(i)",
453 }
454 return GetOutput(0);
455 }
456
458 bool IsReductionDim(int64_t dim) const {
459 // All outputs have the same shape and reduction dims. Even if they
460 // don't have the same initial strides, the reduced strides are always
461 // set to 0. Thus it is okay to use outputs_[0].
462 return outputs_[0].byte_strides_[dim] == 0 && primary_shape_[dim] > 1;
463 }
464
470 OPEN3D_HOST_DEVICE char* GetInputPtr(int64_t input_idx,
471 int64_t workload_idx) const {
472 if (input_idx < 0 || input_idx >= num_inputs_) {
473 return nullptr;
474 }
475 return GetWorkloadDataPtr(inputs_[input_idx],
476 inputs_contiguous_[input_idx], workload_idx);
477 }
478
487 template <typename T>
488 OPEN3D_HOST_DEVICE T* GetInputPtr(int64_t input_idx,
489 int64_t workload_idx) const {
490 if (input_idx < 0 || input_idx >= num_inputs_) {
491 return nullptr;
492 }
493 return GetWorkloadDataPtr<T>(inputs_[input_idx],
494 inputs_contiguous_[input_idx],
495 workload_idx);
496 }
497
502 OPEN3D_HOST_DEVICE char* GetOutputPtr(int64_t workload_idx) const {
504 workload_idx);
505 }
506
514 template <typename T>
515 OPEN3D_HOST_DEVICE T* GetOutputPtr(int64_t workload_idx) const {
516 return GetWorkloadDataPtr<T>(outputs_[0], outputs_contiguous_[0],
517 workload_idx);
518 }
519
525 OPEN3D_HOST_DEVICE char* GetOutputPtr(int64_t output_idx,
526 int64_t workload_idx) const {
527 return GetWorkloadDataPtr(outputs_[output_idx],
528 outputs_contiguous_[output_idx],
529 workload_idx);
530 }
531
537 template <typename T>
538 OPEN3D_HOST_DEVICE T* GetOutputPtr(int64_t output_idx,
539 int64_t workload_idx) const {
540 return GetWorkloadDataPtr<T>(outputs_[output_idx],
541 outputs_contiguous_[output_idx],
542 workload_idx);
543 }
544
545#ifdef BUILD_ISPC_MODULE
547 ispc::Indexer ToISPC() const;
548#endif
549
550protected:
553 void CoalesceDimensions();
554
555 // Permute reduction dimensions to front.
556 // TODO: Sort the dimensions based on strides in ascending orderto improve
557 // thread coalescing.
558 void ReorderDimensions(const SizeVector& reduction_dims);
559
562
565
592 static void BroadcastRestride(TensorRef& src,
593 int64_t dst_ndims,
594 const int64_t* dst_shape);
595
598 static void ReductionRestride(TensorRef& dst,
599 int64_t src_ndims,
600 const int64_t* src_shape,
601 const SizeVector& reduction_dims);
602
607 bool tr_contiguous,
608 int64_t workload_idx) const {
609 // For 0-sized input reduction op, the output Tensor
610 // workload_idx == 1 > NumWorkloads() == 0.
611 if (workload_idx < 0) {
612 return nullptr;
613 }
614
615 int64_t offset = 0;
616 bool use_linear = tr_contiguous;
617 for (int64_t i = 0; i < ndims_; ++i) {
618 if (tr.byte_strides_[i] == 0) {
619 use_linear = false;
620 break;
621 }
622 }
623 if (use_linear) {
624 int64_t tr_elements = 1;
625 for (int64_t i = 0; i < tr.ndims_; ++i) {
626 tr_elements *= tr.shape_[i];
627 }
628 int64_t primary_elements = 1;
629 for (int64_t i = 0; i < ndims_; ++i) {
630 primary_elements *= primary_shape_[i];
631 }
632 if (tr_elements != primary_elements) {
633 use_linear = false;
634 }
635 }
636 if (use_linear) {
637 offset = workload_idx * tr.dtype_byte_size_;
638 } else {
639 for (int64_t i = 0; i < ndims_; ++i) {
640 offset += workload_idx / primary_strides_[i] *
641 tr.byte_strides_[i];
642 workload_idx = workload_idx % primary_strides_[i];
643 }
644 }
645
647 "Index operation data pointer is out of range.");
648 return static_cast<char*>(tr.data_ptr_) + offset;
649 }
650
657 template <typename T>
659 bool tr_contiguous,
660 int64_t workload_idx) const {
661 // See note of this function.
662 // If sizeof(T) == tr.dtype_byte_size_, then we can just static cast the
663 // byte pointer.
664 return static_cast<T*>(static_cast<void*>(
665 GetWorkloadDataPtr(tr, tr_contiguous, workload_idx)));
666 }
667
669 int64_t num_inputs_ = 0;
670 int64_t num_outputs_ = 0;
671
673 TensorRef inputs_[MAX_INPUTS];
674
676 TensorRef outputs_[MAX_OUTPUTS];
677
679 bool inputs_contiguous_[MAX_INPUTS];
680
682 bool outputs_contiguous_[MAX_OUTPUTS];
683
695 int64_t primary_shape_[MAX_DIMS];
696
699 int64_t primary_strides_[MAX_DIMS];
700
702 int64_t ndims_ = 0;
703
707 bool final_output_ = true;
708
711 bool accumulate_ = false;
712};
713
715public:
716 struct Iterator {
718 Iterator(const Indexer& indexer);
719 Iterator(Iterator&& other) = default;
720
721 Indexer& operator*() const;
723 bool operator==(const Iterator& other) const;
724 bool operator!=(const Iterator& other) const;
725
726 std::vector<std::unique_ptr<Indexer>> vec_;
727 };
728
730
731 Iterator begin() const;
732 Iterator end() const;
733
734private:
735 const Indexer& indexer_;
736};
737
738} // namespace core
739} // namespace open3d
Common CUDA utilities.
#define OPEN3D_HOST_DEVICE
Definition CUDAUtils.h:43
#define OPEN3D_ASSERT(...)
Definition Macro.h:58
const NeighborOffsets & offsets
Definition NormalDistributionsTransform.cpp:254
double t
Definition SurfaceReconstructionPoisson.cpp:175
size_t stride
Definition TriangleMeshBuffers.cpp:163
Indexer indexer
Definition UnaryEWSYCL.cpp:35
Definition Indexer.h:326
const TensorRef & GetInput(int64_t i) const
Definition Indexer.h:416
void UpdatePrimaryStrides()
Update primary_strides_ based on primary_shape_.
Definition Indexer.cpp:556
void UpdateContiguousFlags()
Update input_contiguous_ and output_contiguous_.
Definition Indexer.cpp:565
bool inputs_contiguous_[MAX_INPUTS]
Array of contiguous flags for all input TensorRefs.
Definition Indexer.h:679
bool outputs_contiguous_[MAX_OUTPUTS]
Array of contiguous flags for all output TensorRefs.
Definition Indexer.h:682
Indexer()
Definition Indexer.h:328
OPEN3D_HOST_DEVICE T * GetOutputPtr(int64_t output_idx, int64_t workload_idx) const
Definition Indexer.h:538
int64_t num_outputs_
Definition Indexer.h:670
OPEN3D_HOST_DEVICE char * GetOutputPtr(int64_t output_idx, int64_t workload_idx) const
Definition Indexer.h:525
TensorRef & GetOutput(int64_t i)
Returns output TensorRef.
Definition Indexer.h:425
static void ReductionRestride(TensorRef &dst, int64_t src_ndims, const int64_t *src_shape, const SizeVector &reduction_dims)
Definition Indexer.cpp:602
TensorRef outputs_[MAX_OUTPUTS]
Array of output TensorRefs.
Definition Indexer.h:676
bool IsReductionDim(int64_t dim) const
Returns true if the dim -th dimension is reduced.
Definition Indexer.h:458
int64_t NumReductionDims() const
Returns the number of reduction dimensions.
Definition Indexer.cpp:395
int64_t NumInputs() const
Number of input Tensors.
Definition Indexer.h:403
int64_t primary_strides_[MAX_DIMS]
Definition Indexer.h:699
const TensorRef & GetOutput() const
Definition Indexer.h:449
Indexer(const Indexer &)=default
bool IsFinalOutput() const
Definition Indexer.h:363
void ReorderDimensions(const SizeVector &reduction_dims)
Definition Indexer.cpp:491
void CoalesceDimensions()
Definition Indexer.cpp:425
Indexer & operator=(const Indexer &)=default
int64_t NumOutputElements() const
Returns the number of output elements.
Definition Indexer.cpp:414
int64_t num_inputs_
Number of input and output Tensors.
Definition Indexer.h:669
bool accumulate_
Definition Indexer.h:711
bool CanUse32BitIndexing() const
Returns true iff the maximum_offsets in bytes are smaller than 2^31 - 1.
Definition Indexer.cpp:198
TensorRef inputs_[MAX_INPUTS]
Array of input TensorRefs.
Definition Indexer.h:673
OPEN3D_HOST_DEVICE char * GetWorkloadDataPtr(const TensorRef &tr, bool tr_contiguous, int64_t workload_idx) const
Definition Indexer.h:606
OPEN3D_HOST_DEVICE T * GetOutputPtr(int64_t workload_idx) const
Definition Indexer.h:515
bool ShouldAccumulate() const
Definition Indexer.h:361
const int64_t * GetPrimaryStrides() const
Definition Indexer.h:385
Indexer GetPerOutputIndexer(int64_t output_idx) const
Definition Indexer.cpp:303
std::unique_ptr< Indexer > SplitLargestDim()
Definition Indexer.cpp:238
OPEN3D_HOST_DEVICE T * GetWorkloadDataPtr(const TensorRef &tr, bool tr_contiguous, int64_t workload_idx) const
Definition Indexer.h:658
OPEN3D_HOST_DEVICE char * GetOutputPtr(int64_t workload_idx) const
Definition Indexer.h:502
OPEN3D_HOST_DEVICE T * GetInputPtr(int64_t input_idx, int64_t workload_idx) const
Definition Indexer.h:488
int64_t NumWorkloads() const
Definition Indexer.cpp:406
OPEN3D_HOST_DEVICE char * GetInputPtr(int64_t input_idx, int64_t workload_idx) const
Definition Indexer.h:470
IndexerIterator SplitTo32BitIndexing() const
Definition Indexer.cpp:234
const int64_t * GetPrimaryShape() const
Definition Indexer.h:380
TensorRef & GetInput(int64_t i)
Returns input TensorRef.
Definition Indexer.h:409
TensorRef & GetOutput()
Definition Indexer.h:442
static void BroadcastRestride(TensorRef &src, int64_t dst_ndims, const int64_t *dst_shape)
Definition Indexer.cpp:575
bool final_output_
Definition Indexer.h:707
const TensorRef & GetOutput(int64_t i) const
Definition Indexer.h:432
int64_t ndims_
Indexer's global number of dimensions.
Definition Indexer.h:702
void ShrinkDim(int64_t dim, int64_t start, int64_t size)
Definition Indexer.cpp:364
int64_t NumDims() const
Returns number of dimensions of the Indexer.
Definition Indexer.h:376
int64_t NumOutputs() const
Number of output Tensors.
Definition Indexer.h:406
int64_t * GetPrimaryShape()
Definition Indexer.h:381
int64_t primary_shape_[MAX_DIMS]
Definition Indexer.h:695
Definition Indexer.h:714
Iterator end() const
Definition Indexer.cpp:671
Iterator begin() const
Definition Indexer.cpp:667
Definition SizeVector.h:69
size_t size() const
Definition SmallVector.h:120
Definition Tensor.h:32
Definition Indexer.h:267
OPEN3D_HOST_DEVICE int64_t NumWorkloads() const
Definition Indexer.h:282
TensorRef input_
Definition Indexer.h:314
TensorIterator(const Tensor &tensor)
Definition Indexer.h:269
bool is_contiguous_
Definition Indexer.h:316
OPEN3D_HOST_DEVICE void * GetPtr(int64_t workload_idx) const
Pointer to the element at linear index workload_idx, or nullptr.
Definition Indexer.h:291
int64_t ndims_
Definition Indexer.h:315
int size
Definition FilePCD.cpp:41
int offset
Definition FilePCD.cpp:46
int64_t WrapDim(int64_t dim, int64_t max_dim, bool inclusive)
Wrap around negative dim.
Definition ShapeUtil.cpp:131
SizeVector DefaultStrides(const SizeVector &shape)
Compute default strides for a shape when a tensor is contiguous.
Definition ShapeUtil.cpp:214
DtypePolicy
Definition Indexer.h:241
Definition PinholeCameraIntrinsic.cpp:16
bool operator!=(const Iterator &other) const
Definition Indexer.cpp:663
Iterator()
Definition Indexer.h:717
std::vector< std::unique_ptr< Indexer > > vec_
Definition Indexer.h:726
Iterator(Iterator &&other)=default
Indexer & operator*() const
Definition Indexer.cpp:649
bool operator==(const Iterator &other) const
Definition Indexer.cpp:660
Iterator & operator++()
Definition Indexer.cpp:651
Definition Indexer.h:48
index_t sizes_[MAX_DIMS]
Definition Indexer.h:100
OPEN3D_HOST_DEVICE utility::MiniVec< index_t, NARGS > get(index_t linear_idx) const
Definition Indexer.h:69
int dims_
Definition Indexer.h:99
OffsetCalculator(int dims, const int64_t *sizes, const int64_t *const *strides)
Definition Indexer.h:49
index_t strides_[MAX_DIMS][NARGS]
Definition Indexer.h:101
A minimalistic class that reference a Tensor.
Definition Indexer.h:105
int64_t dtype_byte_size_
Definition Indexer.h:234
void UpdateByteOffsetBounds()
Definition Indexer.h:130
int64_t min_byte_offset_
Definition Indexer.h:235
void Permute(const SizeVector &dims)
Permute (dimension shuffle) the reference to a Tensor.
Definition Indexer.h:168
int64_t ndims_
Definition Indexer.h:233
OPEN3D_HOST_DEVICE bool ContainsByteOffset(int64_t offset) const
Definition Indexer.h:154
bool operator!=(const TensorRef &other) const
Definition Indexer.h:225
TensorRef(const Tensor &t)
Definition Indexer.h:111
TensorRef()
Definition Indexer.h:109
int64_t shape_[MAX_DIMS]
Definition Indexer.h:237
bool IsContiguous() const
Definition Indexer.h:201
int64_t total_byte_size_
Definition Indexer.h:236
void * data_ptr_
Definition Indexer.h:232
bool operator==(const TensorRef &other) const
Definition Indexer.h:211
int64_t byte_strides_[MAX_DIMS]
Definition Indexer.h:238
Definition MiniVec.h:24