Open3D (C++ API)  0.19.0
Loading...
Searching...
No Matches
BlockCopyDispatch.h
Go to the documentation of this file.
1// ----------------------------------------------------------------------------
2// - Open3D: www.open3d.org -
3// ----------------------------------------------------------------------------
4// Copyright (c) 2018-2024 www.open3d.org
5// SPDX-License-Identifier: MIT
6// ----------------------------------------------------------------------------
7
14
15#pragma once
16
17#include <cstdint>
18
19#ifdef SYCL_LANGUAGE_VERSION
20#include <sycl/sycl.hpp>
21#endif
22
23namespace open3d {
24namespace core {
25
26// Vectorized trivial-object copy block sizes (bytes). Used for: HashMap SoA
27// value buffers (VoxelBlockGrid blocks, etc.), Dtype::Object advanced index
28// get/set, and non-contiguous SYCL tensor copy of object dtypes.
29inline constexpr int64_t kBlockCopyDivisors[] = {64, 16, 12, 4, 1};
30
32inline int64_t GetLargestAlignedObjectBlockSize(int64_t object_byte_size) {
33 for (int64_t divisor : kBlockCopyDivisors) {
34 if (object_byte_size % divisor == 0) {
35 return divisor;
36 }
37 }
38 return 1;
39}
40
41} // namespace core
42} // namespace open3d
43
44#ifdef __CUDACC__
45#include <cuda_runtime.h>
46
47// Reinterpret hash maps' void* value arrays as CUDA primitive type arrays to
48// avoid slow memcpy or byte-by-byte copy in kernels. Not used on CPU (memcpy is
49// fast enough). BlockCopy64 is at namespace scope because nvcc disallows
50// types with no linkage as template arguments for __global__ instantiations.
51struct BlockCopy64 {
52 int4 v[4];
53};
54
56#define DISPATCH_DIVISOR_SIZE_TO_BLOCK_T(DIVISOR, ...) \
57 [&] { \
58 if (DIVISOR == 64) { \
59 using block_t = BlockCopy64; \
60 return __VA_ARGS__(); \
61 } else if (DIVISOR == 16) { \
62 using block_t = int4; \
63 return __VA_ARGS__(); \
64 } else if (DIVISOR == 12) { \
65 using block_t = int3; \
66 return __VA_ARGS__(); \
67 } else if (DIVISOR == 4) { \
68 using block_t = int; \
69 return __VA_ARGS__(); \
70 } else { \
71 using block_t = uint8_t; \
72 return __VA_ARGS__(); \
73 } \
74 }()
75#endif // __CUDACC__
76
77#ifdef SYCL_LANGUAGE_VERSION
78
84#define DISPATCH_DIVISOR_SIZE_TO_BLOCK_T_SYCL(DIVISOR, ...) \
85 [&] { \
86 if (DIVISOR == 64) { \
87 using block_t = sycl::vec<uint32_t, 16>; \
88 return __VA_ARGS__(); \
89 } else if (DIVISOR == 16) { \
90 using block_t = sycl::vec<uint32_t, 4>; \
91 return __VA_ARGS__(); \
92 } else if (DIVISOR == 12) { \
93 using block_t = sycl::vec<uint32_t, 3>; \
94 return __VA_ARGS__(); \
95 } else if (DIVISOR == 4) { \
96 using block_t = uint32_t; \
97 return __VA_ARGS__(); \
98 } else { \
99 using block_t = uint8_t; \
100 return __VA_ARGS__(); \
101 } \
102 }()
103
104#endif // SYCL_LANGUAGE_VERSION
constexpr int64_t kBlockCopyDivisors[]
Definition BlockCopyDispatch.h:29
int64_t GetLargestAlignedObjectBlockSize(int64_t object_byte_size)
Largest entry in kBlockCopyDivisors that divides object_byte_size.
Definition BlockCopyDispatch.h:32
Definition PinholeCameraIntrinsic.cpp:16