code wiki / (root) / nx_upsample.nx

nx_upsample.nx

buildroot/runtime/nx_upsample.nx

13845 B355 linesdepth 4pulls 5 transitivereach 1 importersview sourcekind tool
docsdependenciesstructsconstsfunctions

about

nx_upsample.nx -- 2x upsample for 4D feature maps. Closes the missing-dep gap for VAE decoder + UNet up-blocks. Modern image-gen architectures use 2x nearest-neighbor or 2x bilinear upsample inside the decoder stages: VAE decoder: 4 stages of 2x upsample (8x total = 64x64 latent -> 512x512 image) UNet up-path: 2x upsample at each scale level Super-resolution networks: 2x or 4x upsample L3 canonical primitive composing: NxTensor (L1, 4D NCHW input/output) nx_loop.LoopVerdict (control) -- no other deps; pure pixel-replication / linear-interp math ===== Tensor layout ============================================= Input: [N, C, H, W] NCHW Q10 Output: [N, C, 2H, 2W] 2x upscaled in spatial dims; channels unchanged ===== Filter modes ============================================== NX_UP_NEAREST -- each output pixel = nearest input pixel. Blocky but cheap. Common in VAE decoder when followed by a 3x3 conv that smooths the artifacts. NX_UP_BILINEAR -- 4-tap bilinear from the 4 nearest input pixels. Smoother; slightly more expensive. ===== Pixel-center convention =================================== Output pixel (oy, ox) maps to input pixel at: iy = (oy + 0.5) / 2 - 0.5 ix = (ox + 0.5) / 2 - 0.5 This is the "align_corners=False" convention from PyTorch -- the standard for VAE-class upsampling. In Q10 fixed-point: iy_q10 = (oy + 1) * Q10 / 2 - Q10 / 2 ; if (... ) ... simplifies

dependencies 4 imports · 1 importers

nx_syscalls.nx nx_tier.nx nx_loop.nx nx_tensor.nx nx_upsample.nx nx_vae_decode_stage.nx

imports: nx_syscalls.nxnx_tier.nxnx_loop.nxnx_tensor.nx

imported by: nx_vae_decode_stage.nx

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main sys_mmap nx_t_alloc nx_dt_is_valid nx_dt_element_bytes sys_mmap ↻ nx_t_compute_strides_rowma nx_upsample_2x nx_t_is_contiguous _up_nearest _up_bilinear nx_up_verdict_is_valid nx_up_filter_is_valid

structs

none

consts

60const NX_UP_Q10: nx_int = 1024
64const NX_UP_NEAREST: nx_int = 0
65const NX_UP_BILINEAR: nx_int = 1
66const NX_UP_FILTER_N: nx_int = 2
76const NX_UP_OK: nx_int = 0
77const NX_UP_ERR_BAD_DTYPE: nx_int = 1
78const NX_UP_ERR_BAD_NDIM: nx_int = 2
79const NX_UP_ERR_SHAPE_MISMATCH: nx_int = 3
80const NX_UP_ERR_NOT_CONTIGUOUS: nx_int = 4
81const NX_UP_ERR_BAD_FILTER: nx_int = 5
82const NX_UP_N_VERDICTS: nx_int = 6

functions

68func nx_up_filter_is_valid(k: nx_int) -> nx_int
called by 1: main
84func nx_up_verdict_is_valid(v: nx_int) -> nx_int
called by 1: main
92func _up_nearest(input: *NxTensor, output: *NxTensor) -> nx_int
called by 1: nx_upsample_2x
162func _up_bilinear(input: *NxTensor, output: *NxTensor) -> nx_int
called by 1: nx_upsample_2x
254func nx_upsample_2x(input: *NxTensor, output: *NxTensor, filter: nx_int) -> nx_int
286func main() -> i64