Compute Graph Framework SDK Reference  5.8
Buffer.hpp
Go to the documentation of this file.
1
2// This code contains NVIDIA Confidential Information and is disclosed
3// under the Mutual Non-Disclosure Agreement.
4//
5// Notice
6// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
7// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
8// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
9// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
10//
11// NVIDIA Corporation assumes no responsibility for the consequences of use of such
12// information or for any infringement of patents or other rights of third parties that may
13// result from its use. No license is granted by implication or otherwise under any patent
14// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
15// expressly authorized by NVIDIA. Details are subject to change without notice.
16// This code supersedes and replaces all information previously supplied.
17// NVIDIA Corporation products are not authorized for use as critical
18// components in life support devices or systems without express written approval of
19// NVIDIA Corporation.
20//
21// Copyright (c) 2021-2022 NVIDIA Corporation. All rights reserved.
22//
23// NVIDIA Corporation and its licensors retain all intellectual property and proprietary
24// rights in and to this software and related documentation and any modifications thereto.
25// Any use, reproduction, disclosure or distribution of this software and related
26// documentation without an express license agreement from NVIDIA Corporation is
27// strictly prohibited.
28//
30
31#ifndef DW_FRAMEWORK_BUFFER_HPP_
32#define DW_FRAMEWORK_BUFFER_HPP_
33
34#include <cstddef>
35#include <dwcgf/Types.hpp>
36#include <nvscibuf.h>
37#include <dw/core/language/Optional.hpp>
38#include <dw/cuda/misc/DevicePtr.hpp>
39
40namespace dw
41{
42namespace framework
43{
44
45enum class BufferBackendType : uint32_t
46{
47 CPU = 0,
48 CUDA = 1,
49 // Add others as appropriate
50};
51
52using BufferFlags = uint32_t;
53
55{
56 return (static_cast<uint32_t>(flags) & (1U << static_cast<uint32_t>(type))) != 0U;
57}
58
60{
61 flags |= (1U << static_cast<uint32_t>(type));
62}
63
65{
67 size_t byteSize;
68};
69
71{
72public:
73 static constexpr char LOG_TAG[] = "Buffer";
74
76 : m_properties(std::move(properties))
77 {
78 }
79
81 {
82 return m_properties;
83 }
84
85 virtual void bindNvSciBufObj(NvSciBufObj bufObj)
86 {
87 if (m_bufObj)
88 {
89 throw Exception(DW_CALL_NOT_ALLOWED, "BufferBase: Cannot bind NvSciBufObj twice");
90 }
91 m_bufObj = bufObj;
92 }
93
94 void fillNvSciBufAttrs(NvSciBufAttrList attrList) const
95 {
96 const NvSciBufType bufferType = NvSciBufType_RawBuffer;
97 const NvSciBufAttrValAccessPerm permissions = NvSciBufAccessPerm_ReadWrite;
98 const uint64_t rawAlign = 4;
99
100 Array<NvSciBufAttrKeyValuePair, 3> rawBufferAttributes =
101 {{{NvSciBufGeneralAttrKey_Types, &bufferType, sizeof(bufferType)},
102 {NvSciBufGeneralAttrKey_RequiredPerm, &permissions, sizeof(permissions)},
103 {NvSciBufRawBufferAttrKey_Align, &rawAlign, sizeof(rawAlign)}}};
104
105 FRWK_CHECK_NVSCI_ERROR(NvSciBufAttrListSetAttrs(attrList,
106 rawBufferAttributes.data(),
107 rawBufferAttributes.size()));
108
109 if (m_properties.byteSize > 0U)
110 {
111 const uint64_t rawSize = m_properties.byteSize;
112 Array<NvSciBufAttrKeyValuePair, 1> rawBufferSizeAttributes =
113 {{{NvSciBufRawBufferAttrKey_Size, &rawSize, sizeof(rawSize)}}};
114 FRWK_CHECK_NVSCI_ERROR(NvSciBufAttrListSetAttrs(attrList,
115 rawBufferSizeAttributes.data(),
116 rawBufferSizeAttributes.size()));
117 }
118 }
119
120 NvSciBufObj getNvSci()
121 {
122 return m_bufObj;
123 }
124
125protected:
127 NvSciBufObj m_bufObj{};
128};
129
130class BufferCPU : public BufferBase
131{
132public:
135 {
136 }
137
138 void fillSpecificAttributes(NvSciBufAttrList attrList) const
139 {
140 const bool cpuAccessFlag = true;
141
142 Array<NvSciBufAttrKeyValuePair, 1> rawBufferAttributes =
143 {{{NvSciBufGeneralAttrKey_NeedCpuAccess, &cpuAccessFlag, sizeof(cpuAccessFlag)}}};
144
145 FRWK_CHECK_NVSCI_ERROR(NvSciBufAttrListSetAttrs(attrList,
146 rawBufferAttributes.data(),
147 rawBufferAttributes.size()));
148 }
149
150 void bindNvSciBufObj(NvSciBufObj bufObj) override
151 {
153 FRWK_CHECK_NVSCI_ERROR(NvSciBufObjGetCpuPtr(m_bufObj, &m_ptr));
154 }
155
156 void* getCpuPtr(size_t offset)
157 {
158 return &(static_cast<uint8_t*>(m_ptr)[offset]);
159 }
160
161private:
162 void* m_ptr;
163};
164
165// BufferCUDA class encapsulates API mapping operations on single nvscibuf for cuda.
166// @note - If a buffer needs to be mapped for multiple cuda devices, multiple instances of this class
167// should be used and the appropriate device must be set as current before calling into each instance.
168class BufferCUDA : public BufferBase
169{
170public:
173 {
174 }
175
177 {
178 if (m_cudaHandle)
179 {
180 FRWK_CHECK_CUDA_ERROR_NOTHROW(cudaFree(m_ptr));
181 FRWK_CHECK_CUDA_ERROR_NOTHROW(cudaDestroyExternalMemory(m_cudaHandle));
182 }
183 }
184
185 void fillSpecificAttributes(NvSciBufAttrList attrList) const
186 {
187 NvSciRmGpuId gpuIds[] = {{0}};
188 int32_t cudaDevice;
189 FRWK_CHECK_CUDA_ERROR(cudaGetDevice(&cudaDevice));
190#ifndef DW_IS_SAFETY // TODO(dwsafety): DRIV-8345
191 cudaDeviceProp deviceProps{};
192 FRWK_CHECK_CUDA_ERROR(cudaGetDeviceProperties(&deviceProps, cudaDevice));
193 static_assert(sizeof(deviceProps.uuid) == sizeof(gpuIds[0]), "BufferCUDA: cuda uuid size does not match size of NvSciRmGpuId");
194 memcpy(static_cast<void*>(&gpuIds[0]), static_cast<void*>(&deviceProps.uuid), sizeof(gpuIds[0]));
195
196 Array<NvSciBufAttrKeyValuePair, 1> rawBufferAttributes =
197 {{{NvSciBufGeneralAttrKey_GpuId, &gpuIds, sizeof(gpuIds)}}};
198
199 FRWK_CHECK_NVSCI_ERROR(NvSciBufAttrListSetAttrs(attrList,
200 rawBufferAttributes.data(),
201 rawBufferAttributes.size()));
202#endif
203 }
204
205 void bindNvSciBufObj(NvSciBufObj bufObj) override
206 {
208 cudaExternalMemoryHandleDesc cudaMemHandleDesc = {};
209 cudaMemHandleDesc.type = cudaExternalMemoryHandleTypeNvSciBuf;
210 cudaMemHandleDesc.handle.nvSciBufObject = bufObj;
211 cudaMemHandleDesc.size = m_properties.byteSize;
212 cudaMemHandleDesc.flags = 0;
213 FRWK_CHECK_CUDA_ERROR(cudaImportExternalMemory(&m_cudaHandle, &cudaMemHandleDesc));
214
215 cudaExternalMemoryBufferDesc cudaBufferDesc = {};
216 memset(&cudaBufferDesc, 0, sizeof(cudaBufferDesc));
217 cudaBufferDesc.size = m_properties.byteSize;
218 cudaBufferDesc.offset = 0;
219 FRWK_CHECK_CUDA_ERROR(cudaExternalMemoryGetMappedBuffer(&m_ptr, m_cudaHandle, &cudaBufferDesc));
220 }
221
222 core::DevicePtr<void> getCudaPtr(size_t offset)
223 {
224 void* ptr = &(static_cast<uint8_t*>(m_ptr)[offset]);
225 return core::MakeDevicePtr(ptr);
226 }
227
228private:
229 cudaExternalMemory_t m_cudaHandle{};
230 void* m_ptr{};
231};
232
233// Buffer class encapsulates API mapping operations on single nvscibuf.
234// @note - If a buffer needs to be mapped for multiple cuda devices, multiple instances of this class
235// should be used and the appropriate device must be set as current before calling into each instance.
236class Buffer : public BufferBase
237{
238
239public:
242 {
243 auto enabledBackends = m_properties.enabledBackends;
245 {
246 m_bufferCpu.emplace(properties);
247 }
249 {
250 m_bufferCuda.emplace(properties);
251 }
252 }
253
254 void bindNvSciBufObj(NvSciBufObj bufObj) override
255 {
257 if (m_bufferCpu)
258 {
259 m_bufferCpu.value().bindNvSciBufObj(bufObj);
260 }
261 if (m_bufferCuda)
262 {
263 m_bufferCuda.value().bindNvSciBufObj(bufObj);
264 }
265 }
266
267 void fillNvSciBufAttrs(NvSciBufAttrList attrList) const
268 {
270 if (m_bufferCpu)
271 {
272 m_bufferCpu.value().fillSpecificAttributes(attrList);
273 }
274 if (m_bufferCuda)
275 {
276 m_bufferCuda.value().fillSpecificAttributes(attrList);
277 }
278 }
279
280 void* getCpuPtr(size_t offset)
281 {
282 return m_bufferCpu.value().getCpuPtr(offset);
283 }
284
285 core::DevicePtr<void> getCudaPtr(size_t offset)
286 {
287 return m_bufferCuda.value().getCudaPtr(offset);
288 }
289
290private:
291 dw::core::Optional<BufferCPU> m_bufferCpu{};
292 dw::core::Optional<BufferCUDA> m_bufferCuda{};
293};
294
295} // namespace framework
296} // namespace dw
297
298#endif // DW_FRAMEWORK_BUFFER_HPP_
#define FRWK_CHECK_CUDA_ERROR_NOTHROW(x)
Definition: Exception.hpp:350
#define FRWK_CHECK_CUDA_ERROR(x)
Definition: Exception.hpp:340
#define FRWK_CHECK_NVSCI_ERROR(e)
Definition: Exception.hpp:373
const BufferProperties & getProperties() const
Definition: Buffer.hpp:80
void fillNvSciBufAttrs(NvSciBufAttrList attrList) const
Definition: Buffer.hpp:94
NvSciBufObj getNvSci()
Definition: Buffer.hpp:120
BufferBase(BufferProperties properties)
Definition: Buffer.hpp:75
virtual void bindNvSciBufObj(NvSciBufObj bufObj)
Definition: Buffer.hpp:85
static constexpr char LOG_TAG[]
Definition: Buffer.hpp:73
BufferProperties m_properties
Definition: Buffer.hpp:126
BufferCPU(BufferProperties properties)
Definition: Buffer.hpp:133
void * getCpuPtr(size_t offset)
Definition: Buffer.hpp:156
void bindNvSciBufObj(NvSciBufObj bufObj) override
Definition: Buffer.hpp:150
void fillSpecificAttributes(NvSciBufAttrList attrList) const
Definition: Buffer.hpp:138
void fillSpecificAttributes(NvSciBufAttrList attrList) const
Definition: Buffer.hpp:185
core::DevicePtr< void > getCudaPtr(size_t offset)
Definition: Buffer.hpp:222
void bindNvSciBufObj(NvSciBufObj bufObj) override
Definition: Buffer.hpp:205
BufferCUDA(BufferProperties properties)
Definition: Buffer.hpp:171
void * getCpuPtr(size_t offset)
Definition: Buffer.hpp:280
void bindNvSciBufObj(NvSciBufObj bufObj) override
Definition: Buffer.hpp:254
void fillNvSciBufAttrs(NvSciBufAttrList attrList) const
Definition: Buffer.hpp:267
Buffer(BufferProperties properties)
Definition: Buffer.hpp:240
core::DevicePtr< void > getCudaPtr(size_t offset)
Definition: Buffer.hpp:285
void BufferFlagsEnableBackend(BufferFlags &flags, BufferBackendType type)
Definition: Buffer.hpp:59
bool BufferFlagsBackendEnabled(BufferFlags flags, BufferBackendType type)
Definition: Buffer.hpp:54
uint32_t BufferFlags
Definition: Buffer.hpp:52
dwCalibrationProperties properties
Definition: Exception.hpp:47