diffct 2.2.1__tar.gz → 2.4.0__tar.gz

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.
Files changed (143) hide show
  1. {diffct-2.2.1 → diffct-2.4.0}/CHANGELOG.md +64 -0
  2. {diffct-2.2.1 → diffct-2.4.0}/CITATION.cff +5 -5
  3. {diffct-2.2.1 → diffct-2.4.0}/PKG-INFO +33 -24
  4. {diffct-2.2.1 → diffct-2.4.0}/README.md +30 -21
  5. {diffct-2.2.1 → diffct-2.4.0}/diffct/__init__.py +17 -1
  6. diffct-2.4.0/diffct/_solver_state.py +301 -0
  7. diffct-2.4.0/diffct/_solver_tv.py +110 -0
  8. {diffct-2.2.1 → diffct-2.4.0}/diffct/analytical.py +55 -34
  9. diffct-2.4.0/diffct/analytical_execution.py +427 -0
  10. diffct-2.4.0/diffct/backends.py +765 -0
  11. {diffct-2.2.1 → diffct-2.4.0}/diffct/chunking.py +34 -0
  12. {diffct-2.2.1 → diffct-2.4.0}/diffct/constants.py +10 -5
  13. diffct-2.4.0/diffct/distribution.py +197 -0
  14. {diffct-2.2.1 → diffct-2.4.0}/diffct/geometry.py +93 -17
  15. diffct-2.4.0/diffct/kernels/__init__.py +52 -0
  16. {diffct-2.2.1 → diffct-2.4.0}/diffct/kernels/cone_beam.py +21 -8
  17. diffct-2.4.0/diffct/kernels/surface_geometry.py +130 -0
  18. {diffct-2.2.1 → diffct-2.4.0}/diffct/operators.py +880 -388
  19. {diffct-2.2.1 → diffct-2.4.0}/diffct/projectors.py +94 -46
  20. {diffct-2.2.1 → diffct-2.4.0}/diffct/reconstruction.py +108 -24
  21. diffct-2.4.0/diffct/solvers.py +325 -0
  22. diffct-2.4.0/diffct/streaming.py +140 -0
  23. diffct-2.4.0/diffct/surface_gradients.py +117 -0
  24. diffct-2.4.0/diffct/surfaces.py +146 -0
  25. {diffct-2.2.1 → diffct-2.4.0}/diffct/utils.py +9 -1
  26. diffct-2.4.0/docs/video/README.md +244 -0
  27. {diffct-2.2.1 → diffct-2.4.0}/examples/README.md +18 -3
  28. diffct-2.4.0/examples/_block_cgls.py +265 -0
  29. diffct-2.4.0/examples/_common.py +296 -0
  30. diffct-2.4.0/examples/data/preprocess_walnut.py +329 -0
  31. diffct-2.4.0/examples/walnut_reconstruction.py +143 -0
  32. {diffct-2.2.1 → diffct-2.4.0}/pyproject.toml +4 -4
  33. {diffct-2.2.1 → diffct-2.4.0}/tests/test_analytical_autograd.py +2 -2
  34. diffct-2.4.0/tests/test_analytical_distribution.py +159 -0
  35. diffct-2.4.0/tests/test_analytical_weight_distribution.py +83 -0
  36. diffct-2.4.0/tests/test_angular_low_precision.py +70 -0
  37. diffct-2.4.0/tests/test_batch_execution_edges.py +205 -0
  38. {diffct-2.2.1 → diffct-2.4.0}/tests/test_block_storage.py +80 -20
  39. diffct-2.4.0/tests/test_call_trajectory.py +252 -0
  40. {diffct-2.2.1 → diffct-2.4.0}/tests/test_chunked_projector.py +40 -25
  41. diffct-2.4.0/tests/test_cone_backprojection_transpose.py +189 -0
  42. diffct-2.4.0/tests/test_cpu_install.py +100 -0
  43. diffct-2.4.0/tests/test_distributed_training_transforms.py +233 -0
  44. diffct-2.4.0/tests/test_execution_features.py +618 -0
  45. diffct-2.4.0/tests/test_geometry_conversions.py +178 -0
  46. diffct-2.4.0/tests/test_lazy_native_observers.py +142 -0
  47. diffct-2.4.0/tests/test_native_surface_transforms.py +110 -0
  48. diffct-2.4.0/tests/test_native_volume_layout.py +328 -0
  49. diffct-2.4.0/tests/test_native_volume_layout_distributed.py +79 -0
  50. diffct-2.4.0/tests/test_parallel3d.py +376 -0
  51. diffct-2.4.0/tests/test_parallel3d_surface_oracle.py +149 -0
  52. diffct-2.4.0/tests/test_partition_lifecycle.py +197 -0
  53. diffct-2.4.0/tests/test_plan_memory_bounds.py +252 -0
  54. diffct-2.4.0/tests/test_portable_distributed_geometry.py +206 -0
  55. diffct-2.4.0/tests/test_portable_endpoint_precision.py +68 -0
  56. diffct-2.4.0/tests/test_portable_execution_bounds.py +203 -0
  57. diffct-2.4.0/tests/test_portable_numeric_regressions.py +185 -0
  58. diffct-2.4.0/tests/test_portable_surface_admission.py +85 -0
  59. {diffct-2.2.1 → diffct-2.4.0}/tests/test_projector_api.py +1 -1
  60. {diffct-2.2.1 → diffct-2.4.0}/tests/test_reconstruction_api.py +176 -0
  61. diffct-2.4.0/tests/test_reference_backend.py +473 -0
  62. diffct-2.4.0/tests/test_review_230.py +99 -0
  63. diffct-2.4.0/tests/test_review_regressions.py +345 -0
  64. diffct-2.4.0/tests/test_solver_admission_regressions.py +273 -0
  65. diffct-2.4.0/tests/test_solver_api.py +710 -0
  66. diffct-2.4.0/tests/test_solver_checkpoint_edges.py +287 -0
  67. diffct-2.4.0/tests/test_solver_collective_failures.py +225 -0
  68. diffct-2.4.0/tests/test_surface_collective_failures.py +521 -0
  69. diffct-2.4.0/tests/test_surface_composition_kernel.py +358 -0
  70. diffct-2.4.0/tests/test_surface_compute_shards.py +564 -0
  71. diffct-2.4.0/tests/test_surface_geometry_cudasim.py +514 -0
  72. diffct-2.4.0/tests/test_surface_gradient_replay.py +226 -0
  73. diffct-2.4.0/tests/test_surface_native_regressions.py +281 -0
  74. diffct-2.4.0/tests/test_surface_pipeline_contracts.py +388 -0
  75. diffct-2.4.0/tests/test_surface_trajectory_transform.py +142 -0
  76. diffct-2.4.0/tests/test_training_transforms.py +95 -0
  77. diffct-2.4.0/tests/test_trajectory_admission_cost.py +257 -0
  78. diffct-2.4.0/tests/test_trajectory_surface_integration.py +615 -0
  79. diffct-2.4.0/tests/test_tv_zero_dependency.py +75 -0
  80. diffct-2.4.0/tests/test_two_far_endpoints.py +84 -0
  81. diffct-2.2.1/diffct/kernels/__init__.py +0 -51
  82. diffct-2.2.1/diffct/streaming.py +0 -48
  83. diffct-2.2.1/diffct/surfaces.py +0 -103
  84. diffct-2.2.1/docs/video/README.md +0 -119
  85. {diffct-2.2.1 → diffct-2.4.0}/.gitignore +0 -0
  86. {diffct-2.2.1 → diffct-2.4.0}/LICENSE +0 -0
  87. {diffct-2.2.1 → diffct-2.4.0}/NOTICE +0 -0
  88. {diffct-2.2.1 → diffct-2.4.0}/diffct/differentiable.py +0 -0
  89. {diffct-2.2.1 → diffct-2.4.0}/diffct/kernels/analytical_transpose.py +0 -0
  90. {diffct-2.2.1 → diffct-2.4.0}/diffct/kernels/fan_beam.py +0 -0
  91. {diffct-2.2.1 → diffct-2.4.0}/diffct/kernels/geometry_vjp.py +0 -0
  92. {diffct-2.2.1 → diffct-2.4.0}/diffct/kernels/parallel_beam.py +0 -0
  93. {diffct-2.2.1 → diffct-2.4.0}/diffct/pipeline.py +0 -0
  94. {diffct-2.2.1 → diffct-2.4.0}/diffct/storage.py +0 -0
  95. {diffct-2.2.1 → diffct-2.4.0}/examples/data/NOTICE +0 -0
  96. {diffct-2.2.1 → diffct-2.4.0}/formal/README.md +0 -0
  97. {diffct-2.2.1 → diffct-2.4.0}/pytest.ini +0 -0
  98. {diffct-2.2.1 → diffct-2.4.0}/tests/__init__.py +0 -0
  99. {diffct-2.2.1 → diffct-2.4.0}/tests/_phantoms.py +0 -0
  100. {diffct-2.2.1 → diffct-2.4.0}/tests/benchmarks/README.md +0 -0
  101. {diffct-2.2.1 → diffct-2.4.0}/tests/benchmarks/__init__.py +0 -0
  102. {diffct-2.2.1 → diffct-2.4.0}/tests/benchmarks/_common.py +0 -0
  103. {diffct-2.2.1 → diffct-2.4.0}/tests/benchmarks/test_bench_cone.py +0 -0
  104. {diffct-2.2.1 → diffct-2.4.0}/tests/benchmarks/test_bench_fan.py +0 -0
  105. {diffct-2.2.1 → diffct-2.4.0}/tests/benchmarks/test_bench_parallel.py +0 -0
  106. {diffct-2.2.1 → diffct-2.4.0}/tests/distributed_projector_check.py +0 -0
  107. {diffct-2.2.1 → diffct-2.4.0}/tests/test_adjoint_inner_product.py +0 -0
  108. {diffct-2.2.1 → diffct-2.4.0}/tests/test_allocator_capacity.py +0 -0
  109. {diffct-2.2.1 → diffct-2.4.0}/tests/test_analytical_regressions.py +0 -0
  110. {diffct-2.2.1 → diffct-2.4.0}/tests/test_axis_aligned_chords.py +0 -0
  111. {diffct-2.2.1 → diffct-2.4.0}/tests/test_batched_surfaces.py +0 -0
  112. {diffct-2.2.1 → diffct-2.4.0}/tests/test_block_cgls.py +0 -0
  113. {diffct-2.2.1 → diffct-2.4.0}/tests/test_cgls_state_admission.py +0 -0
  114. {diffct-2.2.1 → diffct-2.4.0}/tests/test_completed_transfer_reuse.py +0 -0
  115. {diffct-2.2.1 → diffct-2.4.0}/tests/test_cone_projector_autograd.py +0 -0
  116. {diffct-2.2.1 → diffct-2.4.0}/tests/test_cuda_exit_deallocations.py +0 -0
  117. {diffct-2.2.1 → diffct-2.4.0}/tests/test_cuda_sink_lifetimes.py +0 -0
  118. {diffct-2.2.1 → diffct-2.4.0}/tests/test_cuda_smoke.py +0 -0
  119. {diffct-2.2.1 → diffct-2.4.0}/tests/test_detector_surface_dtypes.py +0 -0
  120. {diffct-2.2.1 → diffct-2.4.0}/tests/test_detector_surface_mapping.py +0 -0
  121. {diffct-2.2.1 → diffct-2.4.0}/tests/test_detector_surface_units.py +0 -0
  122. {diffct-2.2.1 → diffct-2.4.0}/tests/test_detector_surfaces.py +0 -0
  123. {diffct-2.2.1 → diffct-2.4.0}/tests/test_example_psnr.py +0 -0
  124. {diffct-2.2.1 → diffct-2.4.0}/tests/test_execution_buffers.py +0 -0
  125. {diffct-2.2.1 → diffct-2.4.0}/tests/test_execution_schedules.py +0 -0
  126. {diffct-2.2.1 → diffct-2.4.0}/tests/test_fbp_fan_accuracy.py +0 -0
  127. {diffct-2.2.1 → diffct-2.4.0}/tests/test_fbp_fan_offsets.py +0 -0
  128. {diffct-2.2.1 → diffct-2.4.0}/tests/test_fbp_parallel_accuracy.py +0 -0
  129. {diffct-2.2.1 → diffct-2.4.0}/tests/test_fdk_cone_accuracy.py +0 -0
  130. {diffct-2.2.1 → diffct-2.4.0}/tests/test_fdk_cone_offsets.py +0 -0
  131. {diffct-2.2.1 → diffct-2.4.0}/tests/test_geometry_autograd.py +0 -0
  132. {diffct-2.2.1 → diffct-2.4.0}/tests/test_geometry_gradients.py +0 -0
  133. {diffct-2.2.1 → diffct-2.4.0}/tests/test_gradcheck.py +0 -0
  134. {diffct-2.2.1 → diffct-2.4.0}/tests/test_multi_gpu_exit.py +0 -0
  135. {diffct-2.2.1 → diffct-2.4.0}/tests/test_output_pipeline_overlap.py +0 -0
  136. {diffct-2.2.1 → diffct-2.4.0}/tests/test_projector_degenerate_geometry.py +0 -0
  137. {diffct-2.2.1 → diffct-2.4.0}/tests/test_projector_geometry_devices.py +0 -0
  138. {diffct-2.2.1 → diffct-2.4.0}/tests/test_ramp_filter_windows.py +0 -0
  139. {diffct-2.2.1 → diffct-2.4.0}/tests/test_release_2_0_1.py +0 -0
  140. {diffct-2.2.1 → diffct-2.4.0}/tests/test_spatial_partition.py +0 -0
  141. {diffct-2.2.1 → diffct-2.4.0}/tests/test_transfer_pipeline.py +0 -0
  142. {diffct-2.2.1 → diffct-2.4.0}/tests/test_transfer_retirement_lifetimes.py +0 -0
  143. {diffct-2.2.1 → diffct-2.4.0}/tests/test_weights.py +0 -0
@@ -7,6 +7,70 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [2.4.0] - 2026-10-20
11
+
12
+ ### Added
13
+
14
+ - Per-call `trajectory` overrides on `Projector` operations, preserving the constructor default and each call's geometry graph without rebuilding the projector (#29).
15
+ - Angle-tensor inputs for circular trajectory helpers and differentiable `transform_trajectory` rigid transforms (#29).
16
+ - `beam="parallel3d"` and `circular_trajectory_3d_parallel`, using infinite parallel rays and the PyTorch backend on CPU and CUDA, with data and first-order geometry gradients (#29).
17
+ - `Projector(native_volume_layout=True)` returns native full-CUDA cone backprojections of unbatched flat-detector inputs as `(D, H, W)` tensors with the kernels' `(W, H, D)`-contiguous strides instead of contiguous copies, and native cone projections accept such tensors without copying. An iterative solver that keeps its volumes in this layout saves two whole-volume copies per normal-operator application on one device. The default is unchanged (#27).
18
+
19
+ ### Changed
20
+
21
+ - The native cone backprojection kernel steps through the z crossings of each xy cell in an inner loop and groups adjacent detector rows in a warp, so the atomic additions of a warp hit neighbouring voxels of one column. Each ray's segments and arithmetic are unchanged; backprojection takes 1.25–1.8x less time on large cone and helical problems, depending on the geometry (#35).
22
+ - Projector execution planning takes no allocator snapshot when a full launch clearly fits: lower bounds of the memory limits come from `mem_get_info` and one statistics query, and the exact planner runs only when they do not suffice. Plans are unchanged. Host time per call for small problems drops by about 1 ms. Distributed operators keep the exact planner (#26).
23
+ - Distributed calls and solvers check rank agreement with one fixed-size collective per request instead of Python object exchanges, skip the callback protocol when no callback is given, and accumulate solver norms on the device with one host read per norm. Results are unchanged (#34).
24
+ - The introduction video explains 2.3.0 tiled execution and view, space and hybrid partitions with a computed walnut example; the README GIF is 12 MB instead of 22 MB (#25).
25
+
26
+ ### Fixed
27
+
28
+ - Detector surfaces expand world points on each compute device after view sharding, preserving native composition precision. Memory planning uses local view counts and composition dtypes. Streamed execution accepts CPU or CUDA offsets from both surface interfaces (#30).
29
+ - Surface snapshots preserve gradient connections on CPU. Streamed composition and geometry backward use bounded fragments. Distributed calls check callback layouts and propagate validation errors before numerical work (#30).
30
+ - Native surface admission sizes validation batches from available memory and staging limits, replacing fixed one-view batches (#32).
31
+ - Rigid trajectory transforms accept valid surface detector frames whose reference center coincides with the source or whose reference plane is edge-on (#29).
32
+ - Call-time trajectory validation checks flat detectors by corners and coordinate bounds, with exact pixel checks for ambiguous views. Frames stage once per validation device. Native surface validation uses bounded batches on each compute device after view sharding (#29).
33
+
34
+ ## [2.3.0] - 2026-10-14
35
+
36
+ ### Added
37
+
38
+ - `backend="auto"`, `"numba"` or `"torch"` and `precision="fast"`, `"float32"` or `"float64"` on `Projector`, `fbp` and `fdk`. These settings are opt-in. Default calls keep native FP32 execution where compatible.
39
+ - `backend="auto"` selects the PyTorch backend for `precision="float32"`, `precision="float64"`, per-axis `voxel_spacing` and hybrid partitions. An incompatible explicit `backend="numba"` request raises an error.
40
+ - `backend="torch"` runs on CPU, NVIDIA CUDA and PyTorch ROCm. `precision="float64"` runs the data operations in FP64.
41
+ - Portable FP32 ray setup clips rays and locates tile entries in FP64. Traversal measures distances from each entry, so distant endpoints keep voxel widths.
42
+ - Per-axis `voxel_spacing`, such as `(dy, dx)` or `(dz, dy, dx)`, in tensor axis order.
43
+ - Leading batch and channel dimensions for projection and adjoint, including empty batches.
44
+ - Data gradients, JVP, `vmap`, `jacrev`, `jacfwd` and second data derivatives for the PyTorch projector. Dense Jacobians need a single-process projector.
45
+ - `view_chunk_size` and `volume_chunk_shape` on `fbp` and `fdk` stream view batches and spatial tiles. `devices` schedules tiles across local devices.
46
+ - `fbp_into` and `fdk_into` write into `TensorStore`, `NpyStore` or compatible block stores.
47
+ - `partition="hybrid"` with `partition_grid=(view_ranks, space_ranks)` for projectors and analytical reconstruction. Uneven and empty shards are supported.
48
+ - `cgls`, `sirt`, `tv_reconstruction` and `SolverResult`, with residual thresholds, residual history, callbacks and optional `x0`.
49
+ - `cgls_into` keeps solver state in mapped files. It rejects non-finite measurements in bounded blocks before any output write.
50
+ - `checkpoint_directory` and `resume` for `cgls`, `sirt` and `tv_reconstruction`. Fingerprints bind the acquisition, measurements, precision, ownership and settings.
51
+ - `total_variation` with `reduction="mean"` or `"sum"`. Spatial and hybrid runs exchange neighbouring faces.
52
+ - `docs/EXECUTION.md` documents precision, memory bounds, distributed loss replica divisors and checkpoint contracts.
53
+
54
+ ### Changed
55
+
56
+ - Importing `diffct` and using `backend="torch"` no longer loads Numba CUDA or requires a CUDA runtime. Native execution initializes them on first use.
57
+ - `pip install diffct` is enough for `backend="torch"`. Native Numba execution needs the CUDA extras `diffct[cu12]` or `diffct[cu13]`.
58
+ - Distributed PyTorch-backend projectors require the same `volume_chunk_shape`, `view_chunk_size` and `detector_chunk_shape` on every rank.
59
+ - The source distribution includes the four example helpers used by its shipped tests.
60
+
61
+ ### Fixed
62
+
63
+ - Parker short-scan distance and detector-u offset checks bound position and
64
+ detector-axis rounding per component along the checked direction, not by the
65
+ absolute coordinate size.
66
+ A bfloat16 or float16 detector-v axis made a 50-unit change in detector distance
67
+ pass, and the Parker weights then used the first view's distance.
68
+ - Fan and cone normalization in the analytical gather and its transpose uses each view's SID and SDD. Inactive views no longer rescale active views.
69
+ - `angular_integration_weights` and `parker_weights` keep FP32 and FP64 input precision. FP16 and BF16 angles are computed in FP32.
70
+ - Angular gaps come directly from sorted neighbouring angles. Float32 neighbours one ulp apart no longer get a zero weight, and Parker rows no longer depend on the input order.
71
+ - Valid low-precision Parker short scans keep finite weights and angle gradients.
72
+ - Output stores that overlap internally raise before any I/O. Disjoint interleaved `TensorStore` slices are accepted.
73
+
10
74
  ## [2.2.1] - 2026-10-13
11
75
 
12
76
  ### Added
@@ -13,8 +13,8 @@ authors:
13
13
  given-names: Yipeng
14
14
  email: yipeng.sun@fau.de
15
15
  alias: sypsyp97
16
- version: 2.2.1
17
- date-released: "2026-10-13"
16
+ version: 2.4.0
17
+ date-released: "2026-10-20"
18
18
  license: Apache-2.0
19
19
  repository-code: "https://github.com/sypsyp97/diffct"
20
20
  url: "https://sypsyp97.github.io/diffct/"
@@ -43,9 +43,9 @@ preferred-citation:
43
43
  - family-names: Maier
44
44
  given-names: Andreas
45
45
  year: 2026
46
- month: 5
46
+ month: 10
47
47
  journal: Preprints
48
48
  publisher:
49
49
  name: Preprints
50
- doi: 10.20944/preprints202605.1446.v1
51
- url: "https://doi.org/10.20944/preprints202605.1446.v1"
50
+ doi: 10.20944/preprints202605.1446.v2
51
+ url: "https://doi.org/10.20944/preprints202605.1446.v2"
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: diffct
3
- Version: 2.2.1
4
- Summary: Differentiable CUDA projectors for CT: arbitrary trajectories, multi-GPU and multi-node execution, geometry gradients
3
+ Version: 2.4.0
4
+ Summary: Differentiable CT projection and reconstruction: precision modes, streaming, distributed execution and geometry gradients
5
5
  Project-URL: Homepage, https://github.com/sypsyp97/diffct
6
6
  Project-URL: Documentation, https://sypsyp97.github.io/diffct/
7
7
  Project-URL: Changelog, https://github.com/sypsyp97/diffct/blob/main/CHANGELOG.md
@@ -10,7 +10,7 @@ Author-email: Yipeng Sun <yipeng.sun@fau.de>
10
10
  License-Expression: Apache-2.0
11
11
  License-File: LICENSE
12
12
  License-File: NOTICE
13
- Keywords: CT reconstruction,CUDA,PyTorch,computed tomography,differentiable programming
13
+ Keywords: CT reconstruction,CUDA,PyTorch,ROCm,computed tomography,differentiable programming
14
14
  Classifier: Development Status :: 5 - Production/Stable
15
15
  Classifier: Environment :: GPU :: NVIDIA CUDA
16
16
  Classifier: Intended Audience :: Science/Research
@@ -47,13 +47,13 @@ Description-Content-Type: text/markdown
47
47
  </p>
48
48
 
49
49
  <p align="center">
50
- <img src="https://raw.githubusercontent.com/sypsyp97/diffct/edf7c52227ec2cc14c988918faa7313f8ee0fe03/docs/assets/diffct_intro.gif" width="100%" alt="diffct intro: projection, sinogram, trajectories, multi-GPU split, reconstruction and geometry calibration">
50
+ <img src="https://raw.githubusercontent.com/sypsyp97/diffct/main/docs/assets/diffct_intro.gif" width="100%" alt="diffct intro: projection, sinogram, trajectories, multi-GPU split, reconstruction and geometry calibration">
51
51
  </p>
52
52
 
53
53
  <p align="center">
54
- <a href="https://github.com/sypsyp97/diffct/blob/edf7c52227ec2cc14c988918faa7313f8ee0fe03/docs/assets/diffct_intro.mp4">Intro video (MP4)</a> ·
55
- <a href="https://www.preprints.org/manuscript/202605.1446/v1">Technical report</a> ·
56
- <a href="https://doi.org/10.20944/preprints202605.1446.v1">DOI</a>
54
+ <a href="https://github.com/sypsyp97/diffct/blob/main/docs/assets/diffct_intro.mp4">Intro video (MP4)</a> ·
55
+ <a href="https://www.preprints.org/manuscript/202605.1446/v2">Technical report</a> ·
56
+ <a href="https://doi.org/10.20944/preprints202605.1446.v2">DOI</a>
57
57
  </p>
58
58
 
59
59
  <p align="center">
@@ -68,36 +68,40 @@ Description-Content-Type: text/markdown
68
68
  > **Version 2.0** replaces the circular-orbit API of 1.x with per-view trajectories. Code written for 1.x needs changes; see the [migration notes](https://github.com/sypsyp97/diffct/blob/main/docs/MIGRATION.md).
69
69
  > For Apple Silicon, use the [MLX port by Linda-Sophie Schneider](https://github.com/Linda-SophieSchneider/DiffCT-MLX).
70
70
 
71
+ This README describes the source checkout, including [unreleased APIs](CHANGELOG.md#unreleased). Per-call trajectories, angle-tensor circular helpers, `transform_trajectory`, `parallel3d` and `native_volume_layout` require installation from source.
72
+
71
73
  ## Why diffct
72
74
 
73
75
  To our knowledge, diffct is the only open-source GPU CT library that combines arbitrary per-view trajectories, autograd through the volume, first-order gradients through the acquisition geometry, and built-in multi-GPU and multi-node execution. We compared it with LEAP, TIGRE, ASTRA/tomosipo, DiffDRR and others in October 2026.
74
76
 
75
- - **Arbitrary trajectories.** Each view has its own source, detector centre and detector axes. Circular, helical, saddle, sinusoidal, random and calibrated scans use the same code. Trajectory tensors with `requires_grad=True` receive geometry gradients for calibration.
77
+ - **Arbitrary trajectories.** Each view has its own ray direction or source, detector centre and detector axes. Circular, helical, saddle, sinusoidal, random and calibrated scans use the same code. Trajectory tensors with `requires_grad=True` receive geometry gradients for calibration.
76
78
  - **Curved detectors.** `ParameterizedSurface` defines native arc, cylindrical or arbitrary pixels from global coordinates and explicit parameters, sampled in bounded view/pixel batches. Legacy `detector_surface(u, v)` callbacks remain available. Projection and matched backprojection support first-order surface gradients. See [the surface API](https://github.com/sypsyp97/diffct/blob/main/docs/REFERENCE.md#parameterized-detector-surfaces).
77
79
  - **Matched operators.** `project()` and `backproject()` form an exact adjoint pair for the cell-constant Siddon model. Both support PyTorch autograd, with volume/sinogram gradients and Hessian-vector products.
78
80
  - **Large volumes.** Automatic spatial, view and pixel blocks with bounded transfer buffers control working memory. `project_into`/`backproject_into` accept caller-owned tensor or disk stores; tensor autograd keeps complete data on its input device. See [chunked execution](https://github.com/sypsyp97/diffct/blob/main/docs/REFERENCE.md#chunked-execution).
79
- - **Multi-GPU and multi-node.** Use `devices=[0, 1, 2, 3]` in one process, or torchrun and NCCL across ranks. Default `partition="views"` shards projections and replicates volumes. `partition="space"` gives each rank an owned volume slab and combines ray contributions. Speedup depends on workload and communication costs.
81
+ - **Multi-GPU and multi-node.** Use `devices=[0, 1, 2, 3]` in one process, or torchrun and NCCL across ranks. Views, space and hybrid partitions control replication of volumes and projections. Speedup depends on workload and communication costs.
82
+ - **Precision and training.** Explicit native/PyTorch backends, FP32/FP64 modes, per-axis voxel spacing, leading batch/channel dimensions and data `torch.func` transforms. The portable path supports CPU and PyTorch CUDA/ROCm devices; see [execution contracts](docs/EXECUTION.md).
83
+ - **Solver API.** `cgls`, `sirt` and `tv_reconstruction` report residual history, tolerances and callbacks, with scan/data fingerprints and complete checkpoint state. `cgls_into` keeps state in bounded mapped blocks.
80
84
  - **Differentiable FBP and FDK.** `fbp`, `fdk` and approximate `helical_fdk` compose the public filters, weights and analytical backprojectors. Their backward kernels transpose the actual interpolation stencil; custom filters and weights can be learned. See the [analytical guide](docs/source/analytical_learning.rst).
81
85
 
82
86
  Capabilities, limits and isocenter rules: [docs/REFERENCE.md](https://github.com/sypsyp97/diffct/blob/main/docs/REFERENCE.md#capabilities-and-limits).
83
87
 
84
88
  ## Install
85
89
 
86
- You need an NVIDIA GPU. Install PyTorch for your CUDA version first. Then install diffct with the extra for the same CUDA major version:
90
+ For the native path, install NVIDIA CUDA PyTorch first, then diffct with the matching CUDA major extra:
87
91
 
88
92
  ```bash
89
93
  pip install "diffct[cu12]" # PyTorch built for CUDA 12
90
94
  pip install "diffct[cu13]" # PyTorch built for CUDA 13
91
95
  ```
92
96
 
93
- The extra installs the CUDA compiler libraries that Numba CUDA needs to compile the kernels. A plain `pip install diffct` does not install them. Use it only if a CUDA Toolkit is already installed on the system.
97
+ The extra installs the CUDA compiler libraries Numba needs. For CPU or PyTorch ROCm execution, install the appropriate PyTorch build and plain `pip install diffct`, then select `backend="torch"`. Importing diffct and using this backend require no CUDA runtime; Numba CUDA initializes when native execution is used. Plain installation also works for native execution when a compatible CUDA Toolkit is already present.
94
98
 
95
99
  From source, with the examples:
96
100
 
97
101
  ```bash
98
102
  git clone https://github.com/sypsyp97/diffct.git
99
103
  cd diffct && pip install -e ".[cu12]"
100
- python examples/quickstart.py # smoke test: prints adjoint mismatch ~1e-8 for each beam
104
+ python examples/quickstart.py # prints adjoint mismatch and gradients for each beam
101
105
  ```
102
106
 
103
107
  <details>
@@ -136,7 +140,11 @@ loss.backward() # x.grad = A^T (A x - y)
136
140
 
137
141
  **Custom or calibrated trajectories.** Pass calibrated tensors directly instead of a generator; no circular fit is needed. See [REFERENCE](https://github.com/sypsyp97/diffct/blob/main/docs/REFERENCE.md#custom-or-calibrated-trajectories).
138
142
 
139
- **Geometry gradients.** Set `requires_grad=True` on trajectory tensors before you build `Projector`. See [REFERENCE](https://github.com/sypsyp97/diffct/blob/main/docs/REFERENCE.md#geometry-gradients).
143
+ **Geometry gradients.** Reuse one projector with `A.project(volume, trajectory=current)` or `A.backproject(sinogram, trajectory=current)`. Circular helpers accept learnable angle tensors, and `transform_trajectory` applies differentiable rigid transforms. Omitting the override keeps the constructor trajectory. See [REFERENCE](https://github.com/sypsyp97/diffct/blob/main/docs/REFERENCE.md#geometry-gradients).
144
+
145
+ **3D parallel beams.** Use `circular_trajectory_3d_parallel(...)` and `beam="parallel3d"`. The PyTorch backend provides matched projection and backprojection on CPU and CUDA.
146
+
147
+ **Native volume layout.** For unbatched, flat-detector cone operations, set `native_volume_layout=True` to avoid volume layout copies. This applies to the native full-CUDA path on one compute device. Shapes stay `(D, H, W)`; the returned strides follow the kernel layout. The default is `False`. See [chunked execution](docs/REFERENCE.md#chunked-execution) for limits.
140
148
 
141
149
  **Several GPUs and nodes.** See [REFERENCE](https://github.com/sypsyp97/diffct/blob/main/docs/REFERENCE.md#several-gpus-and-nodes) and [DISTRIBUTED.md](https://github.com/sypsyp97/diffct/blob/main/docs/DISTRIBUTED.md).
142
150
 
@@ -169,18 +177,18 @@ volume slabs use `--partition space` under torchrun. Run
169
177
 
170
178
  <p align="center">
171
179
  <picture>
172
- <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/sypsyp97/diffct/main/docs/assets/scaling_dark.png?v=2.2.0">
173
- <img src="https://raw.githubusercontent.com/sypsyp97/diffct/main/docs/assets/scaling_light.png?v=2.2.0" width="100%" alt="Time per forward, adjoint and CGLS iteration on 1, 4 and 8 GPUs, 512^3 volume">
180
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/sypsyp97/diffct/main/docs/assets/scaling_dark.png?v=2.4.0">
181
+ <img src="https://raw.githubusercontent.com/sypsyp97/diffct/main/docs/assets/scaling_light.png?v=2.4.0" width="100%" alt="Time per forward, adjoint and CGLS iteration on 1, 4 and 8 GPUs, 512^3 volume">
174
182
  </picture>
175
183
  </p>
176
184
 
177
185
  | 512³ volume | 1 GPU | 4 GPUs, 1 node | 8 GPUs, 2 nodes |
178
186
  |---|---:|---:|---:|
179
- | Forward projection | 493.05 ms | 132.22 ms (3.7×) | 73.18 ms (6.7×) |
180
- | Adjoint (backprojection) | 1400.80 ms | 369.29 ms (3.8×) | 265.87 ms (5.3×) |
181
- | CGLS iteration | 2054.36 ms | 547.06 ms (3.8×) | 373.38 ms (5.5×) |
187
+ | Forward projection | 493.40 ms | 131.78 ms (3.7×) | 72.42 ms (6.8×) |
188
+ | Adjoint (backprojection) | 1118.98 ms | 293.01 ms (3.8×) | 232.50 ms (4.8×) |
189
+ | CGLS iteration | 1744.92 ms | 465.62 ms (3.7×) | 337.98 ms (5.2×) |
182
190
 
183
- diffct 2.2.0, FP32, A100 64 GB GPUs; circular cone beam, 360 views, 1024×768 detector, pitch 1.25. Default memory settings, without an imposed allocator cap.
191
+ diffct 2.4.0, FP32, A100 64 GB GPUs; circular cone beam, 360 views, 1024×768 detector, pitch 1.25. Default memory settings, without an imposed allocator cap.
184
192
 
185
193
  Projection times are medians of seven samples after three warmups. CGLS uses three ten-iteration solves after a two-iteration warmup; the median includes initialization and is divided by ten. Timings use synchronized wall time and the slowest rank. Raw samples and configuration: [scaling.json](https://github.com/sypsyp97/diffct/blob/main/docs/assets/scaling.json).
186
194
 
@@ -220,12 +228,13 @@ Walnut data: Meaney 2022, Zenodo 6986012, CC BY 4.0; see [examples/data/NOTICE](
220
228
 
221
229
  ## Examples
222
230
 
223
- `quickstart.py`, `curved_detector.py`, `chunked_reconstruction.py`, `disk_reconstruction.py`, `benchmark_execution.py`, `analytical_reconstruction.py`, `learnable_reconstruction.py`, `helical_fdk.py`, `iterative_reconstruction.py`, `walnut_reconstruction.py`, `geometry_calibration.py`, `benchmark_projector.py`, `benchmark_scaling.py`, `plot_trajectory.py`, and the Slurm template `slurm/multi_node.sbatch`. Launch modes and distributed-loss rules are in [examples/README.md](https://github.com/sypsyp97/diffct/blob/main/examples/README.md).
231
+ `quickstart.py`, `curved_detector.py`, `chunked_reconstruction.py`, `disk_reconstruction.py`, `benchmark_execution.py`, `benchmark_trajectory_admission.py`, `analytical_reconstruction.py`, `learnable_reconstruction.py`, `helical_fdk.py`, `iterative_reconstruction.py`, `walnut_reconstruction.py`, `geometry_calibration.py`, `benchmark_projector.py`, `benchmark_scaling.py`, `plot_trajectory.py`, and the Slurm template `slurm/multi_node.sbatch`. Launch modes and distributed-loss rules are in [examples/README.md](https://github.com/sypsyp97/diffct/blob/main/examples/README.md).
224
232
 
225
233
  ## Documentation
226
234
 
227
235
  | Document | Contents |
228
236
  |---|---|
237
+ | [Precision, training and reconstruction](docs/EXECUTION.md) | Backend modes, batch/spacing contracts, analytical storage, hybrid loss scaling and solver checkpoints |
229
238
  | [Trajectory guide](https://github.com/sypsyp97/diffct/blob/main/docs/source/trajectories.rst) | Trajectory tuples and `Projector` usage |
230
239
  | [docs/REFERENCE.md](https://github.com/sypsyp97/diffct/blob/main/docs/REFERENCE.md) | Capabilities and limits, custom trajectories, geometry gradients, multi-GPU details, geometry and units |
231
240
  | [docs/DISTRIBUTED.md](https://github.com/sypsyp97/diffct/blob/main/docs/DISTRIBUTED.md) | Execution/memory choices, distributed loss rules, Slurm and cross-node checks |
@@ -250,12 +259,12 @@ If you use this library in your research, please cite the software and the techn
250
259
  }
251
260
 
252
261
  @article{202605.1446,
253
- doi = {10.20944/preprints202605.1446.v1},
254
- url = {https://doi.org/10.20944/preprints202605.1446.v1},
262
+ doi = {10.20944/preprints202605.1446.v2},
263
+ url = {https://doi.org/10.20944/preprints202605.1446.v2},
255
264
  year = 2026,
256
- month = {May},
265
+ month = {Oct},
257
266
  publisher = {Preprints},
258
- author = {Yipeng Sun and Linda-Sophie Schneider and Chengze ye and Andreas Maier},
267
+ author = {Yipeng Sun and Linda-Sophie Schneider and Chengze Ye and Andreas Maier},
259
268
  title = {diffct: Differentiable CT Operators from Circular Orbits to Arbitrary Trajectories},
260
269
  journal = {Preprints}
261
270
  }
@@ -16,13 +16,13 @@
16
16
  </p>
17
17
 
18
18
  <p align="center">
19
- <img src="https://raw.githubusercontent.com/sypsyp97/diffct/edf7c52227ec2cc14c988918faa7313f8ee0fe03/docs/assets/diffct_intro.gif" width="100%" alt="diffct intro: projection, sinogram, trajectories, multi-GPU split, reconstruction and geometry calibration">
19
+ <img src="https://raw.githubusercontent.com/sypsyp97/diffct/main/docs/assets/diffct_intro.gif" width="100%" alt="diffct intro: projection, sinogram, trajectories, multi-GPU split, reconstruction and geometry calibration">
20
20
  </p>
21
21
 
22
22
  <p align="center">
23
- <a href="https://github.com/sypsyp97/diffct/blob/edf7c52227ec2cc14c988918faa7313f8ee0fe03/docs/assets/diffct_intro.mp4">Intro video (MP4)</a> ·
24
- <a href="https://www.preprints.org/manuscript/202605.1446/v1">Technical report</a> ·
25
- <a href="https://doi.org/10.20944/preprints202605.1446.v1">DOI</a>
23
+ <a href="https://github.com/sypsyp97/diffct/blob/main/docs/assets/diffct_intro.mp4">Intro video (MP4)</a> ·
24
+ <a href="https://www.preprints.org/manuscript/202605.1446/v2">Technical report</a> ·
25
+ <a href="https://doi.org/10.20944/preprints202605.1446.v2">DOI</a>
26
26
  </p>
27
27
 
28
28
  <p align="center">
@@ -37,36 +37,40 @@
37
37
  > **Version 2.0** replaces the circular-orbit API of 1.x with per-view trajectories. Code written for 1.x needs changes; see the [migration notes](https://github.com/sypsyp97/diffct/blob/main/docs/MIGRATION.md).
38
38
  > For Apple Silicon, use the [MLX port by Linda-Sophie Schneider](https://github.com/Linda-SophieSchneider/DiffCT-MLX).
39
39
 
40
+ This README describes the source checkout, including [unreleased APIs](CHANGELOG.md#unreleased). Per-call trajectories, angle-tensor circular helpers, `transform_trajectory`, `parallel3d` and `native_volume_layout` require installation from source.
41
+
40
42
  ## Why diffct
41
43
 
42
44
  To our knowledge, diffct is the only open-source GPU CT library that combines arbitrary per-view trajectories, autograd through the volume, first-order gradients through the acquisition geometry, and built-in multi-GPU and multi-node execution. We compared it with LEAP, TIGRE, ASTRA/tomosipo, DiffDRR and others in October 2026.
43
45
 
44
- - **Arbitrary trajectories.** Each view has its own source, detector centre and detector axes. Circular, helical, saddle, sinusoidal, random and calibrated scans use the same code. Trajectory tensors with `requires_grad=True` receive geometry gradients for calibration.
46
+ - **Arbitrary trajectories.** Each view has its own ray direction or source, detector centre and detector axes. Circular, helical, saddle, sinusoidal, random and calibrated scans use the same code. Trajectory tensors with `requires_grad=True` receive geometry gradients for calibration.
45
47
  - **Curved detectors.** `ParameterizedSurface` defines native arc, cylindrical or arbitrary pixels from global coordinates and explicit parameters, sampled in bounded view/pixel batches. Legacy `detector_surface(u, v)` callbacks remain available. Projection and matched backprojection support first-order surface gradients. See [the surface API](https://github.com/sypsyp97/diffct/blob/main/docs/REFERENCE.md#parameterized-detector-surfaces).
46
48
  - **Matched operators.** `project()` and `backproject()` form an exact adjoint pair for the cell-constant Siddon model. Both support PyTorch autograd, with volume/sinogram gradients and Hessian-vector products.
47
49
  - **Large volumes.** Automatic spatial, view and pixel blocks with bounded transfer buffers control working memory. `project_into`/`backproject_into` accept caller-owned tensor or disk stores; tensor autograd keeps complete data on its input device. See [chunked execution](https://github.com/sypsyp97/diffct/blob/main/docs/REFERENCE.md#chunked-execution).
48
- - **Multi-GPU and multi-node.** Use `devices=[0, 1, 2, 3]` in one process, or torchrun and NCCL across ranks. Default `partition="views"` shards projections and replicates volumes. `partition="space"` gives each rank an owned volume slab and combines ray contributions. Speedup depends on workload and communication costs.
50
+ - **Multi-GPU and multi-node.** Use `devices=[0, 1, 2, 3]` in one process, or torchrun and NCCL across ranks. Views, space and hybrid partitions control replication of volumes and projections. Speedup depends on workload and communication costs.
51
+ - **Precision and training.** Explicit native/PyTorch backends, FP32/FP64 modes, per-axis voxel spacing, leading batch/channel dimensions and data `torch.func` transforms. The portable path supports CPU and PyTorch CUDA/ROCm devices; see [execution contracts](docs/EXECUTION.md).
52
+ - **Solver API.** `cgls`, `sirt` and `tv_reconstruction` report residual history, tolerances and callbacks, with scan/data fingerprints and complete checkpoint state. `cgls_into` keeps state in bounded mapped blocks.
49
53
  - **Differentiable FBP and FDK.** `fbp`, `fdk` and approximate `helical_fdk` compose the public filters, weights and analytical backprojectors. Their backward kernels transpose the actual interpolation stencil; custom filters and weights can be learned. See the [analytical guide](docs/source/analytical_learning.rst).
50
54
 
51
55
  Capabilities, limits and isocenter rules: [docs/REFERENCE.md](https://github.com/sypsyp97/diffct/blob/main/docs/REFERENCE.md#capabilities-and-limits).
52
56
 
53
57
  ## Install
54
58
 
55
- You need an NVIDIA GPU. Install PyTorch for your CUDA version first. Then install diffct with the extra for the same CUDA major version:
59
+ For the native path, install NVIDIA CUDA PyTorch first, then diffct with the matching CUDA major extra:
56
60
 
57
61
  ```bash
58
62
  pip install "diffct[cu12]" # PyTorch built for CUDA 12
59
63
  pip install "diffct[cu13]" # PyTorch built for CUDA 13
60
64
  ```
61
65
 
62
- The extra installs the CUDA compiler libraries that Numba CUDA needs to compile the kernels. A plain `pip install diffct` does not install them. Use it only if a CUDA Toolkit is already installed on the system.
66
+ The extra installs the CUDA compiler libraries Numba needs. For CPU or PyTorch ROCm execution, install the appropriate PyTorch build and plain `pip install diffct`, then select `backend="torch"`. Importing diffct and using this backend require no CUDA runtime; Numba CUDA initializes when native execution is used. Plain installation also works for native execution when a compatible CUDA Toolkit is already present.
63
67
 
64
68
  From source, with the examples:
65
69
 
66
70
  ```bash
67
71
  git clone https://github.com/sypsyp97/diffct.git
68
72
  cd diffct && pip install -e ".[cu12]"
69
- python examples/quickstart.py # smoke test: prints adjoint mismatch ~1e-8 for each beam
73
+ python examples/quickstart.py # prints adjoint mismatch and gradients for each beam
70
74
  ```
71
75
 
72
76
  <details>
@@ -105,7 +109,11 @@ loss.backward() # x.grad = A^T (A x - y)
105
109
 
106
110
  **Custom or calibrated trajectories.** Pass calibrated tensors directly instead of a generator; no circular fit is needed. See [REFERENCE](https://github.com/sypsyp97/diffct/blob/main/docs/REFERENCE.md#custom-or-calibrated-trajectories).
107
111
 
108
- **Geometry gradients.** Set `requires_grad=True` on trajectory tensors before you build `Projector`. See [REFERENCE](https://github.com/sypsyp97/diffct/blob/main/docs/REFERENCE.md#geometry-gradients).
112
+ **Geometry gradients.** Reuse one projector with `A.project(volume, trajectory=current)` or `A.backproject(sinogram, trajectory=current)`. Circular helpers accept learnable angle tensors, and `transform_trajectory` applies differentiable rigid transforms. Omitting the override keeps the constructor trajectory. See [REFERENCE](https://github.com/sypsyp97/diffct/blob/main/docs/REFERENCE.md#geometry-gradients).
113
+
114
+ **3D parallel beams.** Use `circular_trajectory_3d_parallel(...)` and `beam="parallel3d"`. The PyTorch backend provides matched projection and backprojection on CPU and CUDA.
115
+
116
+ **Native volume layout.** For unbatched, flat-detector cone operations, set `native_volume_layout=True` to avoid volume layout copies. This applies to the native full-CUDA path on one compute device. Shapes stay `(D, H, W)`; the returned strides follow the kernel layout. The default is `False`. See [chunked execution](docs/REFERENCE.md#chunked-execution) for limits.
109
117
 
110
118
  **Several GPUs and nodes.** See [REFERENCE](https://github.com/sypsyp97/diffct/blob/main/docs/REFERENCE.md#several-gpus-and-nodes) and [DISTRIBUTED.md](https://github.com/sypsyp97/diffct/blob/main/docs/DISTRIBUTED.md).
111
119
 
@@ -138,18 +146,18 @@ volume slabs use `--partition space` under torchrun. Run
138
146
 
139
147
  <p align="center">
140
148
  <picture>
141
- <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/sypsyp97/diffct/main/docs/assets/scaling_dark.png?v=2.2.0">
142
- <img src="https://raw.githubusercontent.com/sypsyp97/diffct/main/docs/assets/scaling_light.png?v=2.2.0" width="100%" alt="Time per forward, adjoint and CGLS iteration on 1, 4 and 8 GPUs, 512^3 volume">
149
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/sypsyp97/diffct/main/docs/assets/scaling_dark.png?v=2.4.0">
150
+ <img src="https://raw.githubusercontent.com/sypsyp97/diffct/main/docs/assets/scaling_light.png?v=2.4.0" width="100%" alt="Time per forward, adjoint and CGLS iteration on 1, 4 and 8 GPUs, 512^3 volume">
143
151
  </picture>
144
152
  </p>
145
153
 
146
154
  | 512³ volume | 1 GPU | 4 GPUs, 1 node | 8 GPUs, 2 nodes |
147
155
  |---|---:|---:|---:|
148
- | Forward projection | 493.05 ms | 132.22 ms (3.7×) | 73.18 ms (6.7×) |
149
- | Adjoint (backprojection) | 1400.80 ms | 369.29 ms (3.8×) | 265.87 ms (5.3×) |
150
- | CGLS iteration | 2054.36 ms | 547.06 ms (3.8×) | 373.38 ms (5.5×) |
156
+ | Forward projection | 493.40 ms | 131.78 ms (3.7×) | 72.42 ms (6.8×) |
157
+ | Adjoint (backprojection) | 1118.98 ms | 293.01 ms (3.8×) | 232.50 ms (4.8×) |
158
+ | CGLS iteration | 1744.92 ms | 465.62 ms (3.7×) | 337.98 ms (5.2×) |
151
159
 
152
- diffct 2.2.0, FP32, A100 64 GB GPUs; circular cone beam, 360 views, 1024×768 detector, pitch 1.25. Default memory settings, without an imposed allocator cap.
160
+ diffct 2.4.0, FP32, A100 64 GB GPUs; circular cone beam, 360 views, 1024×768 detector, pitch 1.25. Default memory settings, without an imposed allocator cap.
153
161
 
154
162
  Projection times are medians of seven samples after three warmups. CGLS uses three ten-iteration solves after a two-iteration warmup; the median includes initialization and is divided by ten. Timings use synchronized wall time and the slowest rank. Raw samples and configuration: [scaling.json](https://github.com/sypsyp97/diffct/blob/main/docs/assets/scaling.json).
155
163
 
@@ -189,12 +197,13 @@ Walnut data: Meaney 2022, Zenodo 6986012, CC BY 4.0; see [examples/data/NOTICE](
189
197
 
190
198
  ## Examples
191
199
 
192
- `quickstart.py`, `curved_detector.py`, `chunked_reconstruction.py`, `disk_reconstruction.py`, `benchmark_execution.py`, `analytical_reconstruction.py`, `learnable_reconstruction.py`, `helical_fdk.py`, `iterative_reconstruction.py`, `walnut_reconstruction.py`, `geometry_calibration.py`, `benchmark_projector.py`, `benchmark_scaling.py`, `plot_trajectory.py`, and the Slurm template `slurm/multi_node.sbatch`. Launch modes and distributed-loss rules are in [examples/README.md](https://github.com/sypsyp97/diffct/blob/main/examples/README.md).
200
+ `quickstart.py`, `curved_detector.py`, `chunked_reconstruction.py`, `disk_reconstruction.py`, `benchmark_execution.py`, `benchmark_trajectory_admission.py`, `analytical_reconstruction.py`, `learnable_reconstruction.py`, `helical_fdk.py`, `iterative_reconstruction.py`, `walnut_reconstruction.py`, `geometry_calibration.py`, `benchmark_projector.py`, `benchmark_scaling.py`, `plot_trajectory.py`, and the Slurm template `slurm/multi_node.sbatch`. Launch modes and distributed-loss rules are in [examples/README.md](https://github.com/sypsyp97/diffct/blob/main/examples/README.md).
193
201
 
194
202
  ## Documentation
195
203
 
196
204
  | Document | Contents |
197
205
  |---|---|
206
+ | [Precision, training and reconstruction](docs/EXECUTION.md) | Backend modes, batch/spacing contracts, analytical storage, hybrid loss scaling and solver checkpoints |
198
207
  | [Trajectory guide](https://github.com/sypsyp97/diffct/blob/main/docs/source/trajectories.rst) | Trajectory tuples and `Projector` usage |
199
208
  | [docs/REFERENCE.md](https://github.com/sypsyp97/diffct/blob/main/docs/REFERENCE.md) | Capabilities and limits, custom trajectories, geometry gradients, multi-GPU details, geometry and units |
200
209
  | [docs/DISTRIBUTED.md](https://github.com/sypsyp97/diffct/blob/main/docs/DISTRIBUTED.md) | Execution/memory choices, distributed loss rules, Slurm and cross-node checks |
@@ -219,12 +228,12 @@ If you use this library in your research, please cite the software and the techn
219
228
  }
220
229
 
221
230
  @article{202605.1446,
222
- doi = {10.20944/preprints202605.1446.v1},
223
- url = {https://doi.org/10.20944/preprints202605.1446.v1},
231
+ doi = {10.20944/preprints202605.1446.v2},
232
+ url = {https://doi.org/10.20944/preprints202605.1446.v2},
224
233
  year = 2026,
225
- month = {May},
234
+ month = {Oct},
226
235
  publisher = {Preprints},
227
- author = {Yipeng Sun and Linda-Sophie Schneider and Chengze ye and Andreas Maier},
236
+ author = {Yipeng Sun and Linda-Sophie Schneider and Chengze Ye and Andreas Maier},
228
237
  title = {diffct: Differentiable CT Operators from Circular Orbits to Arbitrary Trajectories},
229
238
  journal = {Preprints}
230
239
  }
@@ -20,12 +20,18 @@ from .surfaces import ParameterizedSurface
20
20
  from .reconstruction import (
21
21
  fbp,
22
22
  fdk,
23
+ fbp_into,
24
+ fdk_into,
23
25
  helical_fdk,
24
26
  helical_view_weights,
25
27
  helical_weighted_backproject,
26
28
  )
27
29
 
30
+ from .solvers import SolverResult, cgls, sirt, tv_reconstruction, cgls_into, total_variation
31
+
28
32
  from .geometry import (
33
+ transform_trajectory,
34
+ circular_trajectory_3d_parallel,
29
35
  circular_trajectory_3d,
30
36
  random_trajectory_3d,
31
37
  spiral_trajectory_3d,
@@ -58,7 +64,7 @@ try:
58
64
  except ImportError:
59
65
  pass
60
66
 
61
- __version__ = '2.2.1'
67
+ __version__ = '2.4.0'
62
68
 
63
69
  __all__ = [
64
70
  'Projector',
@@ -67,6 +73,14 @@ __all__ = [
67
73
  'ParameterizedSurface',
68
74
  'fbp',
69
75
  'fdk',
76
+ 'fbp_into',
77
+ 'fdk_into',
78
+ 'SolverResult',
79
+ 'cgls',
80
+ 'sirt',
81
+ 'tv_reconstruction',
82
+ 'cgls_into',
83
+ 'total_variation',
70
84
  'helical_fdk',
71
85
  'helical_view_weights',
72
86
  'helical_weighted_backproject',
@@ -76,6 +90,8 @@ __all__ = [
76
90
  'FanBackprojectorFunction',
77
91
  'ConeProjectorFunction',
78
92
  'ConeBackprojectorFunction',
93
+ 'transform_trajectory',
94
+ 'circular_trajectory_3d_parallel',
79
95
  'circular_trajectory_3d',
80
96
  'random_trajectory_3d',
81
97
  'spiral_trajectory_3d',