xref: /aosp_15_r20/external/executorch/extension/llm/runner/util.h (revision 523fa7a60841cd1ecfb9cc4201f1ca8b03ed023a)
1*523fa7a6SAndroid Build Coastguard Worker /*
2*523fa7a6SAndroid Build Coastguard Worker  * Copyright (c) Meta Platforms, Inc. and affiliates.
3*523fa7a6SAndroid Build Coastguard Worker  * All rights reserved.
4*523fa7a6SAndroid Build Coastguard Worker  *
5*523fa7a6SAndroid Build Coastguard Worker  * This source code is licensed under the BSD-style license found in the
6*523fa7a6SAndroid Build Coastguard Worker  * LICENSE file in the root directory of this source tree.
7*523fa7a6SAndroid Build Coastguard Worker  */
8*523fa7a6SAndroid Build Coastguard Worker 
9*523fa7a6SAndroid Build Coastguard Worker #pragma once
10*523fa7a6SAndroid Build Coastguard Worker #include <executorch/runtime/platform/compiler.h>
11*523fa7a6SAndroid Build Coastguard Worker #include <stdio.h>
12*523fa7a6SAndroid Build Coastguard Worker #include <time.h>
13*523fa7a6SAndroid Build Coastguard Worker #include <cctype>
14*523fa7a6SAndroid Build Coastguard Worker #if defined(__linux__) || defined(__ANDROID__) || defined(__unix__)
15*523fa7a6SAndroid Build Coastguard Worker #include <sys/resource.h>
16*523fa7a6SAndroid Build Coastguard Worker #endif
17*523fa7a6SAndroid Build Coastguard Worker 
18*523fa7a6SAndroid Build Coastguard Worker namespace executorch {
19*523fa7a6SAndroid Build Coastguard Worker namespace extension {
20*523fa7a6SAndroid Build Coastguard Worker namespace llm {
21*523fa7a6SAndroid Build Coastguard Worker 
safe_printf(const char * piece)22*523fa7a6SAndroid Build Coastguard Worker ET_EXPERIMENTAL void inline safe_printf(const char* piece) {
23*523fa7a6SAndroid Build Coastguard Worker   // piece might be a raw byte token, and we only want to print printable chars
24*523fa7a6SAndroid Build Coastguard Worker   // or whitespace because some of the other bytes can be various control codes,
25*523fa7a6SAndroid Build Coastguard Worker   // backspace, etc.
26*523fa7a6SAndroid Build Coastguard Worker   if (piece == nullptr) {
27*523fa7a6SAndroid Build Coastguard Worker     return;
28*523fa7a6SAndroid Build Coastguard Worker   }
29*523fa7a6SAndroid Build Coastguard Worker   if (piece[0] == '\0') {
30*523fa7a6SAndroid Build Coastguard Worker     return;
31*523fa7a6SAndroid Build Coastguard Worker   }
32*523fa7a6SAndroid Build Coastguard Worker   if (piece[1] == '\0') {
33*523fa7a6SAndroid Build Coastguard Worker     unsigned char byte_val = piece[0];
34*523fa7a6SAndroid Build Coastguard Worker     if (!(isprint(byte_val) || isspace(byte_val))) {
35*523fa7a6SAndroid Build Coastguard Worker       return; // bad byte, don't print it
36*523fa7a6SAndroid Build Coastguard Worker     }
37*523fa7a6SAndroid Build Coastguard Worker   }
38*523fa7a6SAndroid Build Coastguard Worker   printf("%s", piece);
39*523fa7a6SAndroid Build Coastguard Worker }
40*523fa7a6SAndroid Build Coastguard Worker 
41*523fa7a6SAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
42*523fa7a6SAndroid Build Coastguard Worker // utilities: time
43*523fa7a6SAndroid Build Coastguard Worker 
time_in_ms()44*523fa7a6SAndroid Build Coastguard Worker ET_EXPERIMENTAL long inline time_in_ms() {
45*523fa7a6SAndroid Build Coastguard Worker   // return time in milliseconds, for benchmarking the model speed
46*523fa7a6SAndroid Build Coastguard Worker   struct timespec time;
47*523fa7a6SAndroid Build Coastguard Worker   clock_gettime(CLOCK_REALTIME, &time);
48*523fa7a6SAndroid Build Coastguard Worker   return time.tv_sec * 1000 + time.tv_nsec / 1000000;
49*523fa7a6SAndroid Build Coastguard Worker }
50*523fa7a6SAndroid Build Coastguard Worker 
51*523fa7a6SAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
52*523fa7a6SAndroid Build Coastguard Worker // utilities: memory usage
53*523fa7a6SAndroid Build Coastguard Worker 
54*523fa7a6SAndroid Build Coastguard Worker // Returns the current RSS in bytes. Returns 0 if not supported.
55*523fa7a6SAndroid Build Coastguard Worker // RSS: Resident Set Size, the amount of memory currently in the RAM for this
56*523fa7a6SAndroid Build Coastguard Worker // process. These values are approximate, and are only used for logging
57*523fa7a6SAndroid Build Coastguard Worker // purposes.
get_rss_bytes()58*523fa7a6SAndroid Build Coastguard Worker ET_EXPERIMENTAL size_t inline get_rss_bytes() {
59*523fa7a6SAndroid Build Coastguard Worker #if defined(__linux__) || defined(__ANDROID__) || defined(__unix__)
60*523fa7a6SAndroid Build Coastguard Worker   struct rusage r_usage;
61*523fa7a6SAndroid Build Coastguard Worker   if (getrusage(RUSAGE_SELF, &r_usage) == 0) {
62*523fa7a6SAndroid Build Coastguard Worker     return r_usage.ru_maxrss * 1024;
63*523fa7a6SAndroid Build Coastguard Worker   }
64*523fa7a6SAndroid Build Coastguard Worker #endif // __linux__ || __ANDROID__ || __unix__
65*523fa7a6SAndroid Build Coastguard Worker   // Unsupported platform like Windows, or getrusage() failed.
66*523fa7a6SAndroid Build Coastguard Worker   // __APPLE__ and __MACH__ are not supported because r_usage.ru_maxrss does not
67*523fa7a6SAndroid Build Coastguard Worker   // consistently return kbytes on macOS. On older versions of macOS, it
68*523fa7a6SAndroid Build Coastguard Worker   // returns bytes, but on newer versions it returns kbytes. Need to figure out
69*523fa7a6SAndroid Build Coastguard Worker   // when this changed.
70*523fa7a6SAndroid Build Coastguard Worker   return 0;
71*523fa7a6SAndroid Build Coastguard Worker }
72*523fa7a6SAndroid Build Coastguard Worker } // namespace llm
73*523fa7a6SAndroid Build Coastguard Worker } // namespace extension
74*523fa7a6SAndroid Build Coastguard Worker } // namespace executorch
75*523fa7a6SAndroid Build Coastguard Worker 
76*523fa7a6SAndroid Build Coastguard Worker namespace torch {
77*523fa7a6SAndroid Build Coastguard Worker namespace executor {
78*523fa7a6SAndroid Build Coastguard Worker namespace util {
79*523fa7a6SAndroid Build Coastguard Worker // TODO(T197294990): Remove these deprecated aliases once all users have moved
80*523fa7a6SAndroid Build Coastguard Worker // to the new `::executorch` namespaces.
81*523fa7a6SAndroid Build Coastguard Worker using ::executorch::extension::llm::get_rss_bytes;
82*523fa7a6SAndroid Build Coastguard Worker using ::executorch::extension::llm::safe_printf;
83*523fa7a6SAndroid Build Coastguard Worker using ::executorch::extension::llm::time_in_ms;
84*523fa7a6SAndroid Build Coastguard Worker } // namespace util
85*523fa7a6SAndroid Build Coastguard Worker } // namespace executor
86*523fa7a6SAndroid Build Coastguard Worker } // namespace torch
87