ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
UnaryEW.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 <benchmark/benchmark.h>
9 
10 #include <random>
11 #include <type_traits>
12 
19 
20 namespace cloudViewer {
21 namespace core {
22 
23 enum class UnaryOpCode {
24  Sqrt,
25  Sin,
26  Cos,
27  Neg,
28  Exp,
29  Abs,
30  IsNan,
31  IsInf,
32  IsFinite,
33  Floor,
34  Ceil,
35  Round,
36  Trunc,
37  LogicalNot,
38 };
39 
40 std::function<Tensor(const Tensor&)> MakeOperation(UnaryOpCode op) {
41  switch (op) {
42  case UnaryOpCode::Sqrt:
43  return [](const Tensor& arg) -> Tensor { return arg.Sqrt(); };
44 
45  case UnaryOpCode::Sin:
46  return [](const Tensor& arg) -> Tensor { return arg.Sin(); };
47 
48  case UnaryOpCode::Cos:
49  return [](const Tensor& arg) -> Tensor { return arg.Cos(); };
50 
51  case UnaryOpCode::Neg:
52  return [](const Tensor& arg) -> Tensor { return arg.Neg(); };
53 
54  case UnaryOpCode::Exp:
55  return [](const Tensor& arg) -> Tensor { return arg.Exp(); };
56 
57  case UnaryOpCode::Abs:
58  return [](const Tensor& arg) -> Tensor { return arg.Abs(); };
59 
60  case UnaryOpCode::IsNan:
61  return [](const Tensor& arg) -> Tensor { return arg.IsNan(); };
62 
63  case UnaryOpCode::IsInf:
64  return [](const Tensor& arg) -> Tensor { return arg.IsInf(); };
65 
67  return [](const Tensor& arg) -> Tensor { return arg.IsFinite(); };
68 
69  case UnaryOpCode::Floor:
70  return [](const Tensor& arg) -> Tensor { return arg.Floor(); };
71 
72  case UnaryOpCode::Ceil:
73  return [](const Tensor& arg) -> Tensor { return arg.Ceil(); };
74 
75  case UnaryOpCode::Round:
76  return [](const Tensor& arg) -> Tensor { return arg.Round(); };
77 
78  case UnaryOpCode::Trunc:
79  return [](const Tensor& arg) -> Tensor { return arg.Trunc(); };
80 
82  return [](const Tensor& arg) -> Tensor { return arg.LogicalNot(); };
83 
84  default:
85  utility::LogError("Unknown operation {}", static_cast<int>(op));
86  }
87 }
88 
89 void UnaryEW(benchmark::State& state,
90  int size,
91  UnaryOpCode op_code,
92  const Dtype& dtype,
93  const Device& device) {
94  Tensor arg = benchmarks::Rand({1, size}, 1, {1, 127}, dtype, device);
95  auto op = MakeOperation(op_code);
96 
97  Tensor result = op(arg);
98  benchmark::DoNotOptimize(result);
99 
100  for (auto _ : state) {
101  Tensor result = op(arg);
102  benchmark::DoNotOptimize(result);
103 
104  cuda::Synchronize(device);
105  }
106 }
107 
108 #define ENUM_BM_SIZE(FN, OP, DEVICE, DEVICE_NAME, DTYPE) \
109  BENCHMARK_CAPTURE(FN, OP##__##DEVICE_NAME##_##DTYPE##__100, 100, \
110  UnaryOpCode::OP, DTYPE, DEVICE) \
111  ->Unit(benchmark::kMillisecond); \
112  BENCHMARK_CAPTURE(FN, OP##__##DEVICE_NAME##_##DTYPE##__100000, 100000, \
113  UnaryOpCode::OP, DTYPE, DEVICE) \
114  ->Unit(benchmark::kMillisecond); \
115  BENCHMARK_CAPTURE(FN, OP##__##DEVICE_NAME##_##DTYPE##__100000000, \
116  100000000, UnaryOpCode::OP, DTYPE, DEVICE) \
117  ->Unit(benchmark::kMillisecond);
118 
119 #define ENUM_BM_DTYPE(FN, OP, DEVICE, DEVICE_NAME) \
120  ENUM_BM_SIZE(FN, OP, DEVICE, DEVICE_NAME, Int8) \
121  ENUM_BM_SIZE(FN, OP, DEVICE, DEVICE_NAME, UInt8) \
122  ENUM_BM_SIZE(FN, OP, DEVICE, DEVICE_NAME, Int16) \
123  ENUM_BM_SIZE(FN, OP, DEVICE, DEVICE_NAME, UInt16) \
124  ENUM_BM_SIZE(FN, OP, DEVICE, DEVICE_NAME, Int32) \
125  ENUM_BM_SIZE(FN, OP, DEVICE, DEVICE_NAME, UInt32) \
126  ENUM_BM_SIZE(FN, OP, DEVICE, DEVICE_NAME, Int64) \
127  ENUM_BM_SIZE(FN, OP, DEVICE, DEVICE_NAME, UInt64) \
128  ENUM_BM_SIZE(FN, OP, DEVICE, DEVICE_NAME, Float32) \
129  ENUM_BM_SIZE(FN, OP, DEVICE, DEVICE_NAME, Float64)
130 
131 #define ENUM_BM_DTYPE_FLOAT(FN, OP, DEVICE, DEVICE_NAME) \
132  ENUM_BM_SIZE(FN, OP, DEVICE, DEVICE_NAME, Float32) \
133  ENUM_BM_SIZE(FN, OP, DEVICE, DEVICE_NAME, Float64)
134 
135 #define ENUM_BM_DTYPE_WITH_BOOL(FN, OP, DEVICE, DEVICE_NAME) \
136  ENUM_BM_SIZE(FN, OP, DEVICE, DEVICE_NAME, Bool) \
137  ENUM_BM_SIZE(FN, OP, DEVICE, DEVICE_NAME, Int8) \
138  ENUM_BM_SIZE(FN, OP, DEVICE, DEVICE_NAME, UInt8) \
139  ENUM_BM_SIZE(FN, OP, DEVICE, DEVICE_NAME, Int16) \
140  ENUM_BM_SIZE(FN, OP, DEVICE, DEVICE_NAME, UInt16) \
141  ENUM_BM_SIZE(FN, OP, DEVICE, DEVICE_NAME, Int32) \
142  ENUM_BM_SIZE(FN, OP, DEVICE, DEVICE_NAME, UInt32) \
143  ENUM_BM_SIZE(FN, OP, DEVICE, DEVICE_NAME, Int64) \
144  ENUM_BM_SIZE(FN, OP, DEVICE, DEVICE_NAME, UInt64) \
145  ENUM_BM_SIZE(FN, OP, DEVICE, DEVICE_NAME, Float32) \
146  ENUM_BM_SIZE(FN, OP, DEVICE, DEVICE_NAME, Float64)
147 
148 // #ifdef BUILD_CUDA_MODULE
149 // #define ENUM_BM_TENSOR(FN, OP)
150 // ENUM_BM_DTYPE(FN, OP, Device("CPU:0"), CPU)
151 // ENUM_BM_DTYPE(FN, OP, Device("CUDA:0"), CUDA)
152 // #else
153 #define ENUM_BM_TENSOR(FN, OP) ENUM_BM_DTYPE(FN, OP, Device("CPU:0"), CPU)
154 // #endif
155 
156 // #ifdef BUILD_CUDA_MODULE
157 // #define ENUM_BM_TENSOR_FLOAT(FN, OP)
158 // ENUM_BM_DTYPE_FLOAT(FN, OP, Device("CPU:0"), CPU)
159 // ENUM_BM_DTYPE_FLOAT(FN, OP, Device("CUDA:0"), CUDA)
160 // #else
161 #define ENUM_BM_TENSOR_FLOAT(FN, OP) \
162  ENUM_BM_DTYPE_FLOAT(FN, OP, Device("CPU:0"), CPU)
163 // #endif
164 
165 // #ifdef BUILD_CUDA_MODULE
166 // #define ENUM_BM_TENSOR_WTIH_BOOL(FN, OP)
167 // ENUM_BM_DTYPE_WITH_BOOL(FN, OP, Device("CPU:0"), CPU)
168 // ENUM_BM_DTYPE_WITH_BOOL(FN, OP, Device("CUDA:0"), CUDA)
169 // #else
170 #define ENUM_BM_TENSOR_WTIH_BOOL(FN, OP) \
171  ENUM_BM_DTYPE_WITH_BOOL(FN, OP, Device("CPU:0"), CPU)
172 // #endif
173 
188 
189 } // namespace core
190 } // namespace cloudViewer
Common CUDA utilities.
#define ENUM_BM_TENSOR_FLOAT(FN, OP)
Definition: UnaryEW.cpp:161
#define ENUM_BM_TENSOR_WTIH_BOOL(FN, OP)
Definition: UnaryEW.cpp:170
#define ENUM_BM_TENSOR(FN, OP)
Definition: UnaryEW.cpp:153
int size
core::Tensor result
Definition: VtkUtils.cpp:76
Tensor Sqrt() const
Element-wise square root of a tensor, returns a new tensor.
Definition: Tensor.cpp:1296
Tensor Neg() const
Element-wise negation of a tensor, returning a new tensor.
Definition: Tensor.cpp:1329
Tensor Round() const
Element-wise round value of a tensor, returning a new tensor.
Definition: Tensor.cpp:1423
Tensor Trunc() const
Element-wise trunc value of a tensor, returning a new tensor.
Definition: Tensor.cpp:1429
Tensor LogicalNot() const
Definition: Tensor.cpp:1442
Tensor Exp() const
Element-wise exponential of a tensor, returning a new tensor.
Definition: Tensor.cpp:1340
Tensor Cos() const
Element-wise cosine of a tensor, returning a new tensor.
Definition: Tensor.cpp:1318
Tensor IsFinite() const
Definition: Tensor.cpp:1382
Tensor Abs() const
Element-wise absolute value of a tensor, returning a new tensor.
Definition: Tensor.cpp:1351
Tensor Sin() const
Element-wise sine of a tensor, returning a new tensor.
Definition: Tensor.cpp:1307
Tensor Ceil() const
Element-wise ceil value of a tensor, returning a new tensor.
Definition: Tensor.cpp:1417
Tensor IsInf() const
Definition: Tensor.cpp:1372
Tensor IsNan() const
Definition: Tensor.cpp:1362
Tensor Floor() const
Element-wise floor value of a tensor, returning a new tensor.
Definition: Tensor.cpp:1411
#define LogError(...)
Definition: Logging.h:60
core::Tensor Rand(const core::SizeVector &shape, size_t seed, const std::pair< core::Scalar, core::Scalar > &range, core::Dtype dtype, const core::Device &device)
Returns a Tensor with random values within the range range .
Definition: Rand.cpp:23
void UnaryEW(benchmark::State &state, int size, UnaryOpCode op_code, const Dtype &dtype, const Device &device)
Definition: UnaryEW.cpp:89
static std::function< Tensor(const Tensor &, const Tensor &)> MakeOperation(BinaryOpCode op)
Definition: BinaryEW.cpp:38
Generic file read and write utility for python interface.