Buffer Creation and Usage¶
In vkdispatch, nearly all data is stored inside “buffers” (each wrapping an individual VkBuffer object and all other objects needed to manage it). These are the equivalent of torch.Tensor
or wp.array()
in warp-lang
.
However, unlike torch.Tensor
or wp.array()
, vkdispatch buffers are by default multi-device. This means that when a vkdispatch buffer is allocated on a multi-device or multi-queue context, multiple VkBuffer
s are allocated (one for each queue on each device). This architecture has the benefit of greatly simplfying multi-GPU programs, since all buffers can be assumed to exist on all devices and all queues.
To allocate a buffer, you can either directly use the constructor
of the Buffer class or the vd.asbuffer
function to directly upload a numpy array to the gpu as a buffer.
Simple GPU Buffer Example¶
import vkdispatch as vd
import numpy as np
# Create a simple numpy array
cpu_data = np.arange(16, dtype=np.int32)
print(f"Original CPU data: {cpu_data}")
# Create a GPU buffer
gpu_buffer = vd.asbuffer(cpu_data)
# Read data back from GPU to CPU to verify
downloaded_data = gpu_buffer.read(0)
print(f"Data downloaded from GPU: {downloaded_data.flatten()}")
# Expected Output:
# Original CPU data: [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]
# Data downloaded from GPU: [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]
What’s happening here?
We import vkdispatch and numpy (a common dependency for numerical data).
We use the
vd.asbuffer
function to upload the numpy array to a vkdispatch buffer.read(0)
retrieves data back from the GPU to the CPU. The number provided as an argument to the function is the queue index to read from. For a simple context with one device and one queue, there is only 1 queue, so we read from index 0. If the index is ommited the function returns a python list of the contents of all buffers on all queues and devices.
Buffer API Reference¶
- class vkdispatch.Buffer(shape: Tuple[int, ...], var_type: dtype)¶
TODO: Docstring
- _destroy() None ¶
Destroy the buffer and all child handles.
- read(index: int | None = None) ndarray ¶
Read the data in the buffer at the specified device index and return it as a numpy array.
Parameters: index (int): The index to read the data from. Default is 0.
Returns: (np.ndarray): The data in the buffer as a numpy array.
- write(data: bytes | ndarray, index: int = -1) None ¶
Given data in some numpy array, write that data to the buffer at the specified index. The default index of -1 will write to all buffers.
Parameters: data (np.ndarray): The data to write to the buffer. index (int): The index to write the data to. Default is -1 and
will write to all buffers.
Returns: None