Add location info in registry (debug mode only)

PiperOrigin-RevId: 508786558
This commit is contained in:
MediaPipe Team 2023-02-10 16:55:26 -08:00 committed by Copybara-Service
parent 23012f2151
commit 2c82f67097
5 changed files with 44 additions and 20 deletions

View File

@ -88,7 +88,8 @@ struct NodeRegistrationStatic {
static mediapipe::RegistrationToken Make() { static mediapipe::RegistrationToken Make() {
return mediapipe::CalculatorBaseRegistry::Register( return mediapipe::CalculatorBaseRegistry::Register(
T::kCalculatorName, T::kCalculatorName,
absl::make_unique<mediapipe::internal::CalculatorBaseFactoryFor<T>>); absl::make_unique<mediapipe::internal::CalculatorBaseFactoryFor<T>>,
__FILE__, __LINE__);
} }
using RequireStatics = ForceStaticInstantiation<&registration>; using RequireStatics = ForceStaticInstantiation<&registration>;
@ -104,8 +105,8 @@ struct SubgraphRegistrationImpl {
static NoDestructor<mediapipe::RegistrationToken> registration; static NoDestructor<mediapipe::RegistrationToken> registration;
static mediapipe::RegistrationToken Make() { static mediapipe::RegistrationToken Make() {
return mediapipe::SubgraphRegistry::Register(T::kCalculatorName, return mediapipe::SubgraphRegistry::Register(
absl::make_unique<T>); T::kCalculatorName, absl::make_unique<T>, __FILE__, __LINE__);
} }
using RequireStatics = ForceStaticInstantiation<&registration>; using RequireStatics = ForceStaticInstantiation<&registration>;
@ -228,7 +229,8 @@ class SubgraphImpl : public Subgraph, public Intf {
REGISTRY_STATIC_VAR(calculator_registration, \ REGISTRY_STATIC_VAR(calculator_registration, \
__LINE__)(mediapipe::CalculatorBaseRegistry::Register( \ __LINE__)(mediapipe::CalculatorBaseRegistry::Register( \
Impl::kCalculatorName, \ Impl::kCalculatorName, \
absl::make_unique<mediapipe::internal::CalculatorBaseFactoryFor<Impl>>)) absl::make_unique<mediapipe::internal::CalculatorBaseFactoryFor<Impl>>, \
__FILE__, __LINE__))
// This macro is used to register a non-split-contract calculator. Deprecated. // This macro is used to register a non-split-contract calculator. Deprecated.
#define MEDIAPIPE_REGISTER_NODE(name) REGISTER_CALCULATOR(name) #define MEDIAPIPE_REGISTER_NODE(name) REGISTER_CALCULATOR(name)
@ -239,7 +241,7 @@ class SubgraphImpl : public Subgraph, public Intf {
static mediapipe::NoDestructor<mediapipe::RegistrationToken> \ static mediapipe::NoDestructor<mediapipe::RegistrationToken> \
REGISTRY_STATIC_VAR(subgraph_registration, \ REGISTRY_STATIC_VAR(subgraph_registration, \
__LINE__)(mediapipe::SubgraphRegistry::Register( \ __LINE__)(mediapipe::SubgraphRegistry::Register( \
Impl::kCalculatorName, absl::make_unique<Impl>)) Impl::kCalculatorName, absl::make_unique<Impl>, __FILE__, __LINE__))
} // namespace api2 } // namespace api2
} // namespace mediapipe } // namespace mediapipe

View File

@ -183,7 +183,8 @@ TEST(CalculatorTest, CreateByNameWhitelisted) {
CalculatorBaseRegistry::Register( CalculatorBaseRegistry::Register(
"::mediapipe::test_ns::whitelisted_ns::DeadCalculator", "::mediapipe::test_ns::whitelisted_ns::DeadCalculator",
absl::make_unique<internal::CalculatorBaseFactoryFor< absl::make_unique<internal::CalculatorBaseFactoryFor<
mediapipe::test_ns::whitelisted_ns::DeadCalculator>>); mediapipe::test_ns::whitelisted_ns::DeadCalculator>>,
__FILE__, __LINE__);
// A whitelisted calculator can be found in its own namespace. // A whitelisted calculator can be found in its own namespace.
MP_EXPECT_OK(CalculatorBaseRegistry::CreateByNameInNamespace( // MP_EXPECT_OK(CalculatorBaseRegistry::CreateByNameInNamespace( //

View File

@ -16,6 +16,7 @@
#define MEDIAPIPE_DEPS_REGISTRATION_H_ #define MEDIAPIPE_DEPS_REGISTRATION_H_
#include <algorithm> #include <algorithm>
#include <cstdint>
#include <functional> #include <functional>
#include <string> #include <string>
#include <tuple> #include <tuple>
@ -161,7 +162,8 @@ class FunctionRegistry {
FunctionRegistry(const FunctionRegistry&) = delete; FunctionRegistry(const FunctionRegistry&) = delete;
FunctionRegistry& operator=(const FunctionRegistry&) = delete; FunctionRegistry& operator=(const FunctionRegistry&) = delete;
RegistrationToken Register(absl::string_view name, Function func) RegistrationToken Register(absl::string_view name, Function func,
std::string filename, uint64_t line)
ABSL_LOCKS_EXCLUDED(lock_) { ABSL_LOCKS_EXCLUDED(lock_) {
std::string normalized_name = GetNormalizedName(name); std::string normalized_name = GetNormalizedName(name);
absl::WriterMutexLock lock(&lock_); absl::WriterMutexLock lock(&lock_);
@ -171,10 +173,21 @@ class FunctionRegistry {
} }
if (functions_.insert(std::make_pair(normalized_name, std::move(func))) if (functions_.insert(std::make_pair(normalized_name, std::move(func)))
.second) { .second) {
#ifndef NDEBUG
locations_.emplace(normalized_name,
std::make_pair(std::move(filename), line));
#endif
return RegistrationToken( return RegistrationToken(
[this, normalized_name]() { Unregister(normalized_name); }); [this, normalized_name]() { Unregister(normalized_name); });
} }
#ifndef NDEBUG
LOG(FATAL) << "Function with name " << name << " already registered."
<< " First registration at "
<< locations_.at(normalized_name).first << ":"
<< locations_.at(normalized_name).second;
#else
LOG(FATAL) << "Function with name " << name << " already registered."; LOG(FATAL) << "Function with name " << name << " already registered.";
#endif
return RegistrationToken([]() {}); return RegistrationToken([]() {});
} }
@ -291,6 +304,11 @@ class FunctionRegistry {
private: private:
mutable absl::Mutex lock_; mutable absl::Mutex lock_;
absl::flat_hash_map<std::string, Function> functions_ ABSL_GUARDED_BY(lock_); absl::flat_hash_map<std::string, Function> functions_ ABSL_GUARDED_BY(lock_);
#ifndef NDEBUG
// Stores filename and line number for useful debug log.
absl::flat_hash_map<std::string, std::pair<std::string, uint32_t>> locations_
ABSL_GUARDED_BY(lock_);
#endif
// For names included in NamespaceAllowlist, strips the namespace. // For names included in NamespaceAllowlist, strips the namespace.
std::string GetAdjustedName(absl::string_view name) { std::string GetAdjustedName(absl::string_view name) {
@ -321,8 +339,10 @@ class GlobalFactoryRegistry {
public: public:
static RegistrationToken Register(absl::string_view name, static RegistrationToken Register(absl::string_view name,
typename Functions::Function func) { typename Functions::Function func,
return functions()->Register(name, std::move(func)); std::string filename, uint64_t line) {
return functions()->Register(name, std::move(func), std::move(filename),
line);
} }
// Invokes the specified factory function and returns the result. // Invokes the specified factory function and returns the result.
@ -382,12 +402,12 @@ class GlobalFactoryRegistry {
#define MEDIAPIPE_REGISTER_FACTORY_FUNCTION(RegistryType, name, ...) \ #define MEDIAPIPE_REGISTER_FACTORY_FUNCTION(RegistryType, name, ...) \
static auto* REGISTRY_STATIC_VAR(registration_##name, __LINE__) = \ static auto* REGISTRY_STATIC_VAR(registration_##name, __LINE__) = \
new mediapipe::RegistrationToken( \ new mediapipe::RegistrationToken( \
RegistryType::Register(#name, __VA_ARGS__)) RegistryType::Register(#name, __VA_ARGS__, __FILE__, __LINE__))
#define REGISTER_FACTORY_FUNCTION_QUALIFIED(RegistryType, var_name, name, ...) \ #define REGISTER_FACTORY_FUNCTION_QUALIFIED(RegistryType, var_name, name, ...) \
static auto* REGISTRY_STATIC_VAR(var_name, __LINE__) = \ static auto* REGISTRY_STATIC_VAR(var_name, __LINE__) = \
new mediapipe::RegistrationToken( \ new mediapipe::RegistrationToken( \
RegistryType::Register(#name, __VA_ARGS__)) RegistryType::Register(#name, __VA_ARGS__, __FILE__, __LINE__))
} // namespace mediapipe } // namespace mediapipe

View File

@ -466,7 +466,8 @@ struct MessageRegistrationImpl {
template <typename T> template <typename T>
NoDestructor<mediapipe::RegistrationToken> NoDestructor<mediapipe::RegistrationToken>
MessageRegistrationImpl<T>::registration(MessageHolderRegistry::Register( MessageRegistrationImpl<T>::registration(MessageHolderRegistry::Register(
T{}.GetTypeName(), MessageRegistrationImpl<T>::CreateMessageHolder)); T{}.GetTypeName(), MessageRegistrationImpl<T>::CreateMessageHolder,
__FILE__, __LINE__));
// For non-Message payloads, this does nothing. // For non-Message payloads, this does nothing.
template <typename T, typename Enable = void> template <typename T, typename Enable = void>

View File

@ -64,13 +64,13 @@ GraphRegistry::GraphRegistry(
void GraphRegistry::Register( void GraphRegistry::Register(
const std::string& type_name, const std::string& type_name,
std::function<std::unique_ptr<Subgraph>()> factory) { std::function<std::unique_ptr<Subgraph>()> factory) {
local_factories_.Register(type_name, factory); local_factories_.Register(type_name, factory, __FILE__, __LINE__);
} }
// TODO: Remove this convenience function. // TODO: Remove this convenience function.
void GraphRegistry::Register(const std::string& type_name, void GraphRegistry::Register(const std::string& type_name,
const CalculatorGraphConfig& config) { const CalculatorGraphConfig& config) {
local_factories_.Register(type_name, [config] { Register(type_name, [config] {
auto result = absl::make_unique<ProtoSubgraph>(config); auto result = absl::make_unique<ProtoSubgraph>(config);
return std::unique_ptr<Subgraph>(result.release()); return std::unique_ptr<Subgraph>(result.release());
}); });
@ -79,7 +79,7 @@ void GraphRegistry::Register(const std::string& type_name,
// TODO: Remove this convenience function. // TODO: Remove this convenience function.
void GraphRegistry::Register(const std::string& type_name, void GraphRegistry::Register(const std::string& type_name,
const CalculatorGraphTemplate& templ) { const CalculatorGraphTemplate& templ) {
local_factories_.Register(type_name, [templ] { Register(type_name, [templ] {
auto result = absl::make_unique<TemplateSubgraph>(templ); auto result = absl::make_unique<TemplateSubgraph>(templ);
return std::unique_ptr<Subgraph>(result.release()); return std::unique_ptr<Subgraph>(result.release());
}); });