source: src/ai/tensor.c @ 49e7171

feature/cnnfeature/crepe
Last change on this file since 49e7171 was 49e7171, checked in by Paul Brossier <piem@piem.org>, 3 years ago

[tensor] add print helpers

  • Property mode set to 100644
File size: 4.4 KB
Line 
1#include "aubio_priv.h"
2#include "fmat.h"
3#include "tensor.h"
4
5#define STRN_LENGTH 40
6#if !HAVE_AUBIO_DOUBLE
7#define AUBIO_SMPL_TFMT "% 9.4f"
8#else
9#define AUBIO_SMPL_TFMT "% 9.4lf"
10#endif /* HAVE_AUBIO_DOUBLE */
11
12aubio_tensor_t *new_aubio_tensor(uint_t ndim, uint_t *shape)
13{
14  aubio_tensor_t *c = AUBIO_NEW(aubio_tensor_t);
15  uint_t items_per_row = 1;
16  uint_t i;
17
18  if ((sint_t)ndim <= 0) goto failure;
19  for (i = 0; i < ndim; i++) {
20    if ((sint_t)shape[i] <= 0) goto failure;
21  }
22
23  c->ndim = ndim;
24  c->shape[0] = shape[0];
25  for (i = 1; i < ndim; i++) {
26    c->shape[i] = shape[i];
27    items_per_row *= shape[i];
28  }
29  c->size = items_per_row * shape[0];
30  c->buffer = AUBIO_ARRAY(smpl_t, c->size);
31  c->data = AUBIO_ARRAY(smpl_t*, shape[0]);
32  for (i = 0; i < c->shape[0]; i++) {
33    c->data[i] = c->buffer + i * items_per_row;
34  }
35
36  return c;
37
38failure:
39  del_aubio_tensor(c);
40  return NULL;
41}
42
43void del_aubio_tensor(aubio_tensor_t *c)
44{
45  if (c->data) {
46    if (c->data[0]) {
47      AUBIO_FREE(c->data[0]);
48    }
49    AUBIO_FREE(c->data);
50  }
51  AUBIO_FREE(c);
52}
53
54uint_t aubio_tensor_as_fvec(aubio_tensor_t *c, fvec_t *o) {
55  if (!c || !o) return AUBIO_FAIL;
56  o->length = c->size;
57  o->data = c->data[0];
58  return AUBIO_OK;
59}
60
61uint_t aubio_fvec_as_tensor(fvec_t *o, aubio_tensor_t *c) {
62  if (!o || !c) return AUBIO_FAIL;
63  c->ndim = 1;
64  c->shape[0] = o->length;
65  c->data = &o->data;
66  c->buffer = o->data;
67  c->size = o->length;
68  return AUBIO_OK;
69}
70
71uint_t aubio_tensor_as_fmat(aubio_tensor_t *c, fmat_t *o) {
72  if (!c || !o) return AUBIO_FAIL;
73  o->height = c->shape[0];
74  o->length = c->size / c->shape[0];
75  o->data = c->data;
76  return AUBIO_OK;
77}
78
79uint_t aubio_fmat_as_tensor(fmat_t *o, aubio_tensor_t *c) {
80  if (!o || !c) return AUBIO_FAIL;
81  c->ndim = 2;
82  c->shape[0] = o->height;
83  c->shape[1] = o->length;
84  c->size = o->height * o->length;
85  c->data = o->data;
86  c->buffer = o->data[0];
87  return AUBIO_OK;
88}
89
90uint_t aubio_tensor_get_subtensor(aubio_tensor_t *t, uint_t i,
91    aubio_tensor_t *st)
92{
93  uint_t j;
94  if (!t || !st) return AUBIO_FAIL;
95  if (i >= t->shape[0]) {
96    AUBIO_ERR("tensor: index %d out of range, only %d subtensors\n",
97        i, t->shape[0]);
98    return AUBIO_FAIL;
99  }
100  if(t->ndim > 1) {
101    st->ndim = t->ndim - 1;
102    for (j = 0; j < st->ndim; j++) {
103      st->shape[j] = t->shape[j + 1];
104    }
105    for (j = st->ndim; j < AUBIO_TENSOR_MAXDIM; j++) {
106      st->shape[j] = 0;
107    }
108    st->size = t->size / t->shape[0];
109  } else {
110    st->ndim = 1;
111    st->shape[0] = 1;
112    st->size = 1;
113  }
114  // st was allocated on the stack, row indices are lost
115  st->data = NULL;
116  st->buffer = &t->buffer[0] + st->size * i;
117  return AUBIO_OK;
118}
119
120uint_t aubio_tensor_have_same_size(aubio_tensor_t *t, aubio_tensor_t *s)
121{
122  uint_t n;
123  if (!t || !s) return 0;
124  if (t->ndim != s->ndim) return 0;
125  if (t->size != s->size) return 0;
126  n = t->ndim;
127  while (n--) {
128    if (t->shape[n] != s->shape[n]) {
129      return 0;
130    }
131  }
132  return 1;
133}
134
135smpl_t aubio_tensor_max(aubio_tensor_t *t)
136{
137  uint_t i;
138  smpl_t max = t->buffer[0];
139  for (i = 0; i < t->size; i++) {
140    max = MAX(t->buffer[i], max);
141  }
142  return max;
143}
144
145const char_t *aubio_tensor_get_shape_string(aubio_tensor_t *t) {
146  uint_t i;
147  if (!t) return NULL;
148  size_t offset = 2;
149  static char_t shape_str[STRN_LENGTH];
150  char_t shape_str_previous[STRN_LENGTH] = "(";
151  for (i = 0; i < t->ndim; i++) {
152    int len = snprintf(shape_str, STRN_LENGTH, "%s%d%s",
153        shape_str_previous, t->shape[i], (i == t->ndim - 1) ? "" : ", ");
154    strncpy(shape_str_previous, shape_str, len);
155  }
156  snprintf(shape_str, strnlen(shape_str, STRN_LENGTH - offset - 1) + offset,
157      "%s)", shape_str_previous);
158  return shape_str;
159}
160
161static void aubio_tensor_print_subtensor(aubio_tensor_t *t, uint_t depth)
162{
163  uint_t i;
164  AUBIO_MSG("[");
165  for (i = 0; i < t->shape[0]; i ++) {
166    AUBIO_MSG("%*s", i == 0 ? 0 : depth + 1, i == 0 ? "" : " ");
167    if (t->ndim == 1) {
168      AUBIO_MSG(AUBIO_SMPL_TFMT, t->buffer[i]);
169    } else {
170      aubio_tensor_t st;
171      aubio_tensor_get_subtensor(t, i, &st);
172      aubio_tensor_print_subtensor(&st, depth + 1); // recursive call
173    }
174    AUBIO_MSG("%s%s", (i < t->shape[0] - 1) ? "," : "",
175        t->ndim == 1 ? " " : ((i < t->shape[0] - 1) ? "\n" : ""));
176  }
177  AUBIO_MSG("]");
178}
179
180void aubio_tensor_print(aubio_tensor_t *t)
181{
182  AUBIO_MSG("tensor of shape %s\n", aubio_tensor_get_shape_string(t));
183  aubio_tensor_print_subtensor(t, 0);
184  AUBIO_MSG("\n");
185}
Note: See TracBrowser for help on using the repository browser.