// Copyright 2019 The MediaPipe Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #ifndef MEDIAPIPE_FRAMEWORK_CALCULATOR_CONTEXT_MANAGER_H_ #define MEDIAPIPE_FRAMEWORK_CALCULATOR_CONTEXT_MANAGER_H_ #include #include #include #include #include "absl/base/thread_annotations.h" #include "absl/synchronization/mutex.h" #include "mediapipe/framework/calculator_context.h" #include "mediapipe/framework/calculator_state.h" #include "mediapipe/framework/port/logging.h" #include "mediapipe/framework/port/status.h" #include "mediapipe/framework/timestamp.h" #include "mediapipe/framework/tool/tag_map.h" namespace mediapipe { // Calculator context manager owns and manages all calculator context objects of // a calculator node. class CalculatorContextManager { public: CalculatorContextManager() {} void Initialize(CalculatorState* calculator_state, std::shared_ptr input_tag_map, std::shared_ptr output_tag_map, bool calculator_run_in_parallel); // Sets the callback that can setup the input and output stream shards in a // newly constructed calculator context. Then, initializes the default // calculator context. absl::Status PrepareForRun( std::function setup_shards_callback); // Invoked by CalculatorNode::CleanupAfterRun(). void CleanupAfterRun() ABSL_LOCKS_EXCLUDED(contexts_mutex_); // Returns true if the default calculator context has been initialized. bool HasDefaultCalculatorContext() const { return default_context_ != nullptr; } // Returns a pointer to the default calculator context that is used for // sequential execution. A source node should always reuse its default // calculator context. CalculatorContext* GetDefaultCalculatorContext() const; // Returns the context with the smallest input timestamp in active_contexts_. // The input timestamp of the calculator context is returned in // *context_input_timestamp. CalculatorContext* GetFrontCalculatorContext( Timestamp* context_input_timestamp) ABSL_LOCKS_EXCLUDED(contexts_mutex_); // For sequential execution, returns a pointer to the default calculator // context. For parallel execution, creates or reuses a calculator context, // and inserts the calculator context with the given input timestamp into // active_contexts_. Returns a pointer to the prepared calculator context. // The ownership of the calculator context object isn't tranferred to the // caller. CalculatorContext* PrepareCalculatorContext(Timestamp input_timestamp) ABSL_LOCKS_EXCLUDED(contexts_mutex_); // Removes the context with the smallest input timestamp from active_contexts_ // and moves the calculator context to idle_contexts_. The caller must // guarantee that the output shards in the calculator context have been // propagated before calling this function. void RecycleCalculatorContext() ABSL_LOCKS_EXCLUDED(contexts_mutex_); // Returns true if active_contexts_ is non-empty. bool HasActiveContexts() ABSL_LOCKS_EXCLUDED(contexts_mutex_); int NumberOfContextTimestamps( const CalculatorContext& calculator_context) const { return calculator_context.NumberOfTimestamps(); } bool ContextHasInputTimestamp( const CalculatorContext& calculator_context) const { return calculator_context.HasInputTimestamp(); } void PushInputTimestampToContext(CalculatorContext* calculator_context, Timestamp input_timestamp) { CHECK(calculator_context); calculator_context->PushInputTimestamp(input_timestamp); } void PopInputTimestampFromContext(CalculatorContext* calculator_context) { CHECK(calculator_context); calculator_context->PopInputTimestamp(); } void SetGraphStatusInContext(CalculatorContext* calculator_context, const absl::Status& status) { CHECK(calculator_context); calculator_context->SetGraphStatus(status); } private: CalculatorState* calculator_state_; std::shared_ptr input_tag_map_; std::shared_ptr output_tag_map_; bool calculator_run_in_parallel_; // The callback to setup the input and output stream shards in a newly // constructed calculator context. // NOTE: This callback invokes input/output stream handler methods. // The callback is used to break the circular dependency between // calculator context manager and input/output stream handlers. std::function setup_shards_callback_; // The default calculator context that is always reused for sequential // execution. It is also used by Open() and Close() method of a parallel // calculator. std::unique_ptr default_context_; // The mutex for synchronizing the operations on active_contexts_ and // idle_contexts_ during parallel execution. absl::Mutex contexts_mutex_; // A map from input timestamps to calculator contexts. std::map> active_contexts_ ABSL_GUARDED_BY(contexts_mutex_); // Idle calculator contexts that are ready for reuse. std::deque> idle_contexts_ ABSL_GUARDED_BY(contexts_mutex_); }; } // namespace mediapipe #endif // MEDIAPIPE_FRAMEWORK_CALCULATOR_CONTEXT_MANAGER_H_