debug.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. #include "debug.h"
  2. #include "log.h"
  3. #include <cmath>
  4. #include <string>
  5. static std::string common_ggml_ne_string(const ggml_tensor * t) {
  6. std::string str;
  7. for (int i = 0; i < GGML_MAX_DIMS; ++i) {
  8. str += std::to_string(t->ne[i]);
  9. if (i + 1 < GGML_MAX_DIMS) {
  10. str += ", ";
  11. }
  12. }
  13. return str;
  14. }
  15. static float common_ggml_get_float_value(const uint8_t * data,
  16. ggml_type type,
  17. const size_t * nb,
  18. size_t i0,
  19. size_t i1,
  20. size_t i2,
  21. size_t i3) {
  22. size_t i = i3 * nb[3] + i2 * nb[2] + i1 * nb[1] + i0 * nb[0];
  23. float v;
  24. if (type == GGML_TYPE_F16) {
  25. v = ggml_fp16_to_fp32(*(const ggml_fp16_t *) &data[i]);
  26. } else if (type == GGML_TYPE_F32) {
  27. v = *(const float *) &data[i];
  28. } else if (type == GGML_TYPE_I64) {
  29. v = (float) *(const int64_t *) &data[i];
  30. } else if (type == GGML_TYPE_I32) {
  31. v = (float) *(const int32_t *) &data[i];
  32. } else if (type == GGML_TYPE_I16) {
  33. v = (float) *(const int16_t *) &data[i];
  34. } else if (type == GGML_TYPE_I8) {
  35. v = (float) *(const int8_t *) &data[i];
  36. } else if (type == GGML_TYPE_BF16) {
  37. v = ggml_bf16_to_fp32(*(const ggml_bf16_t *) &data[i]);
  38. } else {
  39. GGML_ABORT("fatal error");
  40. }
  41. return v;
  42. }
  43. template <bool abort>
  44. void common_debug_print_tensor(uint8_t * data, ggml_type type, const int64_t * ne, const size_t * nb, int64_t n) {
  45. GGML_ASSERT(n > 0);
  46. float sum = 0;
  47. for (int64_t i3 = 0; i3 < ne[3]; i3++) {
  48. for (int64_t i2 = 0; i2 < ne[2]; i2++) {
  49. for (int64_t i1 = 0; i1 < ne[1]; i1++) {
  50. for (int64_t i0 = 0; i0 < ne[0]; i0++) {
  51. const float v = common_ggml_get_float_value(data, type, nb, i0, i1, i2, i3);
  52. sum += v;
  53. }
  54. }
  55. }
  56. }
  57. for (int64_t i3 = 0; i3 < ne[3]; i3++) {
  58. LOG_ERR(" [\n");
  59. for (int64_t i2 = 0; i2 < ne[2]; i2++) {
  60. if (i2 == n && ne[2] > 2 * n) {
  61. LOG_ERR(" ..., \n");
  62. i2 = ne[2] - n;
  63. }
  64. LOG_ERR(" [\n");
  65. for (int64_t i1 = 0; i1 < ne[1]; i1++) {
  66. if (i1 == n && ne[1] > 2 * n) {
  67. LOG_ERR(" ..., \n");
  68. i1 = ne[1] - n;
  69. }
  70. LOG_ERR(" [");
  71. for (int64_t i0 = 0; i0 < ne[0]; i0++) {
  72. if (i0 == n && ne[0] > 2 * n) {
  73. LOG_ERR("..., ");
  74. i0 = ne[0] - n;
  75. }
  76. const float v = common_ggml_get_float_value(data, type, nb, i0, i1, i2, i3);
  77. LOG_ERR("%12.4f", v);
  78. if (i0 < ne[0] - 1) {
  79. LOG_ERR(", ");
  80. }
  81. }
  82. LOG_ERR("],\n");
  83. }
  84. LOG_ERR(" ],\n");
  85. }
  86. LOG_ERR(" ]\n");
  87. LOG_ERR(" sum = %f\n", sum);
  88. }
  89. if constexpr (abort) {
  90. if (std::isnan(sum)) {
  91. LOG_ERR("encountered NaN - aborting\n");
  92. exit(0);
  93. }
  94. }
  95. }
  96. /**
  97. * GGML operations callback during the graph execution.
  98. *
  99. * @param t current tensor
  100. * @param ask when ask is true, the scheduler wants to know if we are interested in data from this tensor
  101. * if we return true, a follow-up call will be made with ask=false in which we can do the actual collection.
  102. * see ggml_backend_sched_eval_callback
  103. * @param user_data user data to pass at each call back
  104. * @return true to receive data or continue the graph, false otherwise
  105. */
  106. template <bool abort_on_nan> bool common_debug_cb_eval(struct ggml_tensor * t, bool ask, void * user_data) {
  107. auto * cb_data = (base_callback_data *) user_data;
  108. const struct ggml_tensor * src0 = t->src[0];
  109. const struct ggml_tensor * src1 = t->src[1];
  110. if (ask) {
  111. return true; // Always retrieve data
  112. }
  113. bool matches_filter = cb_data->tensor_filters.empty();
  114. if (!matches_filter) {
  115. for (const auto & filter : cb_data->tensor_filters) {
  116. if (std::regex_search(t->name, filter)) {
  117. matches_filter = true;
  118. break;
  119. }
  120. }
  121. }
  122. char src1_str[128] = { 0 };
  123. if (src1) {
  124. snprintf(src1_str, sizeof(src1_str), "%s{%s}", src1->name, common_ggml_ne_string(src1).c_str());
  125. }
  126. if (matches_filter) {
  127. LOG_ERR("%s: %24s = (%s) %10s(%s{%s}, %s}) = {%s}\n", __func__, t->name, ggml_type_name(t->type),
  128. ggml_op_desc(t), src0->name, common_ggml_ne_string(src0).c_str(), src1 ? src1_str : "",
  129. common_ggml_ne_string(t).c_str());
  130. }
  131. const bool is_host = ggml_backend_buffer_is_host(t->buffer);
  132. if (!is_host) {
  133. auto n_bytes = ggml_nbytes(t);
  134. cb_data->data.resize(n_bytes);
  135. ggml_backend_tensor_get(t, cb_data->data.data(), 0, n_bytes);
  136. }
  137. if (!ggml_is_quantized(t->type) && matches_filter) {
  138. uint8_t * data = is_host ? (uint8_t *) t->data : cb_data->data.data();
  139. common_debug_print_tensor<abort_on_nan>(data, t->type, t->ne, t->nb, 3);
  140. }
  141. return true;
  142. }
  143. // Explicit template instantiations
  144. template bool common_debug_cb_eval<false>(ggml_tensor *, bool, void *);
  145. template bool common_debug_cb_eval<true>(ggml_tensor *, bool, void *);
  146. template void common_debug_print_tensor<false>(uint8_t *, ggml_type, const int64_t *, const size_t *, int64_t);
  147. template void common_debug_print_tensor<true>(uint8_t *, ggml_type, const int64_t *, const size_t *, int64_t);