rayd 0.6.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,465 @@
1
+ Metadata-Version: 2.4
2
+ Name: rayd
3
+ Version: 0.6.0
4
+ Summary: RayD meta-distribution installing the Dr.Jit and Torch backends.
5
+ Author-email: Xingyu Chen <xic063@ucsd.edu>
6
+ License-Expression: BSD-3-Clause
7
+ Requires-Python: <3.15,>=3.10
8
+ Description-Content-Type: text/markdown
9
+ License-File: LICENSE
10
+ Requires-Dist: rayd-drjit==0.6.0
11
+ Requires-Dist: rayd-torch==0.6.0
12
+ Dynamic: license-file
13
+
14
+ # RayD
15
+
16
+ [![PyPI](https://img.shields.io/pypi/v/rayd)](https://pypi.org/project/rayd/)
17
+ [![Downloads](https://img.shields.io/pypi/dm/rayd)](https://pypi.org/project/rayd/)
18
+ ![Code Size](https://img.shields.io/github/languages/code-size/Asixa/RayD)
19
+ ![Total Lines](https://tokei.tvj.one/b1/github/Asixa/RayD?style=flat)
20
+ [![License](https://img.shields.io/github/license/Asixa/RayD)](LICENSE)
21
+
22
+ RayD is a CUDA/OptiX library for differentiable ray geometry, edge queries,
23
+ visibility, and RF-style multipath primitives. Version 0.6 provides two
24
+ independent, backend-native Python APIs:
25
+
26
+ ```python
27
+ import rayd.drjit as rd
28
+ import rayd.torch as rt
29
+ ```
30
+
31
+ RayD is not a full renderer. It exposes low-level geometry and wave-propagation
32
+ primitives for custom renderers, RF simulators, acoustics, sensing, visibility
33
+ analysis, and inverse-design systems without imposing a material-light-
34
+ integrator framework.
35
+
36
+ ## Installation
37
+
38
+ Install both backends through the meta-distribution:
39
+
40
+ ```bash
41
+ pip install rayd
42
+ ```
43
+
44
+ Install only the backend you use when the other runtime is not needed:
45
+
46
+ ```bash
47
+ pip install rayd-drjit
48
+ pip install rayd-torch
49
+ ```
50
+
51
+ All three distributions share version `0.6.0`. The `rayd` meta-distribution
52
+ pins `rayd-drjit` and `rayd-torch` to exactly the same version.
53
+
54
+ Release artifacts cover CPython 3.10 through 3.14 on Windows x86-64 and
55
+ `manylinux_2_28_x86_64`. The native backend wheels are CPython-specific while
56
+ the Torch backend still contains the transitional `_C` extension. The
57
+ `_stable_ops` library inside `rayd-torch` is untagged and uses the LibTorch 2.10
58
+ Stable ABI boundary. The `rayd` meta-distribution is a universal pure-Python
59
+ wheel and is the only distribution that also publishes an sdist.
60
+
61
+ > [!IMPORTANT]
62
+ > RayD 0.6 uses explicit backend namespaces. The parent `rayd` namespace does
63
+ > not select or re-export a default backend. Replace legacy `import rayd as rd`
64
+ > with `import rayd.drjit as rd` or `import rayd.torch as rt`.
65
+
66
+ For downstream migration details, see
67
+ [`docs/downstream-migration.md`](docs/downstream-migration.md).
68
+
69
+ ## Scope
70
+
71
+ RayD focuses on geometry and wave-propagation primitives:
72
+
73
+ - differentiable ray-mesh intersection
74
+ - scene-level GPU acceleration through OptiX
75
+ - nearest-edge point and ray queries
76
+ - primary-edge and secondary-edge sampling support
77
+ - segment visibility and reflection-path tracing
78
+ - equivalent-path correction (EPC) primitives
79
+ - reflection and diffraction field accumulation
80
+ - Dr.Jit and PyTorch reverse/forward automatic differentiation
81
+ - source-level integration for native downstream CMake projects
82
+
83
+ RayD intentionally does not provide:
84
+
85
+ - BSDFs or emitters
86
+ - rendering integrators
87
+ - scene loaders
88
+ - bitmap or image I/O
89
+ - a material-light-integrator framework
90
+ - implicit conversions between Dr.Jit and Torch objects
91
+
92
+ ## Why RayD?
93
+
94
+ Mitsuba is an excellent physically based renderer, but it can be too high-level
95
+ when the main workload is RF propagation, acoustics, sonar, visibility analysis,
96
+ or a custom wave simulator. Those applications often need direct control over
97
+ ray-scene queries, edges, reflection chains, diffraction state, and geometry
98
+ gradients instead of a complete rendering runtime.
99
+
100
+ RayD keeps that API surface focused: meshes, scenes, rays, intersections,
101
+ edges, visibility, and multipath query results.
102
+
103
+ ## Backend Capabilities
104
+
105
+ | Capability | Dr.Jit | Torch |
106
+ | --- | --- | --- |
107
+ | Ray-mesh intersection | Yes | Yes |
108
+ | Point/ray nearest edge | Yes | Yes |
109
+ | Top-k nearest edges | Yes | No |
110
+ | Segment visibility | Yes | Yes |
111
+ | Pair/chain/edge visibility helpers | Yes | Partial |
112
+ | Reflection tracing and accumulation | Yes | Yes |
113
+ | EPC path and field queries | Yes | Yes |
114
+ | Direct and chained diffraction | Yes | Yes |
115
+ | Surfel primitives | Yes | No |
116
+ | Reverse-mode AD | Yes | Yes |
117
+ | Forward-mode AD | Yes | Yes |
118
+ | `torch.compile` integration | No | Yes |
119
+
120
+ Use `backend_capabilities()` on either backend for the machine-readable
121
+ capability manifest. Unsupported functionality does not silently cross into
122
+ the other runtime.
123
+
124
+ Each backend owns its scene objects, GPU allocations, current stream, OptiX
125
+ pipelines, acceleration structures, and AD graph. A `rayd.drjit.Scene` cannot
126
+ be passed to `rayd.torch`, and a `rayd.torch.Scene` cannot be passed to
127
+ `rayd.drjit`.
128
+
129
+ ## Core API
130
+
131
+ The two backends use the same high-level vocabulary where their capabilities
132
+ overlap:
133
+
134
+ - `Mesh`: triangle geometry, transforms, UVs, and edge topology
135
+ - `Scene`: mesh container plus OptiX acceleration structures
136
+ - `Ray` / `RayAD`: batched origins, directions, and optional `tmax`
137
+ - `scene.intersect(ray)`: closest differentiable ray-mesh hit
138
+ - `scene.nearest_edge(query)`: nearest-edge point or ray query
139
+ - `scene.trace_reflections(...)`: specular reflection chains
140
+ - `scene.accumulate_reflections(...)`: reflected field/power accumulation
141
+ - `scene.accum_dfr_direct(...)` / `scene.accum_dfr(...)`: diffraction
142
+ accumulation
143
+ - `scene.trace_dfr_paths(...)`: compact diffraction path export
144
+
145
+ The Dr.Jit backend additionally exposes:
146
+
147
+ - `scene.shadow_test(ray)`
148
+ - `scene.nearest_edges(point, k)` for `k <= 16`
149
+ - `scene.visible(...)`, `visible_pair(...)`, `visible_chain(...)`, and
150
+ `visible_edge(...)`
151
+ - `scene.set_edge_mask(mask)` / `scene.edge_mask()`
152
+ - surfel intersection, compositing, and rendering primitives
153
+
154
+ ## Differentiation Contract
155
+
156
+ RayD differentiates continuous geometry and field quantities while treating
157
+ the discrete winner selected during the forward pass as fixed:
158
+
159
+ - primitive, edge, visibility, and path selection are discrete
160
+ - hit distance, position, normals, transforms, ray parameters, materials, and
161
+ supported field inputs retain gradients
162
+ - native reflection and diffraction operators provide explicit JVP/VJP paths
163
+ - unsupported AD strategies fail explicitly instead of silently copying data
164
+ through the other backend
165
+
166
+ For Dr.Jit, `RayAD` selects the differentiable intersection overload. Torch
167
+ selects AD from tensors with `requires_grad=True` and supports both backward
168
+ VJP and forward JVP for implemented operators.
169
+
170
+ ## Dr.Jit Quick Start
171
+
172
+ The following example traces one ray against a triangle and differentiates the
173
+ hit distance with respect to the mesh vertices:
174
+
175
+ ```python
176
+ import drjit as dr
177
+ import rayd.drjit as rd
178
+
179
+
180
+ mesh = rd.Mesh(
181
+ dr.cuda.Array3f(
182
+ [0.0, 1.0, 0.0],
183
+ [0.0, 0.0, 1.0],
184
+ [0.0, 0.0, 0.0],
185
+ ),
186
+ dr.cuda.Array3i([0], [1], [2]),
187
+ )
188
+
189
+ vertices = dr.cuda.ad.Array3f(
190
+ [0.0, 1.0, 0.0],
191
+ [0.0, 0.0, 1.0],
192
+ [0.0, 0.0, 0.0],
193
+ )
194
+ dr.enable_grad(vertices)
195
+ mesh.vertex_positions = vertices
196
+
197
+ scene = rd.Scene()
198
+ scene.add_mesh(mesh)
199
+ scene.build()
200
+
201
+ ray = rd.RayAD(
202
+ dr.cuda.ad.Array3f([0.25], [0.25], [-1.0]),
203
+ dr.cuda.ad.Array3f([0.0], [0.0], [1.0]),
204
+ )
205
+
206
+ hit = scene.intersect(ray)
207
+ dr.backward(dr.sum(hit.t))
208
+
209
+ print("t =", hit.t)
210
+ print("vertex z gradients =", dr.grad(vertices).z)
211
+ ```
212
+
213
+ ## Torch Quick Start
214
+
215
+ The equivalent Torch example stays entirely in Torch tensors and autograd:
216
+
217
+ ```python
218
+ import torch
219
+ import rayd.torch as rt
220
+
221
+
222
+ vertices = torch.tensor(
223
+ [[0.0, 0.0, 0.0],
224
+ [1.0, 0.0, 0.0],
225
+ [0.0, 1.0, 0.0]],
226
+ device="cuda",
227
+ dtype=torch.float32,
228
+ requires_grad=True,
229
+ )
230
+ faces = torch.tensor(
231
+ [[0, 1, 2]],
232
+ device="cuda",
233
+ dtype=torch.int32,
234
+ )
235
+
236
+ scene = rt.Scene()
237
+ scene.add_mesh(rt.Mesh(vertices, faces))
238
+ scene.build()
239
+
240
+ ray = rt.Ray(
241
+ torch.tensor([[0.25, 0.25, -1.0]], device="cuda"),
242
+ torch.tensor([[0.0, 0.0, 1.0]], device="cuda"),
243
+ )
244
+
245
+ hit = scene.intersect(ray)
246
+ hit.t.sum().backward()
247
+
248
+ print("t =", hit.t)
249
+ print("vertex z gradients =", vertices.grad[:, 2])
250
+ ```
251
+
252
+ Torch vector inputs use contiguous CUDA `float32` tensors with shape `(N, 3)`;
253
+ index tensors use CUDA `int32`, and masks use `torch.bool`. CUDA operations run
254
+ on the current Torch stream.
255
+
256
+ ## Edge Queries
257
+
258
+ RayD provides scene-level GPU acceleration for point-to-edge and ray-to-edge
259
+ queries. Typical uses include:
260
+
261
+ - diffraction edge selection
262
+ - closest-feature geometry terms
263
+ - visibility-boundary estimators
264
+ - differentiable geometric constraints
265
+
266
+ For finite ray queries, nearest-edge distance uses segment semantics on
267
+ `[0, tmax]`. Dr.Jit's `Scene.set_edge_mask(mask)` filters the secondary-edge
268
+ BVH in scene-global edge index space without changing the underlying edge
269
+ topology or mesh offsets.
270
+
271
+ ## Multipath Queries
272
+
273
+ RayD includes low-level reflection, visibility, and diffraction primitives for
274
+ custom wave simulators:
275
+
276
+ - reflection chains with image sources and scene-global primitive IDs
277
+ - batched segment visibility
278
+ - equivalent-path correction geometry and complex reflected fields
279
+ - reflection field/power accumulation onto receiver grids
280
+ - direct, Keller-cone, suffix-reflection, and order-2/3 diffraction
281
+ - coherent deterministic diffraction accumulation
282
+ - compact path export for downstream channel/CIR processing
283
+
284
+ `trace_*` APIs return geometric or field records per ray/path. `accum_*` APIs
285
+ reduce contributions into aggregate outputs such as receiver-grid cells. RayD
286
+ does not choose the source model, receiver model, material policy, objective,
287
+ or final channel representation for the caller.
288
+
289
+ Naming follows the public API standard in
290
+ [`backends/drjit/API_NAMING_STANDARD.md`](backends/drjit/API_NAMING_STANDARD.md):
291
+ `Dfr` denotes diffraction, `Refl` denotes reflection, `Epc` denotes
292
+ equivalent-path correction, and `AD` is reserved for automatic differentiation.
293
+
294
+ ## Examples
295
+
296
+ Dr.Jit examples are kept as runnable applications under
297
+ [`backends/drjit/examples`](backends/drjit/examples):
298
+
299
+ - [`ray_mesh_intersection.py`](backends/drjit/examples/basics/ray_mesh_intersection.py):
300
+ differentiable triangle intersection
301
+ - [`nearest_edge_query.py`](backends/drjit/examples/basics/nearest_edge_query.py):
302
+ scene-level nearest-edge queries
303
+ - [`surfel_intersection.py`](backends/drjit/examples/basics/surfel_intersection.py):
304
+ differentiable surfel hits
305
+ - [`surfel_multiview_color_fit.py`](backends/drjit/examples/basics/surfel_multiview_color_fit.py):
306
+ multiview surfel optimization
307
+ - [`cornell_box.py`](backends/drjit/examples/renderer/cornell_box.py):
308
+ a compact renderer built from RayD primitives
309
+
310
+ The Torch test and benchmark suite also serves as executable usage coverage:
311
+
312
+ - [`test_intersect_grad.py`](backends/torch/tests/torch_backend/test_intersect_grad.py):
313
+ reverse-mode geometry gradients
314
+ - [`test_multipath.py`](backends/torch/tests/torch_backend/test_multipath.py):
315
+ reflection, EPC, visibility, and diffraction APIs
316
+ - [`benchmark_rayd_backends.py`](backends/torch/tests/benchmark_rayd_backends.py):
317
+ same-process Torch/Dr.Jit comparison
318
+
319
+ ## Performance
320
+
321
+ The historical RayD-versus-Mitsuba benchmark was measured on an NVIDIA RTX
322
+ 5080 and AMD Ryzen 7 9800X3D using a `192 x 192` mesh and `384 x 384` rays.
323
+ RayD stayed aligned with Mitsuba while improving static forward and gradient
324
+ latency. Representative average latencies in milliseconds were:
325
+
326
+ | Workload | RayD | Mitsuba |
327
+ | --- | ---: | ---: |
328
+ | Static full intersection | 0.162 | 0.190 |
329
+ | Static reduced intersection | 0.124 | 0.224 |
330
+ | Dynamic full intersection | 0.741 | 0.740 |
331
+ | Dynamic reduced intersection | 0.689 | 0.714 |
332
+ | Static gradient | 0.411 | 0.757 |
333
+ | Dynamic gradient | 1.324 | 1.413 |
334
+
335
+ Forward mismatch counts were zero in that sweep, and the largest static
336
+ gradient discrepancy was `9.54e-7`. Current backend-to-backend benchmarks live
337
+ under [`backends/torch/tests`](backends/torch/tests) and should be rerun for the
338
+ target GPU, CUDA toolkit, and workload before making deployment decisions.
339
+
340
+ ## Device and Stream Selection
341
+
342
+ The Dr.Jit backend follows Dr.Jit's current-thread CUDA device:
343
+
344
+ ```python
345
+ import rayd.drjit as rd
346
+
347
+ rd.set_device(0)
348
+ ```
349
+
350
+ Existing scenes and OptiX resources should not be reused across device switches
351
+ in the same process.
352
+
353
+ The Torch backend follows the device of its CUDA tensors and launches work on
354
+ the current Torch CUDA stream. Keep every tensor participating in one query on
355
+ the same device.
356
+
357
+ ## Building from Source
358
+
359
+ RayD requires Python 3.10-3.14, CMake 3.22+, a C++17 compiler, CUDA, and the OptiX
360
+ SDK. On Windows, use Visual Studio 2022 with Desktop C++ tools.
361
+
362
+ Create an environment and install common build tools:
363
+
364
+ ```powershell
365
+ conda create -n rayd python=3.11 -y
366
+ conda activate rayd
367
+ python -m pip install -U pip setuptools wheel
368
+ python -m pip install cmake ninja scikit-build-core
369
+ ```
370
+
371
+ Build the Dr.Jit backend:
372
+
373
+ ```powershell
374
+ python -m pip install "drjit==1.3.1" "nanobind==2.9.2"
375
+ python -m pip install --no-build-isolation -ve backends/drjit
376
+ ```
377
+
378
+ Build the Torch backend:
379
+
380
+ ```powershell
381
+ python -m pip install torch==2.10.0 --index-url https://download.pytorch.org/whl/cu128
382
+ python -m pip install --no-build-isolation -ve backends/torch
383
+ ```
384
+
385
+ Native downstream projects can add the Torch backend with CMake and link
386
+ against `rayd_torch_native_core`. The source-level integration declarations
387
+ are provided by
388
+ [`backends/torch/include/rayd/torch/integration.h`](backends/torch/include/rayd/torch/integration.h).
389
+ This interface is intended for projects built in the same CMake/libtorch graph;
390
+ it is not a stable binary ABI across unrelated libtorch builds.
391
+
392
+ ## Repository Layout
393
+
394
+ - [`backends/drjit`](backends/drjit): Dr.Jit Python bindings, C++/CUDA/OptiX
395
+ implementation, examples, and tests
396
+ - [`backends/torch`](backends/torch): Torch Python API, dispatcher/autograd
397
+ bindings, C++/CUDA/OptiX implementation, and tests
398
+ - [`shared/include`](shared/include): backend-neutral device contracts and UTD
399
+ math
400
+ - [`tests/packaging`](tests/packaging): distribution, namespace, and wheel-layout
401
+ checks
402
+ - [`docs`](docs): migration, validation, and OptiX pipeline notes
403
+ - [`CHANGELOG.md`](CHANGELOG.md): release history
404
+
405
+ ## Testing
406
+
407
+ Run packaging and namespace checks from the repository root:
408
+
409
+ ```powershell
410
+ python -m unittest tests.packaging.test_project_metadata -v
411
+ python -m unittest tests.test_namespace_isolation -v
412
+ ```
413
+
414
+ Run representative Dr.Jit suites:
415
+
416
+ ```powershell
417
+ python -m unittest backends.drjit.tests.drjit.test_geometry -v
418
+ python -m unittest backends.drjit.tests.drjit.test_visibility_topk -v
419
+ python -m unittest backends.drjit.tests.drjit.test_reflection_epc -v
420
+ python -m unittest backends.drjit.tests.drjit.test_reflection_accumulation -v
421
+ python -m unittest backends.drjit.tests.drjit.test_diffraction_accumulation -v
422
+ ```
423
+
424
+ Run representative Torch suites:
425
+
426
+ ```powershell
427
+ python -m unittest backends.torch.tests.torch_backend.test_intersect_forward -v
428
+ python -m unittest backends.torch.tests.torch_backend.test_intersect_grad -v
429
+ python -m unittest backends.torch.tests.torch_backend.test_edge_queries -v
430
+ python -m unittest backends.torch.tests.torch_backend.test_multipath -v
431
+ ```
432
+
433
+ The default local development environment used by this repository is
434
+ `witwin3`; downstream migration and release validation in the 0.6 cycle were
435
+ also run in `witwin2`.
436
+
437
+ ## Credits
438
+
439
+ RayD is developed with reference to:
440
+
441
+ - [psdr-jit](https://github.com/andyyankai/psdr-jit)
442
+ - [redner](https://github.com/BachiLi/redner)
443
+ - [Mitsuba 3](https://github.com/mitsuba-renderer/mitsuba3)
444
+
445
+ ## Citation
446
+
447
+ ```bibtex
448
+ @inproceedings{chen2026rfdt,
449
+ title = {Physically Accurate Differentiable Inverse Rendering
450
+ for Radio Frequency Digital Twin},
451
+ author = {Chen, Xingyu and Zhang, Xinyu and Zheng, Kai and
452
+ Fang, Xinmin and Li, Tzu-Mao and Lu, Chris Xiaoxuan
453
+ and Li, Zhengxiong},
454
+ booktitle = {Proceedings of the 32nd Annual International Conference
455
+ on Mobile Computing and Networking (MobiCom)},
456
+ year = {2026},
457
+ doi = {10.1145/3795866.3796686},
458
+ publisher = {ACM},
459
+ address = {Austin, TX, USA},
460
+ }
461
+ ```
462
+
463
+ ## License
464
+
465
+ RayD is released under the BSD 3-Clause License. See [LICENSE](LICENSE).
@@ -0,0 +1,5 @@
1
+ rayd-0.6.0.dist-info/licenses/LICENSE,sha256=Fpzdq8_0qE_nze6n6MQQvpkCc7dZx3tlRPkmExysszw,1516
2
+ rayd-0.6.0.dist-info/METADATA,sha256=QgF6TX6bRMtr_ei4QJ-4p45KRHCLYYh4T_9BPhG4ZIk,16038
3
+ rayd-0.6.0.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
4
+ rayd-0.6.0.dist-info/top_level.txt,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
5
+ rayd-0.6.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (83.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,28 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2025, Xingyu Chen <xic063@ucsd.edu>
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ 3. Neither the name of the copyright holder nor the names of its
16
+ contributors may be used to endorse or promote products derived from
17
+ this software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1 @@
1
+