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
55 55
56// defined in aubio-proxy.c56// defined in aubio-proxy.c
57extern PyObject *PyAubio_CFvecToArray (fvec_t * self);57extern PyObject *PyAubio_CFvecToArray (fvec_t * self);
58extern fvec_t *PyAubio_ArrayToCFvec (PyObject * self);58extern int PyAubio_ArrayToCFvec (PyObject * self, fvec_t *out);
59 59
60extern Py_cvec *PyAubio_CCvecToPyCvec (cvec_t * self);60extern PyObject * PyAubio_CCvecToPyCvec (cvec_t * self, Py_cvec *out);
61extern cvec_t *PyAubio_ArrayToCCvec (PyObject *input);61extern int PyAubio_ArrayToCCvec (PyObject *input, cvec_t *i);
62 62
63extern PyObject *PyAubio_CFmatToArray (fmat_t * self);63extern PyObject *PyAubio_CFmatToArray (fmat_t * self);
64extern fmat_t *PyAubio_ArrayToCFmat (PyObject *input);64extern int PyAubio_ArrayToCFmat (PyObject *input, fmat_t *out);
65 65
66// hand written wrappers66// hand written wrappers
67extern PyTypeObject Py_filterType;67extern PyTypeObject Py_filterType;
python/ext/aubioproxy.c+63−72
@@ -1,12 +1,17 @@
1#include "aubio-types.h"1#include "aubio-types.h"
2 2
3fvec_t *3PyObject *
4PyAubio_ArrayToCFvec (PyObject *input) {4PyAubio_CFvecToArray (fvec_t * self)
5 PyObject *array;5{
6 fvec_t *vec;6 npy_intp dims[] = { self->length, 1 };
7 return PyArray_SimpleNewFromData (1, dims, AUBIO_NPY_SMPL, self->data);
8}
9
10int
11PyAubio_ArrayToCFvec (PyObject *input, fvec_t *out) {
7 if (input == NULL) {12 if (input == NULL) {
8 PyErr_SetString (PyExc_ValueError, "input array is not a python object");13 PyErr_SetString (PyExc_ValueError, "input array is not a python object");
9 goto fail;14 return 0;
10 }15 }
11 // parsing input object into a Py_fvec16 // parsing input object into a Py_fvec
12 if (PyArray_Check(input)) {17 if (PyArray_Check(input)) {
@@ -14,73 +19,62 @@ PyAubio_ArrayToCFvec (PyObject *input) { · 1 unmodified line
14 // we got an array, convert it to an fvec19 // we got an array, convert it to an fvec
15 if (PyArray_NDIM ((PyArrayObject *)input) == 0) {20 if (PyArray_NDIM ((PyArrayObject *)input) == 0) {
16 PyErr_SetString (PyExc_ValueError, "input array is a scalar");21 PyErr_SetString (PyExc_ValueError, "input array is a scalar");
17 goto fail;22 return 0;
18 } else if (PyArray_NDIM ((PyArrayObject *)input) > 1) {23 } else if (PyArray_NDIM ((PyArrayObject *)input) > 1) {
19 PyErr_SetString (PyExc_ValueError,24 PyErr_SetString (PyExc_ValueError,
20 "input array has more than one dimensions");25 "input array has more than one dimensions");
21 goto fail;26 return 0;
22 }27 }
23 28
24 if (!PyArray_ISFLOAT ((PyArrayObject *)input)) {29 if (!PyArray_ISFLOAT ((PyArrayObject *)input)) {
25 PyErr_SetString (PyExc_ValueError, "input array should be float");30 PyErr_SetString (PyExc_ValueError, "input array should be float");
26 goto fail;31 return 0;
27 } else if (PyArray_TYPE ((PyArrayObject *)input) != AUBIO_NPY_SMPL) {32 } else if (PyArray_TYPE ((PyArrayObject *)input) != AUBIO_NPY_SMPL) {
28 PyErr_SetString (PyExc_ValueError, "input array should be float32");33 PyErr_SetString (PyExc_ValueError, "input array should be float32");
29 goto fail;34 return 0;
30 } else {
31 // input data type is float32, nothing else to do
32 array = input;
33 }35 }
34 36
35 // vec = new_fvec (vec->length);37 // vec = new_fvec (vec->length);
36 // no need to really allocate fvec, just its struct member38 // no need to really allocate fvec, just its struct member
37 vec = (fvec_t *)malloc(sizeof(fvec_t));39 long length = PyArray_SIZE ((PyArrayObject *)input);
38 long length = PyArray_SIZE ((PyArrayObject *)array);40 if (length <= 0) {
39 if (length > 0) {
40 vec->length = (uint_t)length;
41 } else {
42 PyErr_SetString (PyExc_ValueError, "input array size should be greater than 0");41 PyErr_SetString (PyExc_ValueError, "input array size should be greater than 0");
43 goto fail;42 return 0;
44 }43 }
45 vec->data = (smpl_t *) PyArray_GETPTR1 ((PyArrayObject *)array, 0);
46 44
47 } else if (PyObject_TypeCheck (input, &PyList_Type)) {45 } else if (PyObject_TypeCheck (input, &PyList_Type)) {
48 PyErr_SetString (PyExc_ValueError, "does not convert from list yet");46 PyErr_SetString (PyExc_ValueError, "does not convert from list yet");
49 return NULL;47 return 0;
50 } else {48 } else {
51 PyErr_SetString (PyExc_ValueError, "can only accept vector of float as input");49 PyErr_SetString (PyExc_ValueError, "can only accept vector of float as input");
52 return NULL;50 return 0;
53 }51 }
54 52
55 return vec;53 out->length = (uint_t) PyArray_SIZE ((PyArrayObject *)input);
56 54 out->data = (smpl_t *) PyArray_GETPTR1 ((PyArrayObject *)input, 0);
57fail:55 return 1;
58 return NULL;
59}56}
60 57
61PyObject *58PyObject *
62PyAubio_CFvecToArray (fvec_t * self)59PyAubio_CCvecToPyCvec (cvec_t * input, Py_cvec *vec) {
63{
64 npy_intp dims[] = { self->length, 1 };
65 return PyArray_SimpleNewFromData (1, dims, AUBIO_NPY_SMPL, self->data);
66}
67
68Py_cvec *
69PyAubio_CCvecToPyCvec (cvec_t * input) {
70 Py_cvec *vec = (Py_cvec*) PyObject_New (Py_cvec, &Py_cvecType);
71 vec->length = input->length;60 vec->length = input->length;
72 vec->o = input;61 vec->o = input;
62 // keep a reference to re-use after returning it
73 Py_INCREF(vec);63 Py_INCREF(vec);
74 return vec;64 return (PyObject *)vec;
75}65}
76 66
77cvec_t *67int
78PyAubio_ArrayToCCvec (PyObject *input) {68PyAubio_ArrayToCCvec (PyObject *input, cvec_t *i) {
79 if (PyObject_TypeCheck (input, &Py_cvecType)) {69 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;
81 } else {75 } else {
82 PyErr_SetString (PyExc_ValueError, "input array should be float32");76 PyErr_SetString (PyExc_ValueError, "input array should be float32");
83 return NULL;77 return 0;
84 }78 }
85}79}
86 80
@@ -101,14 +95,12 @@ PyAubio_CFmatToArray (fmat_t * input) · 14 unmodified lines
101 return array;95 return array;
102}96}
103 97
104fmat_t *98int
105PyAubio_ArrayToCFmat (PyObject *input) {99PyAubio_ArrayToCFmat (PyObject *input, fmat_t *mat) {
106 PyObject *array;
107 fmat_t *mat;
108 uint_t i;100 uint_t i;
109 if (input == NULL) {101 if (input == NULL) {
110 PyErr_SetString (PyExc_ValueError, "input array is not a python object");102 PyErr_SetString (PyExc_ValueError, "input array is not a python object");
111 goto fail;103 return 0;
112 }104 }
113 // parsing input object into a Py_fvec105 // parsing input object into a Py_fvec
114 if (PyArray_Check(input)) {106 if (PyArray_Check(input)) {
@@ -116,56 +108,55 @@ PyAubio_ArrayToCFmat (PyObject *input) { · 1 unmodified line
116 // we got an array, convert it to an fvec108 // we got an array, convert it to an fvec
117 if (PyArray_NDIM ((PyArrayObject *)input) == 0) {109 if (PyArray_NDIM ((PyArrayObject *)input) == 0) {
118 PyErr_SetString (PyExc_ValueError, "input array is a scalar");110 PyErr_SetString (PyExc_ValueError, "input array is a scalar");
119 goto fail;111 return 0;
120 } else if (PyArray_NDIM ((PyArrayObject *)input) > 2) {112 } else if (PyArray_NDIM ((PyArrayObject *)input) > 2) {
121 PyErr_SetString (PyExc_ValueError,113 PyErr_SetString (PyExc_ValueError,
122 "input array has more than two dimensions");114 "input array has more than two dimensions");
123 goto fail;115 return 0;
124 }116 }
125 117
126 if (!PyArray_ISFLOAT ((PyArrayObject *)input)) {118 if (!PyArray_ISFLOAT ((PyArrayObject *)input)) {
127 PyErr_SetString (PyExc_ValueError, "input array should be float");119 PyErr_SetString (PyExc_ValueError, "input array should be float");
128 goto fail;120 return 0;
129 } else if (PyArray_TYPE ((PyArrayObject *)input) != AUBIO_NPY_SMPL) {121 } else if (PyArray_TYPE ((PyArrayObject *)input) != AUBIO_NPY_SMPL) {
130 PyErr_SetString (PyExc_ValueError, "input array should be float32");122 PyErr_SetString (PyExc_ValueError, "input array should be float32");
131 goto fail;123 return 0;
132 } else {
133 // input data type is float32, nothing else to do
134 array = input;
135 }124 }
136 125
137 // no need to really allocate fvec, just its struct member126 // no need to really allocate fvec, just its struct member
138 mat = (fmat_t *)malloc(sizeof(fmat_t));127 long length = PyArray_DIM ((PyArrayObject *)input, 1);
139 long length = PyArray_DIM ((PyArrayObject *)array, 1);128 if (length <= 0) {
140 if (length > 0) {
141 mat->length = (uint_t)length;
142 } else {
143 PyErr_SetString (PyExc_ValueError, "input array dimension 1 should be greater than 0");129 PyErr_SetString (PyExc_ValueError, "input array dimension 1 should be greater than 0");
144 goto fail;130 return 0;
145 }131 }
146 long height = PyArray_DIM ((PyArrayObject *)array, 0);132 long height = PyArray_DIM ((PyArrayObject *)input, 0);
147 if (height > 0) {133 if (height <= 0) {
148 mat->height = (uint_t)height;
149 } else {
150 PyErr_SetString (PyExc_ValueError, "input array dimension 0 should be greater than 0");134 PyErr_SetString (PyExc_ValueError, "input array dimension 0 should be greater than 0");
151 goto fail;135 return 0;
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);
156 }136 }
157 137
158 } else if (PyObject_TypeCheck (input, &PyList_Type)) {138 } else if (PyObject_TypeCheck (input, &PyList_Type)) {
159 PyErr_SetString (PyExc_ValueError, "can not convert list to fmat");139 PyErr_SetString (PyExc_ValueError, "can not convert list to fmat");
160 return NULL;140 return 0;
161 } else {141 } else {
162 PyErr_SetString (PyExc_ValueError, "can only accept matrix of float as input");142 PyErr_SetString (PyExc_ValueError, "can only accept matrix of float as input");
163 return NULL;143 return 0;
164 }144 }
165 145
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 }
167 156
168fail:157 mat->length = (uint_t)PyArray_DIM ((PyArrayObject *)input, 1);
169 return NULL;158 for (i=0; i< mat->height; i++) {
159 mat->data[i] = (smpl_t*)PyArray_GETPTR1 ((PyArrayObject *)input, i);
160 }
161 return 1;
170}162}
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