Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeTable/TypeInfo optimization #5634

Merged
merged 5 commits into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions dali/pipeline/data/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <type_traits>
#include <typeindex>
#include <typeinfo>
#include <unordered_map>
#include <vector>
#include "dali/core/util.h"
#include "dali/core/common.h"
Expand Down Expand Up @@ -472,6 +473,12 @@ class DLL_PUBLIC TypeTable {
static DALIDataType id = [dtype, this]() {
std::lock_guard guard(insert_lock_);
size_t idx = dtype - DALI_NO_TYPE;
stiepan marked this conversation as resolved.
Show resolved Hide resolved
// We need the map because this function (and the static variable) may be instantiated
// in multiple shared objects whereas the map instance is tied to one well defined
// instance of the TypeTable returned by `instance()`.
auto [it, inserted] = type_map_.emplace(typeid(T), dtype);
if (!inserted)
return it->second;
if (!type_info_map_ || idx >= type_info_map_->size()) {
constexpr size_t kMinCapacity = next_pow2(DALI_CUSTOM_TYPE_START + 100);
// we don't need to look at the previous capacity to achieve std::vector-like growth
Expand Down Expand Up @@ -513,6 +520,9 @@ class DLL_PUBLIC TypeTable {
// we need to store TypeInfo instances in a container that never invalidates pointers
// (e.g. a list).
std::list<TypeInfo> type_infos_;
// This is necessary because it turns out that static field in RegisterType has many instances
// in a program built with multiple shared libraries.
std::unordered_map<std::type_index, DALIDataType> type_map_;

int next_id_ = DALI_CUSTOM_TYPE_START;
DLL_PUBLIC static TypeTable &instance();
Expand Down
21 changes: 17 additions & 4 deletions dali/pipeline/data/types_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -97,19 +97,32 @@ typedef ::testing::Types<uint8_t, uint16_t, uint32_t, uint64_t, int8_t, int16_t,

TYPED_TEST_SUITE(TypesTest, TestTypes);

IMPL_HAS_MEMBER(value);

template <typename T, decltype(type2id<T>::value) = {}>
void CheckBuiltinType(const TypeInfo *t) {
EXPECT_EQ(t->id(), type2id<T>::value);
EXPECT_EQ(TypeTable::GetTypeId<T>(), type2id<T>::value);
}

template <typename T>
void CheckBuiltinType(...) {}


Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This passes in a single-DLL scenario, but it's a valid test anyway, so let's keep it.

TYPED_TEST(TypesTest, TestRegisteredType) {
typedef TypeParam T;

TypeInfo type;

// Verify we start with no type
ASSERT_EQ(type.name(), "<no_type>");
ASSERT_EQ(type.size(), 0);
EXPECT_EQ(type.name(), "<no_type>");
EXPECT_EQ(type.size(), 0);

type.SetType<T>();

ASSERT_EQ(type.size(), sizeof(T));
ASSERT_EQ(type.name(), this->TypeName());
EXPECT_EQ(type.size(), sizeof(T));
EXPECT_EQ(type.name(), this->TypeName());
CheckBuiltinType<T>(&type);
}

struct CustomTestType {};
Expand Down
Loading