From 1fe822d5294602eb0834ebe3412519ab27d600df Mon Sep 17 00:00:00 2001 From: Paul Brossier Date: Mon, 31 Dec 2018 17:04:15 +0100 Subject: [PATCH] [ai] add first tensor draft --- src/ai/tensor.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/ai/tensor.h | 60 ++++++++++++++++++++++++++++++++++++ 2 files changed, 155 insertions(+) create mode 100644 src/ai/tensor.c create mode 100644 src/ai/tensor.h diff --git a/src/ai/tensor.c b/src/ai/tensor.c new file mode 100644 index 00000000..de8b2fd7 --- /dev/null +++ b/src/ai/tensor.c @@ -0,0 +1,95 @@ +#include "aubio_priv.h" +#include "fmat.h" +#include "tensor.h" + +aubio_tensor_t *new_aubio_tensor(uint_t n_dims, uint_t *dims) +{ + aubio_tensor_t *c = AUBIO_NEW(aubio_tensor_t); + uint_t i; + + if ((sint_t)n_dims <= 0) goto failure; + for (i = 0; i < n_dims; i++) { + if ((sint_t)dims[i] <= 0) goto failure; + } + + c->n_dims = n_dims; + c->items_per_row = 1; + //c->dims = AUBIO_ARRAY(uint_t, n_dims); + c->dims[0] = dims[0]; + for (i = 1; i < n_dims; i++) { + c->dims[i] = dims[i]; + c->items_per_row *= dims[i]; + } + c->n_items = c->items_per_row * dims[0]; + c->data = AUBIO_ARRAY(smpl_t*, dims[0]); + c->data[0] = AUBIO_ARRAY(smpl_t, c->n_items); + for (i = 1; i < c->dims[0]; i++) { + c->data[i] = c->data[0] + i * c->items_per_row; + } + + return c; + +failure: + del_aubio_tensor(c); + return NULL; +} + +void del_aubio_tensor(aubio_tensor_t *c) +{ + AUBIO_ASSERT(c); + if (c->data) { + if (c->data[0]) { + AUBIO_FREE(c->data[0]); + } + AUBIO_FREE(c->data); + } + //if (c->dims) + // AUBIO_FREE(c->dims); + AUBIO_FREE(c); +} + +uint_t aubio_tensor_as_fvec(aubio_tensor_t *c, fvec_t *o) { + if (c->n_dims != 1) return AUBIO_FAIL; + if (c->dims[0] <= 0) return AUBIO_FAIL; + o->length = c->dims[0]; + o->data = c->data[0]; + return AUBIO_OK; +} + +uint_t aubio_fvec_as_tensor(fvec_t *o, aubio_tensor_t *c) { + if (o == NULL) return AUBIO_FAIL; + c->n_dims = 1; + c->dims[0] = o->length; + c->data = &o->data; + return AUBIO_OK; +} + +uint_t aubio_tensor_as_fmat(aubio_tensor_t *c, fmat_t *o) { + if (c->n_dims != 2) return AUBIO_FAIL; + if (c->dims[0] <= 0) return AUBIO_FAIL; + if (c->dims[1] <= 0) return AUBIO_FAIL; + o->height = c->dims[0]; + o->length = c->dims[1]; + o->data = c->data; + return AUBIO_OK; +} + +uint_t aubio_fmat_as_tensor(fmat_t *o, aubio_tensor_t *c) { + if (o == NULL) return AUBIO_FAIL; + if (c == NULL) return AUBIO_FAIL; + c->n_dims = 2; + c->dims[0] = o->height; + c->dims[1] = o->length; + c->data = o->data; + return AUBIO_OK; +} + +smpl_t aubio_tensor_max(aubio_tensor_t *t) +{ + uint_t i; + smpl_t max = -1000000; + for (i = 0; i < t->n_items; i++) { + max = MAX(t->data[0][i], max); + } + return max; +} diff --git a/src/ai/tensor.h b/src/ai/tensor.h new file mode 100644 index 00000000..e4b87381 --- /dev/null +++ b/src/ai/tensor.h @@ -0,0 +1,60 @@ +/* + Copyright (C) 2018 Paul Brossier + + This file is part of aubio. + + aubio is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + aubio is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with aubio. If not, see . + +*/ + +#ifndef AUBIO_TENSOR_H +#define AUBIO_TENSOR_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + uint_t n_dims; + uint_t dims[8]; + smpl_t **data; + uint_t n_items; + uint_t items_per_row; +} aubio_tensor_t; + +aubio_tensor_t *new_aubio_tensor(uint_t n_dims, uint_t *dims); + +void del_aubio_tensor(aubio_tensor_t *c); + +uint_t aubio_tensor_as_fvec(aubio_tensor_t *c, fvec_t *o); +uint_t aubio_fvec_as_tensor(fvec_t *o, aubio_tensor_t *c); + +uint_t aubio_tensor_as_fmat(aubio_tensor_t *c, fmat_t *o); +uint_t aubio_fmat_as_tensor(fmat_t *o, aubio_tensor_t *c); + +smpl_t aubio_tensor_max(aubio_tensor_t *t); + +#define AUBIO_ASSERT_EQUAL_SHAPE(t1, t2) { \ + AUBIO_ASSERT(t1 && t2); \ + AUBIO_ASSERT(t1->n_dims == t2->n_dims); \ + uint_t nn; \ + for (nn = 0; nn < t1->n_dims; nn++) \ + AUBIO_ASSERT(t1->dims[nn] == t2->dims[nn]); \ + } + +#ifdef __cplusplus +} +#endif + +#endif /* AUBIO_TENSOR_H */ -- 2.11.0