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