From 0d298d7a6732866ab7d1592d531f0ad1bbf4f989 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Tue, 21 Nov 2023 09:35:20 -0800 Subject: [PATCH] No public description PiperOrigin-RevId: 584349220 --- mediapipe/gpu/BUILD | 2 + mediapipe/gpu/gpu_shared_data_internal.cc | 57 +++++++++++++++++------ mediapipe/gpu/gpu_shared_data_internal.h | 7 ++- 3 files changed, 52 insertions(+), 14 deletions(-) diff --git a/mediapipe/gpu/BUILD b/mediapipe/gpu/BUILD index 6ce4ec117..88864e894 100644 --- a/mediapipe/gpu/BUILD +++ b/mediapipe/gpu/BUILD @@ -669,6 +669,8 @@ cc_library( "//mediapipe/framework/port:ret_check", "@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/log:absl_check", + "@com_google_absl//absl/log:absl_log", + "@com_google_absl//absl/status", ] + select({ "//conditions:default": [], "//mediapipe:apple": [ diff --git a/mediapipe/gpu/gpu_shared_data_internal.cc b/mediapipe/gpu/gpu_shared_data_internal.cc index 31bdf18b5..965a8b4c5 100644 --- a/mediapipe/gpu/gpu_shared_data_internal.cc +++ b/mediapipe/gpu/gpu_shared_data_internal.cc @@ -14,10 +14,14 @@ #include "mediapipe/gpu/gpu_shared_data_internal.h" +#include +#include + #include "absl/base/attributes.h" #include "absl/log/absl_check.h" +#include "absl/log/absl_log.h" +#include "absl/status/status.h" #include "mediapipe/framework/deps/no_destructor.h" -#include "mediapipe/framework/port/ret_check.h" #include "mediapipe/gpu/gl_context.h" #include "mediapipe/gpu/gl_context_options.pb.h" #include "mediapipe/gpu/graph_support.h" @@ -83,8 +87,25 @@ GpuResources::StatusOrGpuResources GpuResources::Create( } GpuResources::GpuResources(std::shared_ptr gl_context) + : gl_key_context_(new GlContextMapType(), + [](auto* map) { + // This flushes all pending jobs in all GL contexts, + // ensuring that all GL contexts not referenced + // elsewhere are destroyed as part of this destructor. + // Failure to do this may cause GL threads to outlast + // this destructor and execute jobs after the + // GpuResources object is destroyed. + for (auto& [key, context] : *map) { + const auto status = std::move(context)->Run( + []() { return absl::OkStatus(); }); + ABSL_LOG_IF(ERROR, !status.ok()) + << "Failed to flush GlContext jobs: " << status; + } + delete map; + }) #if MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER - : texture_caches_(std::make_shared()), + , + texture_caches_(std::make_shared()), gpu_buffer_pool_( [tc = texture_caches_](const internal::GpuBufferSpec& spec, const MultiPoolOptions& options) { @@ -92,7 +113,7 @@ GpuResources::GpuResources(std::shared_ptr gl_context) }) #endif // MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER { - gl_key_context_[SharedContextKey()] = gl_context; + gl_key_context_->insert({SharedContextKey(), gl_context}); named_executors_[kGpuExecutorName] = std::make_shared(gl_context.get()); #if __APPLE__ @@ -104,6 +125,15 @@ GpuResources::GpuResources(std::shared_ptr gl_context) } GpuResources::~GpuResources() { + // This flushes all pending jobs in all GL contexts, + // ensuring that all existing jobs, which may refer GpuResource and kept their + // gpu resources (e.g. GpuResources::gpu_buffer_pool_) through a raw pointer, + // have finished before kept gpu resources get deleted. + for (auto& [key, context] : *gl_key_context_) { + const auto status = context->Run([]() { return absl::OkStatus(); }); + ABSL_LOG_IF(ERROR, !status.ok()) + << "Failed to flush GlContext jobs: " << status; + } #if __APPLE__ // Note: on Apple platforms, this object contains Objective-C objects. // The destructor will release them, but ARC must be on. @@ -111,7 +141,7 @@ GpuResources::~GpuResources() { #error This file must be built with ARC. #endif #if MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER - for (auto& kv : gl_key_context_) { + for (auto& kv : *gl_key_context_) { texture_caches_->UnregisterTextureCache(kv.second->cv_texture_cache()); } #endif // MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER @@ -173,23 +203,24 @@ absl::Status GpuResources::PrepareGpuNode(CalculatorNode* node) { const std::shared_ptr& GpuResources::gl_context( CalculatorContext* cc) { if (cc) { - auto it = gl_key_context_.find(node_key_[cc->NodeName()]); - if (it != gl_key_context_.end()) { + auto it = gl_key_context_->find(node_key_[cc->NodeName()]); + if (it != gl_key_context_->end()) { return it->second; } } - return gl_key_context_[SharedContextKey()]; + return gl_key_context_->at(SharedContextKey()); } GlContext::StatusOrGlContext GpuResources::GetOrCreateGlContext( const std::string& key) { - auto it = gl_key_context_.find(key); - if (it == gl_key_context_.end()) { - MP_ASSIGN_OR_RETURN(std::shared_ptr new_context, - GlContext::Create(*gl_key_context_[SharedContextKey()], - kGlContextUseDedicatedThread)); - it = gl_key_context_.emplace(key, new_context).first; + auto it = gl_key_context_->find(key); + if (it == gl_key_context_->end()) { + MP_ASSIGN_OR_RETURN( + std::shared_ptr new_context, + GlContext::Create(*gl_key_context_->at(SharedContextKey()), + kGlContextUseDedicatedThread)); + it = gl_key_context_->emplace(key, new_context).first; #if MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER texture_caches_->RegisterTextureCache(it->second->cv_texture_cache()); #endif // MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER diff --git a/mediapipe/gpu/gpu_shared_data_internal.h b/mediapipe/gpu/gpu_shared_data_internal.h index 3f7c67e2e..5e8be45ab 100644 --- a/mediapipe/gpu/gpu_shared_data_internal.h +++ b/mediapipe/gpu/gpu_shared_data_internal.h @@ -21,6 +21,8 @@ #ifndef MEDIAPIPE_GPU_GPU_SHARED_DATA_INTERNAL_H_ #define MEDIAPIPE_GPU_GPU_SHARED_DATA_INTERNAL_H_ +#include + #include "mediapipe/framework/calculator_context.h" #include "mediapipe/framework/calculator_node.h" #include "mediapipe/framework/executor.h" @@ -82,7 +84,10 @@ class GpuResources { const std::string& ContextKey(const std::string& canonical_node_name); std::map node_key_; - std::map> gl_key_context_; + + using GlContextMapType = std::map>; + std::unique_ptr + gl_key_context_; #ifdef MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER std::shared_ptr texture_caches_;