Felipe97/llama-cpp-compiled
01.1k
1#include "debug.h"2 3#include "common.h"4#include "log.h"5 6#include <cmath>7#include <regex>8#include <string>9#include <vector>10 11struct common_debug_cb_user_data::impl {12 std::vector<uint8_t> data;13 std::vector<std::regex> tensor_filters;14 bool abort_on_nan{false};15};16 17common_debug_cb_user_data::common_debug_cb_user_data() : pimpl(std::make_unique<impl>()) {}18common_debug_cb_user_data::~common_debug_cb_user_data() = default;19 20common_debug_cb_user_data::common_debug_cb_user_data(common_params & params, const std::vector<std::string> & filter_patterns, bool abort_on_nan)21 : pimpl(std::make_unique<impl>())22{23 for (const auto & pattern : filter_patterns) {24 try {25 std::string anchored_pattern = "^" + pattern;26 pimpl->tensor_filters.emplace_back(anchored_pattern, std::regex::optimize);27 } catch (const std::regex_error & e) {28 throw std::runtime_error("Invalid regex pattern '" + pattern + "': " + e.what());29 }30 }31 pimpl->abort_on_nan = abort_on_nan;32 33 params.cb_eval = common_debug_cb_eval;34 params.cb_eval_user_data = this;35}36 37static std::string common_ggml_ne_string(const ggml_tensor * t) {38 std::string str;39 for (int i = 0; i < GGML_MAX_DIMS; ++i) {40 str += std::to_string(t->ne[i]);41 if (i + 1 < GGML_MAX_DIMS) {42 str += ", ";43 }44 }45 return str;46}47 48static float common_ggml_get_float_value(const uint8_t * data,49 ggml_type type,50 const size_t * nb,51 size_t i0,52 size_t i1,53 size_t i2,54 size_t i3) {55 size_t i = i3 * nb[3] + i2 * nb[2] + i1 * nb[1] + i0 * nb[0];56 float v;57 if (type == GGML_TYPE_F16) {58 v = ggml_fp16_to_fp32(*(const ggml_fp16_t *) &data[i]);59 } else if (type == GGML_TYPE_F32) {60 v = *(const float *) &data[i];61 } else if (type == GGML_TYPE_I64) {62 v = (float) *(const int64_t *) &data[i];63 } else if (type == GGML_TYPE_I32) {64 v = (float) *(const int32_t *) &data[i];65 } else if (type == GGML_TYPE_I16) {66 v = (float) *(const int16_t *) &data[i];67 } else if (type == GGML_TYPE_I8) {68 v = (float) *(const int8_t *) &data[i];69 } else if (type == GGML_TYPE_BF16) {70 v = ggml_bf16_to_fp32(*(const ggml_bf16_t *) &data[i]);71 } else {72 GGML_ABORT("fatal error");73 }74 return v;75}76 77#define INDENT " "78 79static void common_debug_print_tensor(uint8_t * data, ggml_type type, const int64_t * ne, const size_t * nb, int64_t n, bool abort_on_nan) {80 GGML_ASSERT(n > 0);81 float sum = 0;82 for (int64_t i3 = 0; i3 < ne[3]; i3++) {83 for (int64_t i2 = 0; i2 < ne[2]; i2++) {84 for (int64_t i1 = 0; i1 < ne[1]; i1++) {85 for (int64_t i0 = 0; i0 < ne[0]; i0++) {86 const float v = common_ggml_get_float_value(data, type, nb, i0, i1, i2, i3);87 sum += v;88 }89 }90 }91 }92 for (int64_t i3 = 0; i3 < ne[3]; i3++) {93 LOG(INDENT "[\n");94 for (int64_t i2 = 0; i2 < ne[2]; i2++) {95 if (i2 == n && ne[2] > 2 * n) {96 LOG(INDENT INDENT "..., \n");97 i2 = ne[2] - n;98 }99 LOG(INDENT INDENT "[\n");100 for (int64_t i1 = 0; i1 < ne[1]; i1++) {101 if (i1 == n && ne[1] > 2 * n) {102 LOG(INDENT INDENT INDENT "..., \n");103 i1 = ne[1] - n;104 }105 LOG(INDENT INDENT INDENT "[");106 for (int64_t i0 = 0; i0 < ne[0]; i0++) {107 if (i0 == n && ne[0] > 2 * n) {108 LOG(" ..., ");109 i0 = ne[0] - n;110 }111 const float v = common_ggml_get_float_value(data, type, nb, i0, i1, i2, i3);112 LOG("%12.4f", v);113 if (i0 < ne[0] - 1) {114 LOG(", ");115 }116 }117 LOG(" ],\n");118 }119 LOG(INDENT INDENT "],\n");120 }121 LOG(INDENT "]\n");122 LOG(INDENT "sum = %f\n", sum);123 }124 125 if (abort_on_nan) {126 if (std::isnan(sum)) {127 LOG("encountered NaN - aborting\n");128 exit(0);129 }130 }131}132 133/**134 * GGML operations callback during the graph execution.135 *136 * @param t current tensor137 * @param ask when ask is true, the scheduler wants to know if we are interested in data from this tensor138 * if we return true, a follow-up call will be made with ask=false in which we can do the actual collection.139 * see ggml_backend_sched_eval_callback140 * @param user_data user data to pass at each call back141 * @return true to receive data or continue the graph, false otherwise142 */143bool common_debug_cb_eval(struct ggml_tensor * t, bool ask, void * user_data) {144 auto * cb_data = (common_debug_cb_user_data *) user_data;145 auto * pimpl = cb_data->pimpl.get();146 147 const struct ggml_tensor * src0 = t->src[0];148 const struct ggml_tensor * src1 = t->src[1];149 150 if (ask) {151 return true; // Always retrieve data152 }153 154 bool matches_filter = pimpl->tensor_filters.empty();155 156 if (!matches_filter) {157 for (const auto & filter : pimpl->tensor_filters) {158 if (std::regex_search(t->name, filter)) {159 matches_filter = true;160 break;161 }162 }163 }164 165 char src1_str[128] = { 0 };166 if (src1) {167 snprintf(src1_str, sizeof(src1_str), "%s{%s}", src1->name, common_ggml_ne_string(src1).c_str());168 }169 170 if (matches_filter) {171 LOG("%s: %24s = (%s) %10s(%s{%s}, %s}) = {%s}\n", __func__, t->name, ggml_type_name(t->type),172 ggml_op_desc(t), src0->name, common_ggml_ne_string(src0).c_str(), src1 ? src1_str : "",173 common_ggml_ne_string(t).c_str());174 }175 176 const bool is_host = ggml_backend_buffer_is_host(t->buffer);177 178 if (!is_host) {179 auto n_bytes = ggml_nbytes(t);180 pimpl->data.resize(n_bytes);181 ggml_backend_tensor_get(t, pimpl->data.data(), 0, n_bytes);182 }183 184 if (!ggml_is_quantized(t->type) && matches_filter) {185 uint8_t * data = is_host ? (uint8_t *) t->data : pimpl->data.data();186 common_debug_print_tensor(data, t->type, t->ne, t->nb, 3, pimpl->abort_on_nan);187 }188 189 return true;190}191 