HealPixConv — API reference#
Parameters, methods, tensor shapes and cost of HealPixConv. The guide is
HealPixConv — gauge-equivariant convolution; the geometry behind it is HealPixConv — how the geometry is built.
The layer#
Constructor parameters#
HealPixConv(
level,
in_channels,
out_channels,
kernel_sz = 3,
n_gauges = 1,
gauge_type = "phi",
singularity_lonlat = None,
ref_direction = None,
cell_ids = None,
nest = True,
use_norm = False,
device = None,
ellipsoid = "WGS84",
dtype = torch.float32,
)
Parameter |
Type |
Default |
Description |
|---|---|---|---|
|
|
— |
Grid4Earth/HEALPix level, integer ≥ 0. Internally, |
|
|
— |
Number of input feature channels C_in. |
|
|
— |
Output channels per gauge C_out. Total output channels = G × C_out. |
|
|
|
Stencil side length. Must be a positive odd integer. P = kernel_sz². |
|
|
|
Number of gauge orientations G. Gauge g rotates the stencil by g·π/G. |
|
|
|
One of |
|
|
|
Geographic coordinates of the desired singularity point(s) in degrees. For |
|
|
|
Low-level alternative: raw unit reference vector(s). Shape |
|
|
|
NESTED pixel indices for a partial-sky patch. |
|
|
|
Pixel ordering of the input map. |
|
|
|
Apply GroupNorm + ReLU after the convolution. |
|
|
|
Target device. Defaults to CUDA if available, else CPU. |
|
|
|
Reference ellipsoid for healpix_geo coordinate conversions. |
|
|
|
Floating-point precision for all buffers and parameters. |
Raises:
ValueError— iflevelis not a non-negative integer.ValueError— ifkernel_szis not a positive odd integer.ValueError— ifgauge_typeis not one of the four valid strings.ValueError— ifcell_idscontains identifiers outside the selected level’s valid pixel range.ValueError— ifsingularity_lonlatis used with a gauge type that does not support it, or if the wrong number of pairs is provided for"two_ref".
forward(x)#
Apply the gauge-equivariant spherical convolution.
y = conv(x)
Parameters:
Parameter |
Type |
Shape |
Description |
|---|---|---|---|
|
|
|
Input map(s) at the HEALPix resolution of this layer. N must equal |
Returns:
Name |
Type |
Shape |
Description |
|---|---|---|---|
|
same type as |
|
Convolved output. Output type and number of dimensions match the input. |
Raises:
ValueError— ifxhas the wrong number of channels or pixels.
set_kernel(W, bias=None, requires_grad=False)#
Replace the learnable kernel with a fixed (or re-initialised) array.
Returns self for chaining.
conv.set_kernel(W, bias=None, requires_grad=False)
Parameter |
Type |
Shape |
Description |
|---|---|---|---|
|
|
|
Kernel weights. The first form broadcasts the same kernel over all G gauges. |
|
|
|
Bias vector. |
|
|
— |
If |
Example — isotropic Gaussian smoothing (kernel_sz=3):
W = np.zeros((1, 1, 9), dtype=np.float32)
W[0, 0, 4] = 0.5 # centre point (index 4 in a 3×3 grid)
W[0, 0, [0,1,2,3,5,6,7,8]] = 0.5 / 8 # 8 neighbours equally weighted
conv.set_kernel(W)
singularity_info()#
Return a human-readable string describing where the gauge singularities are placed.
print(conv.singularity_info())
Example output for "two_ref":
gauge_type='two_ref':
singularity 1 : lon=-55.00° lat=-10.00° (index +1, user-defined)
singularity 1b : lon=+125.00° lat=+10.00° (index +1, antipode of 1)
singularity 2 : lon=+20.00° lat=+10.00° (index +1, user-defined)
singularity 2b : lon=+200.00° lat=-10.00° (index +1, antipode of 2)
N/S poles : index -1 each (side-effect, keep outside domain of interest)
ref_directions : r1=[...]
r2=[...]
Tensor shapes#
Symbol |
Meaning |
|---|---|
B |
Batch size |
C_in |
Input channels |
C_out |
Output channels per gauge |
G |
Number of gauges ( |
K |
Number of pixels ( |
P |
Stencil points ( |
Buffer / tensor |
Shape |
Description |
|---|---|---|
|
|
Column indices into the sorted input for each bilinear neighbour |
|
|
Renormalised bilinear weights |
|
|
Index that sorts pixel ids ascending |
|
|
Inverse permutation to restore original order |
|
|
Learned kernel (nn.Parameter) |
|
|
Learned bias (nn.Parameter) |
Cost#
Constructor (one-time cost)#
The geometry precomputation scales as O(K · G · P) and is dominated by the
healpix_geo coordinate lookup and the get_interp_weights call. For
typical configurations (nside=64, G=4, kernel_sz=3):
Operation |
K·G·P entries |
Approx. time |
|---|---|---|
|
49 152 |
< 0.1 s |
|
49 152 × 4 × 9 = 1.77 M |
~0.5 s |
|
1.77 M searchsorted |
~0.3 s |
Forward pass (per batch)#
The forward is a single index_select over [G · 4 · K · P] entries,
followed by a weighted sum and one einsum. On GPU (A100) with batch size
8, nside=64, G=4, C_in=16, C_out=32: typically under 5 ms.
Memory#
The dominant buffers are _pos_safe and _w_norm, each of shape
[G, 4, K·P]. For nside=128, G=4, kernel_sz=5 (P=25):
K = 12 × 128² = 196 608
Buffer size = 4 × 4 × 196 608 × 25 × 4 bytes (float32) ≈ 750 MB
For very large nside, consider reducing G or kernel_sz, or using
torch.float16 for the buffers.