nv-sgl 0.6.0__cp313-cp313-win_amd64.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (142) hide show
  1. include/tevclient.h +393 -0
  2. nv_sgl-0.6.0.dist-info/LICENSE +29 -0
  3. nv_sgl-0.6.0.dist-info/METADATA +21 -0
  4. nv_sgl-0.6.0.dist-info/RECORD +142 -0
  5. nv_sgl-0.6.0.dist-info/WHEEL +5 -0
  6. nv_sgl-0.6.0.dist-info/top_level.txt +1 -0
  7. sgl/__init__.py +15 -0
  8. sgl/__init__.pyi +6738 -0
  9. sgl/d3d12/D3D12Core.dll +0 -0
  10. sgl/d3d12/d3d12SDKLayers.dll +0 -0
  11. sgl/dxcompiler.dll +0 -0
  12. sgl/dxil.dll +0 -0
  13. sgl/gfx.dll +0 -0
  14. sgl/include/sgl/app/app.h +113 -0
  15. sgl/include/sgl/core/bitmap.h +302 -0
  16. sgl/include/sgl/core/crypto.h +89 -0
  17. sgl/include/sgl/core/data_type.h +46 -0
  18. sgl/include/sgl/core/dds_file.h +103 -0
  19. sgl/include/sgl/core/enum.h +201 -0
  20. sgl/include/sgl/core/error.h +161 -0
  21. sgl/include/sgl/core/file_stream.h +77 -0
  22. sgl/include/sgl/core/file_system_watcher.h +141 -0
  23. sgl/include/sgl/core/format.h +36 -0
  24. sgl/include/sgl/core/fwd.h +90 -0
  25. sgl/include/sgl/core/hash.h +45 -0
  26. sgl/include/sgl/core/input.h +522 -0
  27. sgl/include/sgl/core/logger.h +214 -0
  28. sgl/include/sgl/core/macros.h +184 -0
  29. sgl/include/sgl/core/maths.h +45 -0
  30. sgl/include/sgl/core/memory_mapped_file.h +112 -0
  31. sgl/include/sgl/core/memory_mapped_file_stream.h +32 -0
  32. sgl/include/sgl/core/memory_stream.h +74 -0
  33. sgl/include/sgl/core/object.h +683 -0
  34. sgl/include/sgl/core/platform.h +239 -0
  35. sgl/include/sgl/core/plugin.h +331 -0
  36. sgl/include/sgl/core/resolver.h +39 -0
  37. sgl/include/sgl/core/short_vector.h +141 -0
  38. sgl/include/sgl/core/static_vector.h +111 -0
  39. sgl/include/sgl/core/stream.h +54 -0
  40. sgl/include/sgl/core/string.h +276 -0
  41. sgl/include/sgl/core/struct.h +360 -0
  42. sgl/include/sgl/core/thread.h +28 -0
  43. sgl/include/sgl/core/timer.h +52 -0
  44. sgl/include/sgl/core/traits.h +15 -0
  45. sgl/include/sgl/core/type_utils.h +19 -0
  46. sgl/include/sgl/core/window.h +177 -0
  47. sgl/include/sgl/device/agility_sdk.h +24 -0
  48. sgl/include/sgl/device/blit.h +88 -0
  49. sgl/include/sgl/device/buffer_cursor.h +162 -0
  50. sgl/include/sgl/device/command.h +539 -0
  51. sgl/include/sgl/device/cuda_api.h +766 -0
  52. sgl/include/sgl/device/cuda_interop.h +39 -0
  53. sgl/include/sgl/device/cuda_utils.h +107 -0
  54. sgl/include/sgl/device/cursor_utils.h +129 -0
  55. sgl/include/sgl/device/device.h +668 -0
  56. sgl/include/sgl/device/device_resource.h +37 -0
  57. sgl/include/sgl/device/fence.h +91 -0
  58. sgl/include/sgl/device/formats.h +330 -0
  59. sgl/include/sgl/device/framebuffer.h +85 -0
  60. sgl/include/sgl/device/fwd.h +164 -0
  61. sgl/include/sgl/device/helpers.h +20 -0
  62. sgl/include/sgl/device/hot_reload.h +75 -0
  63. sgl/include/sgl/device/input_layout.h +74 -0
  64. sgl/include/sgl/device/kernel.h +69 -0
  65. sgl/include/sgl/device/memory_heap.h +155 -0
  66. sgl/include/sgl/device/native_formats.h +342 -0
  67. sgl/include/sgl/device/native_handle.h +73 -0
  68. sgl/include/sgl/device/native_handle_traits.h +65 -0
  69. sgl/include/sgl/device/pipeline.h +138 -0
  70. sgl/include/sgl/device/print.h +45 -0
  71. sgl/include/sgl/device/python/cursor_utils.h +853 -0
  72. sgl/include/sgl/device/query.h +52 -0
  73. sgl/include/sgl/device/raytracing.h +84 -0
  74. sgl/include/sgl/device/reflection.h +1254 -0
  75. sgl/include/sgl/device/resource.h +705 -0
  76. sgl/include/sgl/device/sampler.h +57 -0
  77. sgl/include/sgl/device/shader.h +516 -0
  78. sgl/include/sgl/device/shader_cursor.h +85 -0
  79. sgl/include/sgl/device/shader_object.h +94 -0
  80. sgl/include/sgl/device/shader_offset.h +67 -0
  81. sgl/include/sgl/device/shared_handle.h +12 -0
  82. sgl/include/sgl/device/slang_utils.h +54 -0
  83. sgl/include/sgl/device/swapchain.h +74 -0
  84. sgl/include/sgl/device/types.h +782 -0
  85. sgl/include/sgl/math/colorspace.h +56 -0
  86. sgl/include/sgl/math/constants.h +7 -0
  87. sgl/include/sgl/math/float16.h +146 -0
  88. sgl/include/sgl/math/matrix.h +6 -0
  89. sgl/include/sgl/math/matrix_math.h +746 -0
  90. sgl/include/sgl/math/matrix_types.h +207 -0
  91. sgl/include/sgl/math/python/primitivetype.h +33 -0
  92. sgl/include/sgl/math/quaternion.h +6 -0
  93. sgl/include/sgl/math/quaternion_math.h +484 -0
  94. sgl/include/sgl/math/quaternion_types.h +83 -0
  95. sgl/include/sgl/math/ray.h +47 -0
  96. sgl/include/sgl/math/scalar_math.h +249 -0
  97. sgl/include/sgl/math/scalar_types.h +107 -0
  98. sgl/include/sgl/math/vector.h +6 -0
  99. sgl/include/sgl/math/vector_math.h +1796 -0
  100. sgl/include/sgl/math/vector_types.h +336 -0
  101. sgl/include/sgl/python/nanobind.h +489 -0
  102. sgl/include/sgl/python/py_doc.h +11600 -0
  103. sgl/include/sgl/python/sgl_ext_pch.h +8 -0
  104. sgl/include/sgl/sgl.h +21 -0
  105. sgl/include/sgl/sgl_pch.h +6 -0
  106. sgl/include/sgl/stl/bit.h +377 -0
  107. sgl/include/sgl/tests/testing.h +54 -0
  108. sgl/include/sgl/ui/fwd.h +34 -0
  109. sgl/include/sgl/ui/imgui_config.h +43 -0
  110. sgl/include/sgl/ui/ui.h +71 -0
  111. sgl/include/sgl/ui/widgets.h +918 -0
  112. sgl/include/sgl/utils/python/slangpy.h +366 -0
  113. sgl/include/sgl/utils/renderdoc.h +50 -0
  114. sgl/include/sgl/utils/slangpy.h +153 -0
  115. sgl/include/sgl/utils/tev.h +93 -0
  116. sgl/include/sgl/utils/texture_loader.h +106 -0
  117. sgl/math/__init__.pyi +5083 -0
  118. sgl/platform/__init__.pyi +102 -0
  119. sgl/renderdoc/__init__.pyi +51 -0
  120. sgl/sgl.dll +0 -0
  121. sgl/sgl_ext.cp313-win_amd64.pyd +0 -0
  122. sgl/shaders/nvapi/nvHLSLExtns.h +2315 -0
  123. sgl/shaders/nvapi/nvHLSLExtnsInternal.h +758 -0
  124. sgl/shaders/nvapi/nvShaderExtnEnums.h +142 -0
  125. sgl/shaders/sgl/device/blit.slang +93 -0
  126. sgl/shaders/sgl/device/nvapi.slang +5 -0
  127. sgl/shaders/sgl/device/nvapi.slangh +7 -0
  128. sgl/shaders/sgl/device/print.slang +445 -0
  129. sgl/shaders/sgl/math/constants.slang +4 -0
  130. sgl/shaders/sgl/math/ray.slang +29 -0
  131. sgl/shaders/sgl/ui/imgui.slang +49 -0
  132. sgl/slang-glslang.dll +0 -0
  133. sgl/slang-llvm.dll +0 -0
  134. sgl/slang-rt.dll +0 -0
  135. sgl/slang.dll +0 -0
  136. sgl/slangpy/__init__.pyi +268 -0
  137. sgl/tev/__init__.pyi +108 -0
  138. sgl/tevclient.lib +0 -0
  139. sgl/thread/__init__.pyi +4 -0
  140. sgl/ui/__init__.pyi +1118 -0
  141. share/cmake/tevclient/tevclient-config-release.cmake +19 -0
  142. share/cmake/tevclient/tevclient-config.cmake +108 -0
@@ -0,0 +1,489 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+
3
+ #pragma once
4
+
5
+ #include <nanobind/nanobind.h>
6
+ #include <nanobind/ndarray.h>
7
+ #include <nanobind/operators.h>
8
+ #include <nanobind/trampoline.h>
9
+ #include <nanobind/stl/array.h>
10
+ #include <nanobind/stl/bind_map.h>
11
+ #include <nanobind/stl/filesystem.h>
12
+ #include <nanobind/stl/function.h>
13
+ #include <nanobind/stl/map.h>
14
+ #include <nanobind/stl/set.h>
15
+ #include <nanobind/stl/optional.h>
16
+ #include <nanobind/stl/string_view.h>
17
+ #include <nanobind/stl/string.h>
18
+ #include <nanobind/stl/vector.h>
19
+ #include <nanobind/stl/unique_ptr.h>
20
+
21
+ #include "sgl/core/object.h"
22
+ #include "sgl/core/enum.h"
23
+ #include "sgl/core/type_utils.h"
24
+ #include "sgl/core/struct.h"
25
+ #include "sgl/core/data_type.h"
26
+
27
+ #include "sgl/math/float16.h"
28
+
29
+ #include "sgl/device/cuda_interop.h"
30
+
31
+ #include "py_doc.h"
32
+
33
+ #include <span>
34
+
35
+ namespace nb = nanobind;
36
+ using namespace nb::literals;
37
+
38
+ NAMESPACE_BEGIN(NB_NAMESPACE)
39
+
40
+ template<>
41
+ struct ndarray_traits<sgl::math::float16_t> {
42
+ static constexpr bool is_complex = false;
43
+ static constexpr bool is_float = true;
44
+ static constexpr bool is_bool = false;
45
+ static constexpr bool is_int = false;
46
+ static constexpr bool is_signed = true;
47
+ };
48
+
49
+ NAMESPACE_BEGIN(detail)
50
+
51
+ /// Type caster for sgl::ref<T>
52
+ template<typename T>
53
+ struct type_caster<sgl::ref<T>> {
54
+ using Caster = make_caster<T>;
55
+ static constexpr bool IsClass = true;
56
+ NB_TYPE_CASTER(sgl::ref<T>, Caster::Name);
57
+
58
+ bool from_python(handle src, uint8_t flags, cleanup_list* cleanup) noexcept
59
+ {
60
+ Caster caster;
61
+ if (!caster.from_python(src, flags, cleanup))
62
+ return false;
63
+
64
+ value = Value(caster.operator T*());
65
+ return true;
66
+ }
67
+
68
+ static handle from_cpp(const sgl::ref<T>& value, rv_policy policy, cleanup_list* cleanup) noexcept
69
+ {
70
+ return Caster::from_cpp(value.get(), policy, cleanup);
71
+ }
72
+ };
73
+
74
+ /// Type caster for std::span<T>
75
+ template<typename T>
76
+ struct type_caster<std::span<T>> {
77
+ NB_TYPE_CASTER(
78
+ std::span<T>,
79
+ io_name("Sequence", NB_TYPING_LIST) + const_name("[") + make_caster<T>::Name + const_name("]")
80
+ )
81
+
82
+ using Caster = make_caster<T>;
83
+
84
+ std::vector<T> vec;
85
+
86
+ bool from_python(handle src, uint8_t flags, cleanup_list* cleanup) noexcept
87
+ {
88
+ size_t size;
89
+ PyObject* temp;
90
+ PyObject** o = seq_get(src.ptr(), &size, &temp);
91
+
92
+ vec.clear();
93
+ vec.reserve(size);
94
+
95
+ Caster caster;
96
+ bool success = o != nullptr;
97
+
98
+ flags = flags_for_local_caster<T>(flags);
99
+
100
+ for (size_t i = 0; i < size; ++i) {
101
+ if (!caster.from_python(o[i], flags, cleanup) || !caster.template can_cast<T>()) {
102
+ success = false;
103
+ break;
104
+ }
105
+
106
+ vec.push_back(caster.operator cast_t<T>());
107
+ }
108
+
109
+ Py_XDECREF(temp);
110
+
111
+ value = std::span{vec};
112
+
113
+ return success;
114
+ }
115
+
116
+ static handle from_cpp(const std::span<T>& src, rv_policy policy, cleanup_list* cleanup) noexcept
117
+ {
118
+ object ret = steal(PyList_New(src.size()));
119
+
120
+ if (ret.is_valid()) {
121
+ Py_ssize_t index = 0;
122
+
123
+ for (auto&& value : src) {
124
+ handle h = Caster::from_cpp(forward_like_<T>(value), policy, cleanup);
125
+ if (!h.is_valid()) {
126
+ ret.reset();
127
+ break;
128
+ }
129
+ NB_LIST_SET_ITEM(ret.ptr(), index++, h.ptr());
130
+ }
131
+ }
132
+
133
+ return ret.release();
134
+ }
135
+ };
136
+
137
+ NAMESPACE_END(detail)
138
+
139
+ template<typename T>
140
+ class sgl_enum : public enum_<T> {
141
+ public:
142
+ static_assert(::sgl::has_enum_info<T>, "nanobind::sgl_enum<> requires an enumeration type with infos!");
143
+
144
+ using Base = enum_<T>;
145
+
146
+ template<typename... Extra>
147
+ NB_INLINE sgl_enum(handle scope, const char* name, const Extra&... extra)
148
+ : Base(scope, name, extra...)
149
+ {
150
+ for (const auto& item : ::sgl::EnumInfo<T>::items())
151
+ Base::value(item.second.c_str(), item.first);
152
+ }
153
+ };
154
+
155
+ template<typename T>
156
+ class sgl_enum_flags : public sgl_enum<T> {
157
+ public:
158
+ static_assert(
159
+ std::is_same_v<T, decltype(std::declval<T>() & std::declval<T>())>,
160
+ "nanobind::sgl_enum_flags<> requires an enumeration type with bitwise operators!"
161
+ );
162
+
163
+ using Base = sgl_enum<T>;
164
+
165
+ template<typename... Extra>
166
+ NB_INLINE sgl_enum_flags(handle scope, const char* name, const Extra&... extra)
167
+ : Base(scope, name, nb::is_arithmetic(), nb::is_flag(), extra...)
168
+ {
169
+ }
170
+ };
171
+
172
+ NAMESPACE_END(NB_NAMESPACE)
173
+
174
+
175
+ namespace sgl {
176
+
177
+ /// Helper class passed to GcHelper::traverse() to visit attributes and child objects.
178
+ class GcVisitor {
179
+ public:
180
+ /// Visit an attribute with the given name.
181
+ void operator()(const char* name)
182
+ {
183
+ if (result != 0)
184
+ return;
185
+ if (!nb::hasattr(self, name))
186
+ return;
187
+ nb::object value = nb::getattr(self, name);
188
+ if (value.is_valid() && !value.is_none()) {
189
+ result = [&]()
190
+ {
191
+ Py_VISIT(value.ptr());
192
+ return 0;
193
+ }();
194
+ }
195
+ }
196
+ /// Visit a child object.
197
+ void operator()(Object* object)
198
+ {
199
+ if (result != 0)
200
+ return;
201
+ result = [&]()
202
+ {
203
+ Py_VISIT(object->self_py());
204
+ return 0;
205
+ }();
206
+ }
207
+
208
+ private:
209
+ PyObject* self;
210
+ visitproc visit;
211
+ void* arg;
212
+ int result{0};
213
+ template<typename T>
214
+ friend class GcHelperFunctions;
215
+ };
216
+
217
+ /// Garbage collection helper to be specialized for each object type.
218
+ /// The default implementation does nothing.
219
+ template<typename T>
220
+ struct GcHelper {
221
+ void traverse(T*, GcVisitor&) { }
222
+ void clear(T*) { }
223
+ };
224
+
225
+ /// Implementation of tp_traverse and tp_clear for a given object type.
226
+ template<typename T>
227
+ class GcHelperFunctions {
228
+ public:
229
+ static int tp_traverse(PyObject* self, visitproc visit, void* arg)
230
+ {
231
+ T* object = nb::inst_ptr<T>(self);
232
+ GcVisitor visitor;
233
+ visitor.self = self;
234
+ visitor.visit = visit;
235
+ visitor.arg = arg;
236
+ GcHelper<T>{}.traverse(object, visitor);
237
+ return visitor.result;
238
+ }
239
+
240
+ static int tp_clear(PyObject* self)
241
+ {
242
+ T* object = nb::inst_ptr<T>(self);
243
+ GcHelper<T>{}.clear(object);
244
+ return 0;
245
+ }
246
+
247
+ public:
248
+ static inline PyType_Slot type_slots[] = {
249
+ {Py_tp_traverse, (void*)tp_traverse},
250
+ {Py_tp_clear, (void*)tp_clear},
251
+ {0, nullptr},
252
+ };
253
+ };
254
+
255
+ /// Return Python type slots (tp_traverse, tp_clear) for a given object type.
256
+ template<typename T>
257
+ nb::type_slots gc_helper_type_slots()
258
+ {
259
+ return nb::type_slots(GcHelperFunctions<T>::type_slots);
260
+ }
261
+
262
+ }; // namespace sgl
263
+
264
+ namespace sgl {
265
+
266
+ template<typename... Args>
267
+ size_t is_ndarray_contiguous(const nb::ndarray<Args...>& array)
268
+ {
269
+ if (array.ndim() == 0)
270
+ return false;
271
+ size_t prod = 1;
272
+ for (size_t i = array.ndim() - 1;;) {
273
+ if (array.stride(i) != narrow_cast<int64_t>(prod))
274
+ return false;
275
+ prod *= array.shape(i);
276
+ if (i == 0)
277
+ break;
278
+ --i;
279
+ }
280
+ return true;
281
+ }
282
+
283
+ inline cuda::TensorView ndarray_to_cuda_tensor_view(nb::ndarray<nb::device::cuda> array)
284
+ {
285
+ return cuda::TensorView{
286
+ .data = array.data(),
287
+ .size = array.nbytes(),
288
+ .stride = 0, // TODO
289
+ };
290
+ }
291
+
292
+ inline nb::dlpack::dtype data_type_to_dtype(DataType type)
293
+ {
294
+ switch (type) {
295
+ case DataType::bool_:
296
+ return nb::dtype<bool>();
297
+ case DataType::int8:
298
+ return nb::dtype<int8_t>();
299
+ case DataType::int16:
300
+ return nb::dtype<int16_t>();
301
+ case DataType::int32:
302
+ return nb::dtype<int32_t>();
303
+ case DataType::int64:
304
+ return nb::dtype<int64_t>();
305
+ case DataType::uint8:
306
+ return nb::dtype<uint8_t>();
307
+ case DataType::uint16:
308
+ return nb::dtype<uint16_t>();
309
+ case DataType::uint32:
310
+ return nb::dtype<uint32_t>();
311
+ case DataType::uint64:
312
+ return nb::dtype<uint64_t>();
313
+ case DataType::float16:
314
+ return nb::dtype<math::float16_t>();
315
+ case DataType::float32:
316
+ return nb::dtype<float>();
317
+ case DataType::float64:
318
+ return nb::dtype<double>();
319
+ default:
320
+ break;
321
+ }
322
+ SGL_THROW("Data type is incompatible with DLPack.");
323
+ }
324
+
325
+ inline DataType dtype_to_data_type(nb::dlpack::dtype dtype)
326
+ {
327
+ switch ((nb::dlpack::dtype_code)dtype.code) {
328
+ case nb::dlpack::dtype_code::Float:
329
+ switch (dtype.bits) {
330
+ case 16:
331
+ return DataType::float16;
332
+ case 32:
333
+ return DataType::float32;
334
+ case 64:
335
+ return DataType::float64;
336
+ default:
337
+ break;
338
+ }
339
+ break;
340
+
341
+ case nb::dlpack::dtype_code::Int:
342
+ switch (dtype.bits) {
343
+ case 8:
344
+ return DataType::int8;
345
+ case 16:
346
+ return DataType::int16;
347
+ case 32:
348
+ return DataType::int32;
349
+ case 64:
350
+ return DataType::int64;
351
+ default:
352
+ break;
353
+ }
354
+ break;
355
+
356
+ case nb::dlpack::dtype_code::UInt:
357
+ switch (dtype.bits) {
358
+ case 8:
359
+ return DataType::uint8;
360
+ case 16:
361
+ return DataType::uint16;
362
+ case 32:
363
+ return DataType::uint32;
364
+ case 64:
365
+ return DataType::uint64;
366
+ default:
367
+ break;
368
+ }
369
+ break;
370
+
371
+ case nb::dlpack::dtype_code::Bool:
372
+ switch (dtype.bits) {
373
+ case 8:
374
+ return DataType::bool_;
375
+ default:
376
+ break;
377
+ }
378
+ break;
379
+
380
+ default:
381
+ break;
382
+ }
383
+ SGL_THROW("Unsupported dtype.");
384
+ }
385
+
386
+ inline std::optional<Struct::Type> dtype_to_struct_type(nb::dlpack::dtype dtype)
387
+ {
388
+ switch (dtype.code) {
389
+ case uint8_t(nb::dlpack::dtype_code::Int):
390
+ switch (dtype.bits) {
391
+ case 8:
392
+ return Struct::Type::int8;
393
+ case 16:
394
+ return Struct::Type::int16;
395
+ case 32:
396
+ return Struct::Type::int32;
397
+ case 64:
398
+ return Struct::Type::int64;
399
+ }
400
+ break;
401
+ case uint8_t(nb::dlpack::dtype_code::UInt):
402
+ switch (dtype.bits) {
403
+ case 8:
404
+ return Struct::Type::uint8;
405
+ case 16:
406
+ return Struct::Type::uint16;
407
+ case 32:
408
+ return Struct::Type::uint32;
409
+ case 64:
410
+ return Struct::Type::uint64;
411
+ }
412
+ break;
413
+ case uint8_t(nb::dlpack::dtype_code::Float):
414
+ switch (dtype.bits) {
415
+ case 16:
416
+ return Struct::Type::float16;
417
+ case 32:
418
+ return Struct::Type::float32;
419
+ case 64:
420
+ return Struct::Type::float64;
421
+ }
422
+ break;
423
+ }
424
+ return {};
425
+ }
426
+
427
+ } // namespace sgl
428
+
429
+
430
+ namespace sgl::detail {
431
+ inline constexpr uint64_t const_hash(std::string_view str)
432
+ {
433
+ uint64_t hash = 0xcbf29ce484222325;
434
+ constexpr size_t prime = 0x00000100000001b3;
435
+ for (auto c : str) {
436
+ hash ^= static_cast<size_t>(c);
437
+ hash *= prime;
438
+ }
439
+ return hash;
440
+ }
441
+ } // namespace sgl::detail
442
+
443
+ #define SGL_DICT_TO_DESC_BEGIN(type) \
444
+ type dict_to_##type(nb::dict dict) \
445
+ { \
446
+ type desc = {}; \
447
+ for (const auto& [k, v] : dict) { \
448
+ std::string_view key = nb::cast<std::string_view>(k); \
449
+ uint64_t hash = ::sgl::detail::const_hash(key); \
450
+ switch (hash) {
451
+
452
+ #define SGL_DICT_TO_DESC_FIELD(name, type) \
453
+ case ::sgl::detail::const_hash(#name): \
454
+ desc.name = nb::cast<type>(v); \
455
+ break;
456
+
457
+ #define SGL_DICT_TO_DESC_FIELD_DICT(name, type) \
458
+ case ::sgl::detail::const_hash(#name): \
459
+ extern type dict_to_##type(nb::dict dict); \
460
+ desc.name = dict_to_##type(nb::cast<nb::dict>(v)); \
461
+ break;
462
+
463
+ #define SGL_DICT_TO_DESC_FIELD_LIST(name, type) \
464
+ case ::sgl::detail::const_hash(#name): \
465
+ desc.name = {}; \
466
+ for (const auto& item : v) \
467
+ desc.name.push_back(dict_to_##type(nb::cast<nb::dict>(item))); \
468
+ break;
469
+
470
+ #define SGL_DICT_TO_DESC_FIELD_CUSTOM(name, code) \
471
+ case ::sgl::detail::const_hash(#name): \
472
+ desc.name = code; \
473
+ break;
474
+
475
+ #define SGL_DICT_TO_DESC_END() \
476
+ default: \
477
+ SGL_THROW("Unknown key {}", key); \
478
+ } \
479
+ } \
480
+ return desc; \
481
+ }
482
+
483
+
484
+ #define SGL_PY_DECLARE(name) extern void sgl_python_export_##name(nb::module_& m)
485
+ #define SGL_PY_EXPORT(name) void sgl_python_export_##name([[maybe_unused]] ::nb::module_& m)
486
+ #define SGL_PY_IMPORT(name) sgl_python_export_##name(m)
487
+
488
+ #define D(...) DOC(sgl, __VA_ARGS__)
489
+ #define D_NA(...) "N/A"