@@ -277,10 +277,11 @@ vTensorStorage::vTensorStorage(
277277 storage_type_,
278278 dtype,
279279 allocate_memory)),
280- last_access_{} {}
280+ last_access_{},
281+ has_copies_{false } {}
281282
282283vTensorStorage::vTensorStorage (
283- const vTensorStorage& other,
284+ vTensorStorage& other,
284285 const int64_t buffer_offset)
285286 : context_(other.context_),
286287 storage_type_{other.storage_type_ },
@@ -289,7 +290,10 @@ vTensorStorage::vTensorStorage(
289290 buffer_offset_{buffer_offset},
290291 image_ (other.image_),
291292 buffer_(other.buffer_, buffer_offset),
292- last_access_{other.last_access_ } {}
293+ last_access_{other.last_access_ },
294+ has_copies_{false } {
295+ other.has_copies_ = true ;
296+ }
293297
294298vTensorStorage::~vTensorStorage () {
295299 flush ();
@@ -312,6 +316,21 @@ void vTensorStorage::transition(
312316 vkapi::PipelineStageFlags prev_stage = last_access_.stage ;
313317 vkapi::MemoryAccessFlags prev_access = last_access_.access ;
314318
319+ // If the underlying resource is a copy of another tensor's resource the
320+ // last_access may not be accurate, since the original storage may have been
321+ // written to as part of the original tensor. Likewise, if the underlying
322+ // resource has copies, then the resource may have been updated as part of the
323+ // view tensors.
324+ //
325+ // If the resource is a copy, or has copies of it, then cowardly assume that
326+ // it has previously been written to as part of a compute shader before the
327+ // current access event so that the appropriate memory barriers may be
328+ // inserted.
329+ if (is_copy () || has_copies_) {
330+ prev_stage = vkapi::PipelineStage::COMPUTE;
331+ prev_access = vkapi::kWrite ;
332+ }
333+
315334 const bool prev_written = (prev_access & vkapi::MemoryAccessType::WRITE) != 0 ;
316335
317336 VkImageLayout cur_layout = VK_IMAGE_LAYOUT_UNDEFINED;
@@ -358,6 +377,13 @@ void vTensorStorage::transition(
358377 last_access_.access = cur_access;
359378}
360379
380+ bool vTensorStorage::is_copy () const {
381+ if (storage_type_ == utils::kBuffer ) {
382+ return buffer_.is_copy ();
383+ }
384+ return image_.is_copy ();
385+ }
386+
361387bool vTensorStorage::is_copy_of (const vTensorStorage& other) const {
362388 if (storage_type_ == utils::kBuffer ) {
363389 return buffer_.is_copy_of (other.buffer_ );
@@ -418,7 +444,8 @@ vTensor::vTensor(
418444 }
419445}
420446
421- vTensor::vTensor (const vTensor& other)
447+ // NOLINTNEXTLINE
448+ vTensor::vTensor (vTensor& other)
422449 : dtype_(other.dtype_),
423450 // Copy tensor size metadata
424451 sizes_(other.sizes_.begin(), other.sizes_.end()),
@@ -443,7 +470,7 @@ vTensor::vTensor(const vTensor& other)
443470 storage_(other.storage_) {}
444471
445472vTensor::vTensor (
446- const vTensor& other,
473+ vTensor& other,
447474 const std::vector<int64_t >& sizes,
448475 const std::vector<int64_t >& dim_order,
449476 const int64_t offset_numel)
@@ -671,6 +698,14 @@ void vTensor::virtual_reconfigure(
671698 update_metadata ();
672699}
673700
701+ void vTensor::virtual_clone (const vTensor& other) {
702+ VK_CHECK_COND (is_view_of (other));
703+ sizes_ = other.sizes_ ;
704+ dim_order_ = other.dim_order_ ;
705+ axis_map_ = other.axis_map_ ;
706+ packed_dim_ = other.packed_dim_ ;
707+ }
708+
674709void vTensor::virtual_resize (const std::vector<int64_t >& new_sizes) {
675710 VK_CHECK_COND (
676711 new_sizes.size () == dim_order_.size (),
0 commit comments