foscat.SphericalStencil#
Classes#
GPU-accelerated spherical stencil operator for HEALPix convolutions. |
Module Contents#
- class foscat.SphericalStencil.SphericalStencil(nside: int, kernel_sz: int, *, nest: bool = True, cell_ids=None, device=None, dtype=None, n_gauges=1, gauge_type='phi')[source]#
GPU-accelerated spherical stencil operator for HEALPix convolutions.
- This class implements three phases:
Geometry preparation: build local rotated stencil vectors for each target pixel, compute HEALPix neighbor indices and interpolation weights.
Sparse binding: map neighbor indices/weights to available data samples (sorted ids), and normalize weights.
Convolution: apply multi-channel kernels to sparse gathered data.
Once A+B are prepared, multiple convolutions (C) can be applied efficiently on the GPU.
- Parameters:
nside (
int) – HEALPix resolution parameter.kernel_sz (
int) – Size of local stencil (must be odd, e.g. 3, 5, 7).gauge_type (
str) – Type of gauge : ‘cosmo’ use the same definition than‘phi’ is define at the pole, could be better for earth observation not using intensivly the pole
n_gauge (
float) – Number of oriented gauges (Default 1).blend (
bool) – Whether to blend smoothly between axisA and axisB (dual gauge).power (
float) – Sharpness of blend transition (dual gauge).nest (
bool) – Use nested ordering if True (default), else ring ordering.cell_ids (
np.ndarray | torch.Tensor | None) – If given, initialize Step A immediately for these targets.device (
torch.device | str | None) – Default device (if None, ‘cuda’ if available else ‘cpu’).dtype (
torch.dtype | None) – Default dtype (float32 if None).
- nside#
- KERNELSZ#
- P#
- G = 1#
- gauge_type = 'phi'#
- nest = True#
- device#
- dtype = None#
- Kb = None#
- idx_t = None#
- w_t = None#
- ids_sorted_np = None#
- pos_safe_t = None#
- w_norm_t = None#
- present_t = None#
- cell_ids_default = None#
- static get_interp_weights_from_vec_torch(nside: int, vec, *, nest: bool = True, device=None, dtype=None, chunk_size=1000000)[source]#
Torch wrapper for healpy.get_interp_weights using input vectors.
- Parameters:
- Returns:
idx_t (
LongTensor (4,*leading))w_t (
Tensor (4,*leading))
- prepare_torch(th, ph, alpha=None, G: int = 1)[source]#
Prepare rotated stencil and HEALPix neighbors/weights in Torch for G gauges.
- Parameters:
th, ph (
array-like,shape (K,)) – Target colatitudes/longitudes.alpha (
array-like (K,)orscalarorNone) – Base gauge angle about the local normal at each target. If None -> 0. For each gauge g in [0..G-1], the effective angle is alpha + g*pi/G.G (
int (>=1)) – Number of gauges to generate per target.Side effects
————
Sets –
self.Kb = K
self.G = G
self.idx_t_multi : (G, 4, K*P) LongTensor (neighbors per gauge)
self.w_t_multi : (G, 4, K*P) Tensor (weights per gauge)
- For backward compat when G==1:
self.idx_t : (4, K*P) self.w_t : (4, K*P)
- Returns:
idx_t_multi (
torch.LongTensor,shape (G,4,K*P))w_t_multi (
torch.Tensor, shape (G,4,K*P))
- bind_support_torch_multi(ids_sorted_np, *, device=None, dtype=None)[source]#
- Multi-gauge sparse binding (Step B) WITH ‘reduced domain’ logic:
weights of out-of-domain neighbours set to 0
column renormalisation to 1
si colonne vide: fallback sur le pixel cible (centre du stencil)
- Produit:
self.pos_safe_t_multi : (G, 4, K*P) self.w_norm_t_multi : (G, 4, K*P) self.present_t_multi : (G, 4, K*P)
- bind_support_torch(ids_sorted_np, *, device=None, dtype=None)[source]#
- Single-gauge sparse binding (Step B) WITH ‘reduced domain’ logic:
weights of out-of-domain neighbours set to 0
column renormalisation to 1
si colonne vide: fallback sur le pixel cible (centre du stencil)
- apply_multi(data_sorted_t: torch.Tensor, kernel_t: torch.Tensor)[source]#
Apply multi-gauge convolution.
Inputs#
data_sorted_t : (B, Ci, K) torch.Tensor on self.device/self.dtype kernel_t : either
(Ci, Co_g, P) : shared kernel for all gauges
(G, Ci, Co_g, P) : per-gauge kernels
- returns:
out (
(B,G*Co_g,K) torch.Tensor)
- apply(data_sorted_t, kernel_t)[source]#
Apply the (Ci,Co,P) kernel to batched sparse data (B,Ci,K) using precomputed pos_safe and w_norm. Runs fully on GPU.
- Parameters:
data_sorted_t (
torch.Tensor (B,Ci,K)) – Input data aligned with ids_sorted.kernel_t (
torch.Tensor (Ci,Co,P)) – Convolution kernel.
- Returns:
out (
torch.Tensor (B,Co,K))
- Convol_torch(im, ww, cell_ids=None, nside=None)[source]#
Batched KERNELSZ x KERNELSZ aggregation (dispatcher).
- Supports:
- im: Tensor (B, Ci, K) with
cell_ids is None -> use cached targets (fast path)
cell_ids is 1D (K,) -> one shared grid for whole batch
cell_ids is 2D (B, K) -> per-sample grids, same length; returns (B, Co, K)
cell_ids is list/tuple -> per-sample grids (var-length allowed)
im: list/tuple of Tensors, each (Ci, K_b) with cell_ids list/tuple
Notes
- Kernel shapes accepted:
single/multi shared: (Ci, Co_g, P)
per-gauge kernels: (G, Ci, Co_g, P)
The low-level _Convol_Torch will choose between apply/apply_multi depending on the class state (G>1 and multi-bind present).
- make_matrix(kernel: torch.Tensor, cell_ids=None, *, return_sparse_tensor: bool = False, chunk_k: int = 4096)[source]#
Build the sparse COO matrix M such that applying M to vec(data) reproduces the spherical convolution performed by Convol_torch/_Convol_Torch.
- Supports single- and multi-gauge:
kernel shape (Ci, Co_g, P) -> shared across G gauges, output Co = G*Co_g
kernel shape (G, Ci, Co_g, P) -> per-gauge kernels, same output Co = G*Co_g
- Parameters:
kernel (
torch.Tensor) – (Ci, Co_g, P) or (G, Ci, Co_g, P) with P = kernel_sz**2. Must be on the device/dtype where you want the resulting matrix.cell_ids (
array-likeofshape (K,)ortorch.Tensor, optional) – Target pixel IDs (NESTED if self.nest=True). If None, uses the grid already cached in the class (fast path). If provided, we prepare geometry & sparse binding for these ids.return_sparse_tensor (
bool, defaultFalse) – If True, return a coalesced torch.sparse_coo_tensor of shape (Co*K, Ci*K). Else, return (weights, indices, shape) where:indices is a LongTensor of shape (2, nnz) with [row; col]
weights is a Tensor of shape (nnz,)
shape is the (rows, cols) tuple
chunk_k (
int, default4096) – Chunk size over target pixels to limit peak memory.
- Returns:
If return_sparse_tensor– M : torch.sparse_coo_tensor of shape (Co*K, Ci*K), coalescedelse– weights : torch.Tensor (nnz,) indices : torch.LongTensor (2, nnz) with [row; col] shape : tuple[int, int] (Co*K, Ci*K)
Notes
The resulting matrix implements the same interpolation-and-mixing as the GPU path (gather 4 neighbors -> normalize -> apply spatial+channel kernel), and matches the output of Convol_torch for the same (kernel, cell_ids).
For multi-gauge, rows are grouped as concatenated gauges: first all Co_g channels for gauge 0 over all K, then gauge 1, etc.