Types

class vulky.AABBCollection(device: DeviceWrapper)

Bases: GeometryCollection

append(aabb: Buffer)
get_collection_type() ADSNodeType
class vulky.ADS(device, w_resource: ResourceWrapper, handle, scratch_size, info: Any, ranges, instance_buffer=None)

Bases: Resource

class vulky.ADSNodeType(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

Bases: IntEnum

Determines possible types of an ADS buffer.

AABB = 2

Elements of the (bottom) ADS buffer are boxes.

INSTANCE = 3

Elements of the (top) ADS buffer are instances.

NONE = 0

The element type is unknown.

TRIANGLES = 1

Elements of the (bottom) ADS buffer are triangles.

class vulky.AddressMode(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

Bases: IntEnum

Determines how the sampler behaves at edges.

BORDER = 3

Sampler uses a constant value for coordinates out of range.

CLAMP_EDGE = 2

Sampler repeat color at edge

NONE = 0

The behaviour is unknown.

REPEAT = 1

Sampler repeat coordinates.

class vulky.BorderColor(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

Bases: IntEnum

Determines possible values for the border sampling.

NONE = 0

The value is unknown.

OPAQUE_BLACK_FLOAT = 3

All components are 0.0 but the alpha is full (1.0f)

OPAQUE_BLACK_INT = 4

All components are 0 but the alpha is full

OPAQUE_WHITE_FLOAT = 5

All components are 1.0f

OPAQUE_WHITE_INT = 6

All components are full

TRANSPARENT_BLACK_FLOAT = 1

All values are 0.0f.

TRANSPARENT_BLACK_INT = 2

All values are 0

class vulky.Buffer(device: DeviceManager, w_buffer: ResourceWrapper)

Bases: Resource

Represents a continuous memory on the device.

memory
size
slice(offset: int, size: int)

Gets a new buffer referring to the region from offset, taking size bytes.

Example

>>> import vulky as vk
>>> b = vk.buffer(4000, vk.BufferUsage.STORAGE, vk.MemoryLocation.GPU)
>>> b.slice(0, 500*4).load([0.1]*500)
>>> b.slice(500*4, 500*4).load([0.2]*500)
class vulky.BufferUsage(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

Bases: IntEnum

Determines the usage for a buffer object.

INDEX = 3

The buffer is used as index buffer input in a rasterization pipeline.

NONE = 0

The usage is unknown.

RAYTRACING_ADS = 6

The buffer is used to store a BVH.

RAYTRACING_RESOURCE = 7

The buffer is used as vertices or indices for building a BVH

SHADER_TABLE = 8

The buffer is used to store shader handles.

STAGING = 1

The buffer is used for staging.

STORAGE = 5

The buffer is used as a storage buffer.

UNIFORM = 4

The buffer is used as uniform object.

VERTEX = 2

The buffer is used as vertex buffer input in a rasterization pipeline.

class vulky.CommandManager(device, w_cmdList: CommandBufferWrapper)

Bases: object

freeze()
classmethod get_queue_required() int
image_barrier(image: Image, image_usage: ImageUsage)
is_closed()
is_frozen()
use(image: Image, image_usage: ImageUsage)
class vulky.CompareOp(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

Bases: IntEnum

Determines different comparison operations for depth, blending, stencil and other operations.

ALWAYS = 8

Test always succeed.

EQUAL = 3

Elements are equals.

GREATER = 5

First element is greater than second.

GREATER_OR_EQUAL = 7

First element is greater or equals than second.

LESS = 2

First element is less than second.

LESS_OR_EQUAL = 4

First element is less or equals than second.

NEVER = 1

Test always fails.

NONE = 0

The operation is unknown.

NOT_EQUAL = 6

Elements are different.

class vulky.ComputeManager(device, w_cmdList: CommandBufferWrapper)

Bases: CopyManager

bind(ds: DescriptorSet)
clear_buffer(buffer: Buffer, value: int = 0)
clear_color(image: Image, color)
clear_depth_stencil(image: Image, depth: float = 1.0, stencil: int = 0)
dispatch_groups(groups_x: int, groups_y: int = 1, groups_z: int = 1)
dispatch_threads(dim_x: int, dim_y: int, dim_z: int, group_size_x: int, group_size_y: int, group_size_z: int)
dispatch_threads_1D(dim_x: int, group_size_x: int = 1024)
dispatch_threads_2D(dim_x: int, dim_y: int, group_size_x: int = 32, group_size_y: int = 32)
classmethod get_queue_required() int
set_pipeline(pipeline: Pipeline)
update_constants(**fields)
update_sets(*sets)
class vulky.CopyManager(device, w_cmdList: CommandBufferWrapper)

Bases: CommandManager

copy(src_resource, dst_resource)
classmethod get_queue_required() int
class vulky.DescriptorSet(w_ds: DescriptorSetWrapper, layout_reference_names: Dict[str, Tuple[int, int]])

Bases: object

update(**bindings: Resource | List[Resource] | Tuple[Resource, SamplerWrapper])

Updates the descriptors for bindings in the descriptor set. Notice that grouping bindings updates in a single call might lead to better performance.

Example

>>> pipeline : Pipeline = ...
>>> pipeline.layout(set=0, binding=0, transforms=DescriptorType.UNIFORM_BUFFER)
>>> pipeline.layout(set=0, binding=1, environment=DescriptorType.SAMPLED_IMAGE)
>>> ...
>>> pipeline.close()
>>> dss = pipeline.create_descriptor_set_collection(set=0, count=1)
>>> ds = dss[0]  # peek the only descriptor set in the collection
>>> ds.update(  # write resources descriptors to the slots named within pipeline.layout
>>>     transforms=my_transforms_buffer,
>>>     environment=my_environment_image
>>> )
class vulky.DescriptorSetCollection(w_dsc: DescriptorSetCollectionWrapper, layout_reference_names: Dict[str, Tuple[int, int]])

Bases: object

class vulky.DescriptorType(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

Bases: IntEnum

Determines the type of descriptor of a resource binding.

COMBINED_IMAGE = 6

The descriptor is for an image and a sampler object.

NONE = 0

The descriptor is unknown.

SAMPLED_IMAGE = 5

The descriptor is for an image that can be sampled.

SAMPLER = 1

The descriptor is for a sampler object.

SCENE_ADS = 7

The descriptor is for an (top) ADS buffer.

STORAGE_BUFFER = 3

The descriptor is for a storage buffer object.

STORAGE_IMAGE = 4

The descriptor is for a storage image object.

UNIFORM_BUFFER = 2

The descriptor is for a uniform buffer object.

class vulky.Filter(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

Bases: IntEnum

Filter used during sampling a texel.

LINEAR = 2

Linear (bilinear) interpolation is used.

NONE = 0

The filter is unknown.

POINT = 1

Nearest sample.

class vulky.Format(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

Bases: IntEnum

DEPTH_STENCIL = 20
FLOAT = 7
INT = 8
IVEC2 = 13
IVEC3 = 14
IVEC4 = 15
NONE = 0
PRESENTER = 19
UINT = 9
UINT_BGRA_STD = 3
UINT_BGRA_UNORM = 6
UINT_RGB = 2
UINT_RGBA = 1
UINT_RGBA_STD = 4
UINT_RGBA_UNORM = 5
UVEC2 = 16
UVEC3 = 17
UVEC4 = 18
VEC2 = 10
VEC3 = 11
VEC4 = 12
vulky.FrameBuffer

alias of FrameBufferWrapper

class vulky.GPUPtr(device_ptr: int, obj: Any, is_direct: bool = True)

Bases: object

flush()
invalidate()
mark_as_dirty()
update_mode(additional_mode: Literal['in', 'out', 'inout'])
class vulky.GTensorMeta(name, bases, dct)

Bases: _TensorMeta

class vulky.GeometryCollection(device: DeviceWrapper)

Bases: object

get_collection_type() ADSNodeType
class vulky.GraphicsManager(device, w_cmdList: CommandBufferWrapper)

Bases: ComputeManager

bind_index_buffer(index_buffer: Buffer)
bind_vertex_buffer(binding: int, vertex_buffer: Buffer)
blit_image(src_image: Image, dst_image: Image, filter: Filter = Filter.POINT)
dispatch_indexed_primitives(indices: int, instances: int = 1, first_index: int = 0, vertex_offset: int = 0, first_instance: int = 0)
dispatch_primitives(vertices: int, instances: int = 1, vertex_start: int = 0, instance_start: int = 0)
classmethod get_queue_required() int
set_framebuffer(framebuffer: FrameBufferWrapper)
class vulky.GraphicsPipeline(w_pipeline: PipelineWrapper)

Bases: Pipeline

attach(slot: int, **attach_declaration: Format)
create_framebuffer(width: int, height: int, layers: int = 1, **bindings: Image | None) FrameBufferWrapper
vertex(location: int, **attribute_declaration)
vertex_binding(binding: int, stride: int, **attribute_offset_map)
class vulky.Image(device, w_image: ResourceWrapper, texel_layout: Layout)

Bases: Resource

TODO: NOT IDEAL DESIGN

as_readonly()
static compute_dimension(width: int, height: int, depth: int, mip_level: int)
element_size()
get_array_count() int
get_image_dimension() int
get_mip_count() int
numel()
size
slice_array(array_start, array_count)
slice_mips(mip_start, mip_count)
subresource(mip: int = 0, layer: int = 0)
subresource_footprint(mip: int = 0, layer: int = 0)
class vulky.ImageType(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

Bases: IntEnum

NONE = 0
TEXTURE_1D = 1
TEXTURE_2D = 2
TEXTURE_3D = 3
class vulky.ImageUsage(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

Bases: IntEnum

Determines the usage for an image object.

ANY = 6

The image can be used for sampling, storage and as render target.

DEPTH_STENCIL = 4

The image can be used only as a depth-stencil buffer

NONE = 0

The usage is unknown.

RENDER_TARGET = 3

The image can be used only as render target.

SAMPLED = 2

The image can be sampled from a shader.

STORAGE = 5

The image can be used only as storage

TRANSFER = 1

The image can be copied to/from the cpu

class vulky.Layout(declaration, size, alignment: int = 1, array_stride: int | None = None, matrix_stride: int | None = None, element_layout: Layout | None = None, fields_layout: Dict[str, Tuple[int, Layout]] | None = None)

Bases: object

Represents a specific layout of fields and arrays in memory with alignment rules.

static fix_shape(shape, total)

Converts a shape of a variable dimension (-1) to a fix shape.

static from_aabb()

Creates a layout for an axis-aligned boundary boxes buffer.

static from_description(mode: LayoutAlignment, description: type | dict | list | dtype) Layout

Creates a layout from a general type definition. type definition defines: - arrays with a list in the form [<type>, size] - structures with a dict in the form { field_name : field_type, … } - scalars with the types from _torch.dtype or int, float, complex.

Example

>>> my_vertex_layout = Layout.from_description(
>>>     LayoutAlignment.SCALAR,
>>>     dict(
>>>         P=vec3,
>>>         N=vec3
>>>     )
>>> )
>>> my_ssbo_layout = Layout.from_description(
>>>     LayoutAlignment.STD430,
>>>     dict(
>>>         count=int,
>>>         data=[100, dict(P=vec3, C=vec4)]
>>>     )
>>> )
static from_format(format: Format)

Creates a layout for the image formats.

static from_instance()

Creates a layout for an instance buffer

static from_instance2()

Creates a layout for an instance buffer

static from_structure(mode: LayoutAlignment = LayoutAlignment.SCALAR, **fields)

Creates a layout for a structure.

Example

>>> vertex_layout = Layout.from_structure(P=vec3, N=vec3)
static is_scalar_type(type)
static scalar_size(type: type | dtype) int

Return the size in bytes for a scalar type, int, float, complex or torch dtypes.

static set_24bit_from_int(src: Tensor, dst: Tensor)

Copies the lowest 24 bits from integers in src to dst. src is a tensor of int32 and dst is a tensor of int8 with 3 components for the last dimension.

class vulky.LayoutAlignment(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

Bases: IntEnum

Determines the type of rules for alignment applied in a layout.

COMPACT = 0

No alignment is applied.

SCALAR = 1

Scalar alignment is applied. Struct and arrays are aligned to the maximum scalar contained inside.

STD430 = 2

Applies the std430 layout rules.

class vulky.MemoryLocation(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

Bases: IntEnum

Memory configurations.

CPU = 2

Memory can be read and write directly from the CPU

GPU = 1

Efficient memory for reading and writing on the GPU.

NONE = 0

Memory location is unknown

class vulky.MipMapMode(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

Bases: IntEnum

Filter used during sampling between mip maps.

LINEAR = 2

Linear (bilinear, trilinear) interpolation is used.

NONE = 0

The filter is unknown.

POINT = 1

Nearest sample.

class vulky.ObjectBuffer(device: DeviceManager, w_buffer: ResourceWrapper, layout: Layout)

Bases: Buffer

Buffer used to represent single objects. The buffer is automatically mapped if is on CPU. If the buffer is on GPU the memory must be updated via update_gpu.

Example

>>> import vulky as vk
>>> b = vk.object_buffer(vk.Layout.from_structure(P=vk.vec3, L=float), memory=vk.MemoryLocation.GPU)
>>> with b as map:
>>>     map.P = vk.vec3(0.0, 1.0, 0.0)
>>>     map.L = 0.5
>>> b.update_gpu()
update_gpu()
class vulky.ObjectBufferAccessor(memory: memoryview, layout: Layout)

Bases: object

Auxiliar class to access resource mapped memory efficiently through dot notation and indexing.

Example

>>> import vulky as vk
>>> b = vk.object_buffer(vk.Layout.from_structure(
>>>     light_position=vk.vec3,
>>>     light_intensity=vk.vec3,
>>> ))
>>> with b as data:
>>>     # data is an object buffer accessor
>>>     data.light_position = vk.vec3(0.0, 3.0, 0.0)
>>>     data.light_intensity = vk.vec3(1.0, 1.0, 0.0)
references() set
class vulky.Pipeline(w_pipeline: PipelineWrapper)

Bases: object

close()
create_descriptor_set_collection(set: int, count: int)
is_closed()
layout(set: int, binding: int, array_size: int | None = None, is_variable: bool = False, **bind_declaration: DescriptorType)

Declares a part of the pipeline layout. set: specify the set number this bind belongs to. binding: specify the binding slot. array_size: Number of resources bound as an array. is_variable: If true, the bound array is not fixed although count is used as upper bound. bind_declaration: A single key-value pair indicating the reference name and the descriptor type, Example: >>> pipeline: Pipeline = … >>> pipeline.layout(set=0, binding=0, camera_transforms=DescriptorType.UNIFORM_BUFFER) >>> pipeline.layout(set=1, binding=0, model_transform=DescriptorType.UNIFORM_BUFFER) >>> pipeline.layout(set=1, binding=1, array_size=10, model_textures=DescriptorType.SAMPLED_IMAGE)

load_shader(path, *specialization, main_function='main')
load_shader_from_source(code, *specialization, main_function='main', include_dirs=[])
shader_stages(*shader_stages: ShaderStage)

Activates temporarily a set of shader stages. To be used in a context scope. e.g., >>> pipeline: Pipeline = … >>> # here pipeline has all stages active >>> with pipeline.shader_stages(ShaderStage.VERTEX, ShaderStage.FRAGMENT): >>> … # settings requiring only VS and FS stages active >>> # here pipeline has all stages active again

class vulky.PipelineType(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

Bases: IntEnum

Determines the pipeline type.

COMPUTE = 1

The pipeline is for a compute process.

GRAPHICS = 2

The pipeline is for a rasterization process.

NONE = 0

The pipeline is unknown.

RAYTRACING = 3

The pipeline is for a ray-tracing process.

class vulky.PresenterMode(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

Bases: IntEnum

Presentation mode of a device. Decide if the render target resources are optimized for window presentation or not.

NONE = 0

The presentation mode is unknown

OFFLINE = 1

Render target is not optimized for window presentation.

WINDOW = 2

Render target is optimized for presenting on a window.

class vulky.QueueType(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

Bases: IntEnum

Type of the graphics engine queue used for submitting tasks.

COMPUTE = 2

The queue supports transfer and compute commands.

COPY = 1

The queue supports only transfer commands.

GRAPHICS = 3

The queue supports transfer, compute and rasterization commands.

NONE = 0

The queue is unknown

RAYTRACING = 4

The queue supports transfer, compute, graphics and raytracing commands.

class vulky.RTProgram(pipeline: Pipeline, w_shader_table: ResourceWrapper, miss_offset, hit_offset, callable_offset)

Bases: object

active_raygen_slice()
select_generation(main_index: int)
set_callable(callable_index: int, shader_group: ShaderHandlerWrapper)
set_generation(gen_index: int, shader_group: ShaderHandlerWrapper)
set_hit_group(hit_group_index: int, shader_group: ShaderHandlerWrapper)
set_miss(miss_index: int, shader_group: ShaderHandlerWrapper)
class vulky.RaytracingManager(device, w_cmdList: CommandBufferWrapper)

Bases: GraphicsManager

build_ads(ads: ADS, scratch_buffer: Buffer)
dispatch_rays(program: RTProgram, dim_x: int, dim_y: int, dim_z: int = 1)
classmethod get_queue_required() int
update_ads(ads: ADS, scratch_buffer: Buffer)
class vulky.RaytracingPipeline(w_pipeline: PipelineWrapper)

Bases: Pipeline

create_rt_callable_group(callable_index: int)
create_rt_gen_group(generation_shader_index: int)
create_rt_hit_group(closest_hit: int = None, any_hit: int = None, intersection: int = None)
create_rt_miss_group(miss_shader_index: int)
create_rt_program(max_raygen_shader=1, max_miss_shader=10, max_hit_groups=1000, max_callable=1000) RTProgram
stack_size(depth: int)
class vulky.Resource(device, w_resource: ResourceWrapper)

Bases: object

Base class of all vulky resources.

clear() Resource

Clears current resource with 0 values. This operation is costly. Consider clearing the resources as part of a custom manager.

Return type:

Return the same object.

cpu_ptr
cuda_ptr
device_ptr
is_ads
is_buffer
is_image
is_on_cpu
is_on_gpu
load(src_data)

Loads information from src_data if it is possible. Possibilities are: If src_data is another Resource then Buffer-Buffer, Buffer-Image, Image-Buffer or Image-Image copy is performed. If src_data is a list, then depending on the resource type list is cast to int or float. If src_data is a tensor or numpy array data is copied as a buffer. If src_data is another type, then conversion to numpy or torch is tried.

Note

If current resource is an image (with potential subresources), src_data size should match the linearized version of the image, not the real layout on GPU. Byte size should match. Different image formats can not be copied with this method. Use blit operation instead.

save(dst_data)

Saves information to dst_data if it is possible. Possibilities are: If dst_data is another Resource then Buffer-Buffer, Buffer-Image, Image-Buffer or Image-Image copy is performed. If dst_data is a tensor or numpy array data is copied as a buffer. If dst_data is another type, then conversion to numpy or torch is tried whenever memory is direct.

Note

If current resource is an image (with potential subresources), dst_data size should match the linearized version of the image, not the real layout on GPU. Byte size should match. Different image formats can not be copied with this method. Use blit operation instead.

size
vulky.Sampler

alias of SamplerWrapper

vulky.ShaderHandler

alias of ShaderHandlerWrapper

class vulky.ShaderStage(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

Bases: IntEnum

Determines the shader stage

COMPUTE = 3

Shader stage for a compute process in a compute pipeline.

FRAGMENT = 2

Shader stage for per-fragment process in a rasterization pipeline.

GEOMETRY = 10

Shader stage for geometry process in a rasterization pipeline.

NONE = 0

Shader stage is unknown.

RT_ANY_HIT = 7

Shader stage for any ray hit process in a ray-tracing pipeline.

RT_CALLABLE = 9

Shader stage for a callable shader in a ray-tracing pipeline.

RT_CLOSEST_HIT = 5

Shader stage for closest hit process in a ray-tracing pipeline.

RT_GENERATION = 4

Shader stage for ray generation in a ray-tracing pipeline.

RT_INTERSECTION_HIT = 8

Shader stage for final intersection hit process in a ray-tracing pipeline.

RT_MISS = 6

Shader stage for a ray miss process in a ray-tracing pipeline.

VERTEX = 1

Shader stage for per-vertex process in a rasterization pipeline.

class vulky.StructuredBuffer(device: DeviceManager, w_buffer: ResourceWrapper, layout: Layout)

Bases: Buffer

Buffer used to represent structured arrays. Buffer can be mapped in mode in, out or inout.

Example

>>> import vulky as vk
>>> b = vk.structured_buffer(5, dict(P=vk.vec3, L=float), memory=vk.MemoryLocation.GPU)
>>> with b.map('in') as map:
>>>     map.P = vk.vec3(0.0, 1.0, 0.0)
>>>     map.L = 0.5
map(mode: Literal['in', 'out', 'inout'], clear: bool = False)

Creates a context to map the buffer in a specific mode.

Parameters:
  • mode (str) – If ‘in’ the buffer is updated on the gpu after exit the context. If ‘out’ the buffer is updated on the cpu before entering the context. If ‘inout’ the buffer is updated on the cpu before entering the context and then back to the gpu.

  • clear (bool) – Only applies if mode is ‘in’. Clears all the buffer before entering the context.

class vulky.StructuredBufferAccess(memory: memoryview, structure_stride: int, offset: int, structure_layout: Layout)

Bases: object

Auxiliary class to access structured buffers.

static build_accessor(memory: memoryview, stride: int, offset: int, layout: Layout)
class vulky.StructuredTensor(base_tensor: Tensor, element_layout: Layout)

Bases: object

Allows to access the memory of a tensor assuming a specific layout.

static create(layout: Layout, device: device | str | None = None) StructuredTensor
static create_compatible_tensor(element_layout: Layout, *structure_shape: int, device: device | str | None = None)
get_field(name: str) StructuredTensor
get_item(*index: int) StructuredTensor
numpy()
read(out: Tensor = None)

For basic types (scalars, vectors and matrices), returns a tensor with the request values. For vectors and matrices a GTensor is returned. If out tensor is provided, copy elements to that tensor

structure_shape()
tensor()

If layout is compatible with torch, returns a tensor sharing the same memory

write(data: Tensor)

Writes the content of data to this structure tensor.

class vulky.TriangleCollection(device: DeviceWrapper)

Bases: GeometryCollection

append(vertices: Buffer, indices: Buffer = None, transform: Buffer = None)
get_collection_type() ADSNodeType
class vulky.ViewTensor(*args)

Bases: Tensor

detach()

Returns a new Tensor, detached from the current graph.

The result will never require gradient.

This method also affects forward mode AD gradients and the result will never have forward mode AD gradients.

Note

Returned Tensor shares the same storage with the original one. In-place modifications on either of them will be seen, and may trigger errors in correctness checks. IMPORTANT NOTE: Previously, in-place size / stride / storage changes (such as resize_ / resize_as_ / set_ / transpose_) to the returned tensor also update the original tensor. Now, these in-place changes will not update the original tensor anymore, and will instead trigger an error. For sparse tensors: In-place indices / values changes (such as zero_ / copy_ / add_) to the returned tensor will not update the original tensor anymore, and will instead trigger an error.

static from_blob(ptr: int, shape: Tuple[int] | List[int], dtype: dtype, device: device, *, strides: Tuple[int] | List[int] | None = None, owner: object = None) ViewTensor
static reinterpret(t: Tensor, dtype: dtype | int | float)
view(*shape) Tensor

Returns a new tensor with the same data as the self tensor but of a different shape.

The returned tensor shares the same data and must have the same number of elements, but may have a different size. For a tensor to be viewed, the new view size must be compatible with its original size and stride, i.e., each new view dimension must either be a subspace of an original dimension, or only span across original dimensions \(d, d+1, \dots, d+k\) that satisfy the following contiguity-like condition that \(\forall i = d, \dots, d+k-1\),

\[\text{stride}[i] = \text{stride}[i+1] \times \text{size}[i+1]\]

Otherwise, it will not be possible to view self tensor as shape without copying it (e.g., via contiguous()). When it is unclear whether a view() can be performed, it is advisable to use reshape(), which returns a view if the shapes are compatible, and copies (equivalent to calling contiguous()) otherwise.

Parameters:

shape (torch.Size or int...) – the desired size

Example:

>>> x = torch.randn(4, 4)
>>> x.size()
torch.Size([4, 4])
>>> y = x.view(16)
>>> y.size()
torch.Size([16])
>>> z = x.view(-1, 8)  # the size -1 is inferred from other dimensions
>>> z.size()
torch.Size([2, 8])

>>> a = torch.randn(1, 2, 3, 4)
>>> a.size()
torch.Size([1, 2, 3, 4])
>>> b = a.transpose(1, 2)  # Swaps 2nd and 3rd dimension
>>> b.size()
torch.Size([1, 3, 2, 4])
>>> c = a.view(1, 3, 2, 4)  # Does not change tensor layout in memory
>>> c.size()
torch.Size([1, 3, 2, 4])
>>> torch.equal(b, c)
False
view(dtype) Tensor

Returns a new tensor with the same data as the self tensor but of a different dtype.

If the element size of dtype is different than that of self.dtype, then the size of the last dimension of the output will be scaled proportionally. For instance, if dtype element size is twice that of self.dtype, then each pair of elements in the last dimension of self will be combined, and the size of the last dimension of the output will be half that of self. If dtype element size is half that of self.dtype, then each element in the last dimension of self will be split in two, and the size of the last dimension of the output will be double that of self. For this to be possible, the following conditions must be true:

  • self.dim() must be greater than 0.

  • self.stride(-1) must be 1.

Additionally, if the element size of dtype is greater than that of self.dtype, the following conditions must be true as well:

  • self.size(-1) must be divisible by the ratio between the element sizes of the dtypes.

  • self.storage_offset() must be divisible by the ratio between the element sizes of the dtypes.

  • The strides of all dimensions, except the last dimension, must be divisible by the ratio between the element sizes of the dtypes.

If any of the above conditions are not met, an error is thrown.

Warning

This overload is not supported by TorchScript, and using it in a Torchscript program will cause undefined behavior.

Parameters:

dtype (torch.dtype) – the desired dtype

Example:

>>> x = torch.randn(4, 4)
>>> x
tensor([[ 0.9482, -0.0310,  1.4999, -0.5316],
        [-0.1520,  0.7472,  0.5617, -0.8649],
        [-2.4724, -0.0334, -0.2976, -0.8499],
        [-0.2109,  1.9913, -0.9607, -0.6123]])
>>> x.dtype
torch.float32

>>> y = x.view(torch.int32)
>>> y
tensor([[ 1064483442, -1124191867,  1069546515, -1089989247],
        [-1105482831,  1061112040,  1057999968, -1084397505],
        [-1071760287, -1123489973, -1097310419, -1084649136],
        [-1101533110,  1073668768, -1082790149, -1088634448]],
    dtype=torch.int32)
>>> y[0, 0] = 1000000000
>>> x
tensor([[ 0.0047, -0.0310,  1.4999, -0.5316],
        [-0.1520,  0.7472,  0.5617, -0.8649],
        [-2.4724, -0.0334, -0.2976, -0.8499],
        [-0.2109,  1.9913, -0.9607, -0.6123]])

>>> x.view(torch.cfloat)
tensor([[ 0.0047-0.0310j,  1.4999-0.5316j],
        [-0.1520+0.7472j,  0.5617-0.8649j],
        [-2.4724-0.0334j, -0.2976-0.8499j],
        [-0.2109+1.9913j, -0.9607-0.6123j]])
>>> x.view(torch.cfloat).size()
torch.Size([4, 2])

>>> x.view(torch.uint8)
tensor([[  0, 202, 154,  59, 182, 243, 253, 188, 185, 252, 191,  63, 240,  22,
           8, 191],
        [227, 165,  27, 190, 128,  72,  63,  63, 146, 203,  15,  63,  22, 106,
          93, 191],
        [205,  59,  30, 192, 112, 206,   8, 189,   7,  95, 152, 190,  12, 147,
          89, 191],
        [ 43, 246,  87, 190, 235, 226, 254,  63, 111, 240, 117, 191, 177, 191,
          28, 191]], dtype=torch.uint8)
>>> x.view(torch.uint8).size()
torch.Size([4, 16])
class vulky.Window(device: DeviceManager, w_window: WindowWrapper, format: Format)

Bases: object

class ClientContext(window: Window, map: Image | Buffer | Tensor, man: GraphicsManager | None)

Bases: object

buffer()
property fps
image()
property is_closed
label_text(label: str, text: str)
render_target()
show_tensor(name: str, t: Tensor, width: int, height: int, cmap: str = 'viridis')
property spf
tensor()
vulky.aabb_collection() AABBCollection

Creates a collection to store boxes for ray-cast

vulky.ads_model(collection: GeometryCollection) ADS

Creates an acceleration data structure for a model formed by a set of geometries (bottom-level ads).

vulky.ads_scene(instance_buffer: Buffer) ADS

Creates an acceleration data structure for the scene elements (top-level ads).

vulky.allow_cross_threading()

Allows dispatching cross-threading vulkan calls. The safest way is to include the cross-threading code inside a loop function

vulky.buffer(size: int, usage: BufferUsage, memory: MemoryLocation) Buffer

Creates a buffer for a generic usage. Cuda-visible buffers exposes a cuda_ptr and can be wrap as tensors zero-copy operation.

vulky.buffer_like(t: Tensor | Resource, memory: MemoryLocation) Buffer
vulky.compile_shader_file(filename: str, include_dirs: List)
vulky.compile_shader_source(code, stage, include_dirs)
vulky.compile_shader_source_file(filename, stage, binary_file_name, include_dirs=[])
vulky.compile_shader_sources(directory='.', force_all: bool = False)
vulky.compute_manager() ComputeManager

Gets a compute manager object that can be used to populate with compute commands. Using this object as a context will flush automatically the command list at the end. Creating an object and freeze allows to submit several times after creation.

Example

>>> import vulky as vk
>>> # ... device and pipeline creation
>>> with vk.compute_manager() as man:
>>>     man.set_pipeline(my_compute_pipeline)
>>>     man.update_sets(0)
>>>     man.dispatch_threads_1D(1024*1024)
vulky.copy_manager() CopyManager

Gets a copy manager object that can be used to populate with transfer commands. Using this object as a context will flush automatically the command list at the end. Creating an object and freeze allows to submit several times after creation.

Example

>>> import vulky as vk
>>> # ... device and resources creation
>>> with vk.copy_manager() as man:
>>>     man.copy(resource_src, resource_dst)
vulky.create_device(*, device: int = 0, debug: bool = False, set_active: bool = True) DeviceManager

Creates a device manager. This is the core of vulkan graphics call. This method automatically sets created device as active, further actions will use it. To change to other devices use device_manager method. e.g: device_manager(other_device)

Parameters:
  • device (int) – The index of the physical device used to create vulkan device object. Default is 0

  • debug (bool) – Sets if the vulkan device will include debug layers. Default is False

  • set_active (bool) – Sets if the created device should be set as active. Default is True

Returns:

The created device.

Return type:

DeviceManager

Example

>>> import vulky as vk
>>> vk.create_device()
>>> # Do some rendering here in the GPU0
>>> vk.quit()
vulky.create_mesh(obj_data: dict, mode: Literal['po', 'vo', 'fo'])

Creates the mesh information (vertices, indices) given an obj data. po: Position order - Each position determines a vertex, normals and coordinates belonging to the same vertex are blended vo: Vertex order - Each distinct triple determines a vertex. fo: Face order - Each face determines three new vertices.

vulky.depth_stencil(width: int, height: int) Image

Creates a two-dimensional image object on the GPU to be used as depth stencil buffer.

vulky.device_manager(new_device: DeviceManager | None = None) DeviceManager

Gets or sets the active device used in vulky.

Parameters:

new_device (Optional[DeviceManager]) – The device manager to be set as active. Use None if it is only require querying the currently active device.

Returns:

The current active device.

Return type:

DeviceManager

vulky.execute_loop(main_process: Callable[[Any | None], bool], *process: Callable[[Any | None], None], context: Any | None = None)

Creates a thread to execute the process safety dispatching vulkan calls in the main thread

vulky.external_sync()

Must be used if a tensor bound to a pipeline depends on some external computation, e.g. CUDA.

Example

>>> import vulky as vk
>>> # ... initialization
>>> b = vk.object_buffer(vk.Layout.from_structure(
>>>     ptr=torch.int64  # Ptrs in vulkan are identified with int64 type of torch
>>> ))
>>> t = torch.sigmoid(torch.randn(3, 5, device='cuda'))
>>> vk.external_sync()   # this guarantees that cuda already finished computing tensor content.
>>> with b:
>>>     b.ptr = vk.wrap_gpu(t, 'in')
vulky.graphics_manager() GraphicsManager

Gets a graphics manager object that can be used to populate with graphics commands. Using this object as a context will flush automatically the command list at the end. Creating an object and freeze allows to submit several times after creation. .. rubric:: Example

>>> import vulky as vk
>>> # ... device, pipeline, buffers, framebuffers creation
>>> with vk.graphics_manager() as man:
>>>     man.set_pipeline(my_graphics_pipeline)
>>>     man.update_sets(0)
>>>     man.set_framebuffer(framebuffer)
>>>     man.bind_vertex_buffer(0, vb)
>>>     man.dispatch_primitives(6)
vulky.image(image_type: ImageType, is_cube: bool, image_format: Format, width: int, height: int, depth: int, mips: int, layers: int, usage: ImageUsage, memory: MemoryLocation) Image

Creates an image object on the specified memory (HOST or DEVICE).

vulky.image_1D(image_format: Format, width: int, mips=None, layers=1, usage: ImageUsage = ImageUsage.SAMPLED, memory: MemoryLocation = MemoryLocation.GPU) Image

Creates a one-dimensional image object on the GPU. If mips is None, then the maximum possible value is used.

vulky.image_2D(image_format: Format, width: int, height: int, mips=None, layers=1, usage: ImageUsage = ImageUsage.SAMPLED, memory: MemoryLocation = MemoryLocation.GPU) Image

Creates a two-dimensional image object on the GPU. If mips is None, then the maximum possible value is used.

vulky.image_3D(image_format: Format, width: int, height: int, depth: int, mips: int = None, layers: int = 1, usage: ImageUsage = ImageUsage.SAMPLED, memory: MemoryLocation = MemoryLocation.GPU) Image

Creates a three-dimensional image object on the GPU. If mips is None, then the maximum possible value is used.

vulky.index_buffer(count: int, memory: MemoryLocation = MemoryLocation.GPU) StructuredBuffer

Creates a buffer for an indices store. Each index is a int32 value that can be updated (cpu version). To finally update the resource (in case is allocated on the gpu) use flush_cpu().

vulky.instance_buffer(instances: int, memory: MemoryLocation = MemoryLocation.GPU) StructuredBuffer

Creates a buffer on the GPU to be used to store instances of a scene acceleration-datastructure.

vulky.load_image(filename: str, with_alpha: bool = True) Tensor
vulky.load_texture(filename: str) Image
vulky.load_video(filename: str)
class vulky.mat2(*args, **kwargs)

Bases: _GTensorBase

dimension = 2
tensor_dtype = torch.float32
tensor_shape = (2, 2)
class vulky.mat3(*args, **kwargs)

Bases: _GTensorBase

dimension = 2
static euler_rotation(yaw: Tensor | float, pitch: Tensor | float, roll: Tensor | float) mat3
inverse() Tensor

See torch.inverse()

static quaternion_rotation(q: Tensor | vec4) mat3
static rotation(axis: Tensor | vec3, angle: float | Tensor) mat3
static scale(s: float | Tensor | vec3) mat3
tensor_dtype = torch.float32
tensor_shape = (3, 3)
class vulky.mat3x4(*args, **kwargs)

Bases: _GTensorBase

static composite(internal: mat3x4 | Tensor | None, external: mat3x4 | Tensor | None) mat3x4

Gets the transform composition between two transforms (in transpose mode). x’, 1 = M (x, 1)^T Internal transform is the more local, external the most global.

dimension = 2
tensor_dtype = torch.float32
tensor_shape = (3, 4)
transposed()
class vulky.mat4(*args, **kwargs)

Bases: _GTensorBase

dimension = 2
static inv_look_at(ori: vec3, dir: vec3, nor: vec3)
inverse() Tensor

See torch.inverse()

static look_at(ori: vec3, target: vec3, up: vec3)
static perspective(fov: float | Tensor = 0.7853981633974483, aspect: float | Tensor = 1.0, znear: float | Tensor = 0.001, zfar: float | Tensor = 100)
tensor_dtype = torch.float32
tensor_shape = (4, 4)
static trs(offset: vec3, axis: vec3, angle: float | Tensor, scale: vec3) mat4
class vulky.mat4x3(*args, **kwargs)

Bases: _GTensorBase

static composite(internal: mat4x3 | Tensor | None, external: mat4x3 | Tensor | None) mat4x3
dimension = 2
tensor_dtype = torch.float32
tensor_shape = (4, 3)
transposed()
static trs(offset: vec3 = vec3([0., 0., 0.]), axis: vec3 = vec3([0., 1., 0.]), angle: float | Tensor = 0.0, scale: vec3 = vec3([1., 1., 1.])) mat4x3
vulky.pipeline_compute() Pipeline

Creates a Pipeline to manage the setup of a compute pipeline, resources, include and other attributes.

Example

>>> pipeline = vk.pipeline_compute()
>>> pipeline.load_shader_from_source(...)
>>> pipeline.close()
vulky.pipeline_graphics() GraphicsPipeline

Creates a Pipeline to manage the setup of a graphics pipeline, resources, include and other attributes.

Example

>>> pipeline = vk.pipeline_graphics()
>>> pipeline.attach(0, render_target=vk.Format.UINT_RGBA)
>>> with pipeline.shader_stages(vk.ShaderStage.VERTEX):
>>>     pipeline.load_shader_from_source(...)
>>> pipeline.close()
vulky.pipeline_raytracing() RaytracingPipeline

Creates a Pipeline to manage the setup of a raytracing pipeline, resources, include and other attributes.

Example

>>> pipeline = vk.pipeline_raytracing()
>>> with pipeline.shader_stages(vk.ShaderStage.RT_GENERATION):
>>>     pipeline.load_shader_from_source(...)
>>> pipeline.close()
vulky.quit()

Releases the active device from future usages. Use this function at the end of the program execution to avoid any hanging resources and properly shutdown vulkan objects

vulky.raytracing_manager() RaytracingManager

Gets a raytracing manager object that can be used to populate with raytracing commands. Using this object as a context will flush automatically the command list at the end. Creating an object and freeze allows to submit several times after creation.

vulky.render_target(image_format: Format, width: int, height: int) Image

Creates a two-dimensional image object on the GPU to be used as render target.

vulky.sampler(mag_filter: Filter = Filter.POINT, min_filter: Filter = Filter.POINT, mipmap_mode: MipMapMode = MipMapMode.POINT, address_U: AddressMode = AddressMode.REPEAT, address_V: AddressMode = AddressMode.REPEAT, address_W: AddressMode = AddressMode.REPEAT, mip_LOD_bias: float = 0.0, enable_anisotropy: bool = False, max_anisotropy: float = 0.0, enable_compare: bool = False, compare_op: CompareOp = CompareOp.NEVER, min_LOD: float = 0.0, max_LOD: float = 0.0, border_color: BorderColor = BorderColor.TRANSPARENT_BLACK_FLOAT, use_unnormalized_coordinates: bool = False) SamplerWrapper

Creates a sampler that can be used to bind texture objects.

vulky.sampler_linear(address_U: AddressMode = AddressMode.REPEAT, address_V: AddressMode = AddressMode.REPEAT, address_W: AddressMode = AddressMode.REPEAT, mip_LOD_bias: float = 0.0, enable_anisotropy: bool = False, max_anisotropy: float = 0.0, enable_compare: bool = False, compare_op: CompareOp = CompareOp.NEVER, min_LOD: float = 0.0, max_LOD: float = 1000.0, border_color: BorderColor = BorderColor.TRANSPARENT_BLACK_FLOAT, use_unnormalized_coordinates: bool = False) SamplerWrapper

Creates a linear sampler that can be used to bind texture objects.

vulky.save_image(t: Tensor, filename: str)

t: (HxWx3)

vulky.save_video(t: Tensor, filename: str, fps: int = 20, **kwargs)
vulky.scratch_buffer(*adss) Buffer

Creates a buffer on the GPU to be used as scratch buffer for acceleration-datastructure creation.

vulky.set_debug_name(name: str)

Sets the name for the next resource to be created.

Example

>>> vk.set_debug_name('my_photons')
>>> photon_map = vk.buffer(...)  # during debug prints, this buffer name is my_photons
vulky.submit(man: CommandManager, wait: bool = True)

Allows to submit the command list save in a manager using freeze.

Example

>>> man = vk.compute_manager()
>>> # fill command list
>>> man.freeze()  # can be submitted several times to GPU
>>> vk.submit(man)
vulky.support() Caps

Gets the set of features supported by the rendering system.

vulky.tensor(*shape, dtype: dtype = torch.float32) Tensor

Creates a tensor using a specific shape and type with compatible memory with vulkan, cupy and numpy tensors. The underlying buffer is created with possible usage to transfer to/from, storage binding and gpu addressing.

Example

>>> t = vk.tensor(2, 3)
>>> print(t)
tensor([[0.0, 0.0, 0.0],[0.0, 0.0, 0.0]], device='cuda')
vulky.tensor_copy(t: Tensor) ViewTensor

Creates a clone of a tensor in a memory that is compatible with current vulkan device.

Example

>>> t = torch.randn(2, 3)
>>> t_vk = vk.tensor_copy(t)
>>> print(t)
vulky.tensor_like(t: Tensor) Tensor

Creates a tensor in gpu vulkan memory using another tensor as reference. This tensor grants a zero_copy access from vulkan when used.

Example

>>> t = vk.tensor_like(torch.rand(2, 3))
>>> print(t)
tensor([[0.0, 0.0, 0.0],[0.0, 0.0, 0.0]], device='cuda')
vulky.tensor_to_gtensor_if_possible(t: Tensor, dimension: int) Tensor | _GTensorBase

Tool method to convert a torch tensor into a graphic tensor or scalar

Example

>>> t = torch.randn(4, 4, 3)
>>> s = tensor_to_gtensor_if_possible(t, 0)  # s is the same tensor
>>> v = tensor_to_gtensor_if_possible(t, 1)  # v is a vec3
>>> m = tensor_to_gtensor_if_possible(t, 2)  # m is a mat4x3
vulky.tensor_to_mat(t: Tensor) _GTensorBase

Converts a tensor to a matrix in vulky.

Example

>>> t = torch.randn(100, 100, 3, 4)
>>> m = tensor_to_matrix(t)   # m is a mat3x4

Note

The memory is shared. No copy is performed.

Return type:

The matrix type is determined by the last two dimensions of the tensor.

vulky.tensor_to_vec(t: Tensor) _GTensorBase

Converts a tensor to a vector in vulky.

Example

>>> t = torch.randn(100, 100, 3)
>>> v = tensor_to_vec(t)   # v is a vec3

Note

The memory is shared. No copy is performed.

Return type:

The vector type is determined by the last dimension of the tensor.

vulky.triangle_collection() TriangleCollection

Creates a collection to store triangle meshes for ray-cast

class vulky.vec2(*args, **kwargs)

Bases: _GTensorBase

dimension = 1
tensor_dtype = torch.float32
tensor_shape = (2,)
class vulky.vec3(*args, **kwargs)

Bases: _GTensorBase

classmethod cross(other, dim=None) Tensor

See torch.cross()

dimension = 1
tensor_dtype = torch.float32
tensor_shape = (3,)
class vulky.vec4(*args, **kwargs)

Bases: _GTensorBase

dimension = 1
tensor_dtype = torch.float32
tensor_shape = (4,)
vulky.vertex_buffer(count: int, element_description: type | dtype | Layout | Dict | List, memory: MemoryLocation = MemoryLocation.GPU) StructuredBuffer

Creates a buffer for a structured store. Each index is a Uniform that can be updated (cpu version) accessing to the fields. To finally update the resource (in case is allocated on the gpu) use flush_cpu().

vulky.window(width: int, height: int, format: Format = Format.VEC4) Window

Creates a window with specific client size and a format for the background image.

Parameters:
  • width (int) – Defines the width in pixels of the window client area

  • height (int) – Defines the height in pixels of the window client area

  • format (Format) – Defines the type of the background image for the window. If used Format.PRESENTER the gamma correction is applied automatically.

Return type:

The window object already shown.

Example

>>> window = vk.window(512, 512, vk.Format.VEC4)
>>> while not window.is_closed:
>>>     # Place some imgui commands here
>>>     window.tensor().copy_(torch.rand(512,512,4))  # copies a random tensor to the background
vulky.wrap_gpu(t: Any, mode: Literal['in', 'out', 'inout'] = 'in') GPUPtr

Wraps an object to be accessible from/to the GPU depending on the mode. Returned object can be assigned to fields of type int64_t and use as reference buffers.

Example

>>> import vulky as vk
>>> # ... initialization
>>> b = vk.object_buffer(vk.Layout.from_structure(
>>>     ptr=torch.int64  # Ptrs in vulkan are identified with int64 type of torch
>>> ))
>>> t = torch.zeros(3, 5, device='cuda')
>>> with b:
>>>     b.ptr = vk.wrap_gpu(t, 'inout')