ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
Reduction.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 
11 
12 namespace cloudViewer {
13 namespace core {
14 namespace kernel {
15 
16 void Reduction(const Tensor& src,
17  Tensor& dst,
18  const SizeVector& dims,
19  bool keepdim,
20  ReductionOpCode op_code) {
21  // For ArgMin and ArgMax, keepdim == false, and dims can only contain one or
22  // all dimensions.
23  if (s_arg_reduce_ops.find(op_code) != s_arg_reduce_ops.end()) {
24  if (keepdim) {
25  utility::LogError("Arg-reduction keepdim must be false");
26  }
27  if (dims.size() != 1) {
28  std::vector<bool> seen_dims(src.NumDims(), false);
29  for (const int64_t& dim : dims) {
30  seen_dims[dim] = true;
31  }
32  if (!std::all_of(seen_dims.begin(), seen_dims.end(),
33  [](bool seen) { return seen; })) {
35  "Arg-reduction can only have 1 or all reduction "
36  "dimensions. However, dims = {}.",
37  dims);
38  }
39  }
40  if (src.NumElements() == 0) {
42  "Zero-size Tensor does not support Arg Reductions.");
43  }
44  }
45 
46  SizeVector keepdim_shape =
47  shape_util::ReductionShape(src.GetShape(), dims, true);
48  SizeVector non_keepdim_shape =
49  shape_util::ReductionShape(src.GetShape(), dims, false);
50  if (keepdim && keepdim_shape != dst.GetShape()) {
51  utility::LogError("Expected output shape {} but got {}.",
52  keepdim_shape.ToString(), dst.GetShape().ToString());
53  }
54  if (!keepdim && non_keepdim_shape != dst.GetShape()) {
55  utility::LogError("Expected output shape {} but got {}.",
56  keepdim_shape.ToString(), dst.GetShape().ToString());
57  }
58 
59  // Directly copy for non-reduction.
60  if (dims.size() == 0) {
61  dst.AsRvalue() = src;
62  return;
63  }
64 
65  // Always reshape to keepdim case. This reshaping is copy-free.
66  if (!keepdim) {
67  dst = dst.Reshape(keepdim_shape);
68  }
69 
70  if (src.GetDevice() != dst.GetDevice()) {
71  utility::LogError("Device mismatch {} != {}.",
72  src.GetDevice().ToString(),
73  dst.GetDevice().ToString());
74  }
75 
76  if (src.IsCPU()) {
77  ReductionCPU(src, dst, dims, keepdim, op_code);
78  } else if (src.IsSYCL()) {
79 #ifdef BUILD_SYCL_MODULE
80  ReductionSYCL(src, dst, dims, keepdim, op_code);
81 #else
82  utility::LogError("Not compiled with SYCL, but SYCL device is used.");
83 #endif
84  } else if (src.IsCUDA()) {
85 #ifdef BUILD_CUDA_MODULE
86  ReductionCUDA(src, dst, dims, keepdim, op_code);
87 #else
88  utility::LogError("Not compiled with CUDA, but CUDA device is used.");
89 #endif
90  } else {
91  utility::LogError("Unimplemented device.");
92  }
93 
94  if (!keepdim) {
95  dst = dst.Reshape(non_keepdim_shape);
96  }
97 }
98 
99 } // namespace kernel
100 } // namespace core
101 } // namespace cloudViewer
std::string ToString() const
Returns string representation of device, e.g. "CPU:0", "CUDA:0".
Definition: Device.cpp:89
bool IsCUDA() const
Definition: Device.h:99
bool IsCPU() const
Definition: Device.h:95
std::string ToString() const
Definition: SizeVector.cpp:132
int64_t NumDims() const
Definition: Tensor.h:1172
int64_t NumElements() const
Definition: Tensor.h:1170
Device GetDevice() const override
Definition: Tensor.cpp:1435
Tensor Reshape(const SizeVector &dst_shape) const
Definition: Tensor.cpp:671
SizeVector GetShape() const
Definition: Tensor.h:1127
#define LogError(...)
Definition: Logging.h:60
void ReductionSYCL(const Tensor &src, Tensor &dst, const SizeVector &dims, bool keepdim, ReductionOpCode op_code)
static const std::unordered_set< ReductionOpCode, utility::hash_enum_class > s_arg_reduce_ops
Definition: Reduction.h:41
void ReductionCPU(const Tensor &src, Tensor &dst, const SizeVector &dims, bool keepdim, ReductionOpCode op_code)
void Reduction(const Tensor &src, Tensor &dst, const SizeVector &dims, bool keepdim, ReductionOpCode op_code)
Definition: Reduction.cpp:16
SizeVector ReductionShape(const SizeVector &src_shape, const SizeVector &dims, bool keepdim)
Returns the shape after reduction.
Definition: ShapeUtil.cpp:99
Generic file read and write utility for python interface.