CUDA (GPU) backend
Header: cuda_solver.cuh. Namespace: adrt::cuda. Enable with
-DADRT_ENABLE_CUDA=ON at configure time.
The CUDA backend is a batched solver: it processes an entire spectrum in
parallel with one thread per wavenumber. It provides template-specialised
kernels (solveKernel<N>) for \(N = 2, 4, 8, 16\) with register-resident
matrix operations, and a cuBLAS-based path for larger \(N\). Linear
systems are factorised in double precision.
Configuration
-
struct adrt::cuda::BatchConfig
Scalars shared across all wavenumbers. Mirrors
ADConfigbut with the batch dimensionnum_wavenumbersand anum_moments_max(the maximum number of Legendre moments across layers). Fields includenum_layers,num_quadrature(2, 4, 8, 16, or 32),use_delta_m,use_thermal_emission,use_diffusion_lower_bc,surface_albedo,surface_temperature,top_temperature,solar_flux,solar_mu,wavenumber_low/wavenumber_high, and-
double spectrum_scaling
A constant factor applied to
flux_uponly — for example \(10^{-3}(R_p/R_s)^2\) when producing a planet/star flux ratio.
-
double spectrum_scaling
Device data layouts
-
struct adrt::cuda::DeviceData
Caller-owned device pointers using a structure-of-arrays layout,
array[wav * stride + layer_or_level]. Inputs includedelta_tau,single_scat_albedo,phase_moments(withphase_moments_sharedif the same moments apply to every wavenumber), and eithertemperature(for on-device Planck evaluation) orplanck_levels. Outputs areflux_up,flux_down, and optionalflux_direct.
-
struct adrt::cuda::RawDeviceData
A raw-input interface for retrieval codes such as BeAR. Takes level-major coefficient arrays with BOA at index 0 (
absorption_coeff,scattering_coeff,altitude,temperature,wavenumber, and an optionalcloud_optical_depth). The solver computes optical depths (trapezoidal rule), single-scattering albedos, and the single-wavenumber Planck function inline, and reverses the ordering to TOA-first internally.
Entry points
-
void adrt::cuda::solveBatch(const BatchConfig &config, const DeviceData &data, cudaStream_t stream = 0)
Launch the batched kernel; all data must already be on the GPU. Call
uploadQuadratureData()once beforehand.
-
HostResult adrt::cuda::solveBatchHost(const BatchConfig &config, const std::vector<float> &delta_tau, const std::vector<float> &single_scat_albedo, const std::vector<float> &phase_moments, bool phase_moments_shared, const std::vector<float> &planck_levels, const std::vector<float> &temperature = {})
Convenience wrapper for standalone use: allocates device memory, copies the host arrays over, runs the kernel, and copies the results back into a
HostResult(flux_up,flux_down,flux_direct).
-
void adrt::cuda::solveBatchFromCoefficients(const BatchConfig &config, const RawDeviceData &data, cudaStream_t stream = 0)
Solve from raw retrieval inputs for \(N \leq 8\) with zero intermediate allocation — optical properties and Planck values are computed inside the kernel. Suitable for very large wavenumber counts.
-
void adrt::cuda::solveBatchFromCoefficients(const BatchConfig &config, const RawDeviceData &data, SolverWorkspaceGPU &workspace, cudaStream_t stream = 0)
The \(N > 8\) overload: preprocesses the raw inputs into intermediate arrays held by a persistent
SolverWorkspaceGPU, then runs the cuBLAS-based solver.
-
struct adrt::cuda::SolverWorkspaceGPU
Persistent GPU workspace for the cuBLAS path (\(N > 8\)). Allocate once with
allocate(nwav, nlay)and reuse across retrieval iterations; it frees its device memory on destruction.
Note
The CUDA backend uses single precision for the stored optical properties and double precision for the LU factorisation of the linear systems. Analytic temperature Jacobians are not available on this backend.