2019-06-17 01:03:25 +02:00
|
|
|
// 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.
|
|
|
|
|
|
|
|
#include "mediapipe/framework/profiler/graph_tracer.h"
|
|
|
|
|
|
|
|
#include <fstream>
|
|
|
|
#include <functional>
|
|
|
|
#include <map>
|
|
|
|
#include <memory>
|
|
|
|
#include <utility>
|
|
|
|
#include <vector>
|
|
|
|
|
2021-03-25 23:01:44 +01:00
|
|
|
#include "absl/flags/flag.h"
|
2019-06-17 01:03:25 +02:00
|
|
|
#include "absl/time/time.h"
|
|
|
|
#include "mediapipe/framework/calculator.pb.h"
|
|
|
|
#include "mediapipe/framework/calculator_framework.h"
|
|
|
|
#include "mediapipe/framework/calculator_profile.pb.h"
|
|
|
|
#include "mediapipe/framework/deps/clock.h"
|
|
|
|
#include "mediapipe/framework/port/advanced_proto_inc.h"
|
|
|
|
#include "mediapipe/framework/port/file_helpers.h"
|
|
|
|
#include "mediapipe/framework/port/gmock.h"
|
|
|
|
#include "mediapipe/framework/port/gtest.h"
|
|
|
|
#include "mediapipe/framework/port/integral_types.h"
|
|
|
|
#include "mediapipe/framework/port/logging.h"
|
|
|
|
#include "mediapipe/framework/port/parse_text_proto.h"
|
|
|
|
#include "mediapipe/framework/port/status.h"
|
|
|
|
#include "mediapipe/framework/port/status_matchers.h"
|
|
|
|
#include "mediapipe/framework/profiler/graph_profiler.h"
|
|
|
|
#include "mediapipe/framework/profiler/test_context_builder.h"
|
|
|
|
#include "mediapipe/framework/tool/simulation_clock.h"
|
|
|
|
#include "mediapipe/framework/tool/simulation_clock_executor.h"
|
|
|
|
#include "mediapipe/framework/tool/status_util.h"
|
|
|
|
|
|
|
|
namespace mediapipe {
|
|
|
|
|
|
|
|
using PacketInfoMap =
|
|
|
|
ShardedMap<std::string, std::list<std::pair<int64, PacketInfo>>>;
|
|
|
|
|
|
|
|
class GraphProfilerTestPeer {
|
|
|
|
public:
|
|
|
|
static PacketInfoMap* GetPacketsInfoMap(GraphProfiler* profiler) {
|
|
|
|
return &profiler->packets_info_;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
using testing::ElementsAre;
|
|
|
|
|
|
|
|
class GraphTracerTest : public ::testing::Test {
|
|
|
|
protected:
|
|
|
|
GraphTracerTest() {
|
|
|
|
std::string err;
|
|
|
|
ParseTime("%Y-%m-%d-%H-%M-%E*S", "2020-12-25-15-45-00", &start_time_, &err);
|
|
|
|
start_timestamp_ = Timestamp(ToUnixMicros(start_time_));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Initializes the GraphTracer.
|
2019-09-09 20:02:30 +02:00
|
|
|
void SetUpGraphTracer() {
|
2019-06-17 01:03:25 +02:00
|
|
|
ProfilerConfig profiler_config;
|
2019-08-17 03:49:25 +02:00
|
|
|
profiler_config.set_trace_enabled(true);
|
2019-06-17 01:03:25 +02:00
|
|
|
tracer_ = absl::make_unique<GraphTracer>(profiler_config);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Initializes the input and output stream specs for a calculator node.
|
|
|
|
void SetUpCalculatorContext(const std::string& node_name, int node_id,
|
|
|
|
const std::vector<std::string>& inputs,
|
|
|
|
const std::vector<std::string>& outputs) {
|
|
|
|
context_builders_[node_name].Init(node_name, node_id, inputs, outputs);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ClearCalculatorContext(const std::string& node_name) {
|
|
|
|
context_builders_[node_name].Clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Invokes LogInputEvents with some input packets.
|
|
|
|
void LogInputPackets(const std::string& node_name,
|
|
|
|
GraphTrace::EventType event_type, absl::Time event_time,
|
|
|
|
const std::vector<Packet>& packets) {
|
|
|
|
context_builders_[node_name].AddInputs(packets);
|
|
|
|
tracer_->LogInputEvents(event_type, context_builders_[node_name].get(),
|
|
|
|
event_time);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Invokes LogOutputEvents some output packets.
|
|
|
|
void LogOutputPackets(const std::string& node_name,
|
|
|
|
GraphTrace::EventType event_type, absl::Time event_time,
|
|
|
|
const std::vector<std::vector<Packet>>& packets) {
|
|
|
|
context_builders_[node_name].AddOutputs(packets);
|
|
|
|
tracer_->LogOutputEvents(event_type, context_builders_[node_name].get(),
|
|
|
|
event_time);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Returns the GraphTrace for the logged events.
|
|
|
|
GraphTrace GetTrace() {
|
|
|
|
GraphTrace result;
|
|
|
|
tracer_->GetTrace(absl::InfinitePast(), absl::InfiniteFuture(), &result);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::unique_ptr<GraphTracer> tracer_;
|
|
|
|
std::map<std::string, TestContextBuilder> context_builders_;
|
|
|
|
absl::Time start_time_;
|
|
|
|
Timestamp start_timestamp_;
|
|
|
|
};
|
|
|
|
|
|
|
|
TEST_F(GraphTracerTest, EmptyTrace) {
|
|
|
|
// Define the GraphTracer.
|
2019-09-09 20:02:30 +02:00
|
|
|
SetUpGraphTracer();
|
2019-06-17 01:03:25 +02:00
|
|
|
|
|
|
|
// Validate the GraphTrace data.
|
|
|
|
EXPECT_THAT(GetTrace(),
|
2021-04-01 01:20:27 +02:00
|
|
|
EqualsProto(mediapipe::ParseTextProtoOrDie<GraphTrace>(R"pb(
|
2019-06-17 01:03:25 +02:00
|
|
|
base_time: 0
|
|
|
|
base_timestamp: 0
|
|
|
|
stream_name: ""
|
2021-04-01 01:20:27 +02:00
|
|
|
)pb")));
|
2019-06-17 01:03:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(GraphTracerTest, CalculatorTrace) {
|
|
|
|
// Define the GraphTracer, the CalculatorState, and the stream specs.
|
2019-09-09 20:02:30 +02:00
|
|
|
SetUpGraphTracer();
|
2019-06-17 01:03:25 +02:00
|
|
|
SetUpCalculatorContext("PCalculator_1", /*node_id=*/0, {"input_stream"},
|
|
|
|
{"output_stream"});
|
|
|
|
absl::Time curr_time = start_time_;
|
|
|
|
|
|
|
|
// PCalculator_1 processes one packet from stream "input_stream".
|
|
|
|
LogInputPackets("PCalculator_1", GraphTrace::PROCESS, curr_time,
|
|
|
|
{MakePacket<std::string>("hello").At(start_timestamp_)});
|
|
|
|
curr_time += absl::Microseconds(10000);
|
|
|
|
LogOutputPackets("PCalculator_1", GraphTrace::PROCESS, curr_time,
|
|
|
|
{{MakePacket<std::string>("goodbye").At(start_timestamp_)}});
|
|
|
|
|
|
|
|
// Validate the GraphTrace data.
|
2020-07-09 02:34:05 +02:00
|
|
|
EXPECT_THAT(
|
2021-04-01 01:20:27 +02:00
|
|
|
GetTrace(), EqualsProto(mediapipe::ParseTextProtoOrDie<GraphTrace>(R"pb(
|
2020-07-09 02:34:05 +02:00
|
|
|
base_time: 1608911100000000
|
|
|
|
base_timestamp: 1608911100000000
|
|
|
|
stream_name: ""
|
|
|
|
stream_name: "input_stream"
|
|
|
|
stream_name: "output_stream"
|
|
|
|
calculator_trace {
|
|
|
|
node_id: 0
|
|
|
|
input_timestamp: 0
|
|
|
|
event_type: PROCESS
|
|
|
|
start_time: 0
|
|
|
|
finish_time: 10000
|
|
|
|
thread_id: 0
|
|
|
|
input_trace {
|
|
|
|
finish_time: 0
|
|
|
|
packet_timestamp: 0
|
|
|
|
stream_id: 1
|
|
|
|
event_data: 1
|
|
|
|
}
|
|
|
|
output_trace { packet_timestamp: 0 stream_id: 2 event_data: 2 }
|
|
|
|
}
|
2021-04-01 01:20:27 +02:00
|
|
|
)pb")));
|
2019-06-17 01:03:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(GraphTracerTest, GraphTrace) {
|
|
|
|
// Define the GraphTracer, the CalculatorState, and the stream specs.
|
2019-09-09 20:02:30 +02:00
|
|
|
SetUpGraphTracer();
|
2019-06-17 01:03:25 +02:00
|
|
|
SetUpCalculatorContext("PCalculator_1", /*node_id=*/0, {"input_stream"},
|
|
|
|
{"up_1", "up_2"});
|
|
|
|
absl::Time curr_time = start_time_;
|
|
|
|
|
|
|
|
// PCalculator_1 sends one packet to stream "up_1", and two to "up_2".
|
|
|
|
LogInputPackets("PCalculator_1", GraphTrace::PROCESS, curr_time,
|
|
|
|
{MakePacket<std::string>("hello").At(start_timestamp_)});
|
|
|
|
curr_time += absl::Microseconds(10000);
|
|
|
|
LogOutputPackets(
|
|
|
|
"PCalculator_1", GraphTrace::PROCESS, curr_time,
|
|
|
|
{
|
|
|
|
{MakePacket<std::string>("up").At(start_timestamp_)},
|
|
|
|
{MakePacket<std::string>("up").At(start_timestamp_),
|
|
|
|
MakePacket<std::string>("pup").At(start_timestamp_ + 5)},
|
|
|
|
});
|
|
|
|
curr_time += absl::Microseconds(1000);
|
|
|
|
|
|
|
|
// PCalculator_2 processes one packet from stream "up_1".
|
|
|
|
SetUpCalculatorContext("PCalculator_2", /*node_id=*/1, {"up_1"}, {"down_1"});
|
|
|
|
LogInputPackets("PCalculator_2", GraphTrace::PROCESS, curr_time,
|
|
|
|
{MakePacket<std::string>("up").At(start_timestamp_)});
|
|
|
|
curr_time += absl::Microseconds(10000);
|
|
|
|
LogOutputPackets("PCalculator_2", GraphTrace::PROCESS, curr_time,
|
|
|
|
{{MakePacket<std::string>("down_1").At(start_timestamp_)}});
|
|
|
|
curr_time -= absl::Microseconds(5000);
|
|
|
|
|
|
|
|
// PCalculator_3 processes two packets from stream "up_2".
|
|
|
|
SetUpCalculatorContext("PCalculator_3", /*node_id=*/2, {"up_2"}, {"down_2"});
|
|
|
|
LogInputPackets("PCalculator_3", GraphTrace::PROCESS, curr_time,
|
|
|
|
{MakePacket<std::string>("up").At(start_timestamp_)});
|
|
|
|
curr_time += absl::Microseconds(20000);
|
|
|
|
LogOutputPackets("PCalculator_3", GraphTrace::PROCESS, curr_time,
|
|
|
|
{{MakePacket<std::string>("out").At(start_timestamp_)}});
|
|
|
|
curr_time += absl::Microseconds(2000);
|
2020-07-09 02:34:05 +02:00
|
|
|
|
|
|
|
// Note: the packet data ID is based on the packet's payload address, which
|
|
|
|
// means the same ID can be reused if data is allocated in the same location
|
|
|
|
// as a previously expired packet (b/160212191). This means the generated
|
|
|
|
// trace can change depending on the allocator. To keep results stable, we
|
|
|
|
// must keep the packets used in this test alive until the end. Each
|
|
|
|
// TestContextBuilder happens to keep a reference to all packets for the last
|
|
|
|
// context, so for now we just create a separate TestContextBuilder instead of
|
|
|
|
// clearing it. TODO: revise this test.
|
|
|
|
SetUpCalculatorContext("PCalculator_3a", /*node_id=*/2, {"up_2"}, {"down_2"});
|
|
|
|
LogInputPackets("PCalculator_3a", GraphTrace::PROCESS, curr_time,
|
2019-06-17 01:03:25 +02:00
|
|
|
{MakePacket<std::string>("pup").At(start_timestamp_ + 5)});
|
|
|
|
curr_time += absl::Microseconds(20000);
|
|
|
|
LogOutputPackets(
|
2020-07-09 02:34:05 +02:00
|
|
|
"PCalculator_3a", GraphTrace::PROCESS, curr_time,
|
2019-06-17 01:03:25 +02:00
|
|
|
{{MakePacket<std::string>("pout").At(start_timestamp_ + 5)}});
|
|
|
|
curr_time += absl::Microseconds(1000);
|
|
|
|
|
|
|
|
// Validate the GraphTrace data.
|
2020-07-09 02:34:05 +02:00
|
|
|
EXPECT_THAT(
|
2021-04-01 01:20:27 +02:00
|
|
|
GetTrace(), EqualsProto(mediapipe::ParseTextProtoOrDie<GraphTrace>(R"pb(
|
2020-07-09 02:34:05 +02:00
|
|
|
base_time: 1608911100000000
|
|
|
|
base_timestamp: 1608911100000000
|
|
|
|
stream_name: ""
|
|
|
|
stream_name: "input_stream"
|
|
|
|
stream_name: "up_1"
|
|
|
|
stream_name: "up_2"
|
|
|
|
stream_name: "down_1"
|
|
|
|
stream_name: "down_2"
|
|
|
|
calculator_trace {
|
|
|
|
node_id: 0
|
|
|
|
input_timestamp: 0
|
|
|
|
event_type: PROCESS
|
|
|
|
start_time: 0
|
|
|
|
finish_time: 10000
|
|
|
|
thread_id: 0
|
|
|
|
input_trace {
|
|
|
|
finish_time: 0
|
|
|
|
packet_timestamp: 0
|
|
|
|
stream_id: 1
|
|
|
|
event_data: 1
|
|
|
|
}
|
|
|
|
output_trace { packet_timestamp: 0 stream_id: 2 event_data: 2 }
|
|
|
|
output_trace { packet_timestamp: 0 stream_id: 3 event_data: 3 }
|
|
|
|
output_trace { packet_timestamp: 5 stream_id: 3 event_data: 4 }
|
|
|
|
}
|
|
|
|
calculator_trace {
|
|
|
|
node_id: 1
|
|
|
|
input_timestamp: 0
|
|
|
|
event_type: PROCESS
|
|
|
|
start_time: 11000
|
|
|
|
finish_time: 21000
|
|
|
|
thread_id: 0
|
|
|
|
input_trace {
|
|
|
|
start_time: 10000
|
|
|
|
finish_time: 11000
|
|
|
|
packet_timestamp: 0
|
|
|
|
stream_id: 2
|
|
|
|
event_data: 5
|
|
|
|
}
|
|
|
|
output_trace { packet_timestamp: 0 stream_id: 4 event_data: 6 }
|
|
|
|
}
|
|
|
|
calculator_trace {
|
|
|
|
node_id: 2
|
|
|
|
input_timestamp: 0
|
|
|
|
event_type: PROCESS
|
|
|
|
start_time: 16000
|
|
|
|
finish_time: 36000
|
|
|
|
thread_id: 0
|
|
|
|
input_trace {
|
|
|
|
start_time: 10000
|
|
|
|
finish_time: 16000
|
|
|
|
packet_timestamp: 0
|
|
|
|
stream_id: 3
|
|
|
|
event_data: 7
|
|
|
|
}
|
|
|
|
output_trace { packet_timestamp: 0 stream_id: 5 event_data: 8 }
|
|
|
|
}
|
|
|
|
calculator_trace {
|
|
|
|
node_id: 2
|
|
|
|
input_timestamp: 5
|
|
|
|
event_type: PROCESS
|
|
|
|
start_time: 38000
|
|
|
|
finish_time: 58000
|
|
|
|
thread_id: 0
|
|
|
|
input_trace {
|
|
|
|
start_time: 10000
|
|
|
|
finish_time: 38000
|
|
|
|
packet_timestamp: 5
|
|
|
|
stream_id: 3
|
|
|
|
event_data: 9
|
|
|
|
}
|
|
|
|
output_trace { packet_timestamp: 5 stream_id: 5 event_data: 10 }
|
|
|
|
}
|
2021-04-01 01:20:27 +02:00
|
|
|
)pb")));
|
2019-06-17 01:03:25 +02:00
|
|
|
|
|
|
|
// No timestamps are completed before start_time_.
|
|
|
|
// One timestamp is completed before start_time_ + 10ms.
|
|
|
|
// Two timestamps are completed before start_time_ + 48ms.
|
|
|
|
Timestamp ts_0 = tracer_->TimestampAfter(start_time_);
|
|
|
|
EXPECT_EQ(Timestamp::Min() + 1, ts_0);
|
|
|
|
Timestamp ts_1 =
|
|
|
|
tracer_->TimestampAfter(start_time_ + absl::Microseconds(10000));
|
|
|
|
EXPECT_EQ(start_timestamp_ + 1, ts_1);
|
|
|
|
Timestamp ts_2 =
|
|
|
|
tracer_->TimestampAfter(start_time_ + absl::Microseconds(48000));
|
|
|
|
EXPECT_EQ(start_timestamp_ + 5 + 1, ts_2);
|
|
|
|
|
|
|
|
// 3 calculators run at start_timestamp_.
|
|
|
|
// 1 calculator runs at start_timestamp_ + 5.
|
|
|
|
// 4 calculators run between start_timestamp_ and start_timestamp_ + 5 + 1;
|
|
|
|
absl::Time t_0 = start_time_;
|
|
|
|
absl::Time t_1 = start_time_ + absl::Microseconds(10000);
|
|
|
|
absl::Time t_2 = start_time_ + absl::Microseconds(48000);
|
|
|
|
GraphTrace trace;
|
|
|
|
tracer_->GetTrace(t_0, t_1, &trace);
|
|
|
|
EXPECT_EQ(1, trace.calculator_trace().size());
|
|
|
|
tracer_->GetTrace(t_1, t_2, &trace);
|
|
|
|
EXPECT_EQ(4, trace.calculator_trace().size());
|
|
|
|
tracer_->GetTrace(t_0, t_2, &trace);
|
|
|
|
EXPECT_EQ(4, trace.calculator_trace().size());
|
|
|
|
}
|
|
|
|
|
|
|
|
// Tests showing GraphTracer logging packet latencies.
|
|
|
|
class GraphTracerE2ETest : public ::testing::Test {
|
|
|
|
protected:
|
|
|
|
void SetUpPassThroughGraph() {
|
|
|
|
CHECK(proto_ns::TextFormat::ParseFromString(R"(
|
|
|
|
input_stream: "input_0"
|
|
|
|
node {
|
|
|
|
calculator: "LambdaCalculator"
|
|
|
|
input_side_packet: 'callback_0'
|
|
|
|
input_stream: "input_0"
|
|
|
|
output_stream: "output_0"
|
|
|
|
}
|
|
|
|
profiler_config {
|
|
|
|
histogram_interval_size_usec: 1000
|
|
|
|
num_histogram_intervals: 100
|
2019-08-17 03:49:25 +02:00
|
|
|
trace_enabled: true
|
2019-06-17 01:03:25 +02:00
|
|
|
}
|
|
|
|
)",
|
|
|
|
&graph_config_));
|
|
|
|
}
|
|
|
|
|
|
|
|
void SetUpDemuxInFlightGraph() {
|
|
|
|
CHECK(proto_ns::TextFormat::ParseFromString(R"(
|
|
|
|
node {
|
|
|
|
calculator: "LambdaCalculator"
|
|
|
|
input_side_packet: 'callback_2'
|
|
|
|
output_stream: "input_packets_0"
|
|
|
|
}
|
|
|
|
node {
|
2019-08-17 03:49:25 +02:00
|
|
|
calculator: 'FlowLimiterCalculator'
|
2019-06-17 01:03:25 +02:00
|
|
|
input_stream_handler {
|
|
|
|
input_stream_handler: 'ImmediateInputStreamHandler'
|
|
|
|
}
|
|
|
|
input_side_packet: 'MAX_IN_FLIGHT:max_in_flight'
|
|
|
|
input_stream: 'input_packets_0'
|
|
|
|
input_stream: 'FINISHED:finish_indicator'
|
|
|
|
input_stream_info: {
|
|
|
|
tag_index: 'FINISHED'
|
|
|
|
back_edge: true
|
|
|
|
}
|
|
|
|
output_stream: 'input_0_sampled'
|
|
|
|
}
|
|
|
|
node {
|
|
|
|
calculator: "RoundRobinDemuxCalculator"
|
|
|
|
input_stream: "input_0_sampled"
|
|
|
|
output_stream: "OUTPUT:0:input_0"
|
|
|
|
output_stream: "OUTPUT:1:input_1"
|
|
|
|
}
|
|
|
|
node {
|
|
|
|
calculator: "LambdaCalculator"
|
|
|
|
input_side_packet: 'callback_0'
|
|
|
|
input_stream: "input_0"
|
|
|
|
output_stream: "output_0"
|
|
|
|
}
|
|
|
|
node {
|
|
|
|
calculator: "LambdaCalculator"
|
|
|
|
input_side_packet: 'callback_1'
|
|
|
|
input_stream: "input_1"
|
|
|
|
output_stream: "output_1"
|
|
|
|
}
|
|
|
|
node {
|
|
|
|
calculator: "ImmediateMuxCalculator"
|
|
|
|
input_stream_handler {
|
|
|
|
input_stream_handler: "ImmediateInputStreamHandler"
|
|
|
|
}
|
|
|
|
input_stream: "output_0"
|
|
|
|
input_stream: "output_1"
|
|
|
|
output_stream: 'output_packets_0'
|
|
|
|
output_stream: 'finish_indicator'
|
|
|
|
}
|
|
|
|
profiler_config {
|
|
|
|
histogram_interval_size_usec: 1000
|
|
|
|
num_histogram_intervals: 100
|
2019-08-17 03:49:25 +02:00
|
|
|
trace_enabled: true
|
2019-06-17 01:03:25 +02:00
|
|
|
}
|
|
|
|
)",
|
|
|
|
&graph_config_));
|
|
|
|
}
|
|
|
|
|
|
|
|
absl::Time ParseTime(const std::string& date_time_str) {
|
|
|
|
absl::Time result;
|
|
|
|
absl::ParseTime(absl::RFC3339_sec, date_time_str, &result, nullptr);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
absl::Time StartTime() { return ParseTime("2018-12-06T09:00:00Z"); }
|
|
|
|
|
|
|
|
void SetUpSimulationClock() {
|
|
|
|
auto executor = std::make_shared<SimulationClockExecutor>(8);
|
|
|
|
simulation_clock_ = executor->GetClock();
|
|
|
|
clock_ = simulation_clock_.get();
|
|
|
|
simulation_clock_->ThreadStart();
|
|
|
|
clock_->SleepUntil(StartTime());
|
|
|
|
simulation_clock_->ThreadFinish();
|
2019-09-11 22:58:46 +02:00
|
|
|
MP_ASSERT_OK(graph_.SetExecutor("", executor));
|
2019-06-17 01:03:25 +02:00
|
|
|
}
|
|
|
|
|
2020-12-10 04:13:05 +01:00
|
|
|
void SetUpRealClock() { clock_ = mediapipe::Clock::RealClock(); }
|
2019-06-17 01:03:25 +02:00
|
|
|
|
|
|
|
static Packet PacketAt(int64 ts) {
|
|
|
|
return Adopt(new int64(999)).At(Timestamp(ts));
|
|
|
|
}
|
|
|
|
static Packet None() { return Packet().At(Timestamp::OneOverPostStream()); }
|
|
|
|
static bool IsNone(const Packet& packet) {
|
|
|
|
return packet.Timestamp() == Timestamp::OneOverPostStream();
|
|
|
|
}
|
|
|
|
// Return the values of the timestamps of a vector of Packets.
|
|
|
|
static std::vector<int64> TimestampValues(
|
|
|
|
const std::vector<Packet>& packets) {
|
|
|
|
std::vector<int64> result;
|
|
|
|
for (const Packet& p : packets) {
|
|
|
|
result.push_back(p.Timestamp().Value());
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
GraphTrace NodeTimestamps(const GraphTrace& trace) {
|
|
|
|
GraphTrace result;
|
|
|
|
for (auto& name : trace.calculator_name()) {
|
|
|
|
result.add_calculator_name(name);
|
|
|
|
}
|
|
|
|
for (auto& ct : trace.calculator_trace()) {
|
|
|
|
auto rt = result.add_calculator_trace();
|
|
|
|
rt->set_input_timestamp(ct.input_timestamp() + trace.base_timestamp());
|
|
|
|
rt->set_node_id(ct.node_id());
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
void StripThreadIds(GraphTrace* trace) {
|
|
|
|
for (auto& ct : *trace->mutable_calculator_trace()) {
|
|
|
|
ct.clear_thread_id();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void StripDataIds(GraphTrace* trace) {
|
2020-04-07 04:10:12 +02:00
|
|
|
TraceBuilder builder;
|
2019-06-17 01:03:25 +02:00
|
|
|
for (auto& ct : *trace->mutable_calculator_trace()) {
|
2020-04-07 04:10:12 +02:00
|
|
|
if ((*builder.trace_event_registry())[ct.event_type()].id_event_data()) {
|
|
|
|
for (auto& st : *ct.mutable_input_trace()) {
|
|
|
|
st.clear_event_data();
|
|
|
|
}
|
|
|
|
for (auto& st : *ct.mutable_output_trace()) {
|
|
|
|
st.clear_event_data();
|
|
|
|
}
|
2019-06-17 01:03:25 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// A Calculator::Process callback function.
|
2021-02-27 09:21:16 +01:00
|
|
|
typedef std::function<absl::Status(const InputStreamShardSet&,
|
|
|
|
OutputStreamShardSet*)>
|
2019-06-17 01:03:25 +02:00
|
|
|
ProcessFunction;
|
|
|
|
|
|
|
|
// A testing callback function that passes through all packets.
|
2021-02-27 09:21:16 +01:00
|
|
|
absl::Status PassThrough(const InputStreamShardSet& inputs,
|
|
|
|
OutputStreamShardSet* outputs) {
|
2019-06-17 01:03:25 +02:00
|
|
|
for (int i = 0; i < inputs.NumEntries(); ++i) {
|
|
|
|
if (!inputs.Index(i).Value().IsEmpty()) {
|
|
|
|
outputs->Index(i).AddPacket(inputs.Index(i).Value());
|
|
|
|
}
|
|
|
|
}
|
2021-02-27 09:21:16 +01:00
|
|
|
return absl::OkStatus();
|
2019-06-17 01:03:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void RunPassThroughGraph() {
|
|
|
|
// SetUpSimulationClock can be replaced by SetUpRealClock.
|
|
|
|
SetUpSimulationClock();
|
|
|
|
|
|
|
|
// Callbacks to control the LambdaCalculators.
|
|
|
|
ProcessFunction wait_0 = [&](const InputStreamShardSet& inputs,
|
|
|
|
OutputStreamShardSet* outputs) {
|
|
|
|
clock_->Sleep(absl::Microseconds(20001));
|
|
|
|
return PassThrough(inputs, outputs);
|
|
|
|
};
|
|
|
|
|
|
|
|
// Start the graph with the callbacks.
|
2019-09-11 22:58:46 +02:00
|
|
|
MP_ASSERT_OK(graph_.Initialize(graph_config_,
|
|
|
|
{
|
|
|
|
{"callback_0", Adopt(new auto(wait_0))},
|
|
|
|
}));
|
2019-06-17 01:03:25 +02:00
|
|
|
graph_.profiler()->SetClock(simulation_clock_);
|
|
|
|
std::vector<Packet> out_packets;
|
2019-09-11 22:58:46 +02:00
|
|
|
MP_ASSERT_OK(
|
2019-06-17 01:03:25 +02:00
|
|
|
graph_.ObserveOutputStream("output_0", [&](const Packet& packet) {
|
|
|
|
out_packets.push_back(packet);
|
2021-02-27 09:21:16 +01:00
|
|
|
return absl::OkStatus();
|
2019-06-17 01:03:25 +02:00
|
|
|
}));
|
|
|
|
simulation_clock_->ThreadStart();
|
2019-09-11 22:58:46 +02:00
|
|
|
MP_ASSERT_OK(graph_.StartRun({}));
|
2019-06-17 01:03:25 +02:00
|
|
|
|
|
|
|
// The first 6 packets to send into the graph at 5001 us intervals.
|
|
|
|
for (int ts = 10000; ts < 70000; ts += 10000) {
|
|
|
|
clock_->Sleep(absl::Microseconds(5001));
|
2019-09-11 22:58:46 +02:00
|
|
|
MP_EXPECT_OK(graph_.AddPacketToInputStream("input_0", PacketAt(ts)));
|
2019-06-17 01:03:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Wait for all packets to be processed.
|
2019-09-11 22:58:46 +02:00
|
|
|
MP_ASSERT_OK(graph_.CloseAllPacketSources());
|
2019-06-17 01:03:25 +02:00
|
|
|
clock_->Sleep(absl::Microseconds(240000 + 0));
|
2019-09-11 22:58:46 +02:00
|
|
|
MP_ASSERT_OK(graph_.WaitUntilDone());
|
2019-06-17 01:03:25 +02:00
|
|
|
simulation_clock_->ThreadFinish();
|
|
|
|
|
|
|
|
// Validate the graph run.
|
|
|
|
EXPECT_THAT(TimestampValues(out_packets),
|
|
|
|
ElementsAre(10000, 20000, 30000, 40000, 50000, 60000));
|
|
|
|
}
|
|
|
|
|
|
|
|
void RunDemuxInFlightGraph() {
|
|
|
|
// SetUpSimulationClock can be replaced by SetUpRealClock.
|
|
|
|
SetUpSimulationClock();
|
|
|
|
|
|
|
|
// Callbacks to control the LambdaCalculators.
|
|
|
|
ProcessFunction wait_0 = [&](const InputStreamShardSet& inputs,
|
|
|
|
OutputStreamShardSet* outputs) {
|
|
|
|
clock_->Sleep(absl::Microseconds(20001));
|
|
|
|
return PassThrough(inputs, outputs);
|
|
|
|
};
|
|
|
|
ProcessFunction wait_1 = [&](const InputStreamShardSet& inputs,
|
|
|
|
OutputStreamShardSet* outputs) {
|
|
|
|
clock_->Sleep(absl::Microseconds(30001));
|
|
|
|
return PassThrough(inputs, outputs);
|
|
|
|
};
|
|
|
|
|
|
|
|
// A callback to control the source LambdaCalculator.
|
|
|
|
std::vector<std::pair<int64, Packet>> packets;
|
|
|
|
ProcessFunction wait_2 = [&](const InputStreamShardSet& inputs,
|
|
|
|
OutputStreamShardSet* outputs) {
|
|
|
|
if (!packets.empty()) {
|
|
|
|
clock_->Sleep(absl::Microseconds(packets.front().first));
|
|
|
|
outputs->Index(0).AddPacket(packets.front().second);
|
|
|
|
packets.erase(packets.begin());
|
2021-02-27 09:21:16 +01:00
|
|
|
return absl::OkStatus();
|
2019-06-17 01:03:25 +02:00
|
|
|
}
|
|
|
|
return tool::StatusStop();
|
|
|
|
};
|
|
|
|
|
|
|
|
// The first 6 packets to send into the graph at 5001 us intervals.
|
|
|
|
for (int ts = 10000; ts < 70000; ts += 10000) {
|
|
|
|
packets.emplace_back(5001, PacketAt(ts));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Start the graph with the callbacks.
|
2019-09-11 22:58:46 +02:00
|
|
|
MP_ASSERT_OK(graph_.Initialize(graph_config_,
|
|
|
|
{
|
|
|
|
{"max_in_flight", MakePacket<int>(4)},
|
|
|
|
{"callback_0", Adopt(new auto(wait_0))},
|
|
|
|
{"callback_1", Adopt(new auto(wait_1))},
|
|
|
|
{"callback_2", Adopt(new auto(wait_2))},
|
|
|
|
}));
|
2019-06-17 01:03:25 +02:00
|
|
|
graph_.profiler()->SetClock(simulation_clock_);
|
|
|
|
std::vector<Packet> out_packets;
|
2019-09-11 22:58:46 +02:00
|
|
|
MP_ASSERT_OK(graph_.ObserveOutputStream("output_packets_0",
|
|
|
|
[&](const Packet& packet) {
|
|
|
|
out_packets.push_back(packet);
|
2021-02-27 09:21:16 +01:00
|
|
|
return absl::OkStatus();
|
2019-09-11 22:58:46 +02:00
|
|
|
}));
|
2019-06-17 01:03:25 +02:00
|
|
|
simulation_clock_->ThreadStart();
|
2019-09-11 22:58:46 +02:00
|
|
|
MP_ASSERT_OK(graph_.StartRun({}));
|
2019-06-17 01:03:25 +02:00
|
|
|
|
|
|
|
// Wait for all packets to be added and processed.
|
|
|
|
clock_->Sleep(absl::Microseconds(160000 + 0));
|
2019-09-11 22:58:46 +02:00
|
|
|
MP_ASSERT_OK(graph_.WaitUntilDone());
|
2019-06-17 01:03:25 +02:00
|
|
|
simulation_clock_->ThreadFinish();
|
|
|
|
|
|
|
|
// Validate the graph run.
|
|
|
|
EXPECT_THAT(TimestampValues(out_packets),
|
|
|
|
ElementsAre(10000, 20000, 30000, 50000));
|
|
|
|
}
|
|
|
|
|
|
|
|
CalculatorGraphConfig graph_config_;
|
|
|
|
CalculatorGraph graph_;
|
2020-12-10 04:13:05 +01:00
|
|
|
mediapipe::Clock* clock_;
|
2019-06-17 01:03:25 +02:00
|
|
|
std::shared_ptr<SimulationClock> simulation_clock_;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Initialize a TimeHistogram protobuf with some latency values.
|
|
|
|
void FillHistogram(const std::vector<int64>& values, TimeHistogram* result) {
|
|
|
|
result->set_num_intervals(100);
|
|
|
|
result->set_interval_size_usec(1000);
|
|
|
|
result->mutable_count()->Resize(result->num_intervals(), 0);
|
|
|
|
for (int64 v : values) {
|
|
|
|
result->set_total(result->total() + v);
|
|
|
|
int bin = v / result->interval_size_usec();
|
|
|
|
bin = std::min(bin, (int)result->num_intervals() - 1);
|
|
|
|
result->set_count(bin, result->count(bin) + 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Verify profiler histograms with the PassThrough graph.
|
|
|
|
TEST_F(GraphTracerE2ETest, PassThroughGraphProfile) {
|
|
|
|
SetUpPassThroughGraph();
|
|
|
|
graph_config_.mutable_profiler_config()->set_enable_profiler(true);
|
|
|
|
graph_config_.mutable_profiler_config()->set_enable_stream_latency(true);
|
|
|
|
// Trace log writing should be disabled, otherwise if a default trace log path
|
|
|
|
// is set, the GraphProfiler will dump the profiles to that path and empty out
|
|
|
|
// the CalculatorProfiles.
|
|
|
|
graph_config_.mutable_profiler_config()->set_trace_log_disabled(true);
|
|
|
|
RunPassThroughGraph();
|
|
|
|
std::vector<CalculatorProfile> profiles;
|
2019-09-11 22:58:46 +02:00
|
|
|
MP_EXPECT_OK(graph_.profiler()->GetCalculatorProfiles(&profiles));
|
2019-06-17 01:03:25 +02:00
|
|
|
EXPECT_EQ(1, profiles.size());
|
|
|
|
CalculatorProfile expected =
|
2021-04-01 01:20:27 +02:00
|
|
|
mediapipe::ParseTextProtoOrDie<CalculatorProfile>(R"pb(
|
2019-06-17 01:03:25 +02:00
|
|
|
name: "LambdaCalculator"
|
|
|
|
open_runtime: 0
|
|
|
|
close_runtime: 0
|
2021-04-01 01:20:27 +02:00
|
|
|
input_stream_profiles { name: "input_0" back_edge: false })pb");
|
2019-06-17 01:03:25 +02:00
|
|
|
|
|
|
|
FillHistogram({20001, 20001, 20001, 20001, 20001, 20001},
|
|
|
|
expected.mutable_process_runtime());
|
|
|
|
FillHistogram({0, 15000, 30000, 45000, 60000, 75000},
|
|
|
|
expected.mutable_process_input_latency());
|
|
|
|
FillHistogram({20001, 35001, 50001, 65001, 80001, 95001},
|
|
|
|
expected.mutable_process_output_latency());
|
|
|
|
FillHistogram({0, 15000, 30000, 45000, 60000, 75000},
|
|
|
|
expected.mutable_input_stream_profiles(0)->mutable_latency());
|
|
|
|
|
|
|
|
EXPECT_THAT(profiles[0], EqualsProto(expected));
|
|
|
|
EXPECT_EQ(GraphProfilerTestPeer::GetPacketsInfoMap(graph_.profiler())->size(),
|
|
|
|
2);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(GraphTracerE2ETest, DemuxGraphLog) {
|
|
|
|
SetUpDemuxInFlightGraph();
|
|
|
|
RunDemuxInFlightGraph();
|
|
|
|
|
|
|
|
// Validate a summary of the event trace.
|
|
|
|
GraphTrace trace;
|
|
|
|
graph_.profiler()->tracer()->GetLog(absl::InfinitePast(),
|
|
|
|
absl::InfiniteFuture(), &trace);
|
|
|
|
GraphTrace node_timestamps = NodeTimestamps(trace);
|
|
|
|
EXPECT_THAT(node_timestamps,
|
2021-04-01 01:20:27 +02:00
|
|
|
EqualsProto(mediapipe::ParseTextProtoOrDie<GraphTrace>(R"pb(
|
2019-06-17 01:03:25 +02:00
|
|
|
calculator_trace { node_id: 1 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 2 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 3 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 4 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 5 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 0 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 1 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 1 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 1 input_timestamp: 10000 }
|
2020-04-07 04:10:12 +02:00
|
|
|
calculator_trace { node_id: 1 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 2 input_timestamp: 10000 }
|
2019-06-17 01:03:25 +02:00
|
|
|
calculator_trace { node_id: 2 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 1 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 2 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 2 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 3 input_timestamp: 10000 }
|
2020-04-07 04:10:12 +02:00
|
|
|
calculator_trace { node_id: 3 input_timestamp: 10000 }
|
2021-02-27 09:21:16 +01:00
|
|
|
calculator_trace { node_id: 4 input_timestamp: 10000 }
|
2019-06-17 01:03:25 +02:00
|
|
|
calculator_trace { node_id: 2 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 3 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 0 input_timestamp: 20000 }
|
2020-04-07 04:10:12 +02:00
|
|
|
calculator_trace { node_id: 1 input_timestamp: 20000 }
|
2019-06-17 01:03:25 +02:00
|
|
|
calculator_trace { node_id: 1 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 1 input_timestamp: 20000 }
|
|
|
|
calculator_trace { node_id: 1 input_timestamp: 20000 }
|
2020-04-07 04:10:12 +02:00
|
|
|
calculator_trace { node_id: 2 input_timestamp: 20000 }
|
2019-06-17 01:03:25 +02:00
|
|
|
calculator_trace { node_id: 2 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 1 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 2 input_timestamp: 20000 }
|
|
|
|
calculator_trace { node_id: 2 input_timestamp: 20000 }
|
2020-04-07 04:10:12 +02:00
|
|
|
calculator_trace { node_id: 4 input_timestamp: 20000 }
|
2019-06-17 01:03:25 +02:00
|
|
|
calculator_trace { node_id: 4 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 2 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 4 input_timestamp: 20000 }
|
|
|
|
calculator_trace { node_id: 0 input_timestamp: 30000 }
|
2020-04-07 04:10:12 +02:00
|
|
|
calculator_trace { node_id: 1 input_timestamp: 30000 }
|
2019-06-17 01:03:25 +02:00
|
|
|
calculator_trace { node_id: 1 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 1 input_timestamp: 30000 }
|
|
|
|
calculator_trace { node_id: 1 input_timestamp: 30000 }
|
2020-04-07 04:10:12 +02:00
|
|
|
calculator_trace { node_id: 2 input_timestamp: 30000 }
|
2019-06-17 01:03:25 +02:00
|
|
|
calculator_trace { node_id: 2 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 1 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 2 input_timestamp: 30000 }
|
|
|
|
calculator_trace { node_id: 2 input_timestamp: 30000 }
|
2020-04-07 04:10:12 +02:00
|
|
|
calculator_trace { node_id: 3 input_timestamp: 30000 }
|
2019-06-17 01:03:25 +02:00
|
|
|
calculator_trace { node_id: 2 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 0 input_timestamp: 40000 }
|
2020-04-07 04:10:12 +02:00
|
|
|
calculator_trace { node_id: 1 input_timestamp: 40000 }
|
2019-06-17 01:03:25 +02:00
|
|
|
calculator_trace { node_id: 1 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 1 input_timestamp: 40000 }
|
|
|
|
calculator_trace { node_id: 1 input_timestamp: 40000 }
|
2020-04-07 04:10:12 +02:00
|
|
|
calculator_trace { node_id: 2 input_timestamp: 40000 }
|
2019-06-17 01:03:25 +02:00
|
|
|
calculator_trace { node_id: 2 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 1 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 2 input_timestamp: 40000 }
|
|
|
|
calculator_trace { node_id: 2 input_timestamp: 40000 }
|
2020-04-07 04:10:12 +02:00
|
|
|
calculator_trace { node_id: 4 input_timestamp: 40000 }
|
2019-06-17 01:03:25 +02:00
|
|
|
calculator_trace { node_id: 2 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 3 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 5 input_timestamp: 10000 }
|
2020-04-07 04:10:12 +02:00
|
|
|
calculator_trace { node_id: 5 input_timestamp: 10000 }
|
2019-06-17 01:03:25 +02:00
|
|
|
calculator_trace { node_id: 3 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 5 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 5 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 5 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 1 input_timestamp: 10000 }
|
2020-04-07 04:10:12 +02:00
|
|
|
calculator_trace { node_id: 1 input_timestamp: 10000 }
|
2019-06-17 01:03:25 +02:00
|
|
|
calculator_trace { node_id: 5 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 3 input_timestamp: 30000 }
|
|
|
|
calculator_trace { node_id: 1 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 1 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 0 input_timestamp: 50000 }
|
2020-04-07 04:10:12 +02:00
|
|
|
calculator_trace { node_id: 1 input_timestamp: 50000 }
|
2019-06-17 01:03:25 +02:00
|
|
|
calculator_trace { node_id: 1 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 1 input_timestamp: 50000 }
|
|
|
|
calculator_trace { node_id: 1 input_timestamp: 50000 }
|
2020-04-07 04:10:12 +02:00
|
|
|
calculator_trace { node_id: 2 input_timestamp: 50000 }
|
2019-06-17 01:03:25 +02:00
|
|
|
calculator_trace { node_id: 2 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 1 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 2 input_timestamp: 50000 }
|
|
|
|
calculator_trace { node_id: 2 input_timestamp: 50000 }
|
2020-04-07 04:10:12 +02:00
|
|
|
calculator_trace { node_id: 3 input_timestamp: 50000 }
|
2019-06-17 01:03:25 +02:00
|
|
|
calculator_trace { node_id: 2 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 0 input_timestamp: 60000 }
|
2020-04-07 04:10:12 +02:00
|
|
|
calculator_trace { node_id: 1 input_timestamp: 60000 }
|
2019-06-17 01:03:25 +02:00
|
|
|
calculator_trace { node_id: 1 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 1 input_timestamp: 60000 }
|
|
|
|
calculator_trace { node_id: 2 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 1 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 1 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 2 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 1 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 4 input_timestamp: 20000 }
|
2020-04-07 04:10:12 +02:00
|
|
|
calculator_trace { node_id: 5 input_timestamp: 20000 }
|
2019-06-17 01:03:25 +02:00
|
|
|
calculator_trace { node_id: 5 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 4 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 5 input_timestamp: 20000 }
|
|
|
|
calculator_trace { node_id: 5 input_timestamp: 20000 }
|
|
|
|
calculator_trace { node_id: 5 input_timestamp: 20000 }
|
2020-04-07 04:10:12 +02:00
|
|
|
calculator_trace { node_id: 1 input_timestamp: 20000 }
|
2019-06-17 01:03:25 +02:00
|
|
|
calculator_trace { node_id: 1 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 5 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 4 input_timestamp: 40000 }
|
|
|
|
calculator_trace { node_id: 1 input_timestamp: 20000 }
|
|
|
|
calculator_trace { node_id: 1 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 3 input_timestamp: 30000 }
|
2020-04-07 04:10:12 +02:00
|
|
|
calculator_trace { node_id: 5 input_timestamp: 30000 }
|
2019-06-17 01:03:25 +02:00
|
|
|
calculator_trace { node_id: 5 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 3 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 5 input_timestamp: 30000 }
|
|
|
|
calculator_trace { node_id: 5 input_timestamp: 30000 }
|
|
|
|
calculator_trace { node_id: 5 input_timestamp: 30000 }
|
2020-04-07 04:10:12 +02:00
|
|
|
calculator_trace { node_id: 1 input_timestamp: 30000 }
|
2019-06-17 01:03:25 +02:00
|
|
|
calculator_trace { node_id: 1 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 5 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 3 input_timestamp: 50000 }
|
|
|
|
calculator_trace { node_id: 1 input_timestamp: 30000 }
|
|
|
|
calculator_trace { node_id: 1 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 3 input_timestamp: 50000 }
|
2020-04-07 04:10:12 +02:00
|
|
|
calculator_trace { node_id: 5 input_timestamp: 50000 }
|
2019-06-17 01:03:25 +02:00
|
|
|
calculator_trace { node_id: 5 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 3 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 5 input_timestamp: 50000 }
|
|
|
|
calculator_trace { node_id: 5 input_timestamp: 50000 }
|
|
|
|
calculator_trace { node_id: 5 input_timestamp: 50000 }
|
2020-04-07 04:10:12 +02:00
|
|
|
calculator_trace { node_id: 1 input_timestamp: 50000 }
|
2019-06-17 01:03:25 +02:00
|
|
|
calculator_trace { node_id: 1 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 5 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 5 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 5 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 1 input_timestamp: 50000 }
|
|
|
|
calculator_trace { node_id: 1 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 4 input_timestamp: 40000 }
|
2020-04-07 04:10:12 +02:00
|
|
|
calculator_trace { node_id: 5 input_timestamp: 40000 }
|
2019-06-17 01:03:25 +02:00
|
|
|
calculator_trace { node_id: 5 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 4 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 5 input_timestamp: 40000 }
|
|
|
|
calculator_trace { node_id: 5 input_timestamp: 40000 }
|
2020-04-07 04:10:12 +02:00
|
|
|
calculator_trace { node_id: 1 input_timestamp: 50001 }
|
2019-06-17 01:03:25 +02:00
|
|
|
calculator_trace { node_id: 1 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 5 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 5 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 1 input_timestamp: 50001 }
|
2020-12-10 04:13:05 +01:00
|
|
|
calculator_trace { node_id: 1 input_timestamp: 10000 }
|
|
|
|
calculator_trace { node_id: 1 input_timestamp: 10000 }
|
2021-04-01 01:20:27 +02:00
|
|
|
)pb")));
|
2019-06-17 01:03:25 +02:00
|
|
|
|
|
|
|
// Validate a one-timestamp slice of the event trace.
|
|
|
|
GraphTrace trace_2;
|
|
|
|
graph_.profiler()->tracer()->GetLog(StartTime() + absl::Microseconds(25000),
|
|
|
|
StartTime() + absl::Microseconds(30005),
|
|
|
|
&trace_2);
|
|
|
|
StripThreadIds(&trace_2);
|
|
|
|
StripDataIds(&trace_2);
|
2020-04-07 04:10:12 +02:00
|
|
|
EXPECT_THAT(
|
|
|
|
trace_2,
|
2020-12-10 04:13:05 +01:00
|
|
|
EqualsProto(mediapipe::ParseTextProtoOrDie<GraphTrace>(
|
2021-04-01 01:20:27 +02:00
|
|
|
R"pb(
|
2020-04-07 04:10:12 +02:00
|
|
|
base_time: 1544086800000000
|
|
|
|
base_timestamp: 10000
|
|
|
|
stream_name: ""
|
|
|
|
stream_name: "input_packets_0"
|
|
|
|
stream_name: "input_0_sampled"
|
|
|
|
stream_name: "input_0"
|
|
|
|
stream_name: "input_1"
|
|
|
|
stream_name: "output_0"
|
|
|
|
stream_name: "output_packets_0"
|
|
|
|
stream_name: "finish_indicator"
|
|
|
|
stream_name: "output_1"
|
|
|
|
calculator_trace {
|
|
|
|
node_id: 3
|
|
|
|
input_timestamp: 0
|
|
|
|
event_type: PROCESS
|
|
|
|
finish_time: 25002
|
|
|
|
output_trace { packet_timestamp: 0 stream_id: 5 }
|
|
|
|
}
|
|
|
|
calculator_trace {
|
|
|
|
node_id: 5
|
|
|
|
input_timestamp: 0
|
|
|
|
event_type: PACKET_QUEUED
|
|
|
|
start_time: 25002
|
|
|
|
input_trace { packet_timestamp: 0 stream_id: 5 event_data: 1 }
|
|
|
|
}
|
|
|
|
calculator_trace {
|
|
|
|
node_id: 5
|
|
|
|
event_type: READY_FOR_PROCESS
|
|
|
|
start_time: 25002
|
|
|
|
}
|
|
|
|
calculator_trace {
|
|
|
|
node_id: 3
|
|
|
|
event_type: READY_FOR_PROCESS
|
|
|
|
start_time: 25002
|
|
|
|
}
|
|
|
|
calculator_trace {
|
|
|
|
node_id: 5
|
|
|
|
input_timestamp: 0
|
|
|
|
event_type: PROCESS
|
|
|
|
start_time: 25002
|
|
|
|
input_trace { packet_timestamp: 0 stream_id: 5 }
|
|
|
|
}
|
|
|
|
calculator_trace {
|
|
|
|
node_id: 5
|
|
|
|
input_timestamp: 0
|
|
|
|
event_type: PROCESS
|
|
|
|
finish_time: 25002
|
|
|
|
output_trace { packet_timestamp: 0 stream_id: 6 }
|
|
|
|
}
|
|
|
|
calculator_trace {
|
|
|
|
node_id: 5
|
|
|
|
input_timestamp: 0
|
|
|
|
event_type: PROCESS
|
|
|
|
finish_time: 25002
|
|
|
|
output_trace { packet_timestamp: 0 stream_id: 7 }
|
|
|
|
}
|
|
|
|
calculator_trace {
|
|
|
|
node_id: 1
|
|
|
|
input_timestamp: 0
|
|
|
|
event_type: PACKET_QUEUED
|
|
|
|
start_time: 25002
|
|
|
|
input_trace { packet_timestamp: 0 stream_id: 7 event_data: 1 }
|
|
|
|
}
|
|
|
|
calculator_trace {
|
|
|
|
node_id: 1
|
|
|
|
event_type: READY_FOR_PROCESS
|
|
|
|
start_time: 25002
|
|
|
|
}
|
|
|
|
calculator_trace {
|
|
|
|
node_id: 5
|
|
|
|
event_type: NOT_READY
|
|
|
|
start_time: 25002
|
|
|
|
}
|
|
|
|
calculator_trace {
|
|
|
|
node_id: 3
|
|
|
|
input_timestamp: 20000
|
|
|
|
event_type: PROCESS
|
|
|
|
start_time: 25002
|
|
|
|
input_trace { packet_timestamp: 20000 stream_id: 3 }
|
|
|
|
}
|
|
|
|
calculator_trace {
|
|
|
|
node_id: 1
|
|
|
|
input_timestamp: 0
|
|
|
|
event_type: PROCESS
|
|
|
|
start_time: 25002
|
|
|
|
input_trace { packet_timestamp: 0 stream_id: 7 }
|
|
|
|
}
|
|
|
|
calculator_trace {
|
|
|
|
node_id: 1
|
|
|
|
event_type: NOT_READY
|
|
|
|
start_time: 25002
|
|
|
|
}
|
|
|
|
calculator_trace {
|
|
|
|
node_id: 0
|
|
|
|
input_timestamp: 40000
|
|
|
|
event_type: PROCESS
|
|
|
|
finish_time: 25005
|
|
|
|
output_trace { packet_timestamp: 40000 stream_id: 1 }
|
|
|
|
}
|
|
|
|
calculator_trace {
|
|
|
|
node_id: 1
|
|
|
|
input_timestamp: 40000
|
|
|
|
event_type: PACKET_QUEUED
|
|
|
|
start_time: 25005
|
|
|
|
input_trace { packet_timestamp: 40000 stream_id: 1 event_data: 1 }
|
|
|
|
}
|
|
|
|
calculator_trace {
|
|
|
|
node_id: 1
|
|
|
|
event_type: READY_FOR_PROCESS
|
|
|
|
start_time: 25005
|
|
|
|
}
|
|
|
|
calculator_trace {
|
|
|
|
node_id: 1
|
|
|
|
input_timestamp: 40000
|
|
|
|
event_type: PROCESS
|
|
|
|
start_time: 25005
|
|
|
|
input_trace { packet_timestamp: 40000 stream_id: 1 }
|
|
|
|
}
|
|
|
|
calculator_trace {
|
|
|
|
node_id: 1
|
|
|
|
input_timestamp: 40000
|
|
|
|
event_type: PROCESS
|
|
|
|
finish_time: 25005
|
|
|
|
output_trace { packet_timestamp: 40000 stream_id: 2 }
|
|
|
|
}
|
|
|
|
calculator_trace {
|
|
|
|
node_id: 2
|
|
|
|
input_timestamp: 40000
|
|
|
|
event_type: PACKET_QUEUED
|
|
|
|
start_time: 25005
|
|
|
|
input_trace { packet_timestamp: 40000 stream_id: 2 event_data: 1 }
|
|
|
|
}
|
|
|
|
calculator_trace {
|
|
|
|
node_id: 2
|
|
|
|
event_type: READY_FOR_PROCESS
|
|
|
|
start_time: 25005
|
|
|
|
}
|
|
|
|
calculator_trace {
|
|
|
|
node_id: 1
|
|
|
|
event_type: NOT_READY
|
|
|
|
start_time: 25005
|
|
|
|
}
|
|
|
|
calculator_trace {
|
|
|
|
node_id: 2
|
|
|
|
input_timestamp: 40000
|
|
|
|
event_type: PROCESS
|
|
|
|
start_time: 25005
|
|
|
|
input_trace { packet_timestamp: 40000 stream_id: 2 }
|
|
|
|
}
|
|
|
|
calculator_trace {
|
|
|
|
node_id: 2
|
|
|
|
input_timestamp: 40000
|
|
|
|
event_type: PROCESS
|
|
|
|
finish_time: 25005
|
|
|
|
output_trace { packet_timestamp: 40000 stream_id: 3 }
|
|
|
|
}
|
|
|
|
calculator_trace {
|
|
|
|
node_id: 3
|
|
|
|
input_timestamp: 40000
|
|
|
|
event_type: PACKET_QUEUED
|
|
|
|
start_time: 25005
|
|
|
|
input_trace { packet_timestamp: 40000 stream_id: 3 event_data: 1 }
|
|
|
|
}
|
|
|
|
calculator_trace {
|
|
|
|
node_id: 2
|
|
|
|
event_type: NOT_READY
|
|
|
|
start_time: 25005
|
|
|
|
}
|
2021-04-01 01:20:27 +02:00
|
|
|
)pb")));
|
2019-06-17 01:03:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Read a GraphProfile from a file path.
|
2021-02-27 09:21:16 +01:00
|
|
|
absl::Status ReadGraphProfile(const std::string& path, GraphProfile* profile) {
|
2019-06-17 01:03:25 +02:00
|
|
|
std::ifstream ifs;
|
|
|
|
ifs.open(path);
|
|
|
|
proto_ns::io::IstreamInputStream in_stream(&ifs);
|
|
|
|
profile->ParseFromZeroCopyStream(&in_stream);
|
2021-02-27 09:21:16 +01:00
|
|
|
return ifs.is_open() ? absl::OkStatus()
|
|
|
|
: absl::UnavailableError("Cannot open");
|
2019-06-17 01:03:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(GraphTracerE2ETest, DemuxGraphLogFile) {
|
|
|
|
std::string log_path = absl::StrCat(getenv("TEST_TMPDIR"), "/log_file_");
|
|
|
|
SetUpDemuxInFlightGraph();
|
|
|
|
graph_config_.mutable_profiler_config()->set_trace_log_path(log_path);
|
|
|
|
graph_config_.mutable_profiler_config()->set_trace_log_interval_usec(-1);
|
|
|
|
RunDemuxInFlightGraph();
|
|
|
|
GraphProfile profile;
|
2019-09-11 22:58:46 +02:00
|
|
|
MP_EXPECT_OK(
|
2019-09-09 20:02:30 +02:00
|
|
|
ReadGraphProfile(absl::StrCat(log_path, 0, ".binarypb"), &profile));
|
2021-02-27 09:21:16 +01:00
|
|
|
EXPECT_EQ(113, profile.graph_trace(0).calculator_trace().size());
|
2019-06-17 01:03:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(GraphTracerE2ETest, DemuxGraphLogFiles) {
|
|
|
|
std::string log_path = absl::StrCat(getenv("TEST_TMPDIR"), "/log_files_");
|
|
|
|
SetUpDemuxInFlightGraph();
|
|
|
|
graph_config_.mutable_profiler_config()->set_trace_log_path(log_path);
|
|
|
|
graph_config_.mutable_profiler_config()->set_trace_log_count(100);
|
2019-09-09 20:02:30 +02:00
|
|
|
graph_config_.mutable_profiler_config()->set_trace_log_interval_count(5);
|
2019-06-17 01:03:25 +02:00
|
|
|
graph_config_.mutable_profiler_config()->set_trace_log_interval_usec(2500);
|
|
|
|
RunDemuxInFlightGraph();
|
|
|
|
std::vector<int> event_counts;
|
|
|
|
std::vector<GraphProfile> graph_profiles;
|
|
|
|
for (int i = 0; i < 7; ++i) {
|
|
|
|
GraphProfile profile;
|
2019-09-09 20:02:30 +02:00
|
|
|
std::string log_file_name = absl::StrCat(log_path, i, ".binarypb");
|
|
|
|
if (ReadGraphProfile(log_file_name, &profile).ok()) {
|
|
|
|
int count = 0;
|
|
|
|
for (auto trace : *profile.mutable_graph_trace()) {
|
|
|
|
count += trace.calculator_trace().size();
|
|
|
|
}
|
|
|
|
event_counts.push_back(count);
|
|
|
|
graph_profiles.push_back(profile);
|
2019-06-17 01:03:25 +02:00
|
|
|
}
|
|
|
|
}
|
2020-04-07 04:10:12 +02:00
|
|
|
|
|
|
|
// The expected counts of calculator_trace records in each of the log files.
|
|
|
|
// The processing spans three 12.5ms log files, because
|
|
|
|
// RunDemuxInFlightGraph adds packets over 30ms.
|
2021-02-27 09:21:16 +01:00
|
|
|
std::vector<int> expected = {50, 64, 12};
|
2019-06-17 01:03:25 +02:00
|
|
|
EXPECT_EQ(event_counts, expected);
|
|
|
|
GraphProfile& profile_2 = graph_profiles[2];
|
|
|
|
profile_2.clear_calculator_profiles();
|
|
|
|
profile_2.mutable_config()->mutable_profiler_config()->clear_trace_log_path();
|
|
|
|
for (auto& trace : *profile_2.mutable_graph_trace()) {
|
|
|
|
StripThreadIds(&trace);
|
|
|
|
StripDataIds(&trace);
|
|
|
|
}
|
|
|
|
EXPECT_THAT(profile_2,
|
2021-04-01 01:20:27 +02:00
|
|
|
EqualsProto(mediapipe::ParseTextProtoOrDie<GraphProfile>(R"pb(
|
2019-06-17 01:03:25 +02:00
|
|
|
graph_trace {
|
|
|
|
base_time: 1544086800000000
|
|
|
|
base_timestamp: 0
|
|
|
|
calculator_name: "LambdaCalculator_1"
|
2019-08-17 03:49:25 +02:00
|
|
|
calculator_name: "FlowLimiterCalculator"
|
2019-06-17 01:03:25 +02:00
|
|
|
calculator_name: "RoundRobinDemuxCalculator"
|
2022-03-21 20:07:37 +01:00
|
|
|
calculator_name: "LambdaCalculator_2"
|
|
|
|
calculator_name: "LambdaCalculator_3"
|
2019-06-17 01:03:25 +02:00
|
|
|
calculator_name: "ImmediateMuxCalculator"
|
|
|
|
stream_name: ""
|
|
|
|
stream_name: "input_packets_0"
|
|
|
|
stream_name: "input_0_sampled"
|
|
|
|
stream_name: "input_0"
|
|
|
|
stream_name: "input_1"
|
|
|
|
stream_name: "output_0"
|
|
|
|
stream_name: "output_packets_0"
|
|
|
|
stream_name: "finish_indicator"
|
|
|
|
stream_name: "output_1"
|
|
|
|
calculator_trace {
|
|
|
|
node_id: 4
|
|
|
|
input_timestamp: 40000
|
|
|
|
event_type: PROCESS
|
|
|
|
finish_time: 70004
|
|
|
|
output_trace { packet_timestamp: 40000 stream_id: 8 }
|
|
|
|
}
|
2020-04-07 04:10:12 +02:00
|
|
|
calculator_trace {
|
|
|
|
node_id: 5
|
|
|
|
input_timestamp: 40000
|
|
|
|
event_type: PACKET_QUEUED
|
|
|
|
start_time: 70004
|
|
|
|
input_trace {
|
|
|
|
finish_time: 70004
|
|
|
|
packet_timestamp: 40000
|
|
|
|
stream_id: 8
|
|
|
|
event_data: 1
|
|
|
|
}
|
|
|
|
}
|
2019-06-17 01:03:25 +02:00
|
|
|
calculator_trace {
|
|
|
|
node_id: 5
|
|
|
|
event_type: READY_FOR_PROCESS
|
|
|
|
start_time: 70004
|
|
|
|
}
|
|
|
|
calculator_trace {
|
|
|
|
node_id: 4
|
|
|
|
event_type: READY_FOR_CLOSE
|
|
|
|
start_time: 70004
|
|
|
|
}
|
|
|
|
calculator_trace {
|
|
|
|
node_id: 5
|
|
|
|
input_timestamp: 40000
|
|
|
|
event_type: PROCESS
|
|
|
|
start_time: 70004
|
|
|
|
finish_time: 70004
|
2019-08-17 03:49:25 +02:00
|
|
|
input_trace {
|
|
|
|
start_time: 70004
|
|
|
|
finish_time: 70004
|
|
|
|
packet_timestamp: 40000
|
|
|
|
stream_id: 8
|
|
|
|
}
|
2019-06-17 01:03:25 +02:00
|
|
|
output_trace { packet_timestamp: 50001 stream_id: 7 }
|
|
|
|
}
|
2020-04-07 04:10:12 +02:00
|
|
|
calculator_trace {
|
|
|
|
node_id: 1
|
|
|
|
input_timestamp: 50001
|
|
|
|
event_type: PACKET_QUEUED
|
|
|
|
start_time: 70004
|
|
|
|
input_trace {
|
|
|
|
finish_time: 70004
|
|
|
|
packet_timestamp: 50001
|
|
|
|
stream_id: 7
|
|
|
|
event_data: 1
|
|
|
|
}
|
|
|
|
}
|
2019-06-17 01:03:25 +02:00
|
|
|
calculator_trace {
|
|
|
|
node_id: 1
|
|
|
|
event_type: READY_FOR_PROCESS
|
|
|
|
start_time: 70004
|
|
|
|
}
|
|
|
|
calculator_trace {
|
|
|
|
node_id: 5
|
|
|
|
event_type: NOT_READY
|
|
|
|
start_time: 70004
|
|
|
|
}
|
|
|
|
calculator_trace {
|
|
|
|
node_id: 5
|
|
|
|
event_type: READY_FOR_CLOSE
|
|
|
|
start_time: 70004
|
|
|
|
}
|
|
|
|
calculator_trace {
|
|
|
|
node_id: 1
|
|
|
|
input_timestamp: 50001
|
|
|
|
event_type: PROCESS
|
|
|
|
start_time: 70004
|
2019-08-17 03:49:25 +02:00
|
|
|
input_trace {
|
|
|
|
start_time: 70004
|
|
|
|
finish_time: 70004
|
|
|
|
packet_timestamp: 50001
|
|
|
|
stream_id: 7
|
|
|
|
}
|
2019-06-17 01:03:25 +02:00
|
|
|
}
|
2020-12-10 04:13:05 +01:00
|
|
|
calculator_trace {
|
|
|
|
node_id: 1
|
|
|
|
event_type: READY_FOR_PROCESS
|
|
|
|
start_time: 70004
|
|
|
|
}
|
2019-06-17 01:03:25 +02:00
|
|
|
calculator_trace {
|
|
|
|
node_id: 1
|
|
|
|
event_type: READY_FOR_CLOSE
|
|
|
|
start_time: 70004
|
|
|
|
}
|
|
|
|
}
|
|
|
|
graph_trace {
|
|
|
|
base_time: 1544086800000000
|
|
|
|
base_timestamp: 0
|
|
|
|
stream_name: ""
|
|
|
|
stream_name: "input_packets_0"
|
|
|
|
stream_name: "input_0_sampled"
|
|
|
|
stream_name: "input_0"
|
|
|
|
stream_name: "input_1"
|
|
|
|
stream_name: "output_0"
|
|
|
|
stream_name: "output_packets_0"
|
|
|
|
stream_name: "finish_indicator"
|
|
|
|
stream_name: "output_1"
|
|
|
|
}
|
|
|
|
config {
|
|
|
|
node {
|
|
|
|
name: "LambdaCalculator_1"
|
|
|
|
calculator: "LambdaCalculator"
|
|
|
|
output_stream: "input_packets_0"
|
|
|
|
input_side_packet: "callback_2"
|
|
|
|
}
|
|
|
|
node {
|
2019-08-17 03:49:25 +02:00
|
|
|
name: "FlowLimiterCalculator"
|
|
|
|
calculator: "FlowLimiterCalculator"
|
2019-06-17 01:03:25 +02:00
|
|
|
input_stream: "input_packets_0"
|
|
|
|
input_stream: "FINISHED:finish_indicator"
|
|
|
|
output_stream: "input_0_sampled"
|
|
|
|
input_side_packet: "MAX_IN_FLIGHT:max_in_flight"
|
|
|
|
input_stream_handler {
|
|
|
|
input_stream_handler: "ImmediateInputStreamHandler"
|
|
|
|
}
|
|
|
|
input_stream_info { tag_index: "FINISHED" back_edge: true }
|
|
|
|
}
|
|
|
|
node {
|
|
|
|
name: "RoundRobinDemuxCalculator"
|
|
|
|
calculator: "RoundRobinDemuxCalculator"
|
|
|
|
input_stream: "input_0_sampled"
|
|
|
|
output_stream: "OUTPUT:0:input_0"
|
|
|
|
output_stream: "OUTPUT:1:input_1"
|
|
|
|
}
|
|
|
|
node {
|
2022-03-21 20:07:37 +01:00
|
|
|
name: "LambdaCalculator_2"
|
2019-06-17 01:03:25 +02:00
|
|
|
calculator: "LambdaCalculator"
|
|
|
|
input_stream: "input_0"
|
|
|
|
output_stream: "output_0"
|
|
|
|
input_side_packet: "callback_0"
|
|
|
|
}
|
|
|
|
node {
|
2022-03-21 20:07:37 +01:00
|
|
|
name: "LambdaCalculator_3"
|
2019-06-17 01:03:25 +02:00
|
|
|
calculator: "LambdaCalculator"
|
|
|
|
input_stream: "input_1"
|
|
|
|
output_stream: "output_1"
|
|
|
|
input_side_packet: "callback_1"
|
|
|
|
}
|
|
|
|
node {
|
|
|
|
name: "ImmediateMuxCalculator"
|
|
|
|
calculator: "ImmediateMuxCalculator"
|
|
|
|
input_stream: "output_0"
|
|
|
|
input_stream: "output_1"
|
|
|
|
output_stream: "output_packets_0"
|
|
|
|
output_stream: "finish_indicator"
|
|
|
|
input_stream_handler {
|
|
|
|
input_stream_handler: "ImmediateInputStreamHandler"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
executor {}
|
|
|
|
profiler_config {
|
|
|
|
histogram_interval_size_usec: 1000
|
|
|
|
num_histogram_intervals: 100
|
|
|
|
trace_log_count: 100
|
|
|
|
trace_log_interval_usec: 2500
|
2019-09-09 20:02:30 +02:00
|
|
|
trace_log_interval_count: 5
|
2019-08-17 03:49:25 +02:00
|
|
|
trace_enabled: true
|
2019-06-17 01:03:25 +02:00
|
|
|
}
|
|
|
|
}
|
2021-04-01 01:20:27 +02:00
|
|
|
)pb")));
|
2019-06-17 01:03:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(GraphTracerE2ETest, DisableLoggingToDisk) {
|
|
|
|
std::string log_path =
|
|
|
|
absl::StrCat(getenv("TEST_TMPDIR"), "/log_file_disabled_");
|
|
|
|
SetUpDemuxInFlightGraph();
|
|
|
|
graph_config_.mutable_profiler_config()->set_trace_log_path(log_path);
|
|
|
|
graph_config_.mutable_profiler_config()->set_trace_log_disabled(true);
|
|
|
|
RunDemuxInFlightGraph();
|
2021-02-27 09:21:16 +01:00
|
|
|
EXPECT_TRUE(absl::IsNotFound(
|
2019-06-17 01:03:25 +02:00
|
|
|
mediapipe::file::Exists(absl::StrCat(log_path, 0, ".binarypb"))));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(GraphTracerE2ETest, LoggingHappensWithDefaultPath) {
|
|
|
|
std::string log_path = "/tmp/mediapipe_trace_0.binarypb";
|
|
|
|
SetUpDemuxInFlightGraph();
|
|
|
|
graph_config_.mutable_profiler_config()->set_trace_log_disabled(false);
|
|
|
|
RunDemuxInFlightGraph();
|
2019-09-11 22:58:46 +02:00
|
|
|
MP_EXPECT_OK(mediapipe::file::Exists(log_path));
|
2019-06-17 01:03:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(GraphTracerE2ETest, GpuTaskTrace) {
|
|
|
|
std::string stream_1 = "stream_1";
|
|
|
|
std::string stream_2 = "stream_2";
|
|
|
|
TraceBuffer buffer(10000);
|
|
|
|
buffer.push_back(TraceEvent(TraceEvent::PROCESS)
|
|
|
|
.set_event_time(absl::FromUnixMicros(1100))
|
|
|
|
.set_node_id(333)
|
|
|
|
.set_stream_id(&stream_1)
|
|
|
|
.set_input_ts(Timestamp(1000))
|
|
|
|
.set_packet_ts(Timestamp(1000))
|
|
|
|
.set_is_finish(false));
|
|
|
|
buffer.push_back(TraceEvent(TraceEvent::GPU_TASK)
|
|
|
|
.set_event_time(absl::FromUnixMicros(1200))
|
|
|
|
.set_node_id(333)
|
|
|
|
.set_stream_id(&stream_1)
|
|
|
|
.set_input_ts(Timestamp(1000))
|
|
|
|
.set_packet_ts(Timestamp(1000))
|
|
|
|
.set_is_finish(false));
|
|
|
|
buffer.push_back(TraceEvent(TraceEvent::GPU_TASK)
|
|
|
|
.set_event_time(absl::FromUnixMicros(3200))
|
|
|
|
.set_node_id(333)
|
|
|
|
.set_stream_id(&stream_1)
|
|
|
|
.set_input_ts(Timestamp(1000))
|
|
|
|
.set_packet_ts(Timestamp(1000))
|
|
|
|
.set_is_finish(true));
|
|
|
|
buffer.push_back(TraceEvent(TraceEvent::PROCESS)
|
|
|
|
.set_event_time(absl::FromUnixMicros(2100))
|
|
|
|
.set_node_id(333)
|
|
|
|
.set_stream_id(&stream_2)
|
|
|
|
.set_input_ts(Timestamp(1000))
|
|
|
|
.set_packet_ts(Timestamp(1000))
|
|
|
|
.set_is_finish(true));
|
|
|
|
|
|
|
|
TraceBuilder builder;
|
|
|
|
GraphTrace trace_1;
|
|
|
|
builder.CreateTrace(buffer, absl::InfinitePast(), absl::InfiniteFuture(),
|
|
|
|
&trace_1);
|
2020-07-09 02:34:05 +02:00
|
|
|
EXPECT_THAT(
|
|
|
|
trace_1,
|
2020-12-10 04:13:05 +01:00
|
|
|
EqualsProto(mediapipe::ParseTextProtoOrDie<GraphTrace>(
|
2021-04-01 01:20:27 +02:00
|
|
|
R"pb(
|
2020-07-09 02:34:05 +02:00
|
|
|
base_time: 1100
|
|
|
|
base_timestamp: 1000
|
|
|
|
stream_name: ""
|
|
|
|
stream_name: "stream_1"
|
|
|
|
stream_name: "stream_2"
|
|
|
|
calculator_trace {
|
|
|
|
node_id: 333
|
|
|
|
input_timestamp: 0
|
|
|
|
event_type: PROCESS
|
|
|
|
start_time: 0
|
|
|
|
finish_time: 1000
|
|
|
|
input_trace {
|
|
|
|
finish_time: 0
|
|
|
|
packet_timestamp: 0
|
|
|
|
stream_id: 1
|
|
|
|
event_data: 0
|
|
|
|
}
|
|
|
|
output_trace { packet_timestamp: 0 stream_id: 2 event_data: 0 }
|
|
|
|
thread_id: 0
|
|
|
|
}
|
|
|
|
calculator_trace {
|
|
|
|
node_id: 333
|
|
|
|
input_timestamp: 0
|
|
|
|
event_type: GPU_TASK
|
|
|
|
start_time: 100
|
|
|
|
finish_time: 2100
|
|
|
|
thread_id: 0
|
|
|
|
}
|
2021-04-01 01:20:27 +02:00
|
|
|
)pb")));
|
2019-06-17 01:03:25 +02:00
|
|
|
|
|
|
|
GraphTrace trace_2;
|
|
|
|
builder.CreateLog(buffer, absl::InfinitePast(), absl::InfiniteFuture(),
|
|
|
|
&trace_2);
|
|
|
|
EXPECT_THAT(
|
|
|
|
trace_2,
|
2020-12-10 04:13:05 +01:00
|
|
|
EqualsProto(mediapipe::ParseTextProtoOrDie<GraphTrace>(
|
2021-04-01 01:20:27 +02:00
|
|
|
R"pb(
|
2019-06-17 01:03:25 +02:00
|
|
|
base_time: 1100
|
|
|
|
base_timestamp: 1000
|
|
|
|
stream_name: ""
|
|
|
|
stream_name: "stream_1"
|
|
|
|
stream_name: "stream_2"
|
|
|
|
calculator_trace {
|
|
|
|
node_id: 333
|
|
|
|
input_timestamp: 0
|
|
|
|
event_type: PROCESS
|
|
|
|
start_time: 0
|
2020-04-07 04:10:12 +02:00
|
|
|
input_trace { packet_timestamp: 0 stream_id: 1 event_data: 0 }
|
2019-06-17 01:03:25 +02:00
|
|
|
thread_id: 0
|
|
|
|
}
|
|
|
|
calculator_trace {
|
|
|
|
node_id: 333
|
|
|
|
input_timestamp: 0
|
|
|
|
event_type: GPU_TASK
|
|
|
|
start_time: 100
|
|
|
|
thread_id: 0
|
|
|
|
}
|
|
|
|
calculator_trace {
|
|
|
|
node_id: 333
|
|
|
|
input_timestamp: 0
|
|
|
|
event_type: GPU_TASK
|
|
|
|
finish_time: 2100
|
|
|
|
thread_id: 0
|
|
|
|
}
|
|
|
|
calculator_trace {
|
|
|
|
node_id: 333
|
|
|
|
input_timestamp: 0
|
|
|
|
event_type: PROCESS
|
|
|
|
finish_time: 1000
|
2020-04-07 04:10:12 +02:00
|
|
|
output_trace { packet_timestamp: 0 stream_id: 2 event_data: 0 }
|
2019-06-17 01:03:25 +02:00
|
|
|
thread_id: 0
|
|
|
|
}
|
2021-04-01 01:20:27 +02:00
|
|
|
)pb")));
|
2019-06-17 01:03:25 +02:00
|
|
|
}
|
|
|
|
|
2019-09-09 20:02:30 +02:00
|
|
|
// Show that trace_enabled activates the GlContextProfiler.
|
|
|
|
TEST_F(GraphTracerE2ETest, GpuTracing) {
|
|
|
|
CHECK(proto_ns::TextFormat::ParseFromString(R"(
|
|
|
|
input_stream: "input_buffer"
|
|
|
|
input_stream: "render_data"
|
|
|
|
output_stream: "annotated_buffer"
|
|
|
|
node {
|
|
|
|
calculator: "AnnotationOverlayCalculator"
|
2020-02-29 05:44:27 +01:00
|
|
|
input_stream: "IMAGE:input_buffer"
|
2019-09-09 20:02:30 +02:00
|
|
|
input_stream: "render_data"
|
2020-02-29 05:44:27 +01:00
|
|
|
output_stream: "IMAGE:annotated_buffer"
|
2019-09-09 20:02:30 +02:00
|
|
|
}
|
|
|
|
profiler_config {
|
|
|
|
trace_enabled: true
|
|
|
|
}
|
|
|
|
)",
|
|
|
|
&graph_config_));
|
|
|
|
|
|
|
|
// Create the CalculatorGraph with only trace_enabled set.
|
2019-09-11 22:58:46 +02:00
|
|
|
MP_ASSERT_OK(graph_.Initialize(graph_config_, {}));
|
2019-09-09 20:02:30 +02:00
|
|
|
// Check that GPU profiling is enabled wihout running the graph.
|
|
|
|
// This graph with GlFlatColorCalculator cannot run on desktop.
|
|
|
|
EXPECT_NE(nullptr, graph_.profiler()->CreateGlProfilingHelper());
|
|
|
|
}
|
|
|
|
|
2020-02-10 22:27:13 +01:00
|
|
|
// This test shows that ~CalculatorGraph() can complete successfully, even when
|
|
|
|
// the periodic profiler output is enabled. If periodic profiler output is not
|
|
|
|
// stopped in ~CalculatorGraph(), it will deadlock at ~Executor().
|
|
|
|
TEST_F(GraphTracerE2ETest, DestructGraph) {
|
|
|
|
std::string log_path = absl::StrCat(getenv("TEST_TMPDIR"), "/log_file_");
|
|
|
|
SetUpPassThroughGraph();
|
|
|
|
graph_config_.mutable_profiler_config()->set_trace_enabled(true);
|
|
|
|
graph_config_.mutable_profiler_config()->set_trace_log_path(log_path);
|
|
|
|
graph_config_.set_num_threads(4);
|
|
|
|
|
|
|
|
// Callbacks to control the LambdaCalculator.
|
|
|
|
ProcessFunction wait_0 = [&](const InputStreamShardSet& inputs,
|
|
|
|
OutputStreamShardSet* outputs) {
|
|
|
|
return PassThrough(inputs, outputs);
|
|
|
|
};
|
|
|
|
|
|
|
|
{
|
|
|
|
CalculatorGraph graph;
|
|
|
|
// Start the graph with the callback.
|
|
|
|
MP_ASSERT_OK(graph.Initialize(graph_config_,
|
|
|
|
{
|
|
|
|
{"callback_0", Adopt(new auto(wait_0))},
|
|
|
|
}));
|
|
|
|
MP_ASSERT_OK(graph.StartRun({}));
|
|
|
|
// Destroy the graph immediately.
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-17 01:03:25 +02:00
|
|
|
} // namespace
|
|
|
|
} // namespace mediapipe
|