Team Ai
Datasetpublic

echodict/llama.cpp

version https://git-lfs.github.com/spec/v1 oid sha256:cfc44b7ba25614df70e6b65e3341cae0310163bd32fd31a6b928a542df433faf size 30786

sourceHugging Faceupdated 6mo agoView on Hugging Face
0likes479downloads
log.cpp451 linesDownload Raw Back to common
1#include "common.h"2#include "log.h"3 4#include <chrono>5#include <condition_variable>6#include <cstdarg>7#include <cstdio>8#include <cstdlib>9#include <cstring>10#include <mutex>11#include <sstream>12#include <thread>13#include <vector>14 15#if defined(_WIN32)16#    include <io.h>17#    include <windows.h>18#    define isatty _isatty19#    define fileno _fileno20#else21#    include <unistd.h>22#endif // defined(_WIN32)23 24int common_log_verbosity_thold = LOG_DEFAULT_LLAMA;25 26int common_log_get_verbosity_thold(void) {27    return common_log_verbosity_thold;28}29 30void common_log_set_verbosity_thold(int verbosity) {31    common_log_verbosity_thold = verbosity;32}33 34static int64_t t_us() {35    return std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch()).count();36}37 38// colors39enum common_log_col : int {40    COMMON_LOG_COL_DEFAULT = 0,41    COMMON_LOG_COL_BOLD,42    COMMON_LOG_COL_RED,43    COMMON_LOG_COL_GREEN,44    COMMON_LOG_COL_YELLOW,45    COMMON_LOG_COL_BLUE,46    COMMON_LOG_COL_MAGENTA,47    COMMON_LOG_COL_CYAN,48    COMMON_LOG_COL_WHITE,49};50 51// disable colors by default52static std::vector<const char *> g_col = {53    "",54    "",55    "",56    "",57    "",58    "",59    "",60    "",61    "",62};63 64struct common_log_entry {65    enum ggml_log_level level;66 67    bool prefix;68 69    int64_t timestamp;70 71    std::vector<char> msg;72 73    // signals the worker thread to stop74    bool is_end;75 76    void print(FILE * file = nullptr) const {77        FILE * fcur = file;78        if (!fcur) {79            // stderr displays DBG messages only when their verbosity level is not higher than the threshold80            // these messages will still be logged to a file81            if (level == GGML_LOG_LEVEL_DEBUG && common_log_verbosity_thold < LOG_DEFAULT_DEBUG) {82                return;83            }84 85            fcur = stdout;86 87            if (level != GGML_LOG_LEVEL_NONE) {88                fcur = stderr;89            }90        }91 92        if (level != GGML_LOG_LEVEL_NONE && level != GGML_LOG_LEVEL_CONT && prefix) {93            if (timestamp) {94                // [M.s.ms.us]95                fprintf(fcur, "%s%d.%02d.%03d.%03d%s ",96                        g_col[COMMON_LOG_COL_BLUE],97                        (int) (timestamp / 1000000 / 60),98                        (int) (timestamp / 1000000 % 60),99                        (int) (timestamp / 1000 % 1000),100                        (int) (timestamp % 1000),101                        g_col[COMMON_LOG_COL_DEFAULT]);102            }103 104            switch (level) {105                case GGML_LOG_LEVEL_INFO:  fprintf(fcur, "%sI %s", g_col[COMMON_LOG_COL_GREEN],   g_col[COMMON_LOG_COL_DEFAULT]); break;106                case GGML_LOG_LEVEL_WARN:  fprintf(fcur, "%sW %s", g_col[COMMON_LOG_COL_MAGENTA], ""                        ); break;107                case GGML_LOG_LEVEL_ERROR: fprintf(fcur, "%sE %s", g_col[COMMON_LOG_COL_RED],     ""                        ); break;108                case GGML_LOG_LEVEL_DEBUG: fprintf(fcur, "%sD %s", g_col[COMMON_LOG_COL_YELLOW],  ""                        ); break;109                default:110                    break;111            }112        }113 114        fprintf(fcur, "%s", msg.data());115 116        if (level == GGML_LOG_LEVEL_WARN || level == GGML_LOG_LEVEL_ERROR || level == GGML_LOG_LEVEL_DEBUG) {117            fprintf(fcur, "%s", g_col[COMMON_LOG_COL_DEFAULT]);118        }119 120        fflush(fcur);121    }122};123 124struct common_log {125    // default capacity - will be expanded if needed126    common_log() : common_log(256) {}127 128    common_log(size_t capacity) {129        file = nullptr;130        prefix = false;131        timestamps = false;132        running = false;133        t_start = t_us();134 135        // initial message size - will be expanded if longer messages arrive136        entries.resize(capacity);137        for (auto & entry : entries) {138            entry.msg.resize(256);139        }140 141        head = 0;142        tail = 0;143 144        resume();145    }146 147    ~common_log() {148        pause();149        if (file) {150            fclose(file);151        }152    }153 154private:155    std::mutex mtx;156    std::thread thrd;157    std::condition_variable cv;158 159    FILE * file;160 161    bool prefix;162    bool timestamps;163    bool running;164 165    int64_t t_start;166 167    // ring buffer of entries168    std::vector<common_log_entry> entries;169    size_t head;170    size_t tail;171 172    // worker thread copies into this173    common_log_entry cur;174 175public:176    void add(enum ggml_log_level level, const char * fmt, va_list args) {177        std::lock_guard<std::mutex> lock(mtx);178 179        if (!running) {180            // discard messages while the worker thread is paused181            return;182        }183 184        auto & entry = entries[tail];185 186        {187            // cannot use args twice, so make a copy in case we need to expand the buffer188            va_list args_copy;189            va_copy(args_copy, args);190 191#if 1192            const size_t n = vsnprintf(entry.msg.data(), entry.msg.size(), fmt, args);193            if (n >= entry.msg.size()) {194                entry.msg.resize(n + 1);195                vsnprintf(entry.msg.data(), entry.msg.size(), fmt, args_copy);196            }197#else198            // hack for bolding arguments199 200            std::stringstream ss;201            for (int i = 0; fmt[i] != 0; i++) {202                if (fmt[i] == '%') {203                    ss << LOG_COL_BOLD;204                    while (fmt[i] != ' ' && fmt[i] != ')' && fmt[i] != ']' && fmt[i] != 0) ss << fmt[i++];205                    ss << LOG_COL_DEFAULT;206                    if (fmt[i] == 0) break;207                }208                ss << fmt[i];209            }210            const size_t n = vsnprintf(entry.msg.data(), entry.msg.size(), ss.str().c_str(), args);211            if (n >= entry.msg.size()) {212                entry.msg.resize(n + 1);213                vsnprintf(entry.msg.data(), entry.msg.size(), ss.str().c_str(), args_copy);214            }215#endif216            va_end(args_copy);217        }218 219        entry.level = level;220        entry.prefix = prefix;221        entry.timestamp = 0;222        if (timestamps) {223            entry.timestamp = t_us() - t_start;224        }225        entry.is_end = false;226 227        tail = (tail + 1) % entries.size();228        if (tail == head) {229            // expand the buffer230            std::vector<common_log_entry> new_entries(2*entries.size());231 232            size_t new_tail = 0;233 234            do {235                new_entries[new_tail] = std::move(entries[head]);236 237                head     = (head     + 1) % entries.size();238                new_tail = (new_tail + 1);239            } while (head != tail);240 241            head = 0;242            tail = new_tail;243 244            for (size_t i = tail; i < new_entries.size(); i++) {245                new_entries[i].msg.resize(256);246            }247 248            entries = std::move(new_entries);249        }250 251        cv.notify_one();252    }253 254    void resume() {255        std::lock_guard<std::mutex> lock(mtx);256 257        if (running) {258            return;259        }260 261        running = true;262 263        thrd = std::thread([this]() {264            while (true) {265                {266                    std::unique_lock<std::mutex> lock(mtx);267                    cv.wait(lock, [this]() { return head != tail; });268 269                    cur = entries[head];270 271                    head = (head + 1) % entries.size();272                }273 274                if (cur.is_end) {275                    break;276                }277 278                cur.print(); // stdout and stderr279 280                if (file) {281                    cur.print(file);282                }283            }284        });285    }286 287    void pause() {288        {289            std::lock_guard<std::mutex> lock(mtx);290 291            if (!running) {292                return;293            }294 295            running = false;296 297            // push an entry to signal the worker thread to stop298            {299                auto & entry = entries[tail];300                entry.is_end = true;301 302                tail = (tail + 1) % entries.size();303            }304 305            cv.notify_one();306        }307 308        thrd.join();309    }310 311    void set_file(const char * path) {312        pause();313 314        if (file) {315            fclose(file);316        }317 318        if (path) {319            file = fopen(path, "w");320        } else {321            file = nullptr;322        }323 324        resume();325    }326 327    void set_colors(bool colors) {328        pause();329 330        if (colors) {331            g_col[COMMON_LOG_COL_DEFAULT] = LOG_COL_DEFAULT;332            g_col[COMMON_LOG_COL_BOLD]    = LOG_COL_BOLD;333            g_col[COMMON_LOG_COL_RED]     = LOG_COL_RED;334            g_col[COMMON_LOG_COL_GREEN]   = LOG_COL_GREEN;335            g_col[COMMON_LOG_COL_YELLOW]  = LOG_COL_YELLOW;336            g_col[COMMON_LOG_COL_BLUE]    = LOG_COL_BLUE;337            g_col[COMMON_LOG_COL_MAGENTA] = LOG_COL_MAGENTA;338            g_col[COMMON_LOG_COL_CYAN]    = LOG_COL_CYAN;339            g_col[COMMON_LOG_COL_WHITE]   = LOG_COL_WHITE;340        } else {341            for (size_t i = 0; i < g_col.size(); i++) {342                g_col[i] = "";343            }344        }345 346        resume();347    }348 349    void set_prefix(bool prefix) {350        std::lock_guard<std::mutex> lock(mtx);351 352        this->prefix = prefix;353    }354 355    void set_timestamps(bool timestamps) {356        std::lock_guard<std::mutex> lock(mtx);357 358        this->timestamps = timestamps;359    }360};361 362//363// public API364//365 366struct common_log * common_log_init() {367    return new common_log;368}369 370struct common_log * common_log_main() {371    static struct common_log log;372    static std::once_flag    init_flag;373    std::call_once(init_flag, [&]() {374        // Set default to auto-detect colors375        log.set_colors(tty_can_use_colors());376    });377 378    return &log;379}380 381void common_log_pause(struct common_log * log) {382    log->pause();383}384 385void common_log_resume(struct common_log * log) {386    log->resume();387}388 389void common_log_free(struct common_log * log) {390    delete log;391}392 393void common_log_add(struct common_log * log, enum ggml_log_level level, const char * fmt, ...) {394    va_list args;395    va_start(args, fmt);396    log->add(level, fmt, args);397    va_end(args);398}399 400void common_log_set_file(struct common_log * log, const char * file) {401    log->set_file(file);402}403 404void common_log_set_colors(struct common_log * log, log_colors colors) {405    if (colors == LOG_COLORS_AUTO) {406        log->set_colors(tty_can_use_colors());407        return;408    }409 410    if (colors == LOG_COLORS_DISABLED) {411        log->set_colors(false);412        return;413    }414 415    GGML_ASSERT(colors == LOG_COLORS_ENABLED);416    log->set_colors(true);417}418 419void common_log_set_prefix(struct common_log * log, bool prefix) {420    log->set_prefix(prefix);421}422 423void common_log_set_timestamps(struct common_log * log, bool timestamps) {424    log->set_timestamps(timestamps);425}426 427void common_log_flush(struct common_log * log) {428    log->pause();429    log->resume();430}431 432static int common_get_verbosity(enum ggml_log_level level) {433    switch (level) {434        case GGML_LOG_LEVEL_DEBUG: return LOG_LEVEL_DEBUG;435        case GGML_LOG_LEVEL_INFO:  return LOG_LEVEL_INFO;436        case GGML_LOG_LEVEL_WARN:  return LOG_LEVEL_WARN;437        case GGML_LOG_LEVEL_ERROR: return LOG_LEVEL_ERROR;438        case GGML_LOG_LEVEL_CONT:  return LOG_LEVEL_INFO; // same as INFO439        case GGML_LOG_LEVEL_NONE:440        default:441            return LOG_LEVEL_OUTPUT;442    }443}444 445void common_log_default_callback(enum ggml_log_level level, const char * text, void * /*user_data*/) {446    auto verbosity = common_get_verbosity(level);447    if (verbosity <= common_log_verbosity_thold) {448        common_log_add(common_log_main(), level, "%s", text);449    }450}451