Skip to content

Commit b7e5cff

Browse files
authored
[ET-VK] Introduce TextureMetadata struct (#15317)
Title says it all! Introduce a utility struct `TextureMetadata` to make it easier to pass tensor metadata to compute shaders, as a direct equivalent to `BufferMetadata`. Differential Revision: [D84716457](https://our.internmc.facebook.com/intern/diff/D84716457/) [ghstack-poisoned]
1 parent 7bf27fe commit b7e5cff

File tree

4 files changed

+130
-0
lines changed

4 files changed

+130
-0
lines changed

backends/vulkan/runtime/api/containers/Tensor.cpp

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -836,6 +836,50 @@ void vTensor::BufferMetadata::update(
836836
numel = utils::safe_downcast<uint32_t>(src_numel);
837837
}
838838

839+
vTensor::TextureMetadata::TextureMetadata(
840+
const std::vector<int64_t>& src_sizes,
841+
const TextureLimits& src_logical_limits,
842+
const std::vector<int64_t>& src_axis_map,
843+
const int32_t src_packed_dim) {
844+
update(src_sizes, src_logical_limits, src_axis_map, src_packed_dim);
845+
}
846+
847+
void vTensor::TextureMetadata::update(
848+
const std::vector<int64_t>& src_sizes,
849+
const TextureLimits& src_logical_limits,
850+
const std::vector<int64_t>& src_axis_map,
851+
const int32_t src_packed_dim) {
852+
// Convert sizes to flipped and unsqueezed format (fixed to 4 dimensions for
853+
// texture)
854+
std::vector<int32_t> fu_sizes =
855+
flip_and_unsqueeze<int32_t>(src_sizes, kTensorSizes, 0, 4);
856+
857+
// Copy sizes (up to 4 elements)
858+
for (int i = 0; i < 4; ++i) {
859+
sizes[i] = fu_sizes.at(i);
860+
}
861+
862+
// Copy logical limits (3 elements)
863+
logical_limits[0] =
864+
utils::safe_downcast<int32_t>(src_logical_limits.limits[0]);
865+
logical_limits[1] =
866+
utils::safe_downcast<int32_t>(src_logical_limits.limits[1]);
867+
logical_limits[2] =
868+
utils::safe_downcast<int32_t>(src_logical_limits.limits[2]);
869+
logical_limits[3] = 1u;
870+
871+
// Copy axis map (up to 4 elements)
872+
for (int i = 0; i < 4 && i < src_axis_map.size(); ++i) {
873+
axis_map[i] = utils::safe_downcast<int32_t>(src_axis_map.at(i));
874+
}
875+
// Pad with zeros if axis_map is smaller than 4
876+
for (int i = src_axis_map.size(); i < 4; ++i) {
877+
axis_map[i] = 0;
878+
}
879+
880+
packed_dim = src_packed_dim;
881+
}
882+
839883
vkapi::VulkanImage& vTensor::image(
840884
vkapi::PipelineBarrier& pipeline_barrier,
841885
const vkapi::PipelineStageFlags stage) & {
@@ -948,6 +992,16 @@ const vkapi::BufferBindInfo vTensor::buffer_meta_ubo() {
948992
return vkapi::BufferBindInfo(buffer_meta_.buffer(), 0, ubo_nbytes);
949993
}
950994

995+
const vkapi::BufferBindInfo vTensor::texture_meta_ubo() {
996+
size_t ubo_nbytes = sizeof(TextureMetadata);
997+
if (!texture_meta_.buffer()) {
998+
TextureLimits limits(logical_limits());
999+
TextureMetadata data(sizes_, limits, axis_map_, packed_dim_);
1000+
texture_meta_ = ParamsBuffer(storage_->context_, data);
1001+
}
1002+
return vkapi::BufferBindInfo(texture_meta_.buffer(), 0, ubo_nbytes);
1003+
}
1004+
9511005
VkMemoryRequirements vTensor::get_memory_requirements() const {
9521006
switch (storage_type()) {
9531007
case utils::kBuffer:
@@ -1031,6 +1085,12 @@ void vTensor::update_metadata() {
10311085
BufferMetadata data(sizes_, dim_order_, strides_, numel_);
10321086
buffer_meta_.update(data);
10331087
}
1088+
1089+
if (texture_meta_.buffer()) {
1090+
TextureMetadata data(
1091+
sizes_, uniform_data_->logical_limits, axis_map_, packed_dim_);
1092+
texture_meta_.update(data);
1093+
}
10341094
}
10351095

10361096
void vTensor::check_sizes(const std::vector<int64_t>& sizes) const {

backends/vulkan/runtime/api/containers/Tensor.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,25 @@ class vTensor final {
285285
size_t numel);
286286
};
287287

288+
struct TextureMetadata {
289+
int32_t sizes[4];
290+
int32_t logical_limits[4];
291+
int32_t axis_map[4];
292+
int32_t packed_dim;
293+
294+
TextureMetadata(
295+
const std::vector<int64_t>& sizes,
296+
const TextureLimits& logical_limits,
297+
const std::vector<int64_t>& axis_map,
298+
const int32_t packed_dim);
299+
300+
void update(
301+
const std::vector<int64_t>& sizes,
302+
const TextureLimits& logical_limits,
303+
const std::vector<int64_t>& axis_map,
304+
const int32_t packed_dim);
305+
};
306+
288307
private:
289308
/*
290309
* "Core" tensor metadata. They are the minimum amount of information required
@@ -360,6 +379,12 @@ class vTensor final {
360379
*/
361380
ParamsBuffer buffer_meta_;
362381

382+
/*
383+
* Used to store data for TextureMetadata to pass to shaders as
384+
* texture_meta_ubo
385+
*/
386+
ParamsBuffer texture_meta_;
387+
363388
uint32_t uniforms_size_ = 0u;
364389
uint32_t sizes_uniform_offset_ = kUniformOffsetUnset;
365390
uint32_t dim_order_uniform_offset_ = kUniformOffsetUnset;
@@ -587,6 +612,8 @@ class vTensor final {
587612

588613
const vkapi::BufferBindInfo buffer_meta_ubo();
589614

615+
const vkapi::BufferBindInfo texture_meta_ubo();
616+
590617
public:
591618
inline size_t staging_buffer_numel() const {
592619
return storage_->buffer_len();

backends/vulkan/runtime/graph/ComputeGraph.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,18 @@ class ComputeGraph final {
449449
return values_.at(idx).toTensor().buffer_meta_ubo();
450450
}
451451

452+
inline vkapi::BufferBindInfo texture_meta_ubo(const ValueRef idx) {
453+
return values_.at(idx).toTensor().texture_meta_ubo();
454+
}
455+
456+
inline vkapi::BufferBindInfo meta_ubo(const ValueRef idx) {
457+
if (is_buffer_storage(idx)) {
458+
return buffer_meta_ubo(idx);
459+
} else {
460+
return texture_meta_ubo(idx);
461+
}
462+
}
463+
452464
inline vkapi::BufferBindInfo strides_ubo(const ValueRef idx) {
453465
return values_.at(idx).toTensor().strides_ubo();
454466
}

backends/vulkan/runtime/graph/ops/glsl/indexing.glslh

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,25 @@ bool are_equal(const BufferMetadata meta1, const BufferMetadata meta2) {
8181
return true;
8282
}
8383

84+
bool out_of_bounds(const uint bufi, const BufferMetadata meta) {
85+
return bufi >= meta.ndim_numel[1];
86+
}
87+
88+
//
89+
// TextureMetadata
90+
//
91+
92+
struct TextureMetadata {
93+
ivec4 sizes;
94+
ivec3 limits;
95+
ivec4 axis_map;
96+
int packed_dim;
97+
};
98+
99+
bool out_of_bounds(const ivec3 pos, const TextureMetadata meta) {
100+
return any(greaterThanEqual(pos, meta.limits));
101+
}
102+
84103
//
85104
// TensorIndex
86105
//
@@ -186,6 +205,8 @@ void clamp_tensor_idx(const BufferMetadata meta, inout TensorIndex tidx) {
186205

187206
#ifdef DEBUG_MODE
188207

208+
#extension GL_EXT_debug_printf : enable
209+
189210
void printTensorIndex(const TensorIndex tidx) {
190211
debugPrintfEXT(
191212
"TensorIndex: tidx=[%u %u %u %u %u %u %u %u]\\n",
@@ -211,6 +232,16 @@ void printBufferMetadata(const BufferMetadata meta) {
211232
);
212233
}
213234

235+
void printTextureMetadata(const TextureMetadata meta) {
236+
debugPrintfEXT(
237+
"TextureMetadata:\\n sizes=[%u %u %u %u]\\n limits=[%u %u %u]\\n axis_map=[%u %u %u %u]\\n packed_dim=%u\\n",
238+
meta.sizes[0], meta.sizes[1], meta.sizes[2], meta.sizes[3],
239+
meta.limits[0], meta.limits[1], meta.limits[2],
240+
meta.axis_map[0], meta.axis_map[1], meta.axis_map[2], meta.axis_map[3],
241+
meta.packed_dim
242+
);
243+
}
244+
214245
#endif
215246

216247
#endif // INDEXING_GLSLH

0 commit comments

Comments
 (0)