Skip to content

Commit 9f1f23b

Browse files
committed
Consolidate closure statistics and long only once at the end.
1 parent 6614471 commit 9f1f23b

8 files changed

Lines changed: 40 additions & 32 deletions

ift/encoder/closure_glyph_segmenter.cc

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,7 @@ StatusOr<std::vector<Merger>> ToMergers(
437437
static StatusOr<GlyphSegmentation> ToFinalSegmentation(
438438
SegmentationContext& context,
439439
UnmappedGlyphHandling unmapped_glyph_handling) {
440+
context.LogClosureStatistics();
440441
return context.ToGlyphSegmentation();
441442
}
442443

@@ -561,8 +562,6 @@ StatusOr<GlyphSegmentation> ClosureGlyphSegmenter::CodepointToGlyphSegments(
561562
modified.glyphs.union_set(analysis_modified_gids);
562563

563564
TRYV(context.GroupGlyphs(modified.glyphs, modified.segments));
564-
565-
context.glyph_closure_cache.LogClosureCount("Condition grouping");
566565
}
567566

568567
return absl::InternalError("unreachable");
@@ -594,10 +593,8 @@ ClosureGlyphSegmenter::InitializeSegmentationContext(
594593
segment_index++) {
595594
TRY(context.ReprocessSegment(segment_index));
596595
}
597-
context.glyph_closure_cache.LogClosureCount("Inital segment analysis");
598596

599597
TRYV(context.GroupGlyphs(context.SegmentationInfo().NonInitFontGlyphs(), {}));
600-
context.glyph_closure_cache.LogClosureCount("Condition grouping");
601598

602599
return context;
603600
}

ift/encoder/dependency_closure.cc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ flat_hash_map<hb_codepoint_t, glyph_id_t> DependencyClosure::UnicodeToGid(
255255

256256
StatusOr<DependencyClosure::AnalysisAccuracy> DependencyClosure::AnalyzeSegment(
257257
const common::SegmentSet& segments, GlyphSet& and_gids, GlyphSet& or_gids,
258-
GlyphSet& exclusive_gids) const {
258+
GlyphSet& exclusive_gids) {
259259

260260
// This uses a dependency graph (from harfbuzz) to infer how 'segment_id'
261261
// appears in the activation conditions of any glyphs reachable from it.
@@ -294,6 +294,7 @@ StatusOr<DependencyClosure::AnalysisAccuracy> DependencyClosure::AnalyzeSegment(
294294
const Segment& segment = segmentation_info_->Segments().at(segment_id);
295295
if (!segment.Definition().feature_tags.empty()) {
296296
// Feature based segments not yet handled.
297+
inaccurate_results_++;
297298
return INACCURATE;
298299
}
299300

@@ -302,6 +303,7 @@ StatusOr<DependencyClosure::AnalysisAccuracy> DependencyClosure::AnalyzeSegment(
302303

303304
flat_hash_map<Node, unsigned> traversed_edge_counts;
304305
if (TraverseGraph(start_nodes, traversed_edge_counts) == INACCURATE) {
306+
inaccurate_results_++;
305307
return INACCURATE;
306308
}
307309

@@ -326,6 +328,7 @@ StatusOr<DependencyClosure::AnalysisAccuracy> DependencyClosure::AnalyzeSegment(
326328
// glyphs that are reachable from any shared_glyphs found above.
327329
flat_hash_map<Node, unsigned> all_shared_nodes;
328330
if (TraverseGraph(shared_nodes, all_shared_nodes) == INACCURATE) {
331+
inaccurate_results_++;
329332
return INACCURATE;
330333
}
331334

@@ -339,6 +342,7 @@ StatusOr<DependencyClosure::AnalysisAccuracy> DependencyClosure::AnalyzeSegment(
339342
}
340343
exclusive_gids.subtract(or_gids);
341344

345+
accurate_results_++;
342346
return ACCURATE;
343347
}
344348

ift/encoder/dependency_closure.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,10 @@ class DependencyClosure {
5555
absl::StatusOr<AnalysisAccuracy> AnalyzeSegment(const common::SegmentSet& segments,
5656
common::GlyphSet& and_gids,
5757
common::GlyphSet& or_gids,
58-
common::GlyphSet& exclusive_gids) const;
58+
common::GlyphSet& exclusive_gids);
59+
60+
uint64_t AccurateResults() const { return accurate_results_; }
61+
uint64_t InaccurateResults() const { return inaccurate_results_; }
5962

6063
private:
6164
enum NodeType {
@@ -191,6 +194,9 @@ class DependencyClosure {
191194
// These glyphs may participate in complex substitutions and as a result we can't
192195
// analyze via the dep graph.
193196
common::GlyphSet context_glyphs_;
197+
198+
uint64_t accurate_results_ = 0;
199+
uint64_t inaccurate_results_ = 0;
194200
};
195201

196202
} // namespace ift::encoder

ift/encoder/glyph_closure_cache.cc

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@ StatusOr<common::GlyphSet> GlyphClosureCache::GlyphClosure(
2525
}
2626

2727
glyph_closure_cache_miss_++;
28-
closure_count_cumulative_++;
29-
closure_count_delta_++;
3028

3129
hb_subset_input_t* input = hb_subset_input_create_or_fail();
3230
if (!input) {

ift/encoder/glyph_closure_cache.h

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#ifndef IFT_ENCODER_GLYPH_CLOSURE_CACHE_H_
22
#define IFT_ENCODER_GLYPH_CLOSURE_CACHE_H_
33

4-
#include "absl/log/log.h"
54
#include "absl/status/status.h"
65
#include "common/font_data.h"
76
#include "common/int_set.h"
@@ -33,32 +32,17 @@ class GlyphClosureCache {
3332
const common::SegmentSet& segment_ids, common::GlyphSet& and_gids,
3433
common::GlyphSet& or_gids, common::GlyphSet& exclusive_gids);
3534

36-
void LogCacheStats() const {
37-
double closure_hit_rate =
38-
100.0 * ((double)glyph_closure_cache_hit_) /
39-
((double)(glyph_closure_cache_hit_ + glyph_closure_cache_miss_));
40-
VLOG(1) << "Glyph closure cache hit rate: " << closure_hit_rate << "% ("
41-
<< glyph_closure_cache_hit_ << " hits, "
42-
<< glyph_closure_cache_miss_ << " misses)";
43-
}
44-
45-
void LogClosureCount(absl::string_view operation) {
46-
VLOG(1) << operation << ": cumulative number of glyph closures "
47-
<< closure_count_cumulative_ << " (+" << closure_count_delta_
48-
<< ")";
49-
closure_count_delta_ = 0;
50-
}
35+
uint64_t CacheHits() const { return glyph_closure_cache_hit_; }
36+
uint64_t CacheMisses() const { return glyph_closure_cache_miss_; }
5137

5238
hb_face_t* Face() { return preprocessed_face_.get(); }
5339

5440
private:
5541
common::hb_face_unique_ptr preprocessed_face_;
5642
common::hb_face_unique_ptr original_face_;
5743
absl::flat_hash_map<SubsetDefinition, common::GlyphSet> glyph_closure_cache_;
58-
uint32_t glyph_closure_cache_hit_ = 0;
59-
uint32_t glyph_closure_cache_miss_ = 0;
60-
uint32_t closure_count_cumulative_ = 0;
61-
uint32_t closure_count_delta_ = 0;
44+
uint64_t glyph_closure_cache_hit_ = 0;
45+
uint64_t glyph_closure_cache_miss_ = 0;
6246
};
6347

6448
} // namespace ift::encoder

ift/encoder/glyph_groupings.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <optional>
44

55
#include "absl/container/btree_set.h"
6+
#include "absl/log/log.h"
67
#include "common/int_set.h"
78
#include "common/try.h"
89
#include "ift/encoder/activation_condition.h"

ift/encoder/segmentation_context.cc

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,6 @@ Status SegmentationContext::ReassignInitSubset(SubsetDefinition new_def) {
130130

131131
TRYV(GroupGlyphs(changed_gids, changed_segments));
132132

133-
glyph_closure_cache.LogClosureCount(
134-
"Segmentation reprocess for init def change.");
135-
136133
return absl::OkStatus();
137134
}
138135

@@ -186,6 +183,8 @@ Status SegmentationContext::AnalyzeSegment(const SegmentSet& segment_ids,
186183
PrintDiff("AND", and_gids, dep_and_gids);
187184
PrintDiff("OR ", or_gids, dep_or_gids);
188185
PrintDiff("EXC", exclusive_gids, dep_exclusive_gids);
186+
LOG(ERROR) << "init codepoints = " << segmentation_info_->InitFontSegment().codepoints.ToString();
187+
LOG(ERROR) << "init glyphs = " << segmentation_info_->InitFontGlyphs().ToString();
189188
return absl::InternalError("Depedency graph conditions does not match the closure analysis conditions");
190189
}
191190
}

ift/encoder/segmentation_context.h

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <cstdint>
55
#include <memory>
66

7+
#include "absl/log/log.h"
78
#include "absl/status/status.h"
89
#include "common/font_data.h"
910
#include "common/int_set.h"
@@ -86,11 +87,29 @@ class SegmentationContext {
8687
absl::StatusOr<GlyphSegmentation> ToGlyphSegmentation() const {
8788
GlyphSegmentation segmentation =
8889
TRY(glyph_groupings.ToGlyphSegmentation(*segmentation_info_));
89-
glyph_closure_cache.LogCacheStats();
9090
TRYV(ValidateSegmentation(segmentation));
9191
return segmentation;
9292
}
9393

94+
void LogClosureStatistics() const {
95+
uint64_t dep_graph_closures = depedency_closure_->AccurateResults() * 2;
96+
uint64_t potential_closures =
97+
glyph_closure_cache.CacheHits() + glyph_closure_cache.CacheMisses() +
98+
dep_graph_closures;
99+
100+
double hb_subset_rate = 100.0 * ((double) glyph_closure_cache.CacheMisses() / (double) potential_closures);
101+
double cache_hit_rate = 100.0 * ((double) glyph_closure_cache.CacheHits() / (double) potential_closures);
102+
double dep_graph_hit_rate = 100.0 * ((double) dep_graph_closures / (double) potential_closures);
103+
uint64_t other_closures = glyph_closure_cache.CacheHits() + glyph_closure_cache.CacheMisses() - (2 * depedency_closure_->InaccurateResults());
104+
105+
VLOG(0) << ">> Of " << potential_closures << " potential closure operations:" << std::endl
106+
<< " " << glyph_closure_cache.CacheMisses() << " (" << hb_subset_rate << "%) were handled by hb-subset-plan" << std::endl
107+
<< " " << dep_graph_closures
108+
<< " (" << dep_graph_hit_rate << "%) were handled by dep graph" << std::endl
109+
<< " " << glyph_closure_cache.CacheHits() << " (" << cache_hit_rate << "%) were provided by the cache" << std::endl
110+
<< " " << other_closures << " were from something other than AnalyzeSegment()" << std::endl;
111+
}
112+
94113
const common::SegmentSet& InertSegments() const { return inert_segments_; }
95114

96115
const RequestedSegmentationInformation& SegmentationInfo() const {

0 commit comments

Comments
 (0)