77 */
88
99#include < executorch/backends/vulkan/runtime/api/containers/Tensor.h>
10+ #include < cstring>
1011
1112namespace vkcompute {
1213namespace api {
@@ -446,11 +447,10 @@ vTensor::vTensor(
446447 dim_order_(calculate_dim_order(sizes_.size(), packed_dim_)),
447448 axis_map_(default_axis_map()),
448449 strides_(calculate_strides(sizes, dim_order_)),
449- numel_(utils::multiply_integers(sizes_)),
450450 padded_sizes_{calculate_padded_sizes (sizes, packed_dim_)},
451- unsqueezed_strides_{unsqueeze_strides (strides_, numel_)},
451+ unsqueezed_strides_{
452+ unsqueeze_strides (strides_, utils::multiply_integers (sizes_))},
452453 padded_numel_ (utils::multiply_integers(padded_sizes_)),
453- logical_limits_{{0 , 0 , 0 }},
454454 uniforms_(),
455455 // Utility Uniform Buffers that can be passed to shaders as arguments
456456 uniforms_size_(0 ),
@@ -467,6 +467,11 @@ vTensor::vTensor(
467467 padded_sizes_,
468468 dtype_,
469469 allocate_memory) {
470+ uniform_data_ = std::make_shared<UniformData>(UniformData{
471+ sizes_,
472+ unsqueezed_strides_,
473+ {{0 , 0 , 0 }},
474+ static_cast <size_t >(utils::multiply_integers (sizes_))});
470475 VK_CHECK_COND (
471476 dim_order_is_valid (dim_order_), " computed dim order is invalid" );
472477
@@ -494,11 +499,9 @@ vTensor::vTensor(
494499 dim_order_(),
495500 axis_map_(default_axis_map()),
496501 strides_(),
497- numel_(utils::multiply_integers(sizes_)),
498502 padded_sizes_(calculate_padded_sizes(sizes_, packed_dim_)),
499503 unsqueezed_strides_(),
500504 padded_numel_(utils::multiply_integers(padded_sizes_)),
501- logical_limits_(),
502505 uniforms_(),
503506 // Utility Uniform Buffers that can be passed to shaders as arguments
504507 uniforms_size_(0 ),
@@ -508,6 +511,11 @@ vTensor::vTensor(
508511 logical_limits_uniform_offset_(kUniformOffsetUnset ),
509512 // Construct Tensor storage
510513 storage_(context, image) {
514+ uniform_data_ = std::make_shared<UniformData>(UniformData{
515+ sizes_,
516+ {0 , 0 , 0 , 0 },
517+ {{0 , 0 , 0 }},
518+ static_cast <size_t >(utils::multiply_integers (sizes_))});
511519 set_logical_limits (storage_.image_extents_ );
512520}
513521
@@ -519,13 +527,11 @@ vTensor::vTensor(vTensor& other)
519527 dim_order_ (other.dim_order_.begin(), other.dim_order_.end()),
520528 axis_map_(other.axis_map_.begin(), other.axis_map_.end()),
521529 strides_(other.strides_.begin(), other.strides_.end()),
522- numel_(other.numel_),
523530 padded_sizes_{other.padded_sizes_ .begin (), other.padded_sizes_ .end ()},
524531 unsqueezed_strides_{
525532 other.unsqueezed_strides_ .begin (),
526533 other.unsqueezed_strides_ .end ()},
527534 padded_numel_ (other.padded_numel_),
528- logical_limits_{other.logical_limits_ },
529535 uniforms_(),
530536 // Empty initialize Utility Uniform Buffers
531537 uniforms_size_(0 ),
@@ -534,7 +540,9 @@ vTensor::vTensor(vTensor& other)
534540 numel_uniform_offset_(kUniformOffsetUnset ),
535541 logical_limits_uniform_offset_(kUniformOffsetUnset ),
536542 // Copy Tensor storage
537- storage_(other.storage_) {}
543+ storage_(other.storage_) {
544+ uniform_data_ = std::make_shared<UniformData>(*other.get_uniform_data ());
545+ }
538546
539547vTensor::vTensor (
540548 vTensor& other,
@@ -548,11 +556,10 @@ vTensor::vTensor(
548556 dim_order_(dim_order.begin(), dim_order.end()),
549557 axis_map_(default_axis_map()),
550558 strides_(calculate_strides(sizes_, dim_order_)),
551- numel_(utils::multiply_integers(sizes_)),
552559 padded_sizes_{calculate_padded_sizes (sizes, packed_dim_)},
553- unsqueezed_strides_{unsqueeze_strides (strides_, numel_)},
560+ unsqueezed_strides_{
561+ unsqueeze_strides (strides_, utils::multiply_integers (sizes_))},
554562 padded_numel_ (utils::multiply_integers(padded_sizes_)),
555- logical_limits_(other.logical_limits_),
556563 uniforms_(),
557564 // Empty initialize Utility Uniform Buffers
558565 uniforms_size_(0 ),
@@ -562,14 +569,45 @@ vTensor::vTensor(
562569 logical_limits_uniform_offset_(kUniformOffsetUnset ),
563570 // Copy Tensor storage
564571 storage_(other.storage_, vkapi::element_size(dtype_) * offset_numel) {
572+ uniform_data_ = std::make_shared<UniformData>(UniformData{
573+ sizes_,
574+ unsqueezed_strides_,
575+ {other.logical_limits ()},
576+ static_cast <size_t >(utils::multiply_integers (sizes_))});
577+
565578 VK_CHECK_COND (
566579 dim_order_is_valid (dim_order_), " new dim order provided is invalid" );
567580 VK_CHECK_COND (
568- offset_numel + numel_ <= other.numel (),
581+ offset_numel + numel () <= other.numel (),
569582 " Tensor alias cannot access more elements than available in the original"
570583 " tensor" );
571584}
572585
586+ uint32_t vTensor::UniformData::write_attribute (
587+ void * dst,
588+ const uint32_t dst_offset,
589+ const uint32_t max_dst_size,
590+ const Attribute attr) {
591+ #define WRITE_ATTRIBUTE_CASE (enum_name, member_name ) \
592+ case vTensor::Attribute::enum_name: { \
593+ VK_CHECK_COND ( \
594+ (dst_offset + sizeof (member_name)) <= max_dst_size, \
595+ " Attempting to write tensor attribute outside data boundary." ); \
596+ memcpy ((uint8_t *)dst + dst_offset, &member_name, sizeof (member_name)); \
597+ return sizeof (member_name); \
598+ }
599+ switch (attr) {
600+ WRITE_ATTRIBUTE_CASE (SIZES, sizes_v);
601+ WRITE_ATTRIBUTE_CASE (STRIDES, strides_v);
602+ WRITE_ATTRIBUTE_CASE (LOGICAL_LIMITS, logical_limits);
603+ WRITE_ATTRIBUTE_CASE (NUMEL, numel);
604+ default :
605+ VK_THROW (" Invalid Attribute" );
606+ }
607+ #undef WRITE_ATTRIBUTE_CASE
608+ return 0 ;
609+ }
610+
573611vkapi::VulkanImage& vTensor::image (
574612 vkapi::PipelineBarrier& pipeline_barrier,
575613 const vkapi::PipelineStageFlags stage) & {
@@ -601,9 +639,9 @@ vkapi::VulkanBuffer& vTensor::buffer(
601639}
602640
603641void vTensor::set_logical_limits (const utils::uvec3& image_extents) {
604- logical_limits_ .limits [0 ] = image_extents[axis_map_.at (0 )];
605- logical_limits_ .limits [1 ] = image_extents[axis_map_.at (1 )];
606- logical_limits_ .limits [2 ] = image_extents[axis_map_.at (2 )];
642+ uniform_data_-> logical_limits .limits [0 ] = image_extents[axis_map_.at (0 )];
643+ uniform_data_-> logical_limits .limits [1 ] = image_extents[axis_map_.at (1 )];
644+ uniform_data_-> logical_limits .limits [2 ] = image_extents[axis_map_.at (2 )];
607645}
608646
609647utils::GPUMemoryLayout vTensor::estimate_memory_layout () const {
@@ -661,7 +699,7 @@ const vkapi::BufferBindInfo vTensor::logical_limits_ubo() {
661699 " Uniform data allocation has exceeded Tensor uniform buffer size" );
662700 logical_limits_uniform_offset_ = uniforms_size_;
663701 uniforms_size_ += kSizePerUniform ;
664- uniforms_.update (logical_limits_ , logical_limits_uniform_offset_);
702+ uniforms_.update (logical_limits () , logical_limits_uniform_offset_);
665703 }
666704 return vkapi::BufferBindInfo (
667705 uniforms_.buffer (), logical_limits_uniform_offset_);
@@ -677,7 +715,7 @@ const vkapi::BufferBindInfo vTensor::numel_ubo() {
677715 " Uniform data allocation has exceeded Tensor uniform buffer size" );
678716 numel_uniform_offset_ = uniforms_size_;
679717 uniforms_size_ += kSizePerUniform ;
680- uniforms_.update (numel_ , numel_uniform_offset_);
718+ uniforms_.update (numel () , numel_uniform_offset_);
681719 }
682720 return vkapi::BufferBindInfo (uniforms_.buffer (), numel_uniform_offset_);
683721}
@@ -687,10 +725,10 @@ size_t vTensor::staging_buffer_numel() const {
687725 const bool int8_supported =
688726 storage_.context_ ->adapter_ptr ()->has_full_int8_buffers_support ();
689727 if (is_int8 && !int8_supported) {
690- return utils::align_up_4 (numel_ );
728+ return utils::align_up_4 (numel () );
691729 }
692730 if (storage_type () == utils::kBuffer ) {
693- return numel_ ;
731+ return numel () ;
694732 }
695733 return padded_numel_;
696734}
@@ -720,30 +758,32 @@ void vTensor::bind_allocation(const vkapi::Allocation& allocation) {
720758
721759void vTensor::update_metadata () {
722760 strides_ = calculate_strides (sizes_, dim_order_);
723- numel_ = utils::multiply_integers (sizes_);
761+ uniform_data_-> numel = utils::multiply_integers (sizes_);
724762
725763 padded_sizes_ = calculate_padded_sizes (sizes_, packed_dim_);
726- unsqueezed_strides_ = unsqueeze_strides (strides_, numel_ );
764+ unsqueezed_strides_ = unsqueeze_strides (strides_, numel () );
727765 padded_numel_ = utils::multiply_integers (padded_sizes_);
728766
767+ // Update uniform data if it has been modified
768+ uniform_data_->sizes_v = utils::make_whcn_ivec4 (sizes_);
769+ uniform_data_->strides_v = utils::make_whcn_ivec4 (unsqueezed_strides_);
770+
729771 // Calculate the image extents that would have been used to allocate a texture
730772 // withthe current sizes, and use that to set the logical limits.
731773 set_logical_limits (
732774 calculate_image_extents (padded_sizes_, axis_map_, packed_dim_));
733775
734776 if (sizes_uniform_offset_ != kUniformOffsetUnset ) {
735- uniforms_.update (utils::make_whcn_ivec4 (sizes_) , sizes_uniform_offset_);
777+ uniforms_.update (uniform_data_-> sizes_v , sizes_uniform_offset_);
736778 }
737779 if (unsqueezed_strides_offset_ != kUniformOffsetUnset ) {
738- uniforms_.update (
739- utils::make_whcn_ivec4 (unsqueezed_strides_),
740- unsqueezed_strides_offset_);
780+ uniforms_.update (uniform_data_->strides_v , unsqueezed_strides_offset_);
741781 }
742782 if (numel_uniform_offset_ != kUniformOffsetUnset ) {
743- uniforms_.update (numel_ , numel_uniform_offset_);
783+ uniforms_.update (numel () , numel_uniform_offset_);
744784 }
745785 if (logical_limits_uniform_offset_ != kUniformOffsetUnset ) {
746- uniforms_.update (logical_limits_ , logical_limits_uniform_offset_);
786+ uniforms_.update (logical_limits () , logical_limits_uniform_offset_);
747787 }
748788}
749789
@@ -796,6 +836,8 @@ void vTensor::virtual_clone(const vTensor& other) {
796836 dim_order_ = other.dim_order_ ;
797837 axis_map_ = other.axis_map_ ;
798838 packed_dim_ = other.packed_dim_ ;
839+
840+ *uniform_data_ = *other.get_uniform_data ();
799841}
800842
801843void vTensor::virtual_resize (const std::vector<int64_t >& new_sizes) {
0 commit comments