|
@@ -0,0 +1,115 @@
|
|
|
+#include <string.h>
|
|
|
+
|
|
|
+#include "ollama-debug.h"
|
|
|
+
|
|
|
+static int mul(int64_t *dims, int ndims) {
|
|
|
+ int result = 1;
|
|
|
+ for (int i = 0; i < ndims; i++) {
|
|
|
+ result *= dims[i];
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+}
|
|
|
+
|
|
|
+static void repeat(char c, int n) {
|
|
|
+ for (int i = 0; i < n; i++) {
|
|
|
+ fprintf(stderr, "%c", c);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void print_tensor(const void *tensor, void (*cb)(const void *, int),
|
|
|
+ int shape,
|
|
|
+ int64_t *dims, int ndims, int stride,
|
|
|
+ int nitems, int pad) {
|
|
|
+ fprintf(stderr, "[");
|
|
|
+ for (int i = 0; i < dims[0]; i++) {
|
|
|
+ if (i >= nitems && i < dims[0] - nitems) {
|
|
|
+ fprintf(stderr, "... (%lld more), ", dims[0] - 2 * nitems);
|
|
|
+ int skip = dims[0] - 2 * nitems;
|
|
|
+ if (ndims > 1) {
|
|
|
+ stride += mul(dims + 1, ndims - 1) * skip;
|
|
|
+ repeat('\n', ndims - 1);
|
|
|
+ repeat(' ', shape - ndims + 1 + pad);
|
|
|
+ }
|
|
|
+ i += skip - 1;
|
|
|
+ } else if (ndims > 1) {
|
|
|
+ print_tensor(tensor, cb, shape, dims + 1, ndims - 1, stride,
|
|
|
+ nitems, pad);
|
|
|
+ stride += mul(dims + 1, ndims - 1);
|
|
|
+ if (i < dims[0] - 1) {
|
|
|
+ fprintf(stderr, ", ");
|
|
|
+ repeat('\n', ndims - 1);
|
|
|
+ repeat(' ', shape - ndims + 1 + pad);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ cb(tensor, stride + i);
|
|
|
+ if (i < dims[0] - 1) {
|
|
|
+ fprintf(stderr, ", ");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ fprintf(stderr, "]");
|
|
|
+}
|
|
|
+
|
|
|
+static void print_tensor_f16(const void *tensor, int i) {
|
|
|
+ float value = ggml_fp16_to_fp32(((const ggml_fp16_t *)tensor)[i]);
|
|
|
+ fprintf(stderr, "%s%f", value < 0 ? "" : " ", value);
|
|
|
+}
|
|
|
+
|
|
|
+static void print_tensor_f32(const void *tensor, int i) {
|
|
|
+ float value = ((const float *)tensor)[i];
|
|
|
+ fprintf(stderr, "%s%f", value < 0 ? "" : " ", value);
|
|
|
+}
|
|
|
+
|
|
|
+static void print_tensor_i32(const void *tensor, int i) {
|
|
|
+ int32_t value = ((const int32_t *)tensor)[i];
|
|
|
+ fprintf(stderr, "%s%d", value < 0 ? "" : " ", value);
|
|
|
+}
|
|
|
+
|
|
|
+static void ollama_debug_tensor(const struct ggml_tensor *tensor, bool verbose, const char *prefix, int indent) {
|
|
|
+ fprintf(stderr, "%s%s %s (%s): [%lld %lld %lld %lld]\n", prefix, tensor->name,
|
|
|
+ ggml_op_name(tensor->op), ggml_type_name(tensor->type), tensor->ne[0],
|
|
|
+ tensor->ne[1], tensor->ne[2], tensor->ne[3]);
|
|
|
+
|
|
|
+ if (!verbose) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (int i = 0; i < indent; i++) {
|
|
|
+ fprintf(stderr, " ");
|
|
|
+ }
|
|
|
+
|
|
|
+ switch (tensor->type) {
|
|
|
+ case GGML_TYPE_F16:
|
|
|
+ print_tensor(ggml_get_data(tensor), print_tensor_f16, ggml_n_dims(tensor),
|
|
|
+ (int64_t *)tensor->ne, ggml_n_dims(tensor), 0, 3, indent);
|
|
|
+ break;
|
|
|
+ case GGML_TYPE_F32:
|
|
|
+ print_tensor(ggml_get_data(tensor), print_tensor_f32, ggml_n_dims(tensor),
|
|
|
+ (int64_t *)tensor->ne, ggml_n_dims(tensor), 0, 3, indent);
|
|
|
+ break;
|
|
|
+ case GGML_TYPE_I32:
|
|
|
+ print_tensor(ggml_get_data(tensor), print_tensor_i32, ggml_n_dims(tensor),
|
|
|
+ (int64_t *)tensor->ne, ggml_n_dims(tensor), 0, 3, indent);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ fprintf(stderr, "<unsupported type>\n");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ fprintf(stderr, "\n");
|
|
|
+}
|
|
|
+
|
|
|
+void ollama_debug(const struct ggml_tensor *tensor, bool verbose) {
|
|
|
+ ollama_debug_tensor(tensor, verbose, ">>> ", 4);
|
|
|
+
|
|
|
+ for (int i = 0; i < GGML_MAX_SRC && tensor->src[i] != NULL; ++i) {
|
|
|
+ char src[8];
|
|
|
+ const int n = snprintf(src, sizeof(src), " src%d ", i);
|
|
|
+ if (n >= sizeof(src)) {
|
|
|
+ src[sizeof(src) - 1] = '\0';
|
|
|
+ }
|
|
|
+
|
|
|
+ ollama_debug_tensor(tensor->src[i], verbose, src, 4);
|
|
|
+ }
|
|
|
+}
|