CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
136 lines
5.4 KiB
C++
136 lines
5.4 KiB
C++
// Copyright 2025 The Abseil 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
|
|
//
|
|
// https://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 "absl/profiling/hashtable.h"
|
|
|
|
#include <atomic>
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <string>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
#include "absl/base/config.h"
|
|
#include "absl/container/internal/hashtablez_sampler.h"
|
|
#include "absl/profiling/internal/profile_builder.h"
|
|
#include "absl/status/statusor.h"
|
|
#include "absl/strings/str_cat.h"
|
|
#include "absl/strings/string_view.h"
|
|
#include "absl/time/clock.h"
|
|
#include "absl/time/time.h"
|
|
#include "absl/types/span.h"
|
|
|
|
namespace absl {
|
|
ABSL_NAMESPACE_BEGIN
|
|
|
|
StatusOr<std::string> MarshalHashtableProfile() {
|
|
return debugging_internal::MarshalHashtableProfile(
|
|
container_internal::GlobalHashtablezSampler(), Now());
|
|
}
|
|
|
|
namespace debugging_internal {
|
|
|
|
static void DroppedHashtableSample() {}
|
|
|
|
StatusOr<std::string> MarshalHashtableProfile(
|
|
container_internal::HashtablezSampler& sampler, Time now) {
|
|
static constexpr absl::string_view kDropFrames =
|
|
"(::)?absl::container_internal::.*|"
|
|
"(::)?absl::(flat|node)_hash_(map|set).*";
|
|
|
|
ProfileBuilder builder;
|
|
StringId drop_frames_id = builder.InternString(kDropFrames);
|
|
builder.set_drop_frames_id(drop_frames_id);
|
|
builder.AddSampleType(builder.InternString("capacity"),
|
|
builder.InternString("count"));
|
|
builder.set_default_sample_type_id(builder.InternString("capacity"));
|
|
|
|
const auto capacity_id = builder.InternString("capacity");
|
|
const auto size_id = builder.InternString("size");
|
|
const auto num_erases_id = builder.InternString("num_erases");
|
|
const auto num_insert_hits_id = builder.InternString("num_insert_hits");
|
|
const auto num_rehashes_id = builder.InternString("num_rehashes");
|
|
const auto max_probe_length_id = builder.InternString("max_probe_length");
|
|
const auto total_probe_length_id = builder.InternString("total_probe_length");
|
|
const auto stuck_bits_id = builder.InternString("stuck_bits");
|
|
const auto inline_element_size_id =
|
|
builder.InternString("inline_element_size");
|
|
const auto key_size_id = builder.InternString("key_size");
|
|
const auto value_size_id = builder.InternString("value_size");
|
|
const auto soo_capacity_id = builder.InternString("soo_capacity");
|
|
const auto table_age_id = builder.InternString("table_age");
|
|
const auto max_reserve_id = builder.InternString("max_reserve");
|
|
|
|
size_t dropped =
|
|
sampler.Iterate([&](const container_internal::HashtablezInfo& info) {
|
|
const size_t capacity = info.capacity.load(std::memory_order_relaxed);
|
|
std::vector<std::pair<StringId, int64_t>> labels;
|
|
|
|
auto add_label = [&](StringId tag, uint64_t value) {
|
|
if (value == 0) {
|
|
return;
|
|
}
|
|
labels.emplace_back(tag, static_cast<int64_t>(value));
|
|
};
|
|
|
|
add_label(capacity_id, capacity);
|
|
add_label(size_id, info.size.load(std::memory_order_relaxed));
|
|
add_label(num_erases_id,
|
|
info.num_erases.load(std::memory_order_relaxed));
|
|
// TODO(b/436909492): Revisit whether this value is useful.
|
|
add_label(num_insert_hits_id,
|
|
info.num_insert_hits.load(std::memory_order_relaxed));
|
|
add_label(num_rehashes_id,
|
|
info.num_rehashes.load(std::memory_order_relaxed));
|
|
add_label(max_probe_length_id,
|
|
info.max_probe_length.load(std::memory_order_relaxed));
|
|
add_label(total_probe_length_id,
|
|
info.total_probe_length.load(std::memory_order_relaxed));
|
|
add_label(stuck_bits_id,
|
|
(info.hashes_bitwise_and.load(std::memory_order_relaxed) |
|
|
~info.hashes_bitwise_or.load(std::memory_order_relaxed)));
|
|
add_label(inline_element_size_id, info.inline_element_size);
|
|
add_label(key_size_id, info.key_size);
|
|
add_label(value_size_id, info.value_size);
|
|
add_label(soo_capacity_id, info.soo_capacity);
|
|
add_label(
|
|
table_age_id,
|
|
static_cast<uint64_t>(ToInt64Microseconds(now - info.create_time)));
|
|
add_label(max_reserve_id,
|
|
info.max_reserve.load(std::memory_order_relaxed));
|
|
builder.AddSample(static_cast<int64_t>(capacity) * info.weight,
|
|
MakeSpan(info.stack, info.depth), labels);
|
|
});
|
|
|
|
if (dropped > 0) {
|
|
// If we dropped samples, we don't have information for them, including
|
|
// their sizes. The non-zero weight allows it to be noticed in the profile
|
|
// and examined more closely.
|
|
//
|
|
// We compensate for the fixup done by AddSample by adjusting the address
|
|
// here.
|
|
const void* kFakeStack[] = {
|
|
absl::bit_cast<void*>(
|
|
reinterpret_cast<uintptr_t>(&DroppedHashtableSample)+1)};
|
|
builder.AddSample(static_cast<int64_t>(dropped), kFakeStack, {});
|
|
}
|
|
builder.AddCurrentMappings();
|
|
return std::move(builder).Emit();
|
|
}
|
|
|
|
} // namespace debugging_internal
|
|
ABSL_NAMESPACE_END
|
|
} // namespace absl
|