CoolFace
Modelpublic

Codeprocastinator/optimized-tinyllama-covalent

sourceHugging Faceapache-2.0updated 1y agoView on Hugging Face
0likes119downloads
log.cpp394 linesDownload Raw Back to common
1#include "log.h"2 3#include <chrono>4#include <condition_variable>5#include <cstdarg>6#include <cstdio>7#include <mutex>8#include <sstream>9#include <thread>10#include <vector>11 12int common_log_verbosity_thold = LOG_DEFAULT_LLAMA;13 14void common_log_set_verbosity_thold(int verbosity) {15    common_log_verbosity_thold = verbosity;16}17 18static int64_t t_us() {19    return std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch()).count();20}21 22// colors23enum common_log_col : int {24    COMMON_LOG_COL_DEFAULT = 0,25    COMMON_LOG_COL_BOLD,26    COMMON_LOG_COL_RED,27    COMMON_LOG_COL_GREEN,28    COMMON_LOG_COL_YELLOW,29    COMMON_LOG_COL_BLUE,30    COMMON_LOG_COL_MAGENTA,31    COMMON_LOG_COL_CYAN,32    COMMON_LOG_COL_WHITE,33};34 35// disable colors by default36static std::vector<const char *> g_col = {37    "",38    "",39    "",40    "",41    "",42    "",43    "",44    "",45    "",46};47 48struct common_log_entry {49    enum ggml_log_level level;50 51    bool prefix;52 53    int64_t timestamp;54 55    std::vector<char> msg;56 57    // signals the worker thread to stop58    bool is_end;59 60    void print(FILE * file = nullptr) const {61        FILE * fcur = file;62        if (!fcur) {63            // stderr displays DBG messages only when their verbosity level is not higher than the threshold64            // these messages will still be logged to a file65            if (level == GGML_LOG_LEVEL_DEBUG && common_log_verbosity_thold < LOG_DEFAULT_DEBUG) {66                return;67            }68 69            fcur = stdout;70 71            if (level != GGML_LOG_LEVEL_NONE) {72                fcur = stderr;73            }74        }75 76        if (level != GGML_LOG_LEVEL_NONE && level != GGML_LOG_LEVEL_CONT && prefix) {77            if (timestamp) {78                // [M.s.ms.us]79                fprintf(fcur, "%s%d.%02d.%03d.%03d%s ",80                        g_col[COMMON_LOG_COL_BLUE],81                        (int) (timestamp / 1000000 / 60),82                        (int) (timestamp / 1000000 % 60),83                        (int) (timestamp / 1000 % 1000),84                        (int) (timestamp % 1000),85                        g_col[COMMON_LOG_COL_DEFAULT]);86            }87 88            switch (level) {89                case GGML_LOG_LEVEL_INFO:  fprintf(fcur, "%sI %s", g_col[COMMON_LOG_COL_GREEN],   g_col[COMMON_LOG_COL_DEFAULT]); break;90                case GGML_LOG_LEVEL_WARN:  fprintf(fcur, "%sW %s", g_col[COMMON_LOG_COL_MAGENTA], ""                        ); break;91                case GGML_LOG_LEVEL_ERROR: fprintf(fcur, "%sE %s", g_col[COMMON_LOG_COL_RED],     ""                        ); break;92                case GGML_LOG_LEVEL_DEBUG: fprintf(fcur, "%sD %s", g_col[COMMON_LOG_COL_YELLOW],  ""                        ); break;93                default:94                    break;95            }96        }97 98        fprintf(fcur, "%s", msg.data());99 100        if (level == GGML_LOG_LEVEL_WARN || level == GGML_LOG_LEVEL_ERROR || level == GGML_LOG_LEVEL_DEBUG) {101            fprintf(fcur, "%s", g_col[COMMON_LOG_COL_DEFAULT]);102        }103 104        fflush(fcur);105    }106};107 108struct common_log {109    // default capacity - will be expanded if needed110    common_log() : common_log(256) {}111 112    common_log(size_t capacity) {113        file = nullptr;114        prefix = false;115        timestamps = false;116        running = false;117        t_start = t_us();118 119        // initial message size - will be expanded if longer messages arrive120        entries.resize(capacity);121        for (auto & entry : entries) {122            entry.msg.resize(256);123        }124 125        head = 0;126        tail = 0;127 128        resume();129    }130 131    ~common_log() {132        pause();133        if (file) {134            fclose(file);135        }136    }137 138private:139    std::mutex mtx;140    std::thread thrd;141    std::condition_variable cv;142 143    FILE * file;144 145    bool prefix;146    bool timestamps;147    bool running;148 149    int64_t t_start;150 151    // ring buffer of entries152    std::vector<common_log_entry> entries;153    size_t head;154    size_t tail;155 156    // worker thread copies into this157    common_log_entry cur;158 159public:160    void add(enum ggml_log_level level, const char * fmt, va_list args) {161        std::lock_guard<std::mutex> lock(mtx);162 163        if (!running) {164            // discard messages while the worker thread is paused165            return;166        }167 168        auto & entry = entries[tail];169 170        {171            // cannot use args twice, so make a copy in case we need to expand the buffer172            va_list args_copy;173            va_copy(args_copy, args);174 175#if 1176            const size_t n = vsnprintf(entry.msg.data(), entry.msg.size(), fmt, args);177            if (n >= entry.msg.size()) {178                entry.msg.resize(n + 1);179                vsnprintf(entry.msg.data(), entry.msg.size(), fmt, args_copy);180            }181#else182            // hack for bolding arguments183 184            std::stringstream ss;185            for (int i = 0; fmt[i] != 0; i++) {186                if (fmt[i] == '%') {187                    ss << LOG_COL_BOLD;188                    while (fmt[i] != ' ' && fmt[i] != ')' && fmt[i] != ']' && fmt[i] != 0) ss << fmt[i++];189                    ss << LOG_COL_DEFAULT;190                    if (fmt[i] == 0) break;191                }192                ss << fmt[i];193            }194            const size_t n = vsnprintf(entry.msg.data(), entry.msg.size(), ss.str().c_str(), args);195            if (n >= entry.msg.size()) {196                entry.msg.resize(n + 1);197                vsnprintf(entry.msg.data(), entry.msg.size(), ss.str().c_str(), args_copy);198            }199#endif200            va_end(args_copy);201        }202 203        entry.level = level;204        entry.prefix = prefix;205        entry.timestamp = 0;206        if (timestamps) {207            entry.timestamp = t_us() - t_start;208        }209        entry.is_end = false;210 211        tail = (tail + 1) % entries.size();212        if (tail == head) {213            // expand the buffer214            std::vector<common_log_entry> new_entries(2*entries.size());215 216            size_t new_tail = 0;217 218            do {219                new_entries[new_tail] = std::move(entries[head]);220 221                head     = (head     + 1) % entries.size();222                new_tail = (new_tail + 1);223            } while (head != tail);224 225            head = 0;226            tail = new_tail;227 228            for (size_t i = tail; i < new_entries.size(); i++) {229                new_entries[i].msg.resize(256);230            }231 232            entries = std::move(new_entries);233        }234 235        cv.notify_one();236    }237 238    void resume() {239        std::lock_guard<std::mutex> lock(mtx);240 241        if (running) {242            return;243        }244 245        running = true;246 247        thrd = std::thread([this]() {248            while (true) {249                {250                    std::unique_lock<std::mutex> lock(mtx);251                    cv.wait(lock, [this]() { return head != tail; });252 253                    cur = entries[head];254 255                    head = (head + 1) % entries.size();256                }257 258                if (cur.is_end) {259                    break;260                }261 262                cur.print(); // stdout and stderr263 264                if (file) {265                    cur.print(file);266                }267            }268        });269    }270 271    void pause() {272        {273            std::lock_guard<std::mutex> lock(mtx);274 275            if (!running) {276                return;277            }278 279            running = false;280 281            // push an entry to signal the worker thread to stop282            {283                auto & entry = entries[tail];284                entry.is_end = true;285 286                tail = (tail + 1) % entries.size();287            }288 289            cv.notify_one();290        }291 292        thrd.join();293    }294 295    void set_file(const char * path) {296        pause();297 298        if (file) {299            fclose(file);300        }301 302        if (path) {303            file = fopen(path, "w");304        } else {305            file = nullptr;306        }307 308        resume();309    }310 311    void set_colors(bool colors) {312        pause();313 314        if (colors) {315            g_col[COMMON_LOG_COL_DEFAULT] = LOG_COL_DEFAULT;316            g_col[COMMON_LOG_COL_BOLD]    = LOG_COL_BOLD;317            g_col[COMMON_LOG_COL_RED]     = LOG_COL_RED;318            g_col[COMMON_LOG_COL_GREEN]   = LOG_COL_GREEN;319            g_col[COMMON_LOG_COL_YELLOW]  = LOG_COL_YELLOW;320            g_col[COMMON_LOG_COL_BLUE]    = LOG_COL_BLUE;321            g_col[COMMON_LOG_COL_MAGENTA] = LOG_COL_MAGENTA;322            g_col[COMMON_LOG_COL_CYAN]    = LOG_COL_CYAN;323            g_col[COMMON_LOG_COL_WHITE]   = LOG_COL_WHITE;324        } else {325            for (size_t i = 0; i < g_col.size(); i++) {326                g_col[i] = "";327            }328        }329 330        resume();331    }332 333    void set_prefix(bool prefix) {334        std::lock_guard<std::mutex> lock(mtx);335 336        this->prefix = prefix;337    }338 339    void set_timestamps(bool timestamps) {340        std::lock_guard<std::mutex> lock(mtx);341 342        this->timestamps = timestamps;343    }344};345 346//347// public API348//349 350struct common_log * common_log_init() {351    return new common_log;352}353 354struct common_log * common_log_main() {355    static struct common_log log;356 357    return &log;358}359 360void common_log_pause(struct common_log * log) {361    log->pause();362}363 364void common_log_resume(struct common_log * log) {365    log->resume();366}367 368void common_log_free(struct common_log * log) {369    delete log;370}371 372void common_log_add(struct common_log * log, enum ggml_log_level level, const char * fmt, ...) {373    va_list args;374    va_start(args, fmt);375    log->add(level, fmt, args);376    va_end(args);377}378 379void common_log_set_file(struct common_log * log, const char * file) {380    log->set_file(file);381}382 383void common_log_set_colors(struct common_log * log, bool colors) {384    log->set_colors(colors);385}386 387void common_log_set_prefix(struct common_log * log, bool prefix) {388    log->set_prefix(prefix);389}390 391void common_log_set_timestamps(struct common_log * log, bool timestamps) {392    log->set_timestamps(timestamps);393}394