Project import generated by Copybara.

GitOrigin-RevId: b137378673f7d66d41bcd46e4fc3a0d9ef254894
This commit is contained in:
MediaPipe Team
2019-10-25 14:29:15 -07:00
committed by jqtang
parent a2a63e3876
commit 259b48e082
94 changed files with 8564 additions and 398 deletions
+13
View File
@@ -688,6 +688,12 @@ cc_library(
cc_library(
name = "demangle",
hdrs = ["demangle.h"],
defines = select({
"//mediapipe/framework/profiler:android_release": [
"MEDIAPIPE_HAS_CXA_DEMANGLE=0",
],
"//conditions:default": [],
}),
visibility = ["//visibility:public"],
)
@@ -1713,3 +1719,10 @@ cc_test(
"//mediapipe/framework/tool/testdata:dub_quad_test_subgraph",
],
)
# Expose the proto source files for building mediapipe AAR.
filegroup(
name = "protos_src",
srcs = glob(["*.proto"]),
visibility = ["//mediapipe:__subpackages__"],
)
@@ -756,7 +756,7 @@ TEST(CalculatorGraphBoundsTest, BoundWithoutInputPackets) {
MP_ASSERT_OK(graph.WaitUntilDone());
}
// Shows that when fixed-size-input-stream-hanlder drops packets,
// Shows that when fixed-size-input-stream-handler drops packets,
// no timetamp bounds are announced.
TEST(CalculatorGraphBoundsTest, FixedSizeHandlerBounds) {
// LambdaCalculator with FixedSizeInputStreamHandler will drop packets
@@ -876,5 +876,93 @@ TEST(CalculatorGraphBoundsTest, FixedSizeHandlerBounds) {
MP_ASSERT_OK(graph.WaitUntilDone());
}
// A Calculator that outputs only the last packet from its input stream.
class LastPacketCalculator : public CalculatorBase {
public:
static ::mediapipe::Status GetContract(CalculatorContract* cc) {
cc->Inputs().Index(0).SetAny();
cc->Outputs().Index(0).SetAny();
return ::mediapipe::OkStatus();
}
::mediapipe::Status Open(CalculatorContext* cc) final {
return ::mediapipe::OkStatus();
}
::mediapipe::Status Process(CalculatorContext* cc) final {
cc->Outputs().Index(0).SetNextTimestampBound(cc->InputTimestamp());
last_packet_ = cc->Inputs().Index(0).Value();
return ::mediapipe::OkStatus();
}
::mediapipe::Status Close(CalculatorContext* cc) final {
cc->Outputs().Index(0).AddPacket(last_packet_);
return ::mediapipe::OkStatus();
}
private:
Packet last_packet_;
};
REGISTER_CALCULATOR(LastPacketCalculator);
// Shows that the last packet in an input stream can be detected.
TEST(CalculatorGraphBoundsTest, LastPacketCheck) {
// LastPacketCalculator emits only the last input stream packet.
// It emits a timestamp bound after the arrival of a successor input stream
// packet or input stream close. The output "last_output" shows the
// last packet, and "output" shows the timestamp bounds.
CalculatorGraphConfig config =
::mediapipe::ParseTextProtoOrDie<CalculatorGraphConfig>(R"(
input_stream: 'input'
output_stream: 'output'
output_stream: 'last_output'
node {
calculator: 'PassThroughCalculator'
input_stream: 'input'
output_stream: 'input_2'
}
node {
calculator: 'LastPacketCalculator'
input_stream: 'input_2'
output_stream: 'last_packet'
}
node {
calculator: 'PassThroughCalculator'
input_stream: 'input'
input_stream: 'last_packet'
output_stream: 'output'
output_stream: 'last_output'
}
)");
CalculatorGraph graph;
std::vector<Packet> output_packets;
MP_ASSERT_OK(graph.Initialize(config));
MP_ASSERT_OK(graph.ObserveOutputStream("output", [&](const Packet& p) {
output_packets.push_back(p);
return ::mediapipe::OkStatus();
}));
std::vector<Packet> last_output_packets;
MP_ASSERT_OK(graph.ObserveOutputStream("last_output", [&](const Packet& p) {
last_output_packets.push_back(p);
return ::mediapipe::OkStatus();
}));
MP_ASSERT_OK(graph.StartRun({}));
MP_ASSERT_OK(graph.WaitUntilIdle());
// Add four packets into the graph.
constexpr int kNumInputs = 4;
for (int i = 0; i < kNumInputs; ++i) {
Packet p = MakePacket<int>(33).At(Timestamp(i));
MP_ASSERT_OK(graph.AddPacketToInputStream("input", p));
MP_ASSERT_OK(graph.WaitUntilIdle());
EXPECT_EQ(i, output_packets.size());
EXPECT_EQ(0, last_output_packets.size());
}
// Shutdown the graph.
MP_ASSERT_OK(graph.CloseAllPacketSources());
MP_ASSERT_OK(graph.WaitUntilIdle());
EXPECT_EQ(kNumInputs, output_packets.size());
EXPECT_EQ(1, last_output_packets.size());
MP_ASSERT_OK(graph.WaitUntilDone());
}
} // namespace
} // namespace mediapipe
@@ -743,5 +743,66 @@ TEST(CalculatorGraph, GetOutputSidePacket) {
}
}
typedef std::string HugeModel;
// Generates an output-side-packet once for each calculator-graph.
class OutputSidePacketCachedCalculator : public CalculatorBase {
public:
static ::mediapipe::Status GetContract(CalculatorContract* cc) {
cc->OutputSidePackets().Index(0).Set<HugeModel>();
return ::mediapipe::OkStatus();
}
::mediapipe::Status Open(CalculatorContext* cc) final {
cc->OutputSidePackets().Index(0).Set(MakePacket<HugeModel>(
R"(An expensive side-packet created only once per graph)"));
return ::mediapipe::OkStatus();
}
::mediapipe::Status Process(CalculatorContext* cc) final {
LOG(FATAL) << "Not reached.";
return ::mediapipe::OkStatus();
}
};
REGISTER_CALCULATOR(OutputSidePacketCachedCalculator);
// Returns true if two packets hold the same data.
bool Equals(Packet p1, Packet p2) {
return packet_internal::GetHolder(p1) == packet_internal::GetHolder(p2);
}
TEST(CalculatorGraph, OutputSidePacketCached) {
CalculatorGraphConfig config =
::mediapipe::ParseTextProtoOrDie<CalculatorGraphConfig>(R"(
node {
calculator: "OutputSidePacketCachedCalculator"
output_side_packet: "model"
}
node {
calculator: "SidePacketToStreamPacketCalculator"
input_side_packet: "model"
output_stream: "output"
}
)");
CalculatorGraph graph;
MP_ASSERT_OK(graph.Initialize(config));
std::vector<Packet> output_packets;
MP_ASSERT_OK(graph.ObserveOutputStream(
"output", [&output_packets](const Packet& packet) {
output_packets.push_back(packet);
return ::mediapipe::OkStatus();
}));
// Run the graph three times.
for (int run = 0; run < 3; ++run) {
MP_ASSERT_OK(graph.StartRun({}));
MP_ASSERT_OK(graph.WaitUntilDone());
}
ASSERT_EQ(3, output_packets.size());
for (int run = 0; run < output_packets.size(); ++run) {
EXPECT_TRUE(Equals(output_packets[0], output_packets[run]));
}
}
} // namespace
} // namespace mediapipe
+43 -4
View File
@@ -391,6 +391,38 @@ void CalculatorNode::SetMaxInputStreamQueueSize(int max_queue_size) {
return ::mediapipe::OkStatus();
}
namespace {
// Returns the Packet sent to an OutputSidePacket, or an empty packet
// if none available.
const Packet GetPacket(const OutputSidePacket& out) {
auto impl = dynamic_cast<const OutputSidePacketImpl*>(&out);
return (impl == nullptr) ? Packet() : impl->GetPacket();
}
// Resends the output-side-packets from the previous graph run.
::mediapipe::Status ResendSidePackets(CalculatorContext* cc) {
auto& outs = cc->OutputSidePackets();
for (CollectionItemId id = outs.BeginId(); id < outs.EndId(); ++id) {
Packet packet = GetPacket(outs.Get(id));
if (!packet.IsEmpty()) {
// OutputSidePacket::Set re-announces the side-packet to its mirrors.
outs.Get(id).Set(packet);
}
}
return ::mediapipe::OkStatus();
}
} // namespace
bool CalculatorNode::OutputsAreConstant(CalculatorContext* cc) {
if (cc->Inputs().NumEntries() > 0 || cc->Outputs().NumEntries() > 0) {
return false;
}
if (input_side_packet_handler_.InputSidePacketsChanged()) {
return false;
}
return true;
}
::mediapipe::Status CalculatorNode::OpenNode() {
VLOG(2) << "CalculatorNode::OpenNode() for " << DebugName();
@@ -407,8 +439,9 @@ void CalculatorNode::SetMaxInputStreamQueueSize(int max_queue_size) {
default_context, Timestamp::Unstarted());
::mediapipe::Status result;
{
if (OutputsAreConstant(default_context)) {
result = ResendSidePackets(default_context);
} else {
MEDIAPIPE_PROFILING(OPEN, default_context);
LegacyCalculatorSupport::Scoped<CalculatorContext> s(default_context);
result = calculator_->Open(default_context);
@@ -494,7 +527,10 @@ void CalculatorNode::CloseOutputStreams(OutputStreamShardSet* outputs) {
::mediapipe::Status result;
{
if (OutputsAreConstant(default_context)) {
// Do nothing.
result = ::mediapipe::OkStatus();
} else {
MEDIAPIPE_PROFILING(CLOSE, default_context);
LegacyCalculatorSupport::Scoped<CalculatorContext> s(default_context);
result = calculator_->Close(default_context);
@@ -770,7 +806,10 @@ std::string CalculatorNode::DebugName() const {
VLOG(2) << "Calling Calculator::Process() for node: " << DebugName();
{
if (OutputsAreConstant(calculator_context)) {
// Do nothing.
result = ::mediapipe::OkStatus();
} else {
MEDIAPIPE_PROFILING(PROCESS, calculator_context);
LegacyCalculatorSupport::Scoped<CalculatorContext> s(
calculator_context);
+3
View File
@@ -280,6 +280,9 @@ class CalculatorNode {
// Get a std::string describing the input streams.
std::string DebugInputStreamNames() const;
// Returns true if all outputs will be identical to the previous graph run.
bool OutputsAreConstant(CalculatorContext* cc);
// The calculator.
std::unique_ptr<CalculatorBase> calculator_;
// Keeps data which a Calculator subclass needs access to.
+16
View File
@@ -240,6 +240,22 @@ class Collection {
return tag_map_->EndId(tag);
}
// Equal Collections contain equal mappings and equal elements.
bool operator==(const Collection<T>& other) const {
if (tag_map_->Mapping() != other.TagMap()->Mapping()) {
return false;
}
for (CollectionItemId id = BeginId(); id < EndId(); ++id) {
if (Get(id) != other.Get(id)) {
return false;
}
}
return true;
}
bool operator!=(const Collection<T>& other) const {
return !(*this == other);
}
private:
// An iterator which is identical to ItType** except that the
// dereference operator (operator*) does a double dereference and
+8 -6
View File
@@ -15,23 +15,25 @@
#ifndef MEDIAPIPE_FRAMEWORK_DEMANGLE_H_
#define MEDIAPIPE_FRAMEWORK_DEMANGLE_H_
#ifndef MEDIAPIPE_HAS_CXA_DEMANGLE
// We only support some compilers that support __cxa_demangle.
// TODO: Checks if Android NDK has fixed this issue or not.
#if defined(__ANDROID__) && (defined(__i386__) || defined(__x86_64__))
#define HAS_CXA_DEMANGLE 0
#define MEDIAPIPE_HAS_CXA_DEMANGLE 0
#elif (__GNUC__ >= 4 || (__GNUC__ >= 3 && __GNUC_MINOR__ >= 4)) && \
!defined(__mips__)
#define HAS_CXA_DEMANGLE 1
#define MEDIAPIPE_HAS_CXA_DEMANGLE 1
#elif defined(__clang__) && !defined(_MSC_VER)
#define HAS_CXA_DEMANGLE 1
#define MEDIAPIPE_HAS_CXA_DEMANGLE 1
#else
#define HAS_CXA_DEMANGLE 0
#define MEDIAPIPE_HAS_CXA_DEMANGLE 0
#endif
#endif
#include <stdlib.h>
#include <string>
#if HAS_CXA_DEMANGLE
#if MEDIAPIPE_HAS_CXA_DEMANGLE
#include <cxxabi.h>
#endif
@@ -65,7 +67,7 @@ namespace mediapipe {
inline std::string Demangle(const char* mangled) {
int status = 0;
char* demangled = nullptr;
#if HAS_CXA_DEMANGLE
#if MEDIAPIPE_HAS_CXA_DEMANGLE
demangled = abi::__cxa_demangle(mangled, nullptr, nullptr, &status);
#endif
std::string out;
+2 -3
View File
@@ -15,10 +15,9 @@
# Description:
# The dependencies of mediapipe.
licenses(["notice"]) # Apache 2.0
load("//mediapipe/framework/port:build_config.bzl", "mediapipe_cc_proto_library")
load("//mediapipe/framework/port:build_config.bzl", "mediapipe_py_proto_library")
licenses(["notice"]) # Apache 2.0
package(default_visibility = ["//visibility:private"])
@@ -66,5 +66,9 @@ message ImageFormat {
// LAB, interleaved: one byte for L, then one byte for a, then one
// byte for b for each pixel.
LAB8 = 10;
// sBGRA, interleaved: one byte for B, one byte for G, one byte for R,
// one byte for alpha or unused. This is the N32 format for Skia.
SBGRA = 11;
}
}
@@ -279,6 +279,8 @@ int ImageFrame::NumberOfChannelsForFormat(ImageFormat::Format format) {
return 1;
case ImageFormat::LAB8:
return 3;
case ImageFormat::SBGRA:
return 4;
default:
LOG(FATAL) << InvalidFormatString(format);
}
@@ -304,6 +306,8 @@ int ImageFrame::ChannelSizeForFormat(ImageFormat::Format format) {
return sizeof(float);
case ImageFormat::LAB8:
return sizeof(uint8);
case ImageFormat::SBGRA:
return sizeof(uint8);
default:
LOG(FATAL) << InvalidFormatString(format);
}
@@ -329,6 +333,8 @@ int ImageFrame::ByteDepthForFormat(ImageFormat::Format format) {
return 4;
case ImageFormat::LAB8:
return 1;
case ImageFormat::SBGRA:
return 1;
default:
LOG(FATAL) << InvalidFormatString(format);
}
@@ -59,6 +59,9 @@ int GetMatType(const mediapipe::ImageFormat::Format format) {
case mediapipe::ImageFormat::LAB8:
type = CV_8U;
break;
case mediapipe::ImageFormat::SBGRA:
type = CV_8U;
break;
default:
// Invalid or unknown; Default to uchar.
type = CV_8U;
@@ -32,3 +32,8 @@ message NormalizedLandmark {
optional float y = 2;
optional float z = 3;
}
// Group of NormalizedLandmark protos.
message NormalizedLandmarkList {
repeated NormalizedLandmark landmark = 1;
}
@@ -27,6 +27,7 @@ namespace mediapipe {
std::function<void()> input_side_packets_ready_callback,
std::function<void(::mediapipe::Status)> error_callback) {
int missing_input_side_packet_count;
prev_input_side_packets_ = std::move(input_side_packets_);
ASSIGN_OR_RETURN(
input_side_packets_,
tool::FillPacketSet(*input_side_packet_types, all_side_packets,
@@ -41,6 +42,12 @@ namespace mediapipe {
return ::mediapipe::OkStatus();
}
bool InputSidePacketHandler::InputSidePacketsChanged() {
return prev_input_side_packets_ == nullptr ||
input_side_packets_ == nullptr ||
*input_side_packets_ != *prev_input_side_packets_;
}
void InputSidePacketHandler::Set(CollectionItemId id, const Packet& packet) {
::mediapipe::Status status = SetInternal(id, packet);
if (!status.ok()) {
@@ -52,6 +52,10 @@ class InputSidePacketHandler {
const PacketSet& InputSidePackets() const { return *input_side_packets_; }
// Returns true if the set of input-side-packets has changed since the
// previous run.
bool InputSidePacketsChanged();
// Returns the number of missing input side packets.
int MissingInputSidePacketCount() const {
return missing_input_side_packet_count_.load(std::memory_order_relaxed);
@@ -68,6 +72,7 @@ class InputSidePacketHandler {
const PacketTypeSet* input_side_packet_types_;
std::unique_ptr<PacketSet> input_side_packets_;
std::unique_ptr<PacketSet> prev_input_side_packets_;
std::atomic<int> missing_input_side_packet_count_{0};
@@ -30,7 +30,7 @@ namespace mediapipe {
void OutputSidePacketImpl::PrepareForRun(
std::function<void(::mediapipe::Status)> error_callback) {
error_callback_ = std::move(error_callback);
packet_ = Packet();
initialized_ = false;
}
void OutputSidePacketImpl::Set(const Packet& packet) {
@@ -47,7 +47,7 @@ void OutputSidePacketImpl::AddMirror(
}
::mediapipe::Status OutputSidePacketImpl::SetInternal(const Packet& packet) {
if (!packet_.IsEmpty()) {
if (initialized_) {
return ::mediapipe::AlreadyExistsErrorBuilder(MEDIAPIPE_LOC)
<< "Output side packet \"" << name_ << "\" was already set.";
}
@@ -72,6 +72,7 @@ void OutputSidePacketImpl::AddMirror(
}
packet_ = packet;
initialized_ = true;
for (const auto& mirror : mirrors_) {
mirror.input_side_packet_handler->Set(mirror.id, packet_);
}
@@ -80,6 +80,7 @@ class OutputSidePacketImpl : public OutputSidePacket {
const PacketType* packet_type_;
std::function<void(::mediapipe::Status)> error_callback_;
Packet packet_;
bool initialized_ = false;
std::vector<Mirror> mirrors_;
};
+8
View File
@@ -653,6 +653,14 @@ Packet PointToForeign(const T* ptr) {
return packet_internal::Create(new packet_internal::ForeignHolder<T>(ptr));
}
// Equal Packets refer to the same memory contents, like equal pointers.
inline bool operator==(const Packet& p1, const Packet& p2) {
return packet_internal::GetHolder(p1) == packet_internal::GetHolder(p2);
}
inline bool operator!=(const Packet& p1, const Packet& p2) {
return !(p1 == p2);
}
} // namespace mediapipe
#endif // MEDIAPIPE_FRAMEWORK_PACKET_H_
+18
View File
@@ -28,4 +28,22 @@
#define MEDIAPIPE_MOBILE
#endif
#if !defined(MEDIAPIPE_ANDROID) && defined(__ANDROID__)
#define MEDIAPIPE_ANDROID
#endif
#if defined(__APPLE__)
#include "TargetConditionals.h" // for TARGET_OS_*
#if !defined(MEDIAPIPE_IOS) && !TARGET_OS_OSX
#define MEDIAPIPE_IOS
#endif
#endif
// These platforms do not support OpenGL ES Compute Shaders (v3.1 and up),
// but can still run OpenGL ES 3.0 and below.
#if !defined(MEDIAPIPE_DISABLE_GL_COMPUTE) && \
(defined(__APPLE__) || defined(__EMSCRIPTEN__))
#define MEDIAPIPE_DISABLE_GL_COMPUTE
#endif
#endif // MEDIAPIPE_FRAMEWORK_PORT_H_
@@ -247,25 +247,45 @@ TEST_F(GraphProfilerTestPeer, InitializeConfig) {
// Checks histogram_interval_size_usec and num_histogram_intervals.
CalculatorProfile actual =
GetCalculatorProfilesMap()->find(kDummyTestCalculatorName)->second;
ASSERT_EQ(actual.name(), kDummyTestCalculatorName);
ASSERT_FALSE(actual.has_open_runtime());
ASSERT_FALSE(actual.has_close_runtime());
ASSERT_EQ(actual.process_runtime().interval_size_usec(), 1000);
ASSERT_EQ(actual.process_runtime().num_intervals(), 3);
ASSERT_EQ(actual.process_input_latency().interval_size_usec(), 1000);
ASSERT_EQ(actual.process_input_latency().num_intervals(), 3);
ASSERT_EQ(actual.process_output_latency().interval_size_usec(), 1000);
ASSERT_EQ(actual.process_output_latency().num_intervals(), 3);
ASSERT_EQ(actual.input_stream_profiles().size(), 1);
ASSERT_EQ(actual.input_stream_profiles(0).name(), "input_stream");
ASSERT_FALSE(actual.input_stream_profiles(0).back_edge());
ASSERT_EQ(actual.input_stream_profiles(0).latency().interval_size_usec(),
1000);
ASSERT_EQ(actual.input_stream_profiles(0).latency().num_intervals(), 3);
EXPECT_THAT(actual, EqualsProto(R"(
name: "DummyTestCalculator"
process_runtime {
total: 0
interval_size_usec: 1000
num_intervals: 3
count: 0
count: 0
count: 0
}
process_input_latency {
total: 0
interval_size_usec: 1000
num_intervals: 3
count: 0
count: 0
count: 0
}
process_output_latency {
total: 0
interval_size_usec: 1000
num_intervals: 3
count: 0
count: 0
count: 0
}
input_stream_profiles {
name: "input_stream"
back_edge: false
latency {
total: 0
interval_size_usec: 1000
num_intervals: 3
count: 0
count: 0
count: 0
}
}
)"));
}
// Tests that Initialize() uses the ProfilerConfig in the graph definition.
@@ -291,16 +311,17 @@ TEST_F(GraphProfilerTestPeer, InitializeConfigWithoutStreamLatency) {
// Checks histogram_interval_size_usec and num_histogram_intervals.
CalculatorProfile actual =
GetCalculatorProfilesMap()->find(kDummyTestCalculatorName)->second;
ASSERT_EQ(actual.name(), kDummyTestCalculatorName);
ASSERT_FALSE(actual.has_open_runtime());
ASSERT_FALSE(actual.has_close_runtime());
ASSERT_EQ(actual.process_runtime().interval_size_usec(), 1000);
ASSERT_EQ(actual.process_runtime().num_intervals(), 3);
ASSERT_FALSE(actual.has_process_input_latency());
ASSERT_FALSE(actual.has_process_output_latency());
ASSERT_EQ(actual.input_stream_profiles().size(), 0);
EXPECT_THAT(actual, EqualsProto(R"(
name: "DummyTestCalculator"
process_runtime {
total: 0
interval_size_usec: 1000
num_intervals: 3
count: 0
count: 0
count: 0
}
)"));
}
// Tests that Initialize() reads all the configs defined in the graph
@@ -633,10 +654,11 @@ TEST_F(GraphProfilerTestPeer, SetOpenRuntime) {
simulation_clock->ThreadFinish();
ASSERT_EQ(profiles.size(), 1);
ASSERT_EQ(profiles[0].open_runtime(), 100);
ASSERT_FALSE(profiles[0].has_close_runtime());
ASSERT_THAT(profiles[0].process_runtime(),
Partially(EqualsProto(CreateTimeHistogram(/*total=*/0, {0}))));
EXPECT_THAT(profiles[0], Partially(EqualsProto(R"(
name: "DummyTestCalculator"
open_runtime: 100
process_runtime { total: 0 }
)")));
// Checks packets_info_ map hasn't changed.
ASSERT_EQ(GetPacketsInfoMap()->size(), 0);
}
@@ -688,14 +710,29 @@ TEST_F(GraphProfilerTestPeer, SetOpenRuntimeWithStreamLatency) {
ASSERT_EQ(profiles.size(), 2);
CalculatorProfile source_profile =
GetProfileWithName(profiles, "source_calc");
ASSERT_EQ(source_profile.open_runtime(), 150);
ASSERT_FALSE(source_profile.has_close_runtime());
ASSERT_THAT(source_profile.process_runtime(),
Partially(EqualsProto(CreateTimeHistogram(/*total=*/0, {0}))));
ASSERT_THAT(source_profile.process_input_latency(),
Partially(EqualsProto(CreateTimeHistogram(/*total=*/0, {0}))));
ASSERT_THAT(source_profile.process_output_latency(),
Partially(EqualsProto(CreateTimeHistogram(/*total=*/0, {0}))));
EXPECT_THAT(source_profile, EqualsProto(R"(
name: "source_calc"
open_runtime: 150
process_runtime {
total: 0
interval_size_usec: 1000000
num_intervals: 1
count: 0
}
process_input_latency {
total: 0
interval_size_usec: 1000000
num_intervals: 1
count: 0
}
process_output_latency {
total: 0
interval_size_usec: 1000000
num_intervals: 1
count: 0
}
)"));
// Check packets_info_ map has been updated.
ASSERT_EQ(GetPacketsInfoMap()->size(), 1);
@@ -736,11 +773,16 @@ TEST_F(GraphProfilerTestPeer, SetCloseRuntime) {
std::vector<CalculatorProfile> profiles = Profiles();
simulation_clock->ThreadFinish();
ASSERT_EQ(profiles.size(), 1);
ASSERT_FALSE(profiles[0].open_runtime());
ASSERT_EQ(profiles[0].close_runtime(), 100);
ASSERT_THAT(profiles[0].process_runtime(),
Partially(EqualsProto(CreateTimeHistogram(/*total=*/0, {0}))));
EXPECT_THAT(profiles[0], EqualsProto(R"(
name: "DummyTestCalculator"
close_runtime: 100
process_runtime {
total: 0
interval_size_usec: 1000000
num_intervals: 1
count: 0
}
)"));
}
// Tests that SetCloseRuntime() updates |close_runtime| and doesn't affect other
@@ -789,11 +831,39 @@ TEST_F(GraphProfilerTestPeer, SetCloseRuntimeWithStreamLatency) {
ASSERT_EQ(profiles.size(), 2);
CalculatorProfile source_profile =
GetProfileWithName(profiles, "source_calc");
ASSERT_FALSE(source_profile.open_runtime());
ASSERT_EQ(source_profile.close_runtime(), 100);
ASSERT_THAT(source_profile.process_runtime(),
Partially(EqualsProto(CreateTimeHistogram(/*total=*/0, {0}))));
ASSERT_EQ(GetPacketsInfoMap()->size(), 1);
EXPECT_THAT(source_profile, EqualsProto(R"(
name: "source_calc"
close_runtime: 100
process_runtime {
total: 0
interval_size_usec: 1000000
num_intervals: 1
count: 0
}
process_input_latency {
total: 0
interval_size_usec: 1000000
num_intervals: 1
count: 0
}
process_output_latency {
total: 0
interval_size_usec: 1000000
num_intervals: 1
count: 0
}
input_stream_profiles {
name: "input_stream"
back_edge: false
latency {
total: 0
interval_size_usec: 1000000
num_intervals: 1
count: 0
}
}
)"));
PacketInfo expected_packet_info = {0,
/*production_time_usec=*/1000 + 100,
/*source_process_start_usec=*/1000 + 0};
@@ -933,10 +1003,15 @@ TEST_F(GraphProfilerTestPeer, AddProcessSample) {
simulation_clock->ThreadFinish();
ASSERT_EQ(profiles.size(), 1);
ASSERT_THAT(profiles[0].process_runtime(),
Partially(EqualsProto(CreateTimeHistogram(/*total=*/150, {1}))));
ASSERT_FALSE(profiles[0].has_open_runtime());
ASSERT_FALSE(profiles[0].has_close_runtime());
EXPECT_THAT(profiles[0], EqualsProto(R"(
name: "DummyTestCalculator"
process_runtime {
total: 150
interval_size_usec: 1000000
num_intervals: 1
count: 1
}
)"));
// Checks packets_info_ map hasn't changed.
ASSERT_EQ(GetPacketsInfoMap()->size(), 0);
}
@@ -985,12 +1060,27 @@ TEST_F(GraphProfilerTestPeer, AddProcessSampleWithStreamLatency) {
ASSERT_EQ(profiles.size(), 2);
CalculatorProfile source_profile =
GetProfileWithName(profiles, "source_calc");
ASSERT_THAT(source_profile.process_runtime(),
Partially(EqualsProto(CreateTimeHistogram(/*total=*/150, {1}))));
ASSERT_THAT(source_profile.process_input_latency(),
Partially(EqualsProto(CreateTimeHistogram(/*total=*/0, {1}))));
ASSERT_THAT(source_profile.process_output_latency(),
Partially(EqualsProto(CreateTimeHistogram(/*total=*/150, {1}))));
EXPECT_THAT(profiles[0], Partially(EqualsProto(R"(
process_runtime {
total: 150
interval_size_usec: 1000000
num_intervals: 1
count: 1
}
process_input_latency {
total: 0
interval_size_usec: 1000000
num_intervals: 1
count: 1
}
process_output_latency {
total: 150
interval_size_usec: 1000000
num_intervals: 1
count: 1
}
)")));
// Check packets_info_ map has been updated.
ASSERT_EQ(GetPacketsInfoMap()->size(), 1);
@@ -1019,22 +1109,24 @@ TEST_F(GraphProfilerTestPeer, AddProcessSampleWithStreamLatency) {
CalculatorProfile consumer_profile =
GetProfileWithName(profiles, "consumer_calc");
ASSERT_THAT(consumer_profile.process_runtime(),
Partially(EqualsProto(CreateTimeHistogram(/*total=*/250, {1}))));
ASSERT_THAT(consumer_profile.process_input_latency(),
Partially(EqualsProto(CreateTimeHistogram(
/*total=*/2000 - when_source_started, {1}))));
ASSERT_THAT(consumer_profile.process_output_latency(),
Partially(EqualsProto(CreateTimeHistogram(
/*total=*/2000 + 250 - when_source_started, {1}))));
ASSERT_EQ(consumer_profile.input_stream_profiles().size(), 2);
// For "stream_0" should have not changed since it was empty.
ASSERT_THAT(consumer_profile.input_stream_profiles(0).latency(),
Partially(EqualsProto(CreateTimeHistogram(/*total=*/0, {0}))));
// For "stream_1"
ASSERT_THAT(consumer_profile.input_stream_profiles(1).latency(),
Partially(EqualsProto(CreateTimeHistogram(
/*total=*/2000 - when_source_finished, {1}))));
// process input latency total = 2000 (end) - 1000 (when source started) =
// 1000 process output latency total = 2000 (end) + 250 - 1000 (when source
// started) = 1250 For "stream_0" should have not changed since it was empty.
// For "stream_1" = 2000 (end) - 1250 (when source finished) = 850
EXPECT_THAT(consumer_profile, Partially(EqualsProto(R"(
name: "consumer_calc"
process_input_latency { total: 1000 }
process_output_latency { total: 1250 }
input_stream_profiles {
name: "stream_0"
latency { total: 0 }
}
input_stream_profiles {
name: "stream_1"
latency { total: 850 }
}
)")));
// Check packets_info_ map for PacketId({"stream_1", 100}) should not yet be
// garbage collected.
+14 -3
View File
@@ -39,9 +39,20 @@ inline const void* GetPacketDataId(const HolderBase* holder) {
struct TraceEvent {
using EventType = GraphTrace::EventType;
// GraphTrace::EventType constants, repeated here to match GraphProfilerStub.
static const EventType UNKNOWN, OPEN, PROCESS, CLOSE, NOT_READY,
READY_FOR_PROCESS, READY_FOR_CLOSE, THROTTLED, UNTHROTTLED, CPU_TASK_USER,
CPU_TASK_SYSTEM, GPU_TASK, DSP_TASK, TPU_TASK;
static constexpr EventType UNKNOWN = GraphTrace::UNKNOWN;
static constexpr EventType OPEN = GraphTrace::OPEN;
static constexpr EventType PROCESS = GraphTrace::PROCESS;
static constexpr EventType CLOSE = GraphTrace::CLOSE;
static constexpr EventType NOT_READY = GraphTrace::NOT_READY;
static constexpr EventType READY_FOR_PROCESS = GraphTrace::READY_FOR_PROCESS;
static constexpr EventType READY_FOR_CLOSE = GraphTrace::READY_FOR_CLOSE;
static constexpr EventType THROTTLED = GraphTrace::THROTTLED;
static constexpr EventType UNTHROTTLED = GraphTrace::UNTHROTTLED;
static constexpr EventType CPU_TASK_USER = GraphTrace::CPU_TASK_USER;
static constexpr EventType CPU_TASK_SYSTEM = GraphTrace::CPU_TASK_SYSTEM;
static constexpr EventType GPU_TASK = GraphTrace::GPU_TASK;
static constexpr EventType DSP_TASK = GraphTrace::DSP_TASK;
static constexpr EventType TPU_TASK = GraphTrace::TPU_TASK;
absl::Time event_time;
EventType event_type = UNKNOWN;
bool is_finish = false;
+16 -16
View File
@@ -385,21 +385,21 @@ void TraceBuilder::CreateLog(const TraceBuffer& buffer, absl::Time begin_time,
}
void TraceBuilder::Clear() { impl_->Clear(); }
// Defined here since inline constants fail to link in android builds.
const TraceEvent::EventType //
TraceEvent::UNKNOWN = GraphTrace::UNKNOWN,
TraceEvent::OPEN = GraphTrace::OPEN,
TraceEvent::PROCESS = GraphTrace::PROCESS,
TraceEvent::CLOSE = GraphTrace::CLOSE,
TraceEvent::NOT_READY = GraphTrace::NOT_READY,
TraceEvent::READY_FOR_PROCESS = GraphTrace::READY_FOR_PROCESS,
TraceEvent::READY_FOR_CLOSE = GraphTrace::READY_FOR_CLOSE,
TraceEvent::THROTTLED = GraphTrace::THROTTLED,
TraceEvent::UNTHROTTLED = GraphTrace::UNTHROTTLED,
TraceEvent::CPU_TASK_USER = GraphTrace::CPU_TASK_USER,
TraceEvent::CPU_TASK_SYSTEM = GraphTrace::CPU_TASK_SYSTEM,
TraceEvent::GPU_TASK = GraphTrace::GPU_TASK,
TraceEvent::DSP_TASK = GraphTrace::DSP_TASK,
TraceEvent::TPU_TASK = GraphTrace::TPU_TASK;
// Defined here since constexpr requires out-of-class definition until C++17.
const TraceEvent::EventType //
TraceEvent::UNKNOWN, //
TraceEvent::OPEN, //
TraceEvent::PROCESS, //
TraceEvent::CLOSE, //
TraceEvent::NOT_READY, //
TraceEvent::READY_FOR_PROCESS, //
TraceEvent::READY_FOR_CLOSE, //
TraceEvent::THROTTLED, //
TraceEvent::UNTHROTTLED, //
TraceEvent::CPU_TASK_USER, //
TraceEvent::CPU_TASK_SYSTEM, //
TraceEvent::GPU_TASK, //
TraceEvent::DSP_TASK, //
TraceEvent::TPU_TASK;
} // namespace mediapipe
+5
View File
@@ -127,6 +127,11 @@ class TagMap {
std::vector<std::string> names_;
};
// Equal TagData structs define equal id ranges.
inline bool operator==(const TagMap::TagData& d1, const TagMap::TagData& d2) {
return d1.id == d2.id && d1.count == d2.count;
}
} // namespace tool
} // namespace mediapipe
@@ -567,6 +567,10 @@ class TemplateExpanderImpl {
result = AsDict(args);
} else if (expr.op() == "list") {
result = AsList(args);
} else if (expr.op() == "size") {
return AsArgument(static_cast<double>(
args[0].has_dict() ? args[0].mutable_dict()->arg_size()
: args[0].mutable_element()->size()));
}
return result;
}
+2 -2
View File
@@ -1318,8 +1318,8 @@ bool IsInfixOperator(const std::string& token) {
// A function-style operator, including a for or if expression.
bool IsFunctionOperator(const std::string& token) {
static auto kTokens = new std::set<std::string>{
"min", "max", "for", "if", "!",
"concat", "lowercase", "uppercase", "dict", "list",
"min", "max", "for", "if", "!", "concat",
"lowercase", "uppercase", "size", "dict", "list",
};
return kTokens->count(token) > 0;
}