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