Skip to content

Commit 4a8320a

Browse files
authored
Microprofiler can now output logs for benchmarks in the csv format.
BUG=240626703
1 parent 8b9d469 commit 4a8320a

File tree

3 files changed

+62
-0
lines changed

3 files changed

+62
-0
lines changed

tensorflow/lite/micro/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,7 @@ cc_library(
317317
],
318318
copts = micro_copts(),
319319
deps = [
320+
":micro_compatibility",
320321
":micro_error_reporter",
321322
":micro_time",
322323
"//tensorflow/lite/kernels/internal:compatibility",

tensorflow/lite/micro/micro_profiler.cc

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ limitations under the License.
1616

1717
#include <cinttypes>
1818
#include <cstdint>
19+
#include <cstring>
1920

2021
#include "tensorflow/lite/kernels/internal/compatibility.h"
2122
#include "tensorflow/lite/micro/micro_error_reporter.h"
@@ -67,4 +68,48 @@ void MicroProfiler::LogCsv() const {
6768
#endif
6869
}
6970

71+
void MicroProfiler::LogTicksPerTagCsv() {
72+
#if !defined(TF_LITE_STRIP_ERROR_STRINGS)
73+
MicroPrintf(
74+
"\"Unique Tag\",\"Total ticks across all events with that tag.\"");
75+
int total_ticks = 0;
76+
for (int i = 0; i < num_events_; ++i) {
77+
uint32_t ticks = end_ticks_[i] - start_ticks_[i];
78+
TFLITE_DCHECK(tags_[i] != nullptr);
79+
int position = FindExistingOrNextPosition(tags_[i]);
80+
TFLITE_DCHECK(position >= 0);
81+
total_ticks_per_tag[position].tag = tags_[i];
82+
total_ticks_per_tag[position].ticks =
83+
total_ticks_per_tag[position].ticks + ticks;
84+
total_ticks += ticks;
85+
}
86+
87+
for (int i = 0; i < num_events_; ++i) {
88+
TicksPerTag each_tag_entry = total_ticks_per_tag[i];
89+
if (each_tag_entry.tag == nullptr) {
90+
break;
91+
}
92+
MicroPrintf("%s, %d", each_tag_entry.tag, each_tag_entry.ticks);
93+
}
94+
MicroPrintf("total number of ticks, %d", total_ticks);
95+
#endif
96+
}
97+
98+
// This method finds a particular array element in the total_ticks_per_tag array
99+
// with the matching tag_name passed in the method. If it can find a
100+
// matching array element that has the same tag_name, then it will return the
101+
// position of the matching element. But if it unable to find a matching element
102+
// with the given tag_name, it will return the next available empty position
103+
// from the array.
104+
int MicroProfiler::FindExistingOrNextPosition(const char* tag_name) {
105+
int pos = 0;
106+
for (; pos < num_events_; pos++) {
107+
TicksPerTag each_tag_entry = total_ticks_per_tag[pos];
108+
if (each_tag_entry.tag == nullptr ||
109+
strcmp(each_tag_entry.tag, tag_name) == 0) {
110+
return pos;
111+
}
112+
}
113+
return pos < num_events_ ? pos : -1;
114+
}
70115
} // namespace tflite

tensorflow/lite/micro/micro_profiler.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ class MicroProfiler {
6161
// Separated Value) form.
6262
void LogCsv() const;
6363

64+
// Prints total ticks for each unique tag in CSV format.
65+
// Output will have one row for each unique tag along with the
66+
// total ticks summed across all events with that particular tag.
67+
void LogTicksPerTagCsv();
68+
6469
private:
6570
// Maximum number of events that this class can keep track of. If we call
6671
// AddEvent more than kMaxEvents number of times, then the oldest event's
@@ -72,6 +77,17 @@ class MicroProfiler {
7277
uint32_t end_ticks_[kMaxEvents];
7378
int num_events_ = 0;
7479

80+
struct TicksPerTag {
81+
const char* tag;
82+
uint32_t ticks;
83+
};
84+
// In practice, the number of tags will be much lower than the number of
85+
// events. But it is theoretically possible that each event to be unique and
86+
// hence we allow total_ticks_per_tag to have kMaxEvents entries.
87+
TicksPerTag total_ticks_per_tag[kMaxEvents];
88+
89+
int FindExistingOrNextPosition(const char* tag_name);
90+
7591
TF_LITE_REMOVE_VIRTUAL_DELETE;
7692
};
7793

0 commit comments

Comments
 (0)