@@ -778,6 +778,73 @@ static bool find_memory_index(
778778 memory_type_out);
779779}
780780
781+ bool VgfRepr::map_persistent_io_memory () {
782+ unmap_persistent_io_memory ();
783+
784+ for (auto & io : IOs) {
785+ if (io.memory == VK_NULL_HANDLE ) {
786+ ET_LOG (Error, " Cannot persistently map null Vulkan IO memory" );
787+ unmap_persistent_io_memory ();
788+ return false ;
789+ }
790+
791+ void * persistent_memory = nullptr ;
792+
793+ // IO resources may alias the same VkDeviceMemory. Vulkan memory must not be
794+ // mapped more than once at the same time, so map each unique memory once
795+ // and share the returned pointer across aliased IO entries.
796+ // Make sure that memory is HOST_VISIBLE and HOST_COHERENT.
797+ bool found_existing_mapping = false ;
798+ auto mapped_memory_it = std::find_if (
799+ persistent_mapped_memories.begin (),
800+ persistent_mapped_memories.end (),
801+ [&](const auto & mapped_memory) {
802+ return mapped_memory.memory == io.memory ;
803+ });
804+
805+ if (mapped_memory_it != persistent_mapped_memories.end ()) {
806+ persistent_memory = mapped_memory_it->data ;
807+ found_existing_mapping = true ;
808+ }
809+
810+ if (!found_existing_mapping) {
811+ VkResult result = vkMapMemory (
812+ vk_device, io.memory , 0 , VK_WHOLE_SIZE , 0 , &persistent_memory);
813+ if (result != VK_SUCCESS ) {
814+ ET_LOG (
815+ Error,
816+ " Failed to persistently map Vulkan IO memory, error %d" ,
817+ result);
818+ unmap_persistent_io_memory ();
819+ return false ;
820+ }
821+
822+ persistent_mapped_memories.push_back (PersistentMappedMemory{
823+ .memory = io.memory ,
824+ .data = persistent_memory,
825+ });
826+ }
827+
828+ io.persistent_memory = persistent_memory;
829+ }
830+
831+ return true ;
832+ }
833+
834+ void VgfRepr::unmap_persistent_io_memory () {
835+ for (const auto & mapped_memory : persistent_mapped_memories) {
836+ if (mapped_memory.memory != VK_NULL_HANDLE &&
837+ mapped_memory.data != nullptr ) {
838+ vkUnmapMemory (vk_device, mapped_memory.memory );
839+ }
840+ }
841+ persistent_mapped_memories.clear ();
842+
843+ for (auto & io : IOs) {
844+ io.persistent_memory = nullptr ;
845+ }
846+ }
847+
781848VkResult allocate_memory (
782849 VkPhysicalDevice physical,
783850 VkDevice device,
@@ -1839,6 +1906,7 @@ bool VgfRepr::process_vgf(
18391906 VK_NULL_HANDLE ,
18401907 tensor_memory,
18411908 {0 , 0 , 0 },
1909+ nullptr ,
18421910 owns_memory,
18431911 true ,
18441912 is_in});
@@ -1931,6 +1999,7 @@ bool VgfRepr::process_vgf(
19311999 VK_NULL_HANDLE ,
19322000 buffer_memory,
19332001 {0 , 0 , 0 },
2002+ nullptr ,
19342003 owns_memory,
19352004 true ,
19362005 is_in});
@@ -2117,6 +2186,7 @@ bool VgfRepr::process_vgf(
21172186 image_memory,
21182187 staging_memory,
21192188 image_extent,
2189+ nullptr ,
21202190 true ,
21212191 owns_image_memory,
21222192 is_in});
@@ -3433,6 +3503,15 @@ bool VgfRepr::process_vgf(
34333503 vkEndCommandBuffer (vk_execute_cmd);
34343504 }
34353505
3506+ {
3507+ VGF_PROFILE_SCOPE (event_tracer, " VGF_INIT_MAP_IO_MEMORY" );
3508+
3509+ if (!map_persistent_io_memory ()) {
3510+ ET_LOG (Error, " Failed to persistently map VGF IO memory" );
3511+ return false ;
3512+ }
3513+ }
3514+
34363515 return true ;
34373516}
34383517
@@ -3493,6 +3572,8 @@ bool VgfRepr::execute_vgf(executorch::runtime::EventTracer* event_tracer) {
34933572}
34943573
34953574void VgfRepr::free_vgf () {
3575+ unmap_persistent_io_memory ();
3576+
34963577 if (vk_timestamp_query_pool != VK_NULL_HANDLE ) {
34973578 vkDestroyQueryPool (vk_device, vk_timestamp_query_pool, nullptr );
34983579 vk_timestamp_query_pool = VK_NULL_HANDLE ;
0 commit comments