Open3D (C++ API)  0.20.0
Loading...
Searching...
No Matches
CUDAUtils.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
13
14#pragma once
15
16#include "open3d/core/Device.h"
18
19#ifdef BUILD_CUDA_MODULE
20
21#include <cuda.h>
22#include <cuda_runtime.h>
23
24#include <memory>
25#include <optional>
26#include <vector>
27
28#define OPEN3D_FORCE_INLINE __forceinline__
29#define OPEN3D_HOST_DEVICE __host__ __device__
30#define OPEN3D_DEVICE __device__
31#define OPEN3D_ASSERT_HOST_DEVICE_LAMBDA(type) \
32 static_assert(__nv_is_extended_host_device_lambda_closure_type(type), \
33 #type " must be a __host__ __device__ lambda")
34#define OPEN3D_CUDA_CHECK(err) \
35 open3d::core::__OPEN3D_CUDA_CHECK(err, __FILE__, __LINE__)
36#define OPEN3D_GET_LAST_CUDA_ERROR(message) \
37 __OPEN3D_GET_LAST_CUDA_ERROR(message, __FILE__, __LINE__)
38#define CUDA_CALL(cuda_function, ...) cuda_function(__VA_ARGS__);
39
40#else // #ifdef BUILD_CUDA_MODULE
41
42#define OPEN3D_FORCE_INLINE inline
43#define OPEN3D_HOST_DEVICE
44#define OPEN3D_DEVICE
45#define OPEN3D_ASSERT_HOST_DEVICE_LAMBDA(type)
46#define OPEN3D_CUDA_CHECK(err)
47#define OPEN3D_GET_LAST_CUDA_ERROR(message)
48#define CUDA_CALL(cuda_function, ...) \
49 open3d::utility::LogError( \
50 "Not built with CUDA, cannot call " #cuda_function);
51
52#endif // #ifdef BUILD_CUDA_MODULE
53
54namespace open3d {
55namespace core {
56
57#ifdef BUILD_CUDA_MODULE
58
82class CUDAScopedDevice {
83public:
84 explicit CUDAScopedDevice(int device_id);
85
86 explicit CUDAScopedDevice(const Device& device);
87
89
90 CUDAScopedDevice(const CUDAScopedDevice&) = delete;
91 CUDAScopedDevice& operator=(const CUDAScopedDevice&) = delete;
92
93private:
94 int prev_device_id_;
95};
96
136class CUDAScopedStream {
137private:
138 struct CreateNewStreamTag {
139 constexpr CreateNewStreamTag() = default;
140 CreateNewStreamTag(const CreateNewStreamTag&) = delete;
141 CreateNewStreamTag& operator=(const CreateNewStreamTag&) = delete;
142 CreateNewStreamTag(CreateNewStreamTag&&) = delete;
143 CreateNewStreamTag& operator=(CreateNewStreamTag&&) = delete;
144 };
145
146public:
147 constexpr static CreateNewStreamTag CreateNewStream = {};
148
149 explicit CUDAScopedStream(const CreateNewStreamTag&);
150
151 explicit CUDAScopedStream(cudaStream_t stream);
152
153 ~CUDAScopedStream();
154
155 CUDAScopedStream(const CUDAScopedStream&) = delete;
156 CUDAScopedStream& operator=(const CUDAScopedStream&) = delete;
157
158private:
159 cudaStream_t prev_stream_;
160 cudaStream_t new_stream_;
161 bool owns_new_stream_ = false;
162};
163
177class CUDAState {
178public:
179 static CUDAState& GetInstance();
180
181 CUDAState(const CUDAState&) = delete;
182 CUDAState& operator=(const CUDAState&) = delete;
183
186 bool IsP2PEnabled(int src_id, int tar_id) const;
187
190 bool IsP2PEnabled(const Device& src, const Device& tar) const;
191
194 void ForceDisableP2PForTesting();
195
196private:
197 CUDAState();
198
199 std::vector<std::vector<bool>> p2p_enabled_;
200};
201
203int GetCUDACurrentWarpSize();
204
206int GetCUDACurrentDeviceTextureAlignment();
207
209size_t GetCUDACurrentTotalMemSize();
210
211#else
212
215public:
216 explicit CUDAScopedDevice(int device_id) {}
217 explicit CUDAScopedDevice(const Device& device) {}
221};
222
223#endif
224
225namespace cuda {
226
229int DeviceCount();
230
233bool IsAvailable();
234
236void ReleaseCache();
237
240void Synchronize();
241
246void Synchronize(const Device& device);
247
251void AssertCUDADeviceAvailable(int device_id);
252
256void AssertCUDADeviceAvailable(const Device& device);
257
263bool SupportsMemoryPools(const Device& device);
264
265#ifdef BUILD_CUDA_MODULE
266
267int GetDevice();
268cudaStream_t GetStream();
269cudaStream_t GetDefaultStream();
270
271#endif
272
273} // namespace cuda
274} // namespace core
275} // namespace open3d
276
277// Exposed as implementation detail of macros at the end of the file.
278#ifdef BUILD_CUDA_MODULE
279
280namespace open3d {
281namespace core {
282
283void __OPEN3D_CUDA_CHECK(cudaError_t err, const char* file, const int line);
284
285void __OPEN3D_GET_LAST_CUDA_ERROR(const char* message,
286 const char* file,
287 const int line);
288
289} // namespace core
290
291#if defined(__CUDA_ARCH__)
292
293namespace detail {
294
295OPEN3D_DEVICE __forceinline__ void Open3DCudaAssertReportAndTrap(
296 const char* message) {
297 static __device__ int open3d_cuda_assert_reported;
298 if (atomicExch(&open3d_cuda_assert_reported, 1) == 0) {
299 printf("Open3D CUDA assertion failed at block [%u,%u,%u], thread "
300 "[%u,%u,%u]:\n%s\n",
301 blockIdx.x, blockIdx.y, blockIdx.z, threadIdx.x, threadIdx.y,
302 threadIdx.z, message);
303 }
304 __trap();
305}
306
307} // namespace detail
308
309#endif // defined(__CUDA_ARCH__)
310
311} // namespace open3d
312
313#endif
#define OPEN3D_DEVICE
Definition CUDAUtils.h:44
When CUDA is not enabled, this is a dummy class.
Definition CUDAUtils.h:214
CUDAScopedDevice(const Device &device)
Definition CUDAUtils.h:217
CUDAScopedDevice(const CUDAScopedDevice &)=delete
CUDAScopedDevice(int device_id)
Definition CUDAUtils.h:216
~CUDAScopedDevice()
Definition CUDAUtils.h:218
CUDAScopedDevice & operator=(const CUDAScopedDevice &)=delete
Definition Device.h:18
void ReleaseCache()
Releases CUDA memory manager cache. This is typically used for debugging.
Definition CUDAUtils.cpp:40
bool IsAvailable()
Definition CUDAUtils.cpp:38
bool SupportsMemoryPools(const Device &device)
Definition CUDAUtils.cpp:111
int DeviceCount()
Definition CUDAUtils.cpp:21
void Synchronize()
Definition CUDAUtils.cpp:58
void AssertCUDADeviceAvailable(int device_id)
Definition CUDAUtils.cpp:75
Definition PinholeCameraIntrinsic.cpp:16