History

ext/aubio-types.h: rewrite array to fvec conversions to reduce memory allocations

Paul Brossier committed 10 years ago

Commit bfe82561 parent f2ce0fc2 files · +67 −76Browse files

Showing the changes to python/ext (2 of 2 files). Show all

Unified · Split

2 files
  1. python/ext/aubio-types.h +4 −4
  2. python/ext/aubioproxy.c +63 −72
python/ext/aubio-types.h+4−4
@@ -55,13 +55,13 @@ extern PyTypeObject Py_cvecType; · 54 unmodified lines
5555
5656 // defined in aubio-proxy.c
5757 extern PyObject *PyAubio_CFvecToArray (fvec_t * self);
58−extern fvec_t *PyAubio_ArrayToCFvec (PyObject * self);
58+extern int PyAubio_ArrayToCFvec (PyObject * self, fvec_t *out);
5959
60−extern Py_cvec *PyAubio_CCvecToPyCvec (cvec_t * self);
61−extern cvec_t *PyAubio_ArrayToCCvec (PyObject *input);
60+extern PyObject * PyAubio_CCvecToPyCvec (cvec_t * self, Py_cvec *out);
61+extern int PyAubio_ArrayToCCvec (PyObject *input, cvec_t *i);
6262
6363 extern PyObject *PyAubio_CFmatToArray (fmat_t * self);
64−extern fmat_t *PyAubio_ArrayToCFmat (PyObject *input);
64+extern int PyAubio_ArrayToCFmat (PyObject *input, fmat_t *out);
6565
6666 // hand written wrappers
6767 extern PyTypeObject Py_filterType;
python/ext/aubioproxy.c+63−72
@@ -1,12 +1,17 @@
11 #include "aubio-types.h"
22
3−fvec_t *
4−PyAubio_ArrayToCFvec (PyObject *input) {
5− PyObject *array;
6− fvec_t *vec;
3+PyObject *
4+PyAubio_CFvecToArray (fvec_t * self)
5+{
6+ npy_intp dims[] = { self->length, 1 };
7+ return PyArray_SimpleNewFromData (1, dims, AUBIO_NPY_SMPL, self->data);
8+}
9+
10+int
11+PyAubio_ArrayToCFvec (PyObject *input, fvec_t *out) {
712 if (input == NULL) {
813 PyErr_SetString (PyExc_ValueError, "input array is not a python object");
9− goto fail;
14+ return 0;
1015 }
1116 // parsing input object into a Py_fvec
1217 if (PyArray_Check(input)) {
@@ -14,73 +19,62 @@ PyAubio_ArrayToCFvec (PyObject *input) { · 1 unmodified line
1419 // we got an array, convert it to an fvec
1520 if (PyArray_NDIM ((PyArrayObject *)input) == 0) {
1621 PyErr_SetString (PyExc_ValueError, "input array is a scalar");
17− goto fail;
22+ return 0;
1823 } else if (PyArray_NDIM ((PyArrayObject *)input) > 1) {
1924 PyErr_SetString (PyExc_ValueError,
2025 "input array has more than one dimensions");
21− goto fail;
26+ return 0;
2227 }
2328
2429 if (!PyArray_ISFLOAT ((PyArrayObject *)input)) {
2530 PyErr_SetString (PyExc_ValueError, "input array should be float");
26− goto fail;
31+ return 0;
2732 } else if (PyArray_TYPE ((PyArrayObject *)input) != AUBIO_NPY_SMPL) {
2833 PyErr_SetString (PyExc_ValueError, "input array should be float32");
29− goto fail;
30− } else {
31− // input data type is float32, nothing else to do
32− array = input;
34+ return 0;
3335 }
3436
3537 // vec = new_fvec (vec->length);
3638 // no need to really allocate fvec, just its struct member
37− vec = (fvec_t *)malloc(sizeof(fvec_t));
38− long length = PyArray_SIZE ((PyArrayObject *)array);
39− if (length > 0) {
40− vec->length = (uint_t)length;
41− } else {
39+ long length = PyArray_SIZE ((PyArrayObject *)input);
40+ if (length <= 0) {
4241 PyErr_SetString (PyExc_ValueError, "input array size should be greater than 0");
43− goto fail;
42+ return 0;
4443 }
45− vec->data = (smpl_t *) PyArray_GETPTR1 ((PyArrayObject *)array, 0);
4644
4745 } else if (PyObject_TypeCheck (input, &PyList_Type)) {
4846 PyErr_SetString (PyExc_ValueError, "does not convert from list yet");
49− return NULL;
47+ return 0;
5048 } else {
5149 PyErr_SetString (PyExc_ValueError, "can only accept vector of float as input");
52− return NULL;
50+ return 0;
5351 }
5452
55− return vec;
56−
57−fail:
58− return NULL;
53+ out->length = (uint_t) PyArray_SIZE ((PyArrayObject *)input);
54+ out->data = (smpl_t *) PyArray_GETPTR1 ((PyArrayObject *)input, 0);
55+ return 1;
5956 }
6057
6158 PyObject *
62−PyAubio_CFvecToArray (fvec_t * self)
63−{
64− npy_intp dims[] = { self->length, 1 };
65− return PyArray_SimpleNewFromData (1, dims, AUBIO_NPY_SMPL, self->data);
66−}
67−
68−Py_cvec *
69−PyAubio_CCvecToPyCvec (cvec_t * input) {
70− Py_cvec *vec = (Py_cvec*) PyObject_New (Py_cvec, &Py_cvecType);
59+PyAubio_CCvecToPyCvec (cvec_t * input, Py_cvec *vec) {
7160 vec->length = input->length;
7261 vec->o = input;
62+ // keep a reference to re-use after returning it
7363 Py_INCREF(vec);
74− return vec;
64+ return (PyObject *)vec;
7565 }
7666
77−cvec_t *
78−PyAubio_ArrayToCCvec (PyObject *input) {
67+int
68+PyAubio_ArrayToCCvec (PyObject *input, cvec_t *i) {
7969 if (PyObject_TypeCheck (input, &Py_cvecType)) {
80− return ((Py_cvec*)input)->o;
70+ //*i = *(((Py_cvec*)input)->o);
71+ i->norm = ((Py_cvec*)input)->o->norm;
72+ i->phas = ((Py_cvec*)input)->o->phas;
73+ i->length = ((Py_cvec*)input)->o->length;
74+ return 1;
8175 } else {
8276 PyErr_SetString (PyExc_ValueError, "input array should be float32");
83− return NULL;
77+ return 0;
8478 }
8579 }
8680
@@ -101,14 +95,12 @@ PyAubio_CFmatToArray (fmat_t * input) · 14 unmodified lines
10195 return array;
10296 }
10397
104−fmat_t *
105−PyAubio_ArrayToCFmat (PyObject *input) {
106− PyObject *array;
107− fmat_t *mat;
98+int
99+PyAubio_ArrayToCFmat (PyObject *input, fmat_t *mat) {
108100 uint_t i;
109101 if (input == NULL) {
110102 PyErr_SetString (PyExc_ValueError, "input array is not a python object");
111− goto fail;
103+ return 0;
112104 }
113105 // parsing input object into a Py_fvec
114106 if (PyArray_Check(input)) {
@@ -116,56 +108,55 @@ PyAubio_ArrayToCFmat (PyObject *input) { · 1 unmodified line
116108 // we got an array, convert it to an fvec
117109 if (PyArray_NDIM ((PyArrayObject *)input) == 0) {
118110 PyErr_SetString (PyExc_ValueError, "input array is a scalar");
119− goto fail;
111+ return 0;
120112 } else if (PyArray_NDIM ((PyArrayObject *)input) > 2) {
121113 PyErr_SetString (PyExc_ValueError,
122114 "input array has more than two dimensions");
123− goto fail;
115+ return 0;
124116 }
125117
126118 if (!PyArray_ISFLOAT ((PyArrayObject *)input)) {
127119 PyErr_SetString (PyExc_ValueError, "input array should be float");
128− goto fail;
120+ return 0;
129121 } else if (PyArray_TYPE ((PyArrayObject *)input) != AUBIO_NPY_SMPL) {
130122 PyErr_SetString (PyExc_ValueError, "input array should be float32");
131− goto fail;
132− } else {
133− // input data type is float32, nothing else to do
134− array = input;
123+ return 0;
135124 }
136125
137126 // no need to really allocate fvec, just its struct member
138− mat = (fmat_t *)malloc(sizeof(fmat_t));
139− long length = PyArray_DIM ((PyArrayObject *)array, 1);
140− if (length > 0) {
141− mat->length = (uint_t)length;
142− } else {
127+ long length = PyArray_DIM ((PyArrayObject *)input, 1);
128+ if (length <= 0) {
143129 PyErr_SetString (PyExc_ValueError, "input array dimension 1 should be greater than 0");
144− goto fail;
130+ return 0;
145131 }
146− long height = PyArray_DIM ((PyArrayObject *)array, 0);
147− if (height > 0) {
148− mat->height = (uint_t)height;
149− } else {
132+ long height = PyArray_DIM ((PyArrayObject *)input, 0);
133+ if (height <= 0) {
150134 PyErr_SetString (PyExc_ValueError, "input array dimension 0 should be greater than 0");
151− goto fail;
152− }
153− mat->data = (smpl_t **)malloc(sizeof(smpl_t*) * mat->height);
154− for (i=0; i< mat->height; i++) {
155− mat->data[i] = (smpl_t*)PyArray_GETPTR1 ((PyArrayObject *)array, i);
135+ return 0;
156136 }
157137
158138 } else if (PyObject_TypeCheck (input, &PyList_Type)) {
159139 PyErr_SetString (PyExc_ValueError, "can not convert list to fmat");
160− return NULL;
140+ return 0;
161141 } else {
162142 PyErr_SetString (PyExc_ValueError, "can only accept matrix of float as input");
163− return NULL;
143+ return 0;
164144 }
165145
166− return mat;
146+ if (mat->height != (uint_t)PyArray_DIM ((PyArrayObject *)input, 0)) {
147+ /*
148+ free(mat->data);
149+ mat->height = (uint_t)PyArray_DIM ((PyArrayObject *)input, 0);
150+ mat->data = (smpl_t **)malloc(sizeof(smpl_t*) * mat->height);
151+ */
152+ PyErr_Format(PyExc_ValueError, "too many rows, %d but %ld expected",
153+ mat->height, PyArray_DIM ((PyArrayObject *)input, 0) );
154+ return 0;
155+ }
167156
168−fail:
169− return NULL;
157+ mat->length = (uint_t)PyArray_DIM ((PyArrayObject *)input, 1);
158+ for (i=0; i< mat->height; i++) {
159+ mat->data[i] = (smpl_t*)PyArray_GETPTR1 ((PyArrayObject *)input, i);
160+ }
161+ return 1;
170162 }
171−

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t