Skip to content

cuPhoton 0.1.3

Latest

Choose a tag to compare

@tpn tpn released this 08 Oct 18:07
v0.1.3
b713503

cuPhoton 0.1.3 is a source-only release for CPython 3.12–3.14 on Linux. It adds one FITS reader across the imaging workflows, spatially varying image subtraction in xPois, GPU-resident results in xPois and xFit, a reusable xPois → xFit → xScan device pipeline, and optional MPI and Dragon executors with persistent workers. xRay gains iterative fitting and compact detector spectra, and xDR fixes GPU buffer lifetimes and Gzip tile decoding.

For a hands-on walkthrough of cuPhoton’s GPU imaging workflow, read our NVIDIA Technical Blog post, Faster Scientific Image Analysis with NVIDIA cuPhoton.

cuPhoton 0.1.3 brings together 193 commits across 71 merged pull requests, adding 122 files and 82,553 net lines since v0.1.2 (86,231 added; 3,678 removed).

Contents 🔗

Highlights 🔗

  • One FITS reader for every imaging workflow. cuphoton.core.fits_io serves xPois, xRep, xFit, and xScan with a shared --fits-reader auto|astropy|xdr policy, header-first inspection, and read receipts. xFit fits candidate stamps straight from FITS manifests, and xScan scores FITS candidates through predict_fits. #61, #62, #63, #64
  • Spatially varying image subtraction. solve_spatial_als (--solver spatial-als) fits separable kernels whose profiles vary across the image, in NumPy or CuPy FP64, alongside an experimental Gaussian-polynomial model. #25, #26, #27, #28, #29
  • Results that stay on the GPU. solve_constant_kernel_device and fit_dipoles_device return CuPy results, and cuphoton.xscan.device_pipeline chains constant-kernel xPois, Gaussian xFit, and triplet xScan inference in one DeviceWorkerContext that loads the model once. #31, #12, #13, #42
  • Persistent distributed workers. Shared MPI and Dragon executors run xPois image pairs, xFit candidate chunks, xScan inference minibatches, and the complete pipeline (xscan run-pipeline), keeping CUDA contexts, inputs, and models across warmup and measured rounds. #10, #54, #56
  • More xRay fitting options. Damped-cosine iterative fitting (--fit-method iterative), batched detector FFTs, status-aware diagnostics with optional P2 ridge, and a lossless tile-rows artifact layout. #9, #22, #23, #75
  • xDR correctness fixes. Buffers remain owned until GPU work completes on success, error, and cancellation paths; unaligned Gzip tile payloads are repacked before DEFLATE decoding; independent reads proceed during GDS waits. #36, #81, #39

Measured timings for these changes are collected under Performance.

Performance 🔗

Each figure is a measured speedup for the configuration and timing boundary stated in its pull request. Most compare whole workflows against a named baseline, so amortized startup, I/O, and transfer costs contribute as much as computation. Expect different factors on other hardware, data, and batch sizes.

  • Persistent pipeline versus separate stages. On one RTX PRO 6000 Blackwell with synthetic 1024×1024 pairs (nine candidates each), warm xscan benchmark-pipeline rounds had medians of 0.884–0.901 s, against 8.211–8.407 s for freshly started xPois, xFit, and xScan stage processes (9.3×). The stage figure includes process startup and intermediate files. #55
  • xDR reads in xPois and xRep. Reading a registered image pair for constant-kernel xPois took 0.133 s with xDR instead of 2.20 s with Astropy (16.5×), and xRep on an HSC coadd went from 0.973 s to 0.211 s (4.6×). #62
  • FITS candidate manifests in xFit. For 16 stamps from a retained image subtraction on one GPU, median ingress, crop, and validation fell from 0.764 s to 0.107 s (7.1×). #63
  • FITS inputs in the device pipeline. On registered FITS inputs with 32 candidates, the one-GPU batch median fell from 15.65 s with Astropy to 10.76 s with xDR (1.45×); two-worker MPI and Dragon batches gained 1.26× and 1.30×. #64
  • Dragon control plane. In a two-node, 64-worker control experiment, consumer-local command queues reduced later-round control medians from 47.2/45.3 ms to 33.6/28.1 ms under Python TCP (1.4–1.6×), and native HSTA TCP reached 2.4–3.1 ms (9–20× below Python TCP, depending on queue layout). At 256 GPUs the per-batch coordination remainder fell from 210–357 ms to 24–33 ms with consumer queues (6–15×) and 8.1–8.6 ms with HSTA (24–44×). On eight GB200 GPUs, whole-pipeline batch medians stayed at 7.5–7.7 s under every layout and transport. Dragon execution guide

Install 🔗

Install from the v0.1.3 checkout with uv:

git clone --branch v0.1.3 https://github.com/NVIDIA/cuPhoton.git
cd cuPhoton

Choose a profile for your workflow:

# CPU data inspection and NumPy/SciPy workflows
uv sync --locked
# GPU FITS I/O runtime dependencies only
uv sync --locked --extra io
# GPU workflows: I/O, photometry, PyTorch, Numba-CUDA
uv sync --locked --extra gpu
# GPU workflows with visualization
uv sync --locked --extra gpu --extra viz

uv sync installs an editable Python package. The io and gpu extras supply runtime dependencies; native xDR requires a separate build with a C++17 compiler, CUDA 13 and cuFile development headers, and reentrant CFITSIO. Prepare the prerequisites in the xDR source build instructions, then run bash src/cuphoton/xdr/src/build.sh. The shared FITS reader can use Astropy without that extension. GPU execution needs a CUDA 13-compatible NVIDIA driver; GPUDirect Storage also needs a compatible host and storage configuration.

Extras compose: use uv sync --locked --extra gpu --extra viz --extra mpi for distributed GPU workflows with visualization. Include every extra you want to retain when changing profiles.

Extra Adds
io CuPy, the CUDA 13 runtime with cuFile, KvikIO 26.6, and nvCOMP 5.2 for native FITS I/O (Linux)
photometry Photutils background estimation, source detection, and aperture photometry
torch PyTorch for CPU-capable workflows
gpu io and photometry, plus PyTorch and Numba-CUDA on Linux
viz Bokeh, Pillow, and Tornado
cutile Experimental cuTile backend; needs an external CUDA 13.2 or newer compiler with tileiras, ptxas, and NVVM
mpi mpi4py; the MPI implementation and launcher come from your environment
dragon DragonHPC on Linux with CPython 3.12 or 3.13
dev Development, testing, formatting, and type-checking tools

See the packaging guide for runtime requirements and native source builds, and optional runtimes for MPI, Dragon, and the cuTile PyTorch/compiler constraint. ARM64 caveats for PyTorch and Photutils are under Known limitations.

Upgrading from 0.1.2 🔗

  • Python. CPython 3.12, 3.13, or 3.14 is required; 3.11 is no longer supported. #51
  • Photutils is optional. The base package no longer installs it. Select photometry with uv sync --locked --extra photometry; gpu includes it. #51
  • HDF5 loader removed. The Legate-backed cuphoton.xdr.load_hdf5 API and the hdf5 extra are gone; use h5py, a base dependency. xRay's HDF5 workflows are unchanged. #7
  • Source builds. CUPHOTON_XDR_BUILD_EXT=auto is gone; use 0 (Python-only, the default) or 1 (native). Build native xDR explicitly after preparing its development dependencies. #24, #51
  • Distributed runs. Use uv sync --locked --extra gpu --extra mpi or uv sync --locked --python 3.13 --extra gpu --extra dragon, then pass --executor mpi or --executor dragon under that runtime's launcher. xFit and xScan default to local execution; xscan run-pipeline requires an executor. #56
  • xPois NPY masks. With masking enabled, every NPY reference or target needs an explicit mask path, or select --mask-policy none. #34
  • xRay manifests. Version 1 linear-prediction manifests are recomputed once on resume and rewritten as version 2, whose resume identity includes diagnostics and ridge settings. Iterative fitting writes version 3. xRay guide
  • The spatial, device-result, and iterative-fitting APIs are opt-in. Constant-kernel xPois and xRay linear prediction remain the defaults.

What changed 🔗

FITS reading 🔗

  • cuphoton.core.fits_io inspects headers before reading pixels, preserves HDU order, native-endian dtypes, and integer mask bits, and returns NumPy or CuPy arrays with reader provenance. The default is Astropy and host arrays. #61
  • auto uses xDR for supported inputs and Astropy for FITS scaling, null values, unsupported compression, and uncompressed section reads; xdr requires compatible inputs and the native GPU dependencies. Receipts record the requested and actual reader, HDUs, output location, and decoded bytes. Reader contract
  • xPois and xRep accept --fits-reader independently of the numerical backend. Standalone xPois copies xDR-decoded pixels back to the host; CuPy xRep consumes device arrays directly. WCS and target-grid setup read metadata only. #62

xPois 🔗

  • Spatial ALS. solve_spatial_als and SpatialALSConfig, or --solver spatial-als, fit separable kernels whose profiles vary along both image axes, with a local kernel of rank at most one and a polynomial background. Optional flux conservation holds the signed kernel sum constant while fitting a global photometric scale. NumPy and CuPy FP64 implementations return host arrays and record convergence. #25, #26, #27
  • Gaussian-polynomial model (experimental). solve_spatial_gaussian_polynomial_kernel in cuphoton.xpois.spatial_gaussian_polynomial jointly fits kernel shape, photometric scale, and background fields on CPU or CuPy; explicit pixel-coordinate domains keep coefficients comparable across cutouts. #28, #29
  • Device results. solve_constant_kernel_device returns a DeviceConstantKernelFitResult with the kernel, matched image, and residuals on the active GPU. Scalar diagnostics stay on the host; callers control synchronization and lifetimes. #31
  • cuTile normal equations. backend="cutile" forms constant-kernel normal equations with fused FP64 matrix operations, reuses compiled kernels across fit-pixel counts, and caches up to four padded basis uploads keyed by basis values, shape, padded width, and device. #30, #46
  • Residual diagnostics. standardize_constant_kernel_residual propagates reference noise through the fixed kernel to per-pixel marginal variance; summarize_standardized_residuals adds per-stamp and pooled RMS, centered standard deviation, and spatial lag correlations weighted by valid pixels. #32, #33
  • Reviews and benchmarks. --no-review skips review artifacts; hotspot and mask-component summaries group pixels once. Backend benchmarks apply the same masks, variance, crops, and fit-pixel selection as the fit commands and time loading separately from solving. #14, #15, #34

xFit 🔗

  • cuTile Gaussian fitting. fit_dipoles(..., backend="cutile") uses analytic derivatives and fused normal-equation assembly, with analytic-Jacobian rank and covariance diagnostics, batched final diagnostics, and sturdier fallbacks for stalled fits and failed finite differences. #11
  • Numerical fixes. Overflowing normal equations fall back to the analytic Jacobian without changing termination decisions or diagnostics; cuTile width derivatives follow the analytic model's arithmetic order at extreme widths. #80, #88
  • Device results. fit_dipoles_device returns a DeviceDipoleFitResult whose arrays stay on the GPU; fit_dipoles still returns NumPy. Model evaluation skips derivative work when only values are needed. #12, #65
  • FITS candidate manifests. A JSON manifest selects image HDUs, integer zero-based (x, y) centers, odd stamp sizes, and optional variance and mask HDUs, with paths relative to the manifest. fit-dipoles --fits-reader is independent of --backend; GPU fits keep stamps on the device; artifacts record source hashes and read receipts. #63
  • Input export. The exporter accepts variance and inclusion-mask planes (nonzero includes a pixel; variance in squared image units), preserves dtype and row order, and records source hashes with an optional image-unit label. #21

xScan and the device pipeline 🔗

  • Feature adapters and tensor inference. transform_xfit_result_features and its _device variant in cuphoton.xscan.xfit_features build the canonical feature matrix from xFit results; cupy_to_torch shares CuPy arrays with PyTorch through DLPack; predict_tensors scores float32 image tensors plus optional fit features on a CUDA device and returns logits and probabilities there. FP32 subnormals survive feature conversion. #13, #35
  • Inference policies. Checkpoints apply their saved inference performance policy before compilation; persistent callers can override it. infer-real-bogus --num-workers overrides the checkpoint's loader count (zero disables loaders). #41, #19
  • Device pipeline. cuphoton.xscan.device_pipeline runs constant-kernel xPois, Gaussian difference-mode xFit, and triplet xScan inference for complete image pairs in a DeviceWorkerContext. It requires CUDA 13, CuPy, Torch, a triplet fusion checkpoint with its feature schema, unmasked and unweighted Gaussian difference fits, and matching stamp dimensions; variance and fit-mask inputs are optional. Results carry predictions and compact per-stage evidence. #42
  • Direct FITS inference. cuphoton.xscan.fits_inference.predict_fits scores caller-selected candidates from aligned FITS search and template images and an optional difference image, cropping float32 stamps on the GPU and returning host logits, probabilities, and receipts in candidate order. Supply the checkpoint's pixel normalization and integer zero-based (y, x) centers. Raw DES and LSSTComCam builders accept reader policies, and run-pipeline and benchmark-pipeline take --fits-reader to override manifest policies. #64
  • Pipeline comparison. xscan benchmark-pipeline times the persistent GPU pipeline against separate xPois, xFit, and xScan processes exchanging files, with matching APIs, inputs, batches, and checkpoints, and reports repeated batch timings, initialization, and complete invocation times. #55, benchmark guide

Distributed execution 🔗

  • Shared executors. Dragon and MPI executors in cuphoton.core own worker placement, dispatch, and lifecycle; components initialize once and keep input or model state across tasks and rounds. Dragon places command queues on their consumer's host and reads launch descriptors from the shared filesystem. #54, #40
  • xPois batches. xpois fit-batch --executor mpi|dragon distributes complete image-pair fits with per-item results, run summaries, explicit GPU placement, and failure reporting. --warmup-rounds and --measure-rounds repeat a manifest in persistent workers that keep CUDA contexts and caches; repeated MPI runs use --aggregation-mode mpi. #8, #10, #50
  • xFit and xScan. xfit fit-dipoles --executor dragon|mpi --chunk-size N distributes candidate chunks (NPZ input stays on the host, FITS stamps on the device; merged artifacts restore IDs and order). xscan infer-real-bogus --executor dragon|mpi distributes inference, with --task-batches keeping minibatch boundaries intact and --num-workers defaulting to 0. #56
  • Complete pipeline. xscan run-pipeline distributes xPois / xFit / xScan image-pair jobs from JSON descriptors with one device and model context per worker; run_dragon_device_pipeline is the Python adapter. Dragon inference now starts local DataLoader processes with ordinary spawn queues and reuses them across rounds. #43, #56, #91
  • Timing and guides. Run summaries separate worker-round timing from coordinator processing. See the Dragon execution guide, the cluster launch guide for Slurm and SSH, and the xFit and xScan launch sections. #49, #73

xRay 🔗

  • Diagnostics and ridge. Detector artifacts keep status-aware per-row diagnostics (traces and reconstructions in full mode), linear-prediction diagnostics add residual ratios and P1/P2 conditioning, and --p2-ridge-alpha enables P2 ridge regularization. The default dense NPY layout repeats each row result across its tile's columns. #9
  • Batched detectors. Eligible linear-prediction tiles batch artifact assembly, FFTs, and output transfers across rows; root extraction and least squares stay row-wise. #22
  • Iterative fitting. cuphoton.xray.iterative_fit.iterative_fit fits a fixed number of damped cosine modes plus an offset, with frequency bounds, iteration limits, and amplitude regularization, on CPU by default or with backend="gpu". --fit-method iterative runs the small row fits on CPU with CuPy normalization and FFTs; linear prediction remains the default, and P2 ridge applies only to it. Frequencies are cycles per input time unit; angular_frequency is radians (divide by 2π). #23
  • Compact spectra. --artifact-layout tile-rows (or artifact_layout="tile-rows") stores each row's spectrum once per tile; load_detector_array expands pixel slices, and comparison, visualization, and shard merging handle both layouts. Changing layout invalidates shard resume. #75
  • Detector parity tests now allow bounded float64 roundoff between batched and serial outputs; this changes only test tolerances. #90

xDR and xRep 🔗

  • Buffer lifetimes. Pinned host and GPU work buffers stay owned until copies and decompression complete on their stream, on success, error, and cancellation paths; gzip header bounds and decoded tile layouts are validated. #36
  • Gzip tiles. Unaligned compressed payloads are repacked before DEFLATE decoding; native reads supply the output buffers nvCOMP 5.2 requires and retain decoder inputs and scratch through asynchronous work. #81
  • Concurrent reads. With an explicit CUDA stream, independent reads submit while another waits on GDS I/O, and opening a second loader no longer resets a matching KvikIO pool during another read. #39
  • Builds and benchmarks. Native builds select and report the requested interpreter; FITS benchmarks write JSON reports with --output-json. #16, #18
  • Target-grid reprojection. xrep reproject-stack --target-wcs destination.fits maps a stack onto an existing image's dimensions and celestial WCS (--target-hdu selects the HDU), preserving rotation, reference-pixel offsets, and SIP distortion; --mapping-grid-step 1 evaluates the full mapping per pixel. #20

Documentation and examples 🔗

  • A synthetic imaging walkthrough (script and notebook) runs FITS loading, WCS alignment, kernel subtraction, dipole fitting, and plotting with recovery diagnostics; set KERNEL_SIGMA = SEEING_SIGMA for a matched-kernel comparison. #47, #67
  • A workflow chooser, component guides, and an architecture guide following the optical data flow; the refresh updates installation and artifact contracts, standardizes component names, and replaces the roadmap with issue tracking. #48, #53, #87
  • The cluster launch guide ships host files, a pipeline JSON template, and a CPU preparation script in the source archive. #73

Packaging, CI, and tooling 🔗

  • Versions come from Git tags through setuptools-scm (v0.1.3 builds 0.1.3; later commits get development versions). make build produces the source archive; make wheels and make conda remain available for local binary builds. Build commands preserve each other's outputs, while make clean-dist clears them. Packaging guide
  • Native xDR source builds require reentrant CFITSIO and use the KvikIO 26.6 and nvCOMP 5.2 ABI families. Retained wheel build tooling bundles CFITSIO 4.7.0; Conda build tooling requires HDF5 2.1 or newer. These recipes remain available for local builds. #51, #57, #70
  • viz requires Tornado 6.5.10 or newer; dev requires virtualenv>=21.7.12. #44, #89
  • Development checks add mypy, C/C++/CUDA formatting, and ShellCheck alongside Ruff through make hooks; vetted PR revisions run the L40G GPU checks before the merge gate. #68, #66
  • Public repository templates, 0.1.3 release metadata, both maintainers as code owners, and corrected license and Dragon dependency notices. #6, #38, #45, #69

Known limitations and errata 🔗

  1. xRay linear prediction can drop lightly damped modes when traces contain noise. This predates 0.1.3; see issue #1.
  2. ARM64 dependency check. On Linux ARM64, installs that include PyTorch through the gpu or torch extra make python -m pip check report nvidia-cusparselt-cu13 0.8.1 is not supported on this platform: the wheel is named aarch64 but tagged manylinux2014_sbsa internally. PyTorch imports and the tested GPU workflows pass on GB200; PyTorch 2.13 and 2.14 both pin 0.8.1.
  3. ARM64 Photutils. Photutils 3.0.0 has no Linux ARM64 wheel, so selecting the photometry or gpu extra builds it from source and requires a C compiler and Python headers. The base package and io extra are unaffected.

Contributors 🔗

Thanks to everyone who contributed to this release.

cuPhoton 0.1.3 contributor PRs, assists, and primary PR diff totals. Trent Nelson: 57 PRs, 14 assists, +73,836 -5,525; Carmelo Gonzales: 9 PRs, 36 assists, +3,677 -510; Irina Demeshko: 2 PRs, 0 assists, +5,950 -483; Akhilesh Mishra: 1 PR, 0 assists, +798 -1; Cédric Augonnet: 1 PR, 0 assists, +3,881 -228; Marek Dąbek: 1 PR, 0 assists, +1,196 -38.

Author PRs Assists Primary PR diff stats
Trent Nelson 57 14 +73,836 -5,525
Carmelo Gonzales 9 36 +3,677 -510
Irina Demeshko 2 0 +5,950 -483
Akhilesh Mishra 1 0 +798 -1
Cédric Augonnet 1 0 +3,881 -228
Marek Dąbek 1 0 +1,196 -38

PRs counts first-listed credits in the pull request table below; Assists counts all other credits. Diff stats sum additions and removals for each author’s primary PRs.

Pull requests 🔗

PRComponentChangeContributorsDiff stats
#5-Add CPU checks and opt-in code reviewsTrent Nelson+140 -2
#6-Prepare public repository templates and source archivesTrent Nelson; Carmelo Gonzales+169 -4
#7xDRRemove the Legate-backed xDR HDF5 loaderTrent Nelson+25 -316
#8xPoisAdd Dragon-backed xPois image-pair batchesTrent Nelson; Carmelo Gonzales+5,431 -114
#9xRayAdd xRay fit diagnostics and optional P2 ridgeTrent Nelson; Carmelo Gonzales+2,392 -44
#10xPoisUnify MPI and Dragon xPois batch executionTrent Nelson; Carmelo Gonzales+11,797 -309
#11xFitAdd optional cuTile Gaussian fitting to xFitTrent Nelson; Carmelo Gonzales+1,640 -84
#12xFitKeep xFit results and diagnostics on the GPUTrent Nelson; Carmelo Gonzales+1,224 -96
#13xFit, xScanAdd device xFit features and tensor inference to xScanTrent Nelson; Carmelo Gonzales+2,410 -34
#14xPoisAllow xPois fits without review artifactsCarmelo Gonzales; Trent Nelson+241 -94
#15xPoisGroup xPois review component pixels onceCarmelo Gonzales; Trent Nelson+289 -8
#16xDRSelect the intended Python for native xDR buildsCarmelo Gonzales; Trent Nelson+204 -4
#17-Clarify CPU test skips and expected FITS warningsTrent Nelson+31 -57
#18xDRExport xDR benchmark results as JSONCarmelo Gonzales; Trent Nelson+550 -22
#19xScanAllow xScan inference worker overridesCarmelo Gonzales; Trent Nelson+227 -2
#20xRepReproject stacks onto an existing FITS WCSCarmelo Gonzales; Trent Nelson+488 -46
#21xFit, xScanExport variance and inclusion masks with xFit inputsCarmelo Gonzales; Trent Nelson+758 -22
#22xRayBatch xRay detector artifacts and FFTsTrent Nelson; Carmelo Gonzales+919 -68
#23xRayAdd optional iterative fitting to xRayTrent Nelson; Carmelo Gonzales+2,120 -74
#24-Make package builds deterministic and verify distributionsTrent Nelson+222 -36
#25xPoisAdd a spatial ALS image-matching solverIrina Demeshko; Trent Nelson; Carmelo Gonzales+3,578 -46
#26xPoisAccelerate spatial ALS with CuPyIrina Demeshko; Trent Nelson+2,372 -437
#27xPoisEnable spatial ALS in xPois image-pair batchesTrent Nelson; Carmelo Gonzales+1,010 -169
#28xPoisAdd an experimental spatial Gaussian-polynomial modelTrent Nelson; Carmelo Gonzales+3,239 -0
#29xPoisAccelerate the Gaussian-polynomial model with CuPyTrent Nelson; Carmelo Gonzales+1,232 -128
#30xPoisFuse xPois cuTile normal equations with FP64 MMATrent Nelson; Carmelo Gonzales+295 -149
#31xPoisKeep constant-kernel xPois results on the GPUTrent Nelson; Carmelo Gonzales+901 -43
#32xPoisPropagate fixed-kernel residual varianceTrent Nelson+952 -12
#33xPoisSummarize standardized residual structureTrent Nelson; Carmelo Gonzales+995 -1
#34xPoisMatch xPois benchmark preprocessing to fitted masksCarmelo Gonzales; Trent Nelson+790 -305
#35xScanPreserve subnormal values in device xFit featuresTrent Nelson+119 -6
#36xDRRetain xDR buffers until GPU work completesCédric Augonnet; Trent Nelson; Carmelo Gonzales+3,881 -228
#37-Clarify cuPhoton distribution contentsTrent Nelson+19 -5
#38-Prepare cuPhoton 0.1.3 release metadataTrent Nelson+2 -3
#39xDRAllow independent xDR reads during GDS waitsMarek Dąbek; Trent Nelson; Carmelo Gonzales+1,196 -38
#40xPoisReuse Dragon coordination for package workloadsTrent Nelson+591 -44
#41xScanAllow explicit xScan checkpoint inference policiesTrent Nelson; Carmelo Gonzales+264 -6
#42xPois, xFit, xScanReuse a device context across xPois, xFit and xScanTrent Nelson+4,950 -0
#43xPois, xFit, xScanRun the xPois, xFit and xScan device pipeline through DragonTrent Nelson+2,528 -0
#44-Require Tornado 6.5.10 for visualizationTrent Nelson+10 -6
#45-Add Carmelo as a repository code ownerTrent Nelson+2 -2
#46xPoisReuse padded cuTile basis uploads across fitsCarmelo Gonzales; Trent Nelson+130 -7
#47xDR, xRep, xPois, xFitAdd a synthetic imaging pipeline walkthroughAkhilesh Mishra; Trent Nelson; Carmelo Gonzales+798 -1
#48-Explain cuPhoton workflows and simplify public documentationTrent Nelson; Carmelo Gonzales+763 -590
#49DocumentationDocument Dragon transport, persistent execution, and timingTrent Nelson; Carmelo Gonzales+248 -0
#50xPoisMeasure repeated batches in persistent Dragon and MPI workersTrent Nelson; Carmelo Gonzales+2,485 -63
#51Packaging, xDRShip native xDR wheels and tag-driven Python releasesTrent Nelson; Carmelo Gonzales+3,877 -489
#53DocumentationUpdate documentation for cuPhoton 0.1.3Trent Nelson; Carmelo Gonzales+921 -546
#54Core executorsShare persistent Dragon and MPI execution across componentsTrent Nelson; Carmelo Gonzales+4,595 -570
#55xPois, xFit, xScanCompare persistent pipeline and separate stage executionTrent Nelson; Carmelo Gonzales+2,574 -5
#56xFit, xScanRun fitting, inference, and the device pipeline through Dragon or MPITrent Nelson; Carmelo Gonzales+3,437 -20
#57Packaging, xDRBuild native Linux conda packagesTrent Nelson; Carmelo Gonzales+936 -41
#61Core, xDRAdd a shared FITS reader for CPU and GPU workflowsTrent Nelson+579 -0
#62xPois, xRep, xDRUse xDR in xPois and xRep FITS workflowsTrent Nelson; Carmelo Gonzales+633 -269
#63xFitFit candidate stamps directly from FITS imagesTrent Nelson+1,199 -45
#64xScan, xPois, xFitRead FITS inputs directly in xScan and the device pipelineTrent Nelson; Carmelo Gonzales+2,273 -67
#65xFitSkip unused Gaussian derivatives during model evaluationTrent Nelson+29 -0
#66CIRequire L40G GPU checks for vetted PR revisionsTrent Nelson+119 -3
#67xDR, xRep, xPois, xFitRestore visible fit diagnostics in the imaging walkthroughTrent Nelson+206 -60
#68Developer toolingAdd type checking and native style hooksTrent Nelson+1,362 -727
#69PackagingCorrect license formatting and clarify Dragon dependency noticesTrent Nelson+22 -3
#70PackagingRequire HDF5 2.1 or newer in Conda environmentsTrent Nelson; Carmelo Gonzales+9 -0
#73DocumentationDocument MPI and Dragon cluster launchesTrent Nelson; Carmelo Gonzales+409 -1
#75xRayAdd optional compact tile-row storage for detector spectraTrent Nelson; Carmelo Gonzales+840 -74
#80xFitPreserve solver behavior when normal equations overflowTrent Nelson; Carmelo Gonzales+116 -3
#81xDRFix DEFLATE alignment and nvCOMP output buffersTrent Nelson; Carmelo Gonzales+396 -100
#87DocumentationRefresh cuTile setup and 0.1.3 release documentationTrent Nelson+13 -15
#88xFitAlign cuTile Gaussian width derivatives with the analytic modelTrent Nelson+96 -8
#89Developer toolingRequire patched virtualenv for development toolingTrent Nelson+10 -7
#90xRay testsAllow bounded float64 roundoff in detector parity checksTrent Nelson+17 -6
#91Core executors, xScanFix Dragon inference with local loader processesTrent Nelson+43 -1

Commit counts describe the pull requests before squash merging. Release line and file totals compare v0.1.2 with v0.1.3; individual PR stats show each PR’s diff, including code, tests, documentation, and supporting files.

Full source comparison (merged changes)