numba_vulkan.buffers#
Access to Vulkan storage buffers from LLVM IR.
Shaders have no general pointers, and LLVM’s optimiser readily creates
pointer phis and selects that SPIR-V cannot express. Buffer accesses are
therefore emitted as calls to opaque placeholder functions that take a
binding and an element index, and only expand_buffer_access() turns
them into real loads and stores, after all optimisation has happened.
Attributes#
Functions#
|
Give the print buffer of a kernel its binding. |
|
Binding that stands for a NumPy array used as a global constant. |
|
The constant arrays that LLVM IR refers to, in order of appearance. |
|
Contents of the constant array behind a placeholder binding. |
|
Give the constant arrays of a kernel bindings after its arguments. |
|
Descriptor binding of a kernel argument. |
|
Read one element of a storage buffer. |
|
Write one element of a storage buffer. |
|
Apply an atomic read-modify-write to one element of a buffer. |
|
Atomically replace one 32-bit element if it has the expected value. |
|
Wait until all invocations of the workgroup arrive here. |
|
Replace the placeholder calls in LLVM IR by real buffer accesses. |
Module Contents#
- numba_vulkan.buffers.i32#
- numba_vulkan.buffers.META_BINDING = 0#
- numba_vulkan.buffers.STATUS_INDEX = 0#
- numba_vulkan.buffers.PRINT_BINDING = 1048575#
- numba_vulkan.buffers.PUSH_BINDING = 1048574#
- numba_vulkan.buffers.PUSH_BLOCK = 'nv.args'#
- numba_vulkan.buffers.print_formats#
- numba_vulkan.buffers.renumber_print(text, binding)#
Give the print buffer of a kernel its binding.
- numba_vulkan.buffers.CONSTANT_BASE = 1048576#
- numba_vulkan.buffers.SHARED_BASE = 16777216#
- numba_vulkan.buffers.LOCAL_BASE = 33554432#
- numba_vulkan.buffers.constant_binding(array)#
Binding that stands for a NumPy array used as a global constant.
The array is copied when it is first seen: like Numba on the CPU, the compiled code keeps the values the array had at that time.
- Parameters:
array (numpy.ndarray) – The array.
- Returns:
A binding at or above CONSTANT_BASE, the same for every use of the same array object.
- Return type:
- numba_vulkan.buffers.constant_order(text)#
The constant arrays that LLVM IR refers to, in order of appearance.
- numba_vulkan.buffers.constant_data(binding)#
Contents of the constant array behind a placeholder binding.
- Parameters:
binding (int) – A binding returned by constant_binding.
- Returns:
The values the array had when it was first seen.
- Return type:
- numba_vulkan.buffers.renumber_constants(text, first, order=None)#
Give the constant arrays of a kernel bindings after its arguments.
- Parameters:
text (str) – Textual LLVM IR with placeholder buffer accesses.
first (int) – Binding for the first constant array.
order (list of int, optional) – Placeholder bindings in the order in which they receive their bindings; those that text no longer uses are skipped. By default the order of appearance in text.
- Returns:
text (str) – The IR with the placeholder bindings replaced.
placeholders (dict of int to int) – Placeholder binding of each constant array by its binding in this kernel.
- numba_vulkan.buffers.arg_binding(index)#
Descriptor binding of a kernel argument.
- numba_vulkan.buffers.load_element(builder, binding, elem, index)#
Read one element of a storage buffer.
Emits a call to a placeholder function, which expand_buffer_access later turns into the actual load.
- Parameters:
builder (llvmlite.ir.IRBuilder) – Builder positioned where the code is emitted.
binding (int or llvmlite.ir.Value) – Descriptor binding of the buffer: a number, or a value that is a constant once the kernel is inlined.
elem (llvmlite.ir.Type) – Element type of the buffer.
index (llvmlite.ir.Value) – Element index.
- Returns:
The element, of type
elem.- Return type:
llvmlite.ir.Value
- numba_vulkan.buffers.store_element(builder, binding, elem, index, value)#
Write one element of a storage buffer.
Emits a call to a placeholder function, which expand_buffer_access later turns into the actual store.
- Parameters:
builder (llvmlite.ir.IRBuilder) – Builder positioned where the code is emitted.
binding (int or llvmlite.ir.Value) – Descriptor binding of the buffer: a number, or a value that is a constant once the kernel is inlined.
elem (llvmlite.ir.Type) – Element type of the buffer.
index (llvmlite.ir.Value) – Element index.
value (llvmlite.ir.Value) – Value to store, of type
elem.
- numba_vulkan.buffers.ATOMIC_OPS = ('add', 'sub', 'and', 'or', 'xor', 'xchg', 'max', 'min', 'umax', 'umin', 'fadd')#
- numba_vulkan.buffers.atomic_element(builder, binding, elem, index, op, value)#
Apply an atomic read-modify-write to one element of a buffer.
Emits a call to a placeholder function, which expand_buffer_access later turns into an
atomicrmwinstruction with relaxed ordering.- Parameters:
builder (llvmlite.ir.IRBuilder) – Builder positioned where the code is emitted.
binding (int or llvmlite.ir.Value) – Descriptor binding of the buffer (see load_element), or the binding of a shared array.
elem (llvmlite.ir.Type) – Element type: a 32-bit integer, or
floatforfadd.index (llvmlite.ir.Value) – Element index.
op (str) – One of ATOMIC_OPS.
value (llvmlite.ir.Value) – The operand, of type
elem.
- Returns:
The value the element had before.
- Return type:
llvmlite.ir.Value
- numba_vulkan.buffers.compare_and_swap(builder, binding, index, expected, value)#
Atomically replace one 32-bit element if it has the expected value.
Emits a call to a placeholder function, which expand_buffer_access later expands.
- Parameters:
builder (llvmlite.ir.IRBuilder) – Builder positioned where the code is emitted.
binding (int or llvmlite.ir.Value) – Descriptor binding of the buffer (see load_element), or the binding of a shared array.
index (llvmlite.ir.Value) – Element index.
expected (llvmlite.ir.Value) –
i32values: what the element must hold, and its replacement.value (llvmlite.ir.Value) –
i32values: what the element must hold, and its replacement.
- Returns:
The value the element had before; the swap happened if it equals expected.
- Return type:
llvmlite.ir.Value
- numba_vulkan.buffers.barrier(builder)#
Wait until all invocations of the workgroup arrive here.
Emits a call to a placeholder function. It has unknown memory effects, so LLVM moves no memory access across it, and it is
convergent, so LLVM does not duplicate it into different branches.- Parameters:
builder (llvmlite.ir.IRBuilder) – Builder positioned where the code is emitted.
- numba_vulkan.buffers.expand_buffer_access(text, push_types=())#
Replace the placeholder calls in LLVM IR by real buffer accesses.
Each placeholder becomes a
llvm.spv.resource.handlefrombindingcall, allvm.spv.resource.getpointercall and a load or store. Loads from PUSH_BINDING become loads of members of the push-constant block. The declarations and name strings these need are appended.- Parameters:
- Returns:
text (str) – The rewritten LLVM IR.
written (set of int) – Bindings the code stores to.
read (set of int) – Bindings the code loads from.
- Raises:
SpirvCodegenError – If a placeholder call with a non-constant binding remains.
Notes
This works on text because llvmlite cannot build IR that uses LLVM target extension types, and because it has to run after LLVM’s optimisation passes.