numba_vulkan.narrowing#

Running kernels on devices without 64-bit floats or integers.

Numba types Python literals as float64 and int64 and does all index arithmetic in int64, so almost every kernel uses 64-bit types, which are optional features of a Vulkan device. For a device that lacks them, a kernel is compiled in a narrow Mode:

  • with floats, math functions called with float64 values are evaluated by their float32 versions (see numba_vulkan.libclc.call), and all remaining double values in the optimised LLVM IR become float;

  • with ints, all i64 values in the LLVM IR become i32.

The values a kernel computes with are then 32 bits wide whatever Numba typed them as, and buffers of float64 or int64 elements hold 32-bit elements, which the host converts to and from (see numba_vulkan.dispatcher). Code that depends on the width, such as bit manipulation of float64 values or shifts by 32 and more, is detected and rejected rather than miscompiled.

Attributes#

Classes#

Mode

How a kernel is compiled for the features of a device.

Functions#

convert(values, dtype[, check])

Convert host data to the element type a buffer holds.

using(mode)

Compile in the given mode within the with block.

to_single(builder, value)

Convert a double to float in a kernel compiled without float64.

to_double(builder, value)

Convert a float back to double; the inverse of to_single.

narrow_ir(text, mode)

Replace 64-bit types in LLVM IR by their 32-bit counterparts.

stored_dtype(dtype, mode)

Element type that a buffer holds for arrays of dtype.

Module Contents#

numba_vulkan.narrowing.NARROW_INTS#
numba_vulkan.narrowing.WARNINGS#
numba_vulkan.narrowing.convert(values, dtype, check=True)#

Convert host data to the element type a buffer holds.

Parameters:
  • values (numpy.ndarray) – The data.

  • dtype (numpy.dtype) – The type to convert to, from stored_dtype.

  • check (bool) – Whether to check that integers fit. Arrays that a kernel only writes to may hold anything, as from np.empty.

Returns:

A C-contiguous array of dtype; values itself if it is one.

Return type:

numpy.ndarray

Raises:

OverflowError – If integers do not fit into the narrower type. Wrapping them around would silently change the data.

class numba_vulkan.narrowing.Mode#

How a kernel is compiled for the features of a device.

Variables:
  • floats (bool) – Whether float64 is narrowed to float32.

  • ints (bool) – Whether int64 is narrowed to int32.

  • float_atomics (bool) – Whether float32 atomic additions may use the device’s native instruction (VK_EXT_shader_atomic_float) instead of a compare-and-swap loop.

  • soft_fma (bool) – Whether fused multiply-add is computed in software, because the device does not fuse it (see numba_vulkan.probes).

  • soft_rounding (bool) – Whether float64 truncation and rounding to even are computed from floor, because the device gets them wrong (llvmpipe).

floats: bool = False#
ints: bool = False#
float_atomics: bool = False#
soft_fma: bool = False#
soft_rounding: bool = False#
numba_vulkan.narrowing.current#
numba_vulkan.narrowing.using(mode)#

Compile in the given mode within the with block.

Parameters:

mode (Mode) – The mode to make current.

numba_vulkan.narrowing.to_single(builder, value)#

Convert a double to float in a kernel compiled without float64.

In such a kernel every double ends up as a float, so the conversion does nothing in the end. It is emitted as a call to a placeholder that narrow_ir removes, and not as fptrunc, because LLVM would otherwise rewrite code working on the float into code working on the bits of the double, which narrowing cannot follow.

Parameters:
  • builder (llvmlite.ir.IRBuilder) – Builder positioned where the code is emitted.

  • value (llvmlite.ir.Value) – A float value.

Returns:

The value as float; value itself if it is one already.

Return type:

llvmlite.ir.Value

numba_vulkan.narrowing.to_double(builder, value)#

Convert a float back to double; the inverse of to_single.

numba_vulkan.narrowing.narrow_ir(text, mode)#

Replace 64-bit types in LLVM IR by their 32-bit counterparts.

Parameters:
  • text (str) – Textual LLVM IR of an optimised kernel.

  • mode (Mode) – Which types to narrow.

Returns:

The rewritten IR; text itself if the mode narrows nothing.

Return type:

str

Raises:

VulkanUnsupportedError – If the code depends on the width of the types: it reinterprets float64 values as integers, shifts 64-bit integers by 32 bits or more, or contains integer constants that do not fit in 32 bits.

numba_vulkan.narrowing.stored_dtype(dtype, mode)#

Element type that a buffer holds for arrays of dtype.

Parameters:
  • dtype (numpy.dtype) – Element type of the array on the host.

  • mode (Mode) – Mode of the kernel, or of the device holding the buffer.

Returns:

int32 for booleans (SPIR-V has no storable bool), the 32-bit counterpart of a 64-bit type that the mode narrows, and dtype otherwise. For a structured dtype, the same with the type of each field narrowed (booleans stay single bytes in records).

Return type:

numpy.dtype