Skip to content

[ET-VK] Fix metadata UBO VVL warnings #7480

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 27 additions & 16 deletions backends/vulkan/runtime/api/containers/Tensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -658,66 +658,77 @@ utils::GPUMemoryLayout vTensor::estimate_memory_layout() const {
}

const vkapi::BufferBindInfo vTensor::sizes_ubo() {
const size_t size_per_ubo = context()->adapter_ptr()->min_ubo_alignment();
const size_t max_ubo_size = kMaxMetadataFieldCount * size_per_ubo;
if (!uniforms_.buffer()) {
uniforms_ = ParamsBuffer(storage_.context_, kMaxUniformBufferSize, true);
uniforms_ = ParamsBuffer(storage_.context_, max_ubo_size, true);
}
if (sizes_uniform_offset_ == kUniformOffsetUnset) {
VK_CHECK_COND(
(uniforms_size_ + kSizePerUniform) <= kMaxUniformBufferSize,
(uniforms_size_ + size_per_ubo) <= max_ubo_size,
"Uniform data allocation has exceeded Tensor uniform buffer size");
sizes_uniform_offset_ = uniforms_size_;
uniforms_size_ += kSizePerUniform;
uniforms_size_ += size_per_ubo;
uniforms_.update(utils::make_whcn_ivec4(sizes_), sizes_uniform_offset_);
}
return vkapi::BufferBindInfo(uniforms_.buffer(), sizes_uniform_offset_);
return vkapi::BufferBindInfo(
uniforms_.buffer(), sizes_uniform_offset_, size_per_ubo);
}

const vkapi::BufferBindInfo vTensor::strides_ubo() {
const size_t size_per_ubo = context()->adapter_ptr()->min_ubo_alignment();
const size_t max_ubo_size = kMaxMetadataFieldCount * size_per_ubo;
if (!uniforms_.buffer()) {
uniforms_ = ParamsBuffer(storage_.context_, kMaxUniformBufferSize, true);
uniforms_ = ParamsBuffer(storage_.context_, max_ubo_size, true);
}
if (unsqueezed_strides_offset_ == kUniformOffsetUnset) {
VK_CHECK_COND(
(uniforms_size_ + kSizePerUniform) <= kMaxUniformBufferSize,
(uniforms_size_ + size_per_ubo) <= max_ubo_size,
"Uniform data allocation has exceeded Tensor uniform buffer size");
unsqueezed_strides_offset_ = uniforms_size_;
uniforms_size_ += kSizePerUniform;
uniforms_size_ += size_per_ubo;
uniforms_.update(
utils::make_whcn_ivec4(unsqueezed_strides_),
unsqueezed_strides_offset_);
}
return vkapi::BufferBindInfo(uniforms_.buffer(), unsqueezed_strides_offset_);
return vkapi::BufferBindInfo(
uniforms_.buffer(), unsqueezed_strides_offset_, size_per_ubo);
}

const vkapi::BufferBindInfo vTensor::logical_limits_ubo() {
const size_t size_per_ubo = context()->adapter_ptr()->min_ubo_alignment();
const size_t max_ubo_size = kMaxMetadataFieldCount * size_per_ubo;
if (!uniforms_.buffer()) {
uniforms_ = ParamsBuffer(storage_.context_, kMaxUniformBufferSize, true);
uniforms_ = ParamsBuffer(storage_.context_, max_ubo_size, true);
}
if (logical_limits_uniform_offset_ == kUniformOffsetUnset) {
VK_CHECK_COND(
(uniforms_size_ + kSizePerUniform) <= kMaxUniformBufferSize,
(uniforms_size_ + size_per_ubo) <= max_ubo_size,
"Uniform data allocation has exceeded Tensor uniform buffer size");
logical_limits_uniform_offset_ = uniforms_size_;
uniforms_size_ += kSizePerUniform;
uniforms_size_ += size_per_ubo;
uniforms_.update(logical_limits(), logical_limits_uniform_offset_);
}
return vkapi::BufferBindInfo(
uniforms_.buffer(), logical_limits_uniform_offset_);
uniforms_.buffer(), logical_limits_uniform_offset_, size_per_ubo);
}

const vkapi::BufferBindInfo vTensor::numel_ubo() {
const size_t size_per_ubo = context()->adapter_ptr()->min_ubo_alignment();
const size_t max_ubo_size = kMaxMetadataFieldCount * size_per_ubo;
if (!uniforms_.buffer()) {
uniforms_ = ParamsBuffer(storage_.context_, kMaxUniformBufferSize, true);
uniforms_ = ParamsBuffer(storage_.context_, max_ubo_size, true);
}
if (numel_uniform_offset_ == kUniformOffsetUnset) {
VK_CHECK_COND(
(uniforms_size_ + kSizePerUniform) <= kMaxUniformBufferSize,
(uniforms_size_ + size_per_ubo) <= max_ubo_size,
"Uniform data allocation has exceeded Tensor uniform buffer size");
numel_uniform_offset_ = uniforms_size_;
uniforms_size_ += kSizePerUniform;
uniforms_size_ += size_per_ubo;
uniforms_.update(numel(), numel_uniform_offset_);
}
return vkapi::BufferBindInfo(uniforms_.buffer(), numel_uniform_offset_);
return vkapi::BufferBindInfo(
uniforms_.buffer(), numel_uniform_offset_, size_per_ubo);
}

size_t vTensor::staging_buffer_numel() const {
Expand Down
17 changes: 7 additions & 10 deletions backends/vulkan/runtime/api/containers/Tensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -348,16 +348,13 @@ class vTensor final {
uint32_t numel_uniform_offset_;
uint32_t logical_limits_uniform_offset_;

// Size allocated for each uniform
// each uniform is assumed to be a vec of 4 ints to maintain 16 byte alignemnt
constexpr static size_t kSizePerUniform = sizeof(utils::ivec4);
// Total size of tensor's uniform buffer
constexpr static size_t kMaxUniformBufferSize =
4 * // we have 4 uniforms that are passed on to shaders
kSizePerUniform;

// Initial value of uniform buffer offsets
constexpr static uint32_t kUniformOffsetUnset = kMaxUniformBufferSize;
// Maximum number of metadata fields that can be stored in the metadata UBO.
// This is used to calculate the size of the UBO that should be allocated.
constexpr static size_t kMaxMetadataFieldCount = 4;

// Initial value of uniform buffer offsets. 1 is selected as it is essentially
// impossible for a ubo to have an offset of 1.
constexpr static uint32_t kUniformOffsetUnset = 1;

vTensorStorage storage_;

Expand Down
4 changes: 4 additions & 0 deletions backends/vulkan/runtime/vk_api/Adapter.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,10 @@ class Adapter final {
return supports_8bit_storage_buffers() && supports_int8_shader_types();
}

inline size_t min_ubo_alignment() const {
return physical_device_.min_ubo_alignment;
}

// Command Buffer Submission

void
Expand Down
12 changes: 11 additions & 1 deletion backends/vulkan/runtime/vk_api/Descriptor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,17 @@ BufferBindInfo::BufferBindInfo(
const uint32_t offset_p)
: handle(buffer_p.handle()),
offset(buffer_p.mem_offset() + offset_p),
range(buffer_p.mem_range()) {}
range(buffer_p.mem_range() - offset_p) {}

BufferBindInfo::BufferBindInfo(
const VulkanBuffer& buffer_p,
const uint32_t offset_p,
const uint32_t range_p)
: handle(buffer_p.handle()),
offset(buffer_p.mem_offset() + offset_p),
range(range_p) {
VK_CHECK_COND(range_p <= (buffer_p.mem_range() - offset_p));
}

//
// ParamsBindList
Expand Down
4 changes: 4 additions & 0 deletions backends/vulkan/runtime/vk_api/Descriptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ struct BufferBindInfo final {

BufferBindInfo();
BufferBindInfo(const VulkanBuffer& buffer_p, const uint32_t offset_p = 0u);
BufferBindInfo(
const VulkanBuffer& buffer_p,
const uint32_t offset_p,
const uint32_t range_p);
};

struct ParamsBindList final {
Expand Down
11 changes: 9 additions & 2 deletions backends/vulkan/runtime/vk_api/Device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,17 @@ PhysicalDevice::PhysicalDevice(VkPhysicalDevice physical_device_handle)
num_compute_queues(0),
supports_int16_shader_types(false),
has_unified_memory(false),
has_timestamps(properties.limits.timestampComputeAndGraphics),
timestamp_period(properties.limits.timestampPeriod) {
has_timestamps(false),
timestamp_period(0),
min_ubo_alignment(0) {
// Extract physical device properties
vkGetPhysicalDeviceProperties(handle, &properties);

// Extract fields of interest
has_timestamps = properties.limits.timestampComputeAndGraphics;
timestamp_period = properties.limits.timestampPeriod;
min_ubo_alignment = properties.limits.minUniformBufferOffsetAlignment;

vkGetPhysicalDeviceMemoryProperties(handle, &memory_properties);

VkPhysicalDeviceFeatures2 features2{
Expand Down
1 change: 1 addition & 0 deletions backends/vulkan/runtime/vk_api/Device.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ struct PhysicalDevice final {
bool has_unified_memory;
bool has_timestamps;
float timestamp_period;
size_t min_ubo_alignment;

explicit PhysicalDevice(VkPhysicalDevice);
};
Expand Down
Loading