chrono_batch_render/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
68 / 80
85.0%
Branches:
192 / 235
81.7%
Functions:
2 / 6, 10 excl
33.3%

device/device.h
Line Branch Exec Source
1 // SPDX-License-Identifier: BSD-3-Clause
2 #pragma once
3
4 #include <cstdint>
5 #include <filesystem>
6 #include <memory>
7 #include <optional>
8 #include <string>
9 #include <variant>
10 #include <vector>
11
12 #include <dlpack/dlpack.h>
13
14 #include "chrono_batch_render/device/adapter.h"
15 #include "chrono_batch_render/device/operation.h"
16 #include "chrono_batch_render/device/ref.h"
17 #include "chrono_batch_render/device/stream.h"
18 #include "chrono_batch_render/device/tensor.h"
19 #include "chrono_batch_render/export.h"
20 #include "chrono_batch_render/util/span.h"
21
22 namespace chrono::batch_render {
23 struct DeviceGlobals;
24 }
25
26 namespace chrono::batch_render::device {
27
28
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 struct BuildProgress {
29 uint64_t queued = 0;
30 uint64_t finished = 0;
31 uint64_t cached = 0;
32 std::vector<std::string> building;
33
34 3 bool Done() const {
35 3 return finished >= queued;
36 }
37 };
38
39 CHRONO_BATCH_RENDER_API BuildProgress CurrentBuilds();
40
41 class Accel;
42 class Buffer;
43 class BufferRange;
44 class DebugRecords;
45 class Kernel;
46 class Program;
47 class Queue;
48 class Resource;
49 class Texture;
50 struct AccelBoxes;
51 struct AccelInstances;
52 struct AccelSizes;
53 struct AccelTriangles;
54 struct BufferDesc;
55 struct ProgramDesc;
56 struct TextureDesc;
57 enum class AccelLevel : uint8_t;
58
59 using AccelInput = std::variant<AccelTriangles, AccelBoxes, AccelInstances>;
60
61 namespace vulkan {
62 struct Creator;
63 }
64
65 struct DeviceDesc {
66 std::optional<Backend> backend;
67 std::string adapter;
68 Traversal traversal = Traversal::Auto;
69 Sampling sampling = Sampling::Auto;
70 bool validation = false;
71 bool kernelDebugInfo = false;
72 bool profiling = true;
73 bool synchronous = false;
74 bool presentation = false;
75 std::filesystem::path cacheDirectory;
76 std::shared_ptr<const vulkan::Creator> creator;
77 };
78
79
1/4
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 40 not taken.
✓ Branch 44 taken 49 times.
41455 struct MemoryUse {
80 std::string label;
81 uint32_t buffers = 0;
82 uint32_t textures = 0;
83 uint64_t bytes = 0;
84 };
85
86 struct MemoryHeap {
87 uint64_t usage = 0;
88 uint64_t budget = 0;
89 uint64_t size = 0;
90 bool deviceLocal = false;
91 };
92
93
3/6
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✓ Branch 5 taken 1 time.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 time.
10 struct MemoryStats {
94 std::vector<MemoryUse> uses;
95 std::vector<MemoryHeap> heaps;
96 uint64_t deviceBytes = 0;
97 uint64_t textureBytes = 0;
98 uint64_t uploadBytes = 0;
99 uint64_t readbackBytes = 0;
100 uint64_t sharedBytes = 0;
101 uint64_t reservedBytes = 0;
102 };
103
104 struct TrafficStats {
105 uint64_t uploadBytes = 0;
106 uint64_t readbackBytes = 0;
107 uint64_t inlineBytes = 0;
108 uint64_t copyBytes = 0;
109 uint64_t submissions = 0;
110 uint64_t hostWaits = 0;
111
112 344376 TrafficStats& operator+=(const TrafficStats& other) {
113 344376 uploadBytes += other.uploadBytes;
114 344376 readbackBytes += other.readbackBytes;
115 344376 inlineBytes += other.inlineBytes;
116 344376 copyBytes += other.copyBytes;
117 344376 submissions += other.submissions;
118 344376 hostWaits += other.hostWaits;
119 344376 return *this;
120 }
121 };
122
123 1 inline TrafficStats operator-(const TrafficStats& a, const TrafficStats& b) {
124 1 TrafficStats result;
125 1 result.uploadBytes = a.uploadBytes - b.uploadBytes;
126 1 result.readbackBytes = a.readbackBytes - b.readbackBytes;
127 1 result.inlineBytes = a.inlineBytes - b.inlineBytes;
128 1 result.copyBytes = a.copyBytes - b.copyBytes;
129 1 result.submissions = a.submissions - b.submissions;
130 1 result.hostWaits = a.hostWaits - b.hostWaits;
131 1 return result;
132 }
133
134 class CHRONO_BATCH_RENDER_API Device : public RefCounted {
135 public:
136 static Ref<Device> Create(const DeviceDesc& desc = {});
137
138 ~Device() override;
139
140 40 const AdapterInfo& Adapter() const {
141
5/11
<unknown function 140>:
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 1 taken 1117 times.
✓ Branch 3 taken 1119 times.
✓ Branch 4 taken 20 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 20 times.
<unknown function 141>:
✗ Branch 0 not taken.
✗ Branch 1 not taken.
<unknown function 79>:
✗ Branch 3 not taken.
✓ Branch 4 taken 1 time.
2788 return m_adapter;
142 }
143
144 120678 Traversal GetTraversal() const {
145
5/12
<unknown function 140>:
✗ Branch 0 not taken.
✗ Branch 0 not taken.
✓ Branch 1 taken 119994 times.
✗ Branch 1 not taken.
<unknown function 141>:
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
✓ Branch 3 taken 1 time.
✗ Branch 4 not taken.
<unknown function 144>:
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
<unknown function 79>:
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
120678 return m_traversal;
146 }
147
148 1173 Sampling GetSampling() const {
149
4/4
<unknown function 140>:
✓ Branch 0 taken 1119 times.
✓ Branch 1 taken 20 times.
<unknown function 148>:
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 6 times.
1173 return m_sampling;
150 }
151
152 ✗ bool Presents() const {
153
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ return m_presents;
154 }
155
156 const std::filesystem::path& CacheDirectory() const {
157
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 return m_cacheDirectory;
158 }
159
160 1199 const std::filesystem::path& KernelCacheDirectory() const {
161
4/4
<unknown function 140>:
✓ Branch 1 taken 20 times.
✓ Branch 4 taken 1139 times.
<unknown function 160>:
✓ Branch 1 taken 38 times.
✓ Branch 4 taken 2 times.
1199 return m_kernelCacheDirectory;
162 }
163
164 Ref<Buffer> CreateBuffer(const BufferDesc& desc);
165 Ref<Buffer> Borrow(DLDevice source, uint64_t address, uint64_t bytes,
166 std::string label = "borrowed");
167 Ref<Buffer> CreateBuffer(BufferDesc desc, Span<const std::byte> data);
168 template <class T> Ref<Buffer> CreateBuffer(BufferDesc desc, Span<const T> values);
169 #ifdef __cpp_lib_span
170 template <class T> Ref<Buffer> CreateBuffer(BufferDesc desc, std::span<const T> values);
171 #endif
172 template <class T> Ref<Buffer> CreateBuffer(BufferDesc desc, const std::vector<T>& values);
173
174 AccelSizes AccelBuildSizes(const AccelInput& input) const;
175
176 Ref<Accel> CreateAccel(const AccelInput& input, std::string label = "accel");
177
178 Ref<Texture> CreateTexture(const TextureDesc& desc);
179
180
3/5
✗ Branch 1 not taken.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 time.
✓ Branch 10 taken 1 time.
✓ Branch 13 taken 1 time.
3 Tensor CreateTensor(DType type, std::vector<int64_t> shape, std::string label = "tensor");
181 Tensor CreateSharedTensor(DType type, std::vector<int64_t> shape,
182 std::string label = "shared tensor");
183
184 Operation Copy(const Tensor& src, const Tensor& dst, const Operation& after = {});
185 Tensor Import(const DLTensor& source, Stream producer = Stream::None(),
186
3/3
✓ Branch 1 taken 1 time.
✓ Branch 4 taken 1 time.
✓ Branch 7 taken 1 time.
3 std::string label = "imported");
187 Operation Follow(Stream producer);
188
189 Ref<Program> CreateProgram(const ProgramDesc& desc);
190
191 MemoryStats MemoryUsage() const;
192
193 TrafficStats Traffic() const;
194
195 15666041 Queue& GetQueue() {
196
159/177
<unknown function 141>:
✓ Branch 1 taken 83 times.
✓ Branch 4 taken 1 time.
✓ Branch 4 taken 98 times.
✓ Branch 5 taken 1 time.
✓ Branch 6 taken 64 times.
✓ Branch 7 taken 297 times.
✓ Branch 7 taken 162 times.
✓ Branch 9 taken 1 time.
✓ Branch 9 taken 1 time.
✓ Branch 10 taken 37 times.
✓ Branch 10 taken 162 times.
✓ Branch 11 taken 1 time.
✓ Branch 11 taken 10 times.
✓ Branch 12 taken 2 times.
✓ Branch 13 taken 4 times.
✓ Branch 13 taken 44 times.
✓ Branch 14 taken 1 time.
✓ Branch 16 taken 4 times.
✓ Branch 16 taken 34 times.
✓ Branch 17 taken 1 time.
✓ Branch 19 taken 5 times.
✓ Branch 19 taken 3 times.
✓ Branch 19 taken 29 times.
✓ Branch 20 taken 1 time.
✓ Branch 21 taken 1 time.
✓ Branch 22 taken 7 times.
✓ Branch 22 taken 17 times.
✓ Branch 22 taken 21 times.
✓ Branch 23 taken 1 time.
✓ Branch 24 taken 1 time.
✓ Branch 25 taken 6 times.
✗ Branch 25 not taken.
✓ Branch 25 taken 15 times.
✓ Branch 25 taken 32 times.
✓ Branch 26 taken 1 time.
✓ Branch 27 taken 1 time.
✓ Branch 28 taken 6 times.
✓ Branch 28 taken 21 times.
✓ Branch 28 taken 1 time.
✓ Branch 28 taken 35 times.
✓ Branch 29 taken 1 time.
✓ Branch 31 taken 4 times.
✓ Branch 31 taken 21 times.
✓ Branch 31 taken 1 time.
✓ Branch 31 taken 12 times.
✓ Branch 32 taken 1 time.
✓ Branch 34 taken 1 time.
✓ Branch 34 taken 1 time.
✓ Branch 34 taken 10 times.
✓ Branch 35 taken 1 time.
✓ Branch 37 taken 1 time.
✓ Branch 37 taken 1 time.
✓ Branch 37 taken 9 times.
✓ Branch 38 taken 1 time.
✓ Branch 40 taken 6 times.
✓ Branch 40 taken 8 times.
✓ Branch 41 taken 1 time.
✓ Branch 43 taken 17 times.
✓ Branch 43 taken 8 times.
✓ Branch 46 taken 1 time.
✓ Branch 46 taken 10 times.
✓ Branch 49 taken 1 time.
✓ Branch 49 taken 8 times.
✓ Branch 52 taken 1 time.
✓ Branch 52 taken 3 times.
✓ Branch 53 taken 10 times.
✓ Branch 55 taken 1 time.
✓ Branch 55 taken 3 times.
✓ Branch 56 taken 37 times.
✓ Branch 58 taken 1 time.
✓ Branch 58 taken 3 times.
✓ Branch 61 taken 1 time.
✓ Branch 61 taken 3 times.
✓ Branch 64 taken 1 time.
✓ Branch 64 taken 2 times.
✓ Branch 65 taken 1 time.
✓ Branch 67 taken 2 times.
✓ Branch 67 taken 1 time.
✓ Branch 70 taken 1 time.
✓ Branch 70 taken 1 time.
✓ Branch 70 taken 1 time.
✓ Branch 73 taken 1 time.
✓ Branch 73 taken 5 times.
✓ Branch 73 taken 1 time.
✓ Branch 76 taken 7 times.
✓ Branch 76 taken 1 time.
✓ Branch 79 taken 1 time.
✓ Branch 79 taken 1 time.
✓ Branch 82 taken 82 times.
✓ Branch 82 taken 1 time.
✓ Branch 85 taken 4 times.
✓ Branch 85 taken 1 time.
✓ Branch 88 taken 1 time.
<unknown function 148>:
✓ Branch 3 taken 33 times.
<unknown function 195>:
✓ Branch 0 taken 1905 times.
✓ Branch 0 taken 195 times.
✓ Branch 1 taken 3910 times.
✓ Branch 1 taken 39717 times.
✓ Branch 1 taken 1535 times.
✓ Branch 2 taken 41 times.
✓ Branch 2 taken 4163 times.
✓ Branch 2 taken 500 times.
✓ Branch 2 taken 100 times.
✓ Branch 3 taken 403 times.
✓ Branch 3 taken 548 times.
✓ Branch 3 taken 373 times.
✓ Branch 3 taken 6342 times.
✗ Branch 4 not taken.
✓ Branch 4 taken 27 times.
✓ Branch 4 taken 400 times.
✓ Branch 4 taken 2 times.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 347 times.
✓ Branch 5 taken 304 times.
✓ Branch 5 taken 1521 times.
✓ Branch 5 taken 730 times.
✓ Branch 6 taken 94 times.
✓ Branch 6 taken 13 times.
✓ Branch 6 taken 1016 times.
✓ Branch 6 taken 6340 times.
✓ Branch 7 taken 5 times.
✓ Branch 7 taken 7 times.
✓ Branch 8 taken 17390 times.
✓ Branch 8 taken 343 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 7 times.
✓ Branch 9 taken 273 times.
✓ Branch 10 taken 4 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 22 times.
✓ Branch 11 taken 506 times.
✓ Branch 12 taken 35118 times.
✓ Branch 13 taken 2 times.
✓ Branch 15 taken 273 times.
✓ Branch 16 taken 12716 times.
✓ Branch 18 taken 1 time.
✓ Branch 19 taken 16 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 7 times.
✗ Branch 25 not taken.
✗ Branch 28 not taken.
<unknown function 79>:
✓ Branch 1 taken 3 times.
✓ Branch 4 taken 3 times.
✓ Branch 7 taken 3 times.
✓ Branch 10 taken 4 times.
✓ Branch 10 taken 1 time.
✗ Branch 13 not taken.
✓ Branch 13 taken 1 time.
✓ Branch 16 taken 1 time.
✓ Branch 16 taken 1 time.
✓ Branch 19 taken 1 time.
✓ Branch 19 taken 1 time.
✓ Branch 22 taken 1 time.
✓ Branch 22 taken 1 time.
✓ Branch 25 taken 1 time.
✓ Branch 25 taken 1 time.
✓ Branch 28 taken 1 time.
✓ Branch 31 taken 1 time.
✓ Branch 34 taken 1 time.
✓ Branch 37 taken 1 time.
✓ Branch 50 taken 1 time.
✗ Branch 53 not taken.
✗ Branch 56 not taken.
✗ Branch 59 not taken.
✗ Branch 62 not taken.
✗ Branch 65 not taken.
✗ Branch 68 not taken.
✗ Branch 71 not taken.
✗ Branch 74 not taken.
chrono::batch_render::device::TrafficStats::operator+=(chrono::batch_render::device::TrafficStats const&):
✓ Branch 1 taken 84386 times.
✗ Branch 4 not taken.
✗ Branch 7 not taken.
chrono::batch_render::device::operator-(chrono::batch_render::device::TrafficStats const&, chrono::batch_render::device::TrafficStats const&):
✓ Branch 1 taken 1 time.
✓ Branch 4 taken 1 time.
✓ Branch 7 taken 8 times.
✓ Branch 10 taken 1 time.
✓ Branch 13 taken 1 time.
15666039 return *m_queue;
197 }
198
199 void Require(const Resource& resource, const char* what) const;
200
201 virtual std::optional<DLDevice> SharedDevice();
202 virtual Ref<Buffer> Import(Buffer& foreign);
203
204 bool SharesMemory(DLDeviceType api) {
205 const std::optional<DLDevice> shared = SharedDevice();
206 return shared && shared->device_type == api;
207 }
208
209 bool ReadsDirectly(DLDevice source) const;
210 void CopyIn(BufferRange dst, uint64_t source, Stream producer);
211 Ref<Buffer> Stage(uint64_t source, uint64_t bytes, Stream producer, const std::string& label);
212 Ref<Buffer> StageOnStream(uint64_t source, uint64_t bytes, Stream producer,
213 const std::string& label);
214
215 protected:
216 Device(AdapterInfo adapter, const DeviceDesc& desc, Traversal traversal);
217
218 virtual Ref<Buffer> NewBuffer(const BufferDesc& desc) = 0;
219 virtual void ExternalCopy(BufferRange dst, uint64_t source, Stream producer);
220 virtual Stream CopyStream();
221
222 virtual AccelSizes HardwareBuildSizes(const AccelInput& input) const;
223
224 virtual Ref<Accel> NewAccel(Ref<Buffer> storage, AccelLevel level, AccelSizes sizes,
225 std::string label);
226
227 virtual Ref<Texture> NewTexture(const TextureDesc& desc);
228
229 virtual std::unique_ptr<Kernel> NewKernel() = 0;
230
231 virtual std::vector<MemoryHeap> Heaps() const;
232
233 223241 DebugRecords& Debug() {
234
3/3
<unknown function 140>:
✓ Branch 1 taken 1117 times.
<unknown function 233>:
✓ Branch 1 taken 111868 times.
✓ Branch 5 taken 80099 times.
223241 return *m_debug;
235 }
236
237 static void CloseQueue(Queue& queue) noexcept;
238
239 DeviceGlobals Globals() const;
240
241 17 Buffer& GlobalsBuffer() const {
242 17 return *m_globals;
243 }
244
245 std::unique_ptr<Queue> m_queue;
246
247 private:
248 friend class Buffer;
249 friend class Texture;
250 friend class CommandEncoder;
251 friend class Program;
252 friend class Queue;
253 friend class Resource;
254 struct Counters;
255 struct AccelSizeCache;
256 struct ProgramCache;
257
258 void CountTraffic(const TrafficStats& traffic);
259
260 void CreateGlobals();
261
262 void LastReleased() noexcept override;
263
264 void Retire(Resource& resource) noexcept;
265
266 static void Adopt(Resource& resource);
267
268 void CountMemory(Buffer& buffer, int sign);
269 void CountMemory(Texture& texture, int sign);
270
271 AdapterInfo m_adapter;
272 Traversal m_traversal;
273 Sampling m_sampling;
274 std::filesystem::path m_cacheDirectory;
275 std::filesystem::path m_kernelCacheDirectory;
276 bool m_profiling;
277 bool m_synchronous;
278 bool m_kernelDebugInfo;
279 bool m_presents;
280 std::unique_ptr<DebugRecords> m_debug;
281 Ref<Buffer> m_globals;
282 std::unique_ptr<Counters> m_counters;
283 std::unique_ptr<AccelSizeCache> m_accelSizes;
284 std::shared_ptr<ProgramCache> m_programs;
285 };
286
287 }
288