Documentation
¶
Overview ¶
Package vulkan provides cross-platform GPU acceleration using Vulkan Compute.
This package implements GPU-accelerated vector similarity search using Vulkan's compute shaders, providing high-performance, cross-platform GPU acceleration for Windows, Linux, macOS (via MoltenVK), and Android.
Requirements ¶
For all platforms:
- Vulkan SDK: https://vulkan.lunarg.com/
- GPU with Vulkan 1.1+ support
For Linux:
# Ubuntu/Debian sudo apt install vulkan-tools libvulkan-dev vulkan-validationlayers # Fedora sudo dnf install vulkan-tools vulkan-loader-devel vulkan-validation-layers
For Windows:
- Install Vulkan SDK from LunarG
- Set VULKAN_SDK environment variable
For macOS (via MoltenVK):
- brew install molten-vk
- Or install via Vulkan SDK for macOS
Build Tags ¶
This package is only compiled when the "vulkan" build tag is present:
go build -tags vulkan
Environment Variables ¶
Linux:
export VULKAN_SDK=/path/to/vulkan/sdk export LD_LIBRARY_PATH=$VULKAN_SDK/lib:$LD_LIBRARY_PATH
Windows:
Set VULKAN_SDK to SDK installation path
macOS:
export VULKAN_SDK=/path/to/vulkan/sdk export VK_ICD_FILENAMES=$VULKAN_SDK/share/vulkan/icd.d/MoltenVK_icd.json
Architecture ¶
The Vulkan backend uses:
- Vulkan Compute Shaders (SPIR-V) for GPU operations
- Push constants for small uniform data (query vectors)
- Storage buffers for large data (embeddings, scores)
- Compute command buffers for GPU dispatch
- Descriptor sets for resource binding
Performance Considerations ¶
Vulkan provides:
- Low-level control for maximum performance
- Cross-platform GPU access (NVIDIA, AMD, Intel, Apple via MoltenVK)
- Explicit memory management for optimal GPU utilization
- Async compute for overlapping CPU/GPU work
For best results:
- Use large batch sizes to amortize dispatch overhead
- Keep data on GPU across multiple searches
- Pre-normalize embeddings when possible
Example ¶
Basic usage:
device, err := vulkan.NewDevice(0)
if err != nil {
log.Fatal(err)
}
defer device.Release()
buffer, err := device.NewBuffer(embeddings)
if err != nil {
log.Fatal(err)
}
defer buffer.Release()
results, err := device.Search(buffer, query, numVectors, dimensions, topK, normalized)
if err != nil {
log.Fatal(err)
}
for _, r := range results {
fmt.Printf("Index: %d, Score: %.4f\n", r.Index, r.Score)
}
Package vulkan provides cross-platform GPU acceleration using Vulkan Compute.
This implementation uses purego for FFI to dynamically load the Vulkan library, enabling GPU acceleration without CGO compilation. This is similar to how yzma provides llama.cpp bindings.
Supported Platforms:
- Windows: Loads vulkan-1.dll (included with NVIDIA/AMD drivers)
- Linux: Loads libvulkan.so.1 (from Vulkan SDK or mesa)
- macOS: Loads libvulkan.dylib (from MoltenVK or Vulkan SDK)
The library is automatically detected from standard locations:
- System PATH
- GPU driver directories
- Vulkan SDK installation
Package vulkan provides cross-platform GPU acceleration using Vulkan Compute. This file handles Unix-like systems (Linux, macOS/MoltenVK).
Index ¶
- Constants
- Variables
- func DeviceCount() int
- func IsAvailable() bool
- type Buffer
- type ComputeContext
- func (c *ComputeContext) CosineSimilarityGPU(embeddings, query, scores *Buffer, n, dimensions uint32, normalized bool) error
- func (c *ComputeContext) HNSWBuildTopK(frontier, queries *Buffer, scoresBuf, indicesBuf, topkScoresBuf *Buffer, ...) error
- func (c *ComputeContext) NormalizeVectorsGPU(vectors *Buffer, n, dimensions uint32) error
- func (c *ComputeContext) Release()
- func (c *ComputeContext) SearchGPU(embeddings *Buffer, query []float32, n, dimensions uint32, k int, ...) ([]SearchResult, error)
- func (c *ComputeContext) TopKGPU(scores, topIndices, topScores *Buffer, n, k uint32) error
- type ComputePipeline
- type Device
- func (d *Device) CosineSimilarity(embeddings, query, scores *Buffer, n, dimensions uint32, normalized bool) error
- func (d *Device) ID() int
- func (d *Device) MemoryBytes() uint64
- func (d *Device) MemoryMB() int
- func (d *Device) Name() string
- func (d *Device) NewBuffer(data []float32) (*Buffer, error)
- func (d *Device) NewComputeContext() (*ComputeContext, error)
- func (d *Device) NewEmptyBuffer(count uint64) (*Buffer, error)
- func (d *Device) NormalizeVectors(vectors *Buffer, n, dimensions uint32) error
- func (d *Device) Release()
- func (d *Device) Search(embeddings *Buffer, query []float32, n, dimensions uint32, k int, ...) ([]SearchResult, error)
- func (d *Device) TopK(scores *Buffer, n, k uint32) ([]uint32, []float32, error)
- type PipelineType
- type SearchResult
- type VkApplicationInfo
- type VkBuffer
- type VkBufferCreateInfo
- type VkCommandBuffer
- type VkCommandBufferAllocateInfo
- type VkCommandBufferBeginInfo
- type VkCommandPool
- type VkCommandPoolCreateInfo
- type VkComputePipelineCreateInfo
- type VkDescriptorBufferInfo
- type VkDescriptorPool
- type VkDescriptorPoolCreateInfo
- type VkDescriptorPoolSize
- type VkDescriptorSet
- type VkDescriptorSetAllocateInfo
- type VkDescriptorSetLayout
- type VkDescriptorSetLayoutBinding
- type VkDescriptorSetLayoutCreateInfo
- type VkDevice
- type VkDeviceCreateInfo
- type VkDeviceMemory
- type VkDeviceQueueCreateInfo
- type VkDeviceSize
- type VkFence
- type VkInstance
- type VkInstanceCreateInfo
- type VkMemoryAllocateInfo
- type VkMemoryBarrier
- type VkMemoryHeap
- type VkMemoryRequirements
- type VkMemoryType
- type VkPhysicalDevice
- type VkPhysicalDeviceMemoryProperties
- type VkPhysicalDeviceProperties
- type VkPipeline
- type VkPipelineLayout
- type VkPipelineLayoutCreateInfo
- type VkPipelineShaderStageCreateInfo
- type VkPushConstantRange
- type VkQueue
- type VkQueueFamilyProperties
- type VkResult
- type VkShaderModule
- type VkShaderModuleCreateInfo
- type VkSubmitInfo
- type VkWriteDescriptorSet
Constants ¶
const ( VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO = 16 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO = 18 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO = 29 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO = 30 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO = 32 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO = 33 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO = 34 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET = 35 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO = 40 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO = 42 VK_STRUCTURE_TYPE_SUBMIT_INFO = 4 VK_SHADER_STAGE_COMPUTE_BIT = 0x00000020 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER = 7 VK_COMMAND_BUFFER_LEVEL_PRIMARY = 0 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT = 0x00000001 VK_PIPELINE_BIND_POINT_COMPUTE = 1 VK_STRUCTURE_TYPE_MEMORY_BARRIER = 30 VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT = 0x00000020 VK_ACCESS_SHADER_WRITE_BIT = 0x00000800 VK_ACCESS_SHADER_READ_BIT = 0x00000020 )
Additional Vulkan constants for compute pipelines
const ( VK_SUCCESS = 0 VK_NOT_READY = 1 VK_TIMEOUT = 2 VK_ERROR_OUT_OF_HOST_MEMORY = -1 VK_ERROR_OUT_OF_DEVICE_MEMORY = -2 VK_ERROR_INITIALIZATION_FAILED = -3 VK_ERROR_DEVICE_LOST = -4 VK_STRUCTURE_TYPE_APPLICATION_INFO = 0 VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO = 1 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO = 2 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO = 3 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO = 12 VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO = 5 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO = 39 VK_API_VERSION_1_1 = uint32(0x00401000) // Version 1.1.0 VK_QUEUE_COMPUTE_BIT = 0x00000002 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT = 0x00000020 VK_BUFFER_USAGE_TRANSFER_SRC_BIT = 0x00000001 VK_BUFFER_USAGE_TRANSFER_DST_BIT = 0x00000002 VK_SHARING_MODE_EXCLUSIVE = 0 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT = 0x00000002 VK_MEMORY_PROPERTY_HOST_COHERENT_BIT = 0x00000004 VK_MEMORY_HEAP_DEVICE_LOCAL_BIT = 0x00000001 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT = 0x00000002 )
Vulkan constants
Variables ¶
var ( ErrVulkanNotAvailable = errors.New("vulkan: Vulkan is not available (library not found)") ErrDeviceCreation = errors.New("vulkan: failed to create Vulkan device") ErrBufferCreation = errors.New("vulkan: failed to create buffer") ErrKernelExecution = errors.New("vulkan: kernel execution failed") ErrInvalidBuffer = errors.New("vulkan: invalid buffer") )
Errors
Functions ¶
func IsAvailable ¶
func IsAvailable() bool
IsAvailable checks if Vulkan is available on this system.
Types ¶
type Buffer ¶
type Buffer struct {
// contains filtered or unexported fields
}
Buffer represents a Vulkan memory buffer.
func (*Buffer) ReadFloat32 ¶
ReadFloat32 reads float32 values from the buffer.
func (*Buffer) ReadUint32 ¶
ReadUint32 reads uint32 values from the buffer.
type ComputeContext ¶
type ComputeContext struct {
// contains filtered or unexported fields
}
ComputeContext holds resources for compute operations
func (*ComputeContext) CosineSimilarityGPU ¶
func (c *ComputeContext) CosineSimilarityGPU(embeddings, query, scores *Buffer, n, dimensions uint32, normalized bool) error
CosineSimilarityGPU computes cosine similarity using GPU compute shader
func (*ComputeContext) HNSWBuildTopK ¶ added in v1.1.11
func (c *ComputeContext) HNSWBuildTopK(frontier, queries *Buffer, scoresBuf, indicesBuf, topkScoresBuf *Buffer, frontierN, queryN, dimensions uint32, k int) error
HNSWBuildTopK computes batched cosine top-k for HNSW construction.
The frontier and query buffers must contain normalized vectors in row-major layout: frontier is [frontierN x dimensions], queries is [queryN x dimensions]. Uses pre-allocated descriptor sets and command buffer to avoid per-call allocation overhead. Both dispatches execute in a single GPU submission.
func (*ComputeContext) NormalizeVectorsGPU ¶
func (c *ComputeContext) NormalizeVectorsGPU(vectors *Buffer, n, dimensions uint32) error
NormalizeVectorsGPU normalizes vectors using GPU compute shader
func (*ComputeContext) Release ¶
func (c *ComputeContext) Release()
Release frees all compute context resources
func (*ComputeContext) SearchGPU ¶
func (c *ComputeContext) SearchGPU(embeddings *Buffer, query []float32, n, dimensions uint32, k int, normalized bool) ([]SearchResult, error)
SearchGPU performs complete similarity search on GPU
func (*ComputeContext) TopKGPU ¶
func (c *ComputeContext) TopKGPU(scores, topIndices, topScores *Buffer, n, k uint32) error
TopKGPU finds top-k scores using GPU compute shader. Uses an iterative reduction algorithm that works for any k value. Performance is optimal for k <= 64 (typical for similarity search). For larger k, the algorithm still works but may be slower (O(k×n) complexity).
type ComputePipeline ¶
type ComputePipeline struct {
// contains filtered or unexported fields
}
ComputePipeline represents a compiled compute shader pipeline
func (*ComputePipeline) Release ¶
func (p *ComputePipeline) Release()
Release frees pipeline resources
type Device ¶
type Device struct {
// contains filtered or unexported fields
}
Device represents a Vulkan GPU device.
func (*Device) CosineSimilarity ¶
func (d *Device) CosineSimilarity(embeddings, query, scores *Buffer, n, dimensions uint32, normalized bool) error
CosineSimilarity computes cosine similarity between query and all embeddings. This is a CPU implementation that uses GPU memory buffers.
func (*Device) MemoryBytes ¶
MemoryBytes returns the GPU memory size in bytes.
func (*Device) NewComputeContext ¶
func (d *Device) NewComputeContext() (*ComputeContext, error)
NewComputeContext creates a new compute context with shader pipelines
func (*Device) NewEmptyBuffer ¶
NewEmptyBuffer creates an uninitialized GPU buffer.
func (*Device) NormalizeVectors ¶
NormalizeVectors normalizes vectors in-place to unit length. This is a CPU implementation as compute shaders require more setup.
type PipelineType ¶
type PipelineType int
PipelineType identifies which shader to use
const ( PipelineCosineSimilarity PipelineType = iota PipelineNormalize PipelineTopK PipelineTopKFull PipelineHNSWBuildCosine PipelineHNSWBuildTopKRows )
type SearchResult ¶
SearchResult holds a similarity search result.
type VkApplicationInfo ¶
type VkApplicationInfo struct {
SType uint32
PNext uintptr
PApplicationName uintptr
ApplicationVersion uint32
PEngineName uintptr
EngineVersion uint32
ApiVersion uint32
}
VkApplicationInfo structure
type VkBufferCreateInfo ¶
type VkBufferCreateInfo struct {
SType uint32
PNext uintptr
Flags uint32
Size VkDeviceSize
Usage uint32
SharingMode uint32
QueueFamilyIndexCount uint32
PQueueFamilyIndices *uint32
}
VkBufferCreateInfo structure
type VkCommandBuffer ¶
type VkCommandBuffer uintptr
type VkCommandBufferAllocateInfo ¶
type VkCommandBufferAllocateInfo struct {
SType uint32
PNext uintptr
CommandPool VkCommandPool
Level uint32
CommandBufferCount uint32
}
VkCommandBufferAllocateInfo structure
type VkCommandBufferBeginInfo ¶
type VkCommandBufferBeginInfo struct {
SType uint32
PNext uintptr
Flags uint32
PInheritanceInfo uintptr
}
VkCommandBufferBeginInfo structure
type VkCommandPool ¶
type VkCommandPool uintptr
type VkCommandPoolCreateInfo ¶
type VkCommandPoolCreateInfo struct {
SType uint32
PNext uintptr
Flags uint32
QueueFamilyIndex uint32
}
VkCommandPoolCreateInfo structure
type VkComputePipelineCreateInfo ¶
type VkComputePipelineCreateInfo struct {
SType uint32
PNext uintptr
Flags uint32
Stage VkPipelineShaderStageCreateInfo
Layout VkPipelineLayout
BasePipelineHandle VkPipeline
BasePipelineIndex int32
}
VkComputePipelineCreateInfo structure
type VkDescriptorBufferInfo ¶
type VkDescriptorBufferInfo struct {
Buffer VkBuffer
Offset VkDeviceSize
Range VkDeviceSize
}
VkDescriptorBufferInfo structure
type VkDescriptorPool ¶
type VkDescriptorPool uintptr
type VkDescriptorPoolCreateInfo ¶
type VkDescriptorPoolCreateInfo struct {
SType uint32
PNext uintptr
Flags uint32
MaxSets uint32
PoolSizeCount uint32
PPoolSizes *VkDescriptorPoolSize
}
VkDescriptorPoolCreateInfo structure
type VkDescriptorPoolSize ¶
VkDescriptorPoolSize structure
type VkDescriptorSet ¶
type VkDescriptorSet uintptr
type VkDescriptorSetAllocateInfo ¶
type VkDescriptorSetAllocateInfo struct {
SType uint32
PNext uintptr
DescriptorPool VkDescriptorPool
DescriptorSetCount uint32
PSetLayouts *VkDescriptorSetLayout
}
VkDescriptorSetAllocateInfo structure
type VkDescriptorSetLayout ¶
type VkDescriptorSetLayout uintptr
type VkDescriptorSetLayoutBinding ¶
type VkDescriptorSetLayoutBinding struct {
Binding uint32
DescriptorType uint32
DescriptorCount uint32
StageFlags uint32
PImmutableSamplers uintptr
}
VkDescriptorSetLayoutBinding structure
type VkDescriptorSetLayoutCreateInfo ¶
type VkDescriptorSetLayoutCreateInfo struct {
SType uint32
PNext uintptr
Flags uint32
BindingCount uint32
PBindings *VkDescriptorSetLayoutBinding
}
VkDescriptorSetLayoutCreateInfo structure
type VkDeviceCreateInfo ¶
type VkDeviceCreateInfo struct {
SType uint32
PNext uintptr
Flags uint32
QueueCreateInfoCount uint32
PQueueCreateInfos *VkDeviceQueueCreateInfo
EnabledLayerCount uint32
PpEnabledLayerNames uintptr
EnabledExtensionCount uint32
PpEnabledExtensionNames uintptr
PEnabledFeatures uintptr
}
VkDeviceCreateInfo structure
type VkDeviceMemory ¶
type VkDeviceMemory uintptr
type VkDeviceQueueCreateInfo ¶
type VkDeviceQueueCreateInfo struct {
SType uint32
PNext uintptr
Flags uint32
QueueFamilyIndex uint32
QueueCount uint32
PQueuePriorities *float32
}
VkDeviceQueueCreateInfo structure
type VkDeviceSize ¶
type VkDeviceSize uint64
type VkInstanceCreateInfo ¶
type VkInstanceCreateInfo struct {
SType uint32
PNext uintptr
Flags uint32
PApplicationInfo *VkApplicationInfo
EnabledLayerCount uint32
PpEnabledLayerNames uintptr
EnabledExtensionCount uint32
PpEnabledExtensionNames uintptr
}
VkInstanceCreateInfo structure
type VkMemoryAllocateInfo ¶
type VkMemoryAllocateInfo struct {
SType uint32
PNext uintptr
AllocationSize VkDeviceSize
MemoryTypeIndex uint32
}
VkMemoryAllocateInfo structure
type VkMemoryBarrier ¶ added in v1.1.11
type VkMemoryBarrier struct {
SType uint32
PNext uintptr
SrcAccessMask uint32
DstAccessMask uint32
}
VkMemoryBarrier structure
type VkMemoryHeap ¶
type VkMemoryHeap struct {
Size VkDeviceSize
Flags uint32
}
VkMemoryHeap structure
type VkMemoryRequirements ¶
type VkMemoryRequirements struct {
Size VkDeviceSize
Alignment VkDeviceSize
MemoryTypeBits uint32
}
VkMemoryRequirements structure
type VkMemoryType ¶
VkMemoryType structure
type VkPhysicalDevice ¶
type VkPhysicalDevice uintptr
type VkPhysicalDeviceMemoryProperties ¶
type VkPhysicalDeviceMemoryProperties struct {
MemoryTypeCount uint32
MemoryTypes [32]VkMemoryType
MemoryHeapCount uint32
MemoryHeaps [16]VkMemoryHeap
}
VkPhysicalDeviceMemoryProperties structure
type VkPhysicalDeviceProperties ¶
type VkPhysicalDeviceProperties struct {
ApiVersion uint32
DriverVersion uint32
VendorID uint32
DeviceID uint32
DeviceType uint32
DeviceName [256]byte
PipelineCacheUUID [16]byte
Limits [512]byte // VkPhysicalDeviceLimits is large
SparseProperties [20]byte
}
VkPhysicalDeviceProperties structure
type VkPipeline ¶
type VkPipeline uintptr
type VkPipelineLayout ¶
type VkPipelineLayout uintptr
type VkPipelineLayoutCreateInfo ¶
type VkPipelineLayoutCreateInfo struct {
SType uint32
PNext uintptr
Flags uint32
SetLayoutCount uint32
PSetLayouts *VkDescriptorSetLayout
PushConstantRangeCount uint32
PPushConstantRanges *VkPushConstantRange
}
VkPipelineLayoutCreateInfo structure
type VkPipelineShaderStageCreateInfo ¶
type VkPipelineShaderStageCreateInfo struct {
SType uint32
PNext uintptr
Flags uint32
Stage uint32
Module VkShaderModule
PName uintptr
PSpecializationInfo uintptr
}
VkPipelineShaderStageCreateInfo structure
type VkPushConstantRange ¶
VkPushConstantRange structure
type VkQueueFamilyProperties ¶
type VkQueueFamilyProperties struct {
QueueFlags uint32
QueueCount uint32
TimestampValidBits uint32
MinImageTransferGranularity [3]uint32
}
VkQueueFamilyProperties structure
type VkShaderModuleCreateInfo ¶
type VkShaderModuleCreateInfo struct {
SType uint32
PNext uintptr
Flags uint32
CodeSize uintptr
PCode *uint32
}
VkShaderModuleCreateInfo structure
type VkSubmitInfo ¶
type VkSubmitInfo struct {
SType uint32
PNext uintptr
WaitSemaphoreCount uint32
PWaitSemaphores uintptr
PWaitDstStageMask uintptr
CommandBufferCount uint32
PCommandBuffers *VkCommandBuffer
SignalSemaphoreCount uint32
PSignalSemaphores uintptr
}
VkSubmitInfo structure
type VkWriteDescriptorSet ¶
type VkWriteDescriptorSet struct {
SType uint32
PNext uintptr
DstSet VkDescriptorSet
DstBinding uint32
DstArrayElement uint32
DescriptorCount uint32
DescriptorType uint32
PImageInfo uintptr
PBufferInfo *VkDescriptorBufferInfo
PTexelBufferView uintptr
}
VkWriteDescriptorSet structure