ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
NonZeroCPU.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 
8 #include <Logging.h>
9 #include <Parallel.h>
10 
11 #include <numeric>
12 
15 
16 namespace cloudViewer {
17 namespace core {
18 namespace kernel {
19 
20 Tensor NonZeroCPU(const Tensor& src) {
21  // Get flattened non-zero indices.
22  TensorIterator src_iter(src);
23  const int64_t num_elements = src.NumElements();
24  std::vector<int64_t> indices(static_cast<size_t>(num_elements));
25  std::iota(std::begin(indices), std::end(indices), 0);
26  std::vector<int64_t> non_zero_indices(num_elements);
28  auto it = std::copy_if(
29  indices.begin(), indices.end(), non_zero_indices.begin(),
30  [&src_iter](int64_t index) {
31  const void* src_ptr = src_iter.GetPtr(index);
32  CLOUDVIEWER_ASSERT(src_ptr != nullptr && "Internal error.");
33  return static_cast<float>(
34  *static_cast<const scalar_t*>(src_ptr)) != 0;
35  });
36  non_zero_indices.resize(std::distance(non_zero_indices.begin(), it));
37  });
38 
39  // Transform flattened indices to indices in each dimension.
40  SizeVector shape = src.GetShape();
41  const int64_t num_dims = src.NumDims();
42  const size_t num_non_zeros = non_zero_indices.size();
43 
44  SizeVector result_shape{num_dims, static_cast<int64_t>(num_non_zeros)};
45  Tensor result(result_shape, core::Int64, src.GetDevice());
46  TensorIterator result_iter(result);
47 
48  std::vector<std::vector<int64_t>> non_zero_indices_by_dimensions(
49  num_dims, std::vector<int64_t>(num_non_zeros, 0));
50 #pragma omp parallel for schedule(static) \
51  num_threads(utility::EstimateMaxThreads())
52  for (int64_t i = 0; i < static_cast<int64_t>(num_non_zeros); i++) {
53  int64_t non_zero_index = non_zero_indices[i];
54  for (int64_t dim = num_dims - 1; dim >= 0; dim--) {
55  void* result_ptr = result_iter.GetPtr(dim * num_non_zeros + i);
56  CLOUDVIEWER_ASSERT(result_ptr != nullptr && "Internal error.");
57  *static_cast<int64_t*>(result_ptr) = non_zero_index % shape[dim];
58  non_zero_index = non_zero_index / shape[dim];
59  }
60  }
61 
62  return result;
63 }
64 
65 } // namespace kernel
66 } // namespace core
67 } // namespace cloudViewer
#define DISPATCH_DTYPE_TO_TEMPLATE_WITH_BOOL(DTYPE,...)
Definition: Dispatch.h:68
#define CLOUDVIEWER_ASSERT(...)
Definition: Macro.h:51
core::Tensor result
Definition: VtkUtils.cpp:76
Dtype GetDtype() const
Definition: Tensor.h:1164
int64_t NumElements() const
Definition: Tensor.h:1170
Tensor NonZeroCPU(const Tensor &src)
Definition: NonZeroCPU.cpp:20
const Dtype Int64
Definition: Dtype.cpp:47
Generic file read and write utility for python interface.