Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
7 changes: 7 additions & 0 deletions include/caliper/common/Node.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ class Node : public util::LockfreeIntrusiveTree<Node>
Variant data() const { return m_data; }

cali_id_t id() const { return m_id; }

Node* find_child_node(cali_id_t attr, const Variant& v) {
Node* n = first_child();
while (n && !n->equals(attr, v))
n = n->next_sibling();
return n;
}
};

} // namespace cali
Expand Down
10 changes: 2 additions & 8 deletions src/caliper/MetadataTree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,9 +224,7 @@ Node* MetadataTree::get_path(const Attribute& attr, size_t n, const Variant* dat

for (size_t i = 0; i < n; ++i) {
parent = node;

for (node = parent->first_child(); node && !node->equals(attr.id(), data[i]); node = node->next_sibling())
;
node = parent->find_child_node(attr.id(), data[i]);

if (!node)
break;
Expand Down Expand Up @@ -258,11 +256,7 @@ Node* MetadataTree::get_or_copy_node(const Node* from, Node* parent)
if (!parent)
parent = root();

Node* node = nullptr;

for (node = parent->first_child(); node && !node->equals(from->attribute(), from->data());
node = node->next_sibling())
;
Node* node = parent->find_child_node(from->attribute(), from->data());

if (!node) {
if (!have_free_nodeblock(1))
Expand Down
4 changes: 3 additions & 1 deletion src/common/Attribute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

#include "caliper/common/Node.h"

#include <limits>

using namespace cali;

Attribute Attribute::make_attribute(Node* node)
Expand Down Expand Up @@ -45,7 +47,7 @@ int Attribute::properties() const
{
for (const Node* node = m_node; node; node = node->parent())
if (node->attribute() == PROP_ATTR_ID)
return node->data().to_int();
return static_cast<int>(node->data().c_variant().value.v_int);

return CALI_ATTR_DEFAULT;
}
Expand Down
87 changes: 48 additions & 39 deletions src/reader/Aggregator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ using namespace cali;
namespace
{

std::size_t hash_key(const std::vector<Entry>& key)
std::size_t compute_key_hash(const std::vector<Entry>& key)
{
std::size_t hash = 0;
for (const Entry& e : key) {
Expand Down Expand Up @@ -914,6 +914,7 @@ struct Aggregator::AggregatorImpl {

struct AggregateEntry {
std::vector<Entry> key;
std::vector<Entry> hash_key;
std::vector<std::unique_ptr<AggregateKernel>> kernels;
std::size_t next_entry_idx;
};
Expand Down Expand Up @@ -999,14 +1000,9 @@ struct Aggregator::AggregatorImpl {
inline bool is_key(
const CaliperMetadataAccessInterface& db,
const std::vector<Attribute>& key_attrs,
cali_id_t attr_id
Attribute attr
)
{
Attribute attr = db.get_attribute(attr_id);

if (m_select_nested && attr.is_nested())
return true;

for (const Attribute& key_attr : key_attrs) {
if (key_attr == attr)
return true;
Expand All @@ -1018,35 +1014,43 @@ struct Aggregator::AggregatorImpl {
}

std::shared_ptr<AggregateEntry> get_aggregation_entry(
std::vector<const Node*>::const_iterator nodes_begin,
std::vector<const Node*>::const_iterator nodes_end,
const std::vector<Entry>& immediates,
CaliperMetadataAccessInterface& db
std::vector<Node*>::const_iterator nodes_begin,
std::vector<Node*>::const_iterator nodes_end,
const std::vector<Entry>& immediates,
CaliperMetadataAccessInterface& db
)
{
// --- make key
// --- make hash key from key nodes and immediates

std::vector<Entry> key;
key.reserve(immediates.size() + 1);
std::vector<Entry> hash_key;
hash_key.reserve((nodes_end - nodes_begin) + immediates.size());
hash_key.resize((nodes_end - nodes_begin));

if (nodes_begin != nodes_end) {
std::vector<const Node*> rv_nodes(nodes_end - nodes_begin);
std::reverse_copy(nodes_begin, nodes_end, rv_nodes.begin());
key.push_back(Entry(db.make_tree_entry(rv_nodes.size(), rv_nodes.data())));
}

std::copy(immediates.begin(), immediates.end(), std::back_inserter(key));
std::transform(nodes_begin, nodes_end, hash_key.begin(), [](Node* n){ return Entry(n); });
hash_key.insert(hash_key.end(), immediates.begin(), immediates.end());

// --- lookup key

std::size_t hash = hash_key(key) % m_hashmap.size();
std::size_t hash = compute_key_hash(hash_key) % m_hashmap.size();
for (size_t i = m_hashmap[hash]; i; i = m_entries[i]->next_entry_idx) {
auto e = m_entries[i];
if (key == e->key)
if (hash_key == e->hash_key)
return e;
}

// --- key not found: create entry
// --- hash key not found: create a new entry

// -- merge key nodes into new tree entry to create compact key

std::vector<Entry> key;
key.reserve(immediates.size() + 1);
key.insert(key.end(), immediates.begin(), immediates.end());

if (nodes_begin != nodes_end) {
std::vector<const Node*> rv_nodes(nodes_end - nodes_begin);
std::reverse_copy(nodes_begin, nodes_end, rv_nodes.begin());
key.push_back(Entry(db.make_tree_entry(rv_nodes.size(), rv_nodes.data())));
}

std::vector<std::unique_ptr<AggregateKernel>> kernels;
kernels.reserve(m_kernel_configs.size());
Expand All @@ -1057,6 +1061,7 @@ struct Aggregator::AggregatorImpl {
auto e = std::make_shared<AggregateEntry>();

e->key = std::move(key);
e->hash_key = std::move(hash_key);
e->kernels = std::move(kernels);
e->next_entry_idx = m_hashmap[hash];

Expand All @@ -1073,39 +1078,43 @@ struct Aggregator::AggregatorImpl {

// --- Unravel nodes, filter for key attributes

std::vector<const Node*> nodes;
std::vector<Entry> immediates;
std::vector<Node*> nodes;
std::vector<Node*> non_path_nodes;
std::vector<Entry> immediates;

nodes.reserve(80);
non_path_nodes.reserve(20);
immediates.reserve(key_attrs.size());

bool select_all = m_select_all;

for (const Entry& e : rec) {
if (e.is_reference()) {
for (const Node* node = e.node(); node && node->attribute() != CALI_INV_ID; node = node->parent())
if (select_all || is_key(db, key_attrs, node->attribute()))
nodes.push_back(node);
} else if (e.is_immediate() && is_key(db, key_attrs, e.attribute())) {
for (Node* node = e.node(); node && node->attribute() != CALI_INV_ID; node = node->parent()) {
Attribute attr = db.get_attribute(node->attribute());
bool is_nested = attr.is_nested();
if (m_select_all || (m_select_nested && is_nested) || is_key(db, key_attrs, attr)) {
if (is_nested)
nodes.push_back(node);
else
non_path_nodes.push_back(node);
}
}
} else if (e.is_immediate() && is_key(db, key_attrs, db.get_attribute(e.attribute()))) {
// Only include explicitly selected immediate entries in the key.
immediates.push_back(e);
}
}

// --- Group by attribute, reverse nodes (restores original order) and get/create tree node.
// Keeps nested attributes separate.
// --- Canonicalize key by sorting by attribute ids

auto nonnested_begin = std::stable_partition(nodes.begin(), nodes.end(), [&db](const Node* node) {
return db.get_attribute(node->attribute()).is_nested();
});

std::stable_sort(nonnested_begin, nodes.end(), [](const Node* a, const Node* b) {
std::stable_sort(non_path_nodes.begin(), non_path_nodes.end(), [](const Node* a, const Node* b) {
return a->attribute() < b->attribute();
});
std::sort(immediates.begin(), immediates.end(), [](const Entry& a, const Entry& b) {
return a.attribute() < b.attribute();
});

auto nonnested_begin = nodes.insert(nodes.end(), non_path_nodes.begin(), non_path_nodes.end());

std::lock_guard<std::mutex> g(m_entries_lock);

auto entry = get_aggregation_entry(nodes.begin(), nodes.end(), immediates, db);
Expand Down
19 changes: 8 additions & 11 deletions src/reader/CaliperMetadataDB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,7 @@ struct CaliperMetadataDB::CaliperMetadataDBImpl {
{
std::lock_guard<std::mutex> g(m_node_lock);

for (node = parent->first_child(); node && !node->equals(attr_id, v_data); node = node->next_sibling())
;
node = parent->find_child_node(attr_id, v_data);

if (!node) {
node = create_node(attr_id, v_data, parent);
Expand Down Expand Up @@ -336,6 +335,8 @@ struct CaliperMetadataDB::CaliperMetadataDBImpl {
if (!parent)
parent = &m_root;

std::lock_guard<std::mutex> g(m_node_lock);

for (size_t i = 0; i < n; ++i) {
if (attr[i].store_as_value())
continue;
Expand All @@ -345,10 +346,7 @@ struct CaliperMetadataDB::CaliperMetadataDBImpl {
if (v_data.type() == CALI_TYPE_STRING)
v_data = make_string_variant(static_cast<const char*>(data[i].data()), data[i].size());

std::lock_guard<std::mutex> g(m_node_lock);

for (node = parent->first_child(); node && !node->equals(attr[i].id(), v_data); node = node->next_sibling())
;
node = parent->find_child_node(attr[i].id(), v_data);

if (!node)
node = create_node(attr[i].id(), v_data, parent);
Expand All @@ -366,12 +364,10 @@ struct CaliperMetadataDB::CaliperMetadataDBImpl {
if (!parent)
parent = &m_root;

for (size_t i = 0; i < n; ++i) {
std::lock_guard<std::mutex> g(m_node_lock);
std::lock_guard<std::mutex> g(m_node_lock);

for (node = parent->first_child(); node && !node->equals(nodelist[i]->attribute(), nodelist[i]->data());
node = node->next_sibling())
;
for (size_t i = 0; i < n; ++i) {
node = parent->find_child_node(nodelist[i]->attribute(), nodelist[i]->data());

if (!node)
node = create_node(nodelist[i]->attribute(), nodelist[i]->data(), parent);
Expand Down Expand Up @@ -495,6 +491,7 @@ struct CaliperMetadataDB::CaliperMetadataDBImpl {

CaliperMetadataDBImpl() : m_root { CALI_INV_ID, CALI_INV_ID, {} }
{
m_nodes.reserve(1000);
setup_bootstrap_nodes();

m_alias_attr =
Expand Down