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