Skip to content

hilbertsfc

Core APIs

Hilbert

Morton

Kernel Accessors

Hilbert

Morton

Cache Management

hilbertsfc

Hilbert space-filling curve kernels.

The top-level hilbertsfc package exposes NumPy/Numba-backed 2D/3D Hilbert encode/decode functions, plus matching Morton/z-order helpers, kernel accessors, and cache management utilities.

For GPU acceleration and torch.Tensor inputs, use the optional PyTorch frontend: hilbertsfc.torch.

Functions

hilbert_encode_2d

hilbert_encode_2d(
    x: IntScalar | IntArray,
    y: IntScalar | IntArray,
    *,
    nbits: int | None = None,
    out: IntArray | None = None,
    parallel: bool = False,
) -> int | IntArray

Encode 2D integer coordinates to Hilbert indices.

This function supports both scalar and array inputs:

  • Scalar mode: if x and y are scalar integers, returns a Python int.
  • Array mode: if x and y are NumPy integer arrays, returns an array of unsigned indices with the same shape and supports out=.

Parameters:

Name Type Description Default
x IntScalar | IntArray

Coordinates to encode.

  • Scalar mode: Python int or NumPy integer scalar.
  • Array mode: NumPy integer arrays of identical shape.
required
y IntScalar | IntArray

Coordinates to encode.

  • Scalar mode: Python int or NumPy integer scalar.
  • Array mode: NumPy integer arrays of identical shape.
required
nbits int | None

Number of bits per coordinate axis. This defines a coordinate domain of [0, 2**nbits) on each axis. For inputs outside that domain, only the low nbits bits of each coordinate are used.

Must satisfy 1 <= nbits <= 32. If provided, it must also fit within the usable bits of the coordinate dtype.

If None:

  • Array mode: inferred from the coordinate dtype using its usable bit width, capped at 32. For example, uint16 -> 16, int16 -> 15 (sign bit excluded), and uint64/int64 -> 32.
  • Scalar mode: defaults to 32.

For best performance and tighter output dtypes, pass the smallest value that covers the input coordinate range.

None
out IntArray | None

Optional output array for array mode.

Must have the same shape as x and y and an unsigned integer dtype wide enough to hold 2 * nbits bits.

Not allowed in scalar mode.

None
parallel bool

Controls whether the array-mode Numba kernel may execute in parallel.

In scalar mode, this argument is accepted for API consistency but has no effect. If True, a UserWarning is emitted.

The number of threads can be controlled with NUMBA_NUM_THREADS or numba.set_num_threads().

False

Returns:

Type Description
int | IntArray

Hilbert index or indices.

  • Scalar mode: the Hilbert index as a Python int.
  • Array mode: an array of unsigned indices.

If out is not provided in array mode, the output dtype is the smallest unsigned integer type that can hold 2 * nbits bits.

Raises:

Type Description
TypeError

If x and y are not both scalars or not both arrays, if a non-integer input is provided, or if out is used in scalar mode.

ValueError

If nbits is invalid, if array inputs have mismatched shapes, or if out has the wrong shape or an insufficient dtype.

hilbert_decode_2d

hilbert_decode_2d(
    index: IntScalar | IntArray,
    *,
    nbits: int | None = None,
    out_x: IntArray | None = None,
    out_y: IntArray | None = None,
    parallel: bool = False,
) -> tuple[int, int] | tuple[IntArray, IntArray]

Decode Hilbert indices to 2D integer coordinates.

This function supports both scalar and array inputs:

  • Scalar mode: if index is a scalar integer, returns (x, y) as Python int values.
  • Array mode: if index is a NumPy integer array, returns coordinate arrays with the same shape and supports out_x= / out_y=.

Parameters:

Name Type Description Default
index IntScalar | IntArray

Hilbert index or indices to decode.

  • Scalar mode: Python int or NumPy integer scalar.
  • Array mode: NumPy integer array.
required
nbits int | None

Number of bits per coordinate axis. This defines a coordinate domain of [0, 2**nbits) on each axis and a Hilbert index range of [0, 2**(2 * nbits)). For indices outside that range, only the low 2 * nbits bits are used.

Must satisfy 1 <= nbits <= 32. If provided, it must also fit within the usable bits of the index dtype.

If None:

  • Array mode: inferred from the index dtype as half its usable bit width, capped at 32. For example, uint16 -> 8, uint64 -> 32, and int64 -> 31 (sign bit excluded).
  • Scalar mode: defaults to 32.

For best performance and tighter output dtypes, pass the smallest value that covers the input index range.

None
out_x IntArray | None

Optional output coordinate arrays for array mode. Either provide both or neither.

Each must have the same shape as index and an unsigned integer dtype wide enough to hold nbits bits.

Not allowed in scalar mode.

None
out_y IntArray | None

Optional output coordinate arrays for array mode. Either provide both or neither.

Each must have the same shape as index and an unsigned integer dtype wide enough to hold nbits bits.

Not allowed in scalar mode.

None
parallel bool

Controls whether the array-mode Numba kernel may execute in parallel.

In scalar mode, this argument is accepted for API consistency but has no effect. If True, a UserWarning is emitted.

The number of threads can be controlled with NUMBA_NUM_THREADS or numba.set_num_threads().

False

Returns:

Type Description
tuple[int, int] | tuple[IntArray, IntArray]

Decoded coordinates.

  • Scalar mode: (x, y) as Python int values.
  • Array mode: (x, y) as unsigned integer arrays.

If out_x and out_y are not provided in array mode, each result dtype is the smallest unsigned integer type that can hold nbits bits.

Raises:

Type Description
TypeError

If a non-integer input is provided or if output buffers are used in scalar mode.

ValueError

If nbits is invalid, if it does not fit in the index or output dtypes, or if output buffers are inconsistent or have incorrect shapes.

hilbert_encode_3d

hilbert_encode_3d(
    x: IntScalar | IntArray,
    y: IntScalar | IntArray,
    z: IntScalar | IntArray,
    *,
    nbits: int | None = None,
    out: IntArray | None = None,
    parallel: bool = False,
) -> int | IntArray

Encode 3D integer coordinates to Hilbert indices.

This function supports both scalar and array inputs:

  • Scalar mode: if x, y, and z are scalar integers, returns a Python int.
  • Array mode: if x, y, and z are NumPy integer arrays, returns an array of unsigned indices with the same shape and supports out=.

Parameters:

Name Type Description Default
x IntScalar | IntArray

Coordinates to encode.

  • Scalar mode: Python int or NumPy integer scalar.
  • Array mode: NumPy integer arrays of identical shape.
required
y IntScalar | IntArray

Coordinates to encode.

  • Scalar mode: Python int or NumPy integer scalar.
  • Array mode: NumPy integer arrays of identical shape.
required
z IntScalar | IntArray

Coordinates to encode.

  • Scalar mode: Python int or NumPy integer scalar.
  • Array mode: NumPy integer arrays of identical shape.
required
nbits int | None

Number of bits per coordinate axis. This defines a coordinate domain of [0, 2**nbits) on each axis. For inputs outside that domain, only the low nbits bits of each coordinate are used.

Must satisfy 1 <= nbits <= 21. If provided, it must also fit within the usable bits of the coordinate dtype.

If None:

  • Array mode: inferred from the coordinate dtype using its usable bit width, capped at 21. For example, uint16 -> 16, int16 -> 15 (sign bit excluded), and uint64/int64 -> 21.
  • Scalar mode: defaults to 21.

For best performance and tighter output dtypes, pass the smallest value that covers the input coordinate range.

None
out IntArray | None

Optional output array for array mode.

Must have the same shape as x, y, and z and an unsigned integer dtype wide enough to hold 3 * nbits bits.

Not allowed in scalar mode.

None
parallel bool

Controls whether the array-mode Numba kernel may execute in parallel.

In scalar mode, this argument is accepted for API consistency but has no effect. If True, a UserWarning is emitted.

The number of threads can be controlled with NUMBA_NUM_THREADS or numba.set_num_threads().

False

Returns:

Type Description
int | IntArray

Hilbert index or indices.

  • Scalar mode: the Hilbert index as a Python int.
  • Array mode: an array of unsigned indices.

If out is not provided in array mode, the output dtype is the smallest unsigned integer type that can hold 3 * nbits bits.

Raises:

Type Description
TypeError

If x, y, and z are not all scalars or not all arrays, if a non-integer input is provided, or if out is used in scalar mode.

ValueError

If nbits is invalid, if array inputs have mismatched shapes, or if out has the wrong shape or an insufficient dtype.

hilbert_decode_3d

hilbert_decode_3d(
    index: IntScalar | IntArray,
    *,
    nbits: int | None = None,
    out_x: IntArray | None = None,
    out_y: IntArray | None = None,
    out_z: IntArray | None = None,
    parallel: bool = False,
) -> (
    tuple[int, int, int]
    | tuple[IntArray, IntArray, IntArray]
)

Decode Hilbert indices to 3D integer coordinates.

This function supports both scalar and array inputs:

  • Scalar mode: if index is a scalar integer, returns (x, y, z) as Python int values.
  • Array mode: if index is a NumPy integer array, returns coordinate arrays with the same shape and supports out_x=, out_y=, and out_z=.

Parameters:

Name Type Description Default
index IntScalar | IntArray

Hilbert index or indices to decode.

  • Scalar mode: Python int or NumPy integer scalar.
  • Array mode: NumPy integer array.
required
nbits int | None

Number of bits per coordinate axis. This defines a coordinate domain of [0, 2**nbits) on each axis and a Hilbert index range of [0, 2**(3 * nbits)). For indices outside that range, only the low 3 * nbits bits are used.

Must satisfy 1 <= nbits <= 21. If provided, it must also fit within the usable bits of the index dtype.

If None:

  • Array mode: inferred from the index dtype as one third of its usable bit width, capped at 21. For example, uint16 -> 5, and int64 -> 21.
  • Scalar mode: defaults to 21.

For best performance and tighter output dtypes, pass the smallest value that covers the input index range.

None
out_x IntArray | None

Optional coordinate output arrays for array mode. Either provide all three or none.

Each must have the same shape as index and an unsigned integer dtype wide enough to hold nbits bits.

Not allowed in scalar mode.

None
out_y IntArray | None

Optional coordinate output arrays for array mode. Either provide all three or none.

Each must have the same shape as index and an unsigned integer dtype wide enough to hold nbits bits.

Not allowed in scalar mode.

None
out_z IntArray | None

Optional coordinate output arrays for array mode. Either provide all three or none.

Each must have the same shape as index and an unsigned integer dtype wide enough to hold nbits bits.

Not allowed in scalar mode.

None
parallel bool

Controls whether the array-mode Numba kernel may execute in parallel.

In scalar mode, this argument is accepted for API consistency but has no effect. If True, a UserWarning is emitted.

The number of threads can be controlled with NUMBA_NUM_THREADS or numba.set_num_threads().

False

Returns:

Type Description
tuple[int, int, int] | tuple[IntArray, IntArray, IntArray]

Decoded coordinates.

  • Scalar mode: (x, y, z) as Python int values.
  • Array mode: (x, y, z) as unsigned integer arrays.

If out_x, out_y, and out_z are not provided in array mode, each result dtype is the smallest unsigned integer type that can hold nbits bits.

Raises:

Type Description
TypeError

If a non-integer input is provided or if output buffers are used in scalar mode.

ValueError

If nbits is invalid, if it does not fit in the index or output dtypes, or if output buffers are inconsistent or have incorrect shapes.

morton_encode_2d

morton_encode_2d(
    x: IntScalar | IntArray,
    y: IntScalar | IntArray,
    *,
    nbits: int | None = None,
    out: IntArray | None = None,
    parallel: bool = False,
) -> int | IntArray

Encode 2D integer coordinates to Morton (Z-order) indices.

API semantics (parameters, returns, errors) match hilbert_encode_2d.

This function supports both scalar and array inputs:

  • Scalar mode: if x and y are scalar integers, returns a Python int.
  • Array mode: if x and y are NumPy integer arrays, returns an array of unsigned indices with the same shape and supports out=.

morton_decode_2d

morton_decode_2d(
    index: IntScalar | IntArray,
    *,
    nbits: int | None = None,
    out_x: IntArray | None = None,
    out_y: IntArray | None = None,
    parallel: bool = False,
) -> tuple[int, int] | tuple[IntArray, IntArray]

Decode Morton (Z-order) indices to 2D integer coordinates.

API semantics (parameters, returns, errors) match hilbert_decode_2d.

This function supports both scalar and array inputs:

  • Scalar mode: if index is a scalar integer, returns (x, y) as Python int values.
  • Array mode: if index is a NumPy integer array, returns coordinate arrays with the same shape and supports out_x= / out_y=.

morton_encode_3d

morton_encode_3d(
    x: IntScalar | IntArray,
    y: IntScalar | IntArray,
    z: IntScalar | IntArray,
    *,
    nbits: int | None = None,
    out: IntArray | None = None,
    parallel: bool = False,
) -> int | IntArray

Encode 3D integer coordinates to Morton (Z-order) indices.

API semantics (parameters, returns, errors) match hilbert_encode_3d.

This function supports both scalar and array inputs:

  • Scalar mode: if x, y, and z are scalar integers, returns a Python int.
  • Array mode: if x, y, and z are NumPy integer arrays, returns an array of unsigned indices with the same shape and supports out=.

morton_decode_3d

morton_decode_3d(
    index: IntScalar | IntArray,
    *,
    nbits: int | None = None,
    out_x: IntArray | None = None,
    out_y: IntArray | None = None,
    out_z: IntArray | None = None,
    parallel: bool = False,
) -> (
    tuple[int, int, int]
    | tuple[IntArray, IntArray, IntArray]
)

Decode Morton (Z-order) indices to 3D integer coordinates.

API semantics (parameters, returns, errors) match hilbert_decode_3d.

This function supports both scalar and array inputs:

  • Scalar mode: if index is a scalar integer, returns (x, y, z) as Python int values.
  • Array mode: if index is a NumPy integer array, returns coordinate arrays with the same shape and supports out_x=, out_y=, and out_z=.

get_hilbert_encode_2d_kernel

get_hilbert_encode_2d_kernel(
    nbits: int, *, tile_nbits: TileNBits2D | None = None
) -> Callable[[IntScalar, IntScalar], int]

Return a Numba-compiled scalar 2D Hilbert encoder.

This is the low-level kernel used by hilbert_encode_2d in scalar mode. It is intended for fusing into your own @numba.njit loops.

Parameters:

Name Type Description Default
nbits int

Number of coordinate bits (grid domain is [0, 2**nbits) per axis).

required
tile_nbits TileNBits2D | None

Select the tile size (in bits) / kernel variant.

  • None (default): auto-select (4 for nbits <= 4 or nbits == 8, else 7).

  • 7: uses 7-bit compacted LUTs (128 KiB).

  • 4: uses 4-bit compacted LUTs (2 KiB).

The 7-bit variant uses a larger LUT and is generally faster. The 4-bit variant uses a smaller LUT, which may be preferable in cache-intensive kernels.

None

Returns:

Type Description
callable

A Numba-compiled function with signature (x: int, y: int) -> int.

get_hilbert_decode_2d_kernel

get_hilbert_decode_2d_kernel(
    nbits: int, *, tile_nbits: TileNBits2D | None = None
) -> Callable[[IntScalar], tuple[int, int]]

Return a Numba-compiled scalar 2D Hilbert decoder.

This is the low-level kernel used by hilbert_decode_2d in scalar mode. It is intended for fusing into your own @numba.njit loops.

Parameters:

Name Type Description Default
nbits int

Number of coordinate bits (grid domain is [0, 2**nbits) per axis).

required
tile_nbits TileNBits2D | None

Select the tile size (in bits) / kernel variant.

  • None (default): auto-select (4 for nbits <= 4 or nbits == 8, else 7).

  • 7: uses 7-bit compacted LUTs (128 KiB).

  • 4: uses 4-bit compacted LUTs (2 KiB).

The 7-bit variant uses a larger LUT and is generally faster. The 4-bit variant uses a smaller LUT, which may be preferable in cache-intensive kernels.

None

Returns:

Type Description
callable

A Numba-compiled function with signature (index: int) -> (x: int, y: int).

get_hilbert_encode_3d_kernel

get_hilbert_encode_3d_kernel(
    nbits: int, *, lut_dtype: LutUIntDTypeLike = uint16
) -> Callable[[IntScalar, IntScalar, IntScalar], IntScalar]

Return a Numba-compiled scalar 3D Hilbert encoder.

This is the low-level kernel used by hilbert_encode_3d in scalar mode and is intended for fusing into your own @numba.njit loops.

Parameters:

Name Type Description Default
nbits int

Number of coordinate bits (grid domain is [0, 2**nbits) per axis).

required
lut_dtype LutUIntDTypeLike

Element dtype used for the internal lookup tables.

Default is uint16 (smallest; 3 KiB LUT footprint). When fusing into a cache-intensive kernel, keeping the LUT small can help.

For best throughput, it is usually better to match lut_dtype to your index dtype (uint16/uint32/uint64), which increases LUT size (6 KiB for uint32, 12 KiB for uint64) but reduces widening. In isolation, even the larger LUTs typically fit comfortably within the per-core L1 data cache of modern CPUs.

uint16

Returns:

Type Description
callable

A Numba-compiled function with signature (x: int, y: int, z: int) -> int.

get_hilbert_decode_3d_kernel

get_hilbert_decode_3d_kernel(
    nbits: int, *, lut_dtype: LutUIntDTypeLike = uint16
) -> Callable[[IntScalar], tuple[int, int, int]]

Return a Numba-compiled scalar 3D Hilbert decoder.

This is the low-level kernel used by hilbert_decode_3d in scalar mode and is intended for fusing into your own @numba.njit loops.

Parameters:

Name Type Description Default
nbits int

Number of coordinate bits (grid domain is [0, 2**nbits) per axis).

required
lut_dtype LutUIntDTypeLike

Element dtype used for the internal lookup tables.

See get_hilbert_encode_3d_kernel for the performance tradeoff.

uint16

Returns:

Type Description
callable

A Numba-compiled function with signature (index: int) -> (x: int, y: int, z: int).

get_morton_encode_2d_kernel

get_morton_encode_2d_kernel(
    nbits: int,
) -> Callable[[IntScalar, IntScalar], int]

Return a Numba-compiled scalar 2D Morton encoder.

This is the low-level kernel used by morton_encode_2d in scalar mode. It is intended for fusing into your own @numba.njit loops.

Parameters:

Name Type Description Default
nbits int

Number of coordinate bits (grid domain is [0, 2**nbits) per axis).

required

Returns:

Type Description
callable

A Numba-compiled function with signature (x: int, y: int) -> int.

get_morton_decode_2d_kernel

get_morton_decode_2d_kernel(
    nbits: int,
) -> Callable[[IntScalar], tuple[int, int]]

Return a Numba-compiled scalar 2D Morton decoder.

This is the low-level kernel used by morton_decode_2d in scalar mode. It is intended for fusing into your own @numba.njit loops.

Parameters:

Name Type Description Default
nbits int

Number of coordinate bits (grid domain is [0, 2**nbits) per axis).

required

Returns:

Type Description
callable

A Numba-compiled function with signature (index: int) -> (x: int, y: int).

get_morton_encode_3d_kernel

get_morton_encode_3d_kernel(
    nbits: int,
) -> Callable[[IntScalar, IntScalar, IntScalar], IntScalar]

Return a Numba-compiled scalar 3D Morton encoder.

This is the low-level kernel used by morton_encode_3d in scalar mode. It is intended for fusing into your own @numba.njit loops.

Parameters:

Name Type Description Default
nbits int

Number of coordinate bits (grid domain is [0, 2**nbits) per axis).

required

Returns:

Type Description
callable

A Numba-compiled function with signature (x: int, y: int, z: int) -> int.

get_morton_decode_3d_kernel

get_morton_decode_3d_kernel(
    nbits: int,
) -> Callable[[IntScalar], tuple[int, int, int]]

Return a Numba-compiled scalar 3D Morton decoder.

This is the low-level kernel used by morton_decode_3d in scalar mode. It is intended for fusing into your own @numba.njit loops.

Parameters:

Name Type Description Default
nbits int

Number of coordinate bits (grid domain is [0, 2**nbits) per axis).

required

Returns:

Type Description
callable

A Numba-compiled function with signature (index: int) -> (x: int, y: int, z: int).

clear_lut_caches

clear_lut_caches() -> None

Clear all registered LUT caches.

Notes

This does not clear torch-side device LUT caches; for those, see hilbertsfc.torch.clear_torch_lut_caches.

clear_kernel_caches

clear_kernel_caches() -> None

Clear all registered kernel builder caches.

clear_all_caches

clear_all_caches() -> None

Clear LUT caches and kernel builder caches.

Notes

This does not clear torch-side device LUT caches; for those, see hilbertsfc.torch.clear_torch_lut_caches.