Skip to content

Commit 60522a1

Browse files
authored
Merge pull request #1472 from MTG/numpy2
Update to NumPy 2 C-API
2 parents 4adab13 + 9e72b8d commit 60522a1

22 files changed

+421
-504
lines changed

pyproject-tensorflow.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ test-command = "python -c 'import essentia; import essentia.standard; import ess
2121

2222
[tool.cibuildwheel.macos]
2323

24-
skip = ["pp*"]
24+
skip = ["pp*", "*cp36*", "*cp37*", "*cp38*"]
2525

2626
environment = { PROJECT_NAME="essentia-tensorflow", ESSENTIA_PROJECT_NAME="${PROJECT_NAME}", ESSENTIA_WHEEL_SKIP_3RDPARTY=1, ESSENTIA_WHEEL_ONLY_PYTHON=1 }
2727

@@ -45,7 +45,7 @@ test-command = "python -c 'import essentia; import essentia.standard; import ess
4545
[[tool.cibuildwheel.overrides]]
4646
select = "*macosx_arm64*"
4747

48-
skip = ["pp*"]
48+
skip = ["pp*", "*cp36*", "*cp37*", "*cp38*"]
4949

5050
environment = { PROJECT_NAME="essentia-tensorflow", ESSENTIA_PROJECT_NAME="${PROJECT_NAME}", ESSENTIA_WHEEL_SKIP_3RDPARTY=1, ESSENTIA_WHEEL_ONLY_PYTHON=1, ESSENTIA_MACOSX_ARM64=1 }
5151

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ test-command = "python -c 'import essentia; import essentia.standard; import ess
2020

2121
[tool.cibuildwheel.macos]
2222

23-
skip = ["pp*"]
23+
skip = ["pp*", "*cp36*", "*cp37*", "*cp38*"]
2424

2525
environment = { PROJECT_NAME="essentia", ESSENTIA_PROJECT_NAME="${PROJECT_NAME}", ESSENTIA_WHEEL_SKIP_3RDPARTY=1, ESSENTIA_WHEEL_ONLY_PYTHON=1 }
2626

@@ -42,7 +42,7 @@ test-command = "python -c 'import essentia; import essentia.standard; import ess
4242
[[tool.cibuildwheel.overrides]]
4343
select = "*macosx_arm64*"
4444

45-
skip = ["pp*"]
45+
skip = ["pp*", "*cp36*", "*cp37*", "*cp38*"]
4646

4747
environment = { PROJECT_NAME="essentia", ESSENTIA_PROJECT_NAME="${PROJECT_NAME}", ESSENTIA_WHEEL_SKIP_3RDPARTY=1, ESSENTIA_WHEEL_ONLY_PYTHON=1, ESSENTIA_MACOSX_ARM64=1 }
4848

src/python/globalfuncs.cpp

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -203,11 +203,12 @@ derivative(PyObject* self, PyObject* arg) {
203203
static double
204204
internal_instant_power(PyObject* obj) {
205205
double p = 0;
206-
for (int i=0; i<PyArray_SIZE(obj); i++) {
207-
double x = ((float*)PyArray_DATA(obj))[i];
206+
PyArrayObject* array = (PyArrayObject*)obj;
207+
for (int i=0; i<PyArray_SIZE(array); i++) {
208+
double x = ((float*)PyArray_DATA(array))[i];
208209
p += x * x;
209210
}
210-
p /= PyArray_SIZE(obj);
211+
p /= PyArray_SIZE(array);
211212
return p;
212213
}
213214

@@ -1034,29 +1035,32 @@ static PyObject* almostEqualArray(PyObject* notUsed, PyObject* args) {
10341035

10351036
if (argv.size() != 3 ||
10361037
!PyArray_Check(argv[0]) || !PyArray_Check(argv[1]) ||
1037-
PyArray_TYPE(argv[0]) != PyArray_TYPE(argv[1]) ||
1038-
PyArray_TYPE(argv[0]) != NPY_FLOAT ||
1038+
PyArray_TYPE((const PyArrayObject *) argv[0]) != PyArray_TYPE((const PyArrayObject *) argv[1]) ||
1039+
PyArray_TYPE((const PyArrayObject *) argv[0]) != NPY_FLOAT ||
10391040
!PyFloat_Check(argv[2])) {
10401041
PyErr_SetString(PyExc_TypeError, "expecting arguments (numpy.array(floats) m1, numpy.array(floats) m2, float precision)");
10411042
return NULL;
10421043
}
10431044

1044-
if (PyArray_NDIM(argv[0]) != PyArray_NDIM(argv[1])) Py_RETURN_FALSE;
1045+
PyArrayObject* array0 = (PyArrayObject*) argv[0];
1046+
PyArrayObject* array1 = (PyArrayObject*) argv[1];
10451047

1046-
if (PyArray_NDIM(argv[0]) > 2) {
1048+
if (PyArray_NDIM(array0) != PyArray_NDIM(array1)) Py_RETURN_FALSE;
1049+
1050+
if (PyArray_NDIM(array0) > 2) {
10471051
PyErr_SetString(PyExc_TypeError, "comparing numpy arrays of more than 2 dimensions not implemented");
10481052
return NULL;
10491053
}
10501054

10511055
float precision = PyFloat_AS_DOUBLE(argv[2]);
10521056

10531057
// 1-dimensional arrays
1054-
if (PyArray_NDIM(argv[0]) == 1) {
1055-
if (PyArray_DIM(argv[0], 0) != PyArray_DIM(argv[1], 0)) Py_RETURN_FALSE;
1058+
if (PyArray_NDIM(array0) == 1) {
1059+
if (PyArray_DIM(array0, 0) != PyArray_DIM(array1, 0)) Py_RETURN_FALSE;
10561060

1057-
for (int i=0; i<int(PyArray_DIM(argv[0], 0)); ++i) {
1058-
Real* x = (Real*)(PyArray_BYTES(argv[0]) + i*PyArray_STRIDE(argv[0], 0));
1059-
Real* y = (Real*)(PyArray_BYTES(argv[1]) + i*PyArray_STRIDE(argv[1], 0));
1061+
for (int i=0; i<int(PyArray_DIM(array0, 0)); ++i) {
1062+
Real* x = (Real*)(PyArray_BYTES(array0) + i*PyArray_STRIDE(array0, 0));
1063+
Real* y = (Real*)(PyArray_BYTES(array1) + i*PyArray_STRIDE(array1, 0));
10601064
Real diff = 0;
10611065
if (*y == 0) diff = abs(*x);
10621066
else if (*x == 0) diff = abs(*y);
@@ -1071,16 +1075,16 @@ static PyObject* almostEqualArray(PyObject* notUsed, PyObject* args) {
10711075
}
10721076

10731077
// 2-dimensional arrays
1074-
else if (PyArray_NDIM(argv[0]) == 2) {
1075-
if (PyArray_DIM(argv[0], 0) != PyArray_DIM(argv[1], 0) ||
1076-
PyArray_DIM(argv[0], 1) != PyArray_DIM(argv[1], 1)) {
1078+
else if (PyArray_NDIM(array0) == 2) {
1079+
if (PyArray_DIM(array0, 0) != PyArray_DIM(array1, 0) ||
1080+
PyArray_DIM(array0, 1) != PyArray_DIM(array1, 1)) {
10771081
Py_RETURN_FALSE;
10781082
}
10791083

1080-
for (int i=0; i<int(PyArray_DIM(argv[0], 0)); ++i) {
1081-
for (int j=0; j<int(PyArray_DIM(argv[0], 1)); ++j) {
1082-
Real* x = (Real*)(PyArray_BYTES(argv[0]) + i*PyArray_STRIDE(argv[0], 0) + j*PyArray_STRIDE(argv[0], 1));
1083-
Real* y = (Real*)(PyArray_BYTES(argv[1]) + i*PyArray_STRIDE(argv[1], 0) + j*PyArray_STRIDE(argv[1], 1));
1084+
for (int i=0; i<int(PyArray_DIM(array0, 0)); ++i) {
1085+
for (int j=0; j<int(PyArray_DIM(array0, 1)); ++j) {
1086+
Real* x = (Real*)(PyArray_BYTES(array0) + i*PyArray_STRIDE(array0, 0) + j*PyArray_STRIDE(array0, 1));
1087+
Real* y = (Real*)(PyArray_BYTES(array1) + i*PyArray_STRIDE(array1, 0) + j*PyArray_STRIDE(array1, 1));
10841088
Real diff = 0;
10851089
if (*y == 0) diff = abs(*x);
10861090
else if (*x == 0) diff = abs(*y);

src/python/pytypes/matrixreal.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,20 @@ PyObject* MatrixReal::toPythonRef(TNT::Array2D<Real>* mat) {
3232

3333
PyObject* result;
3434
if (dims[0] == 0 || dims[1] == 0) {
35-
result = PyArray_SimpleNew(2, dims, PyArray_FLOAT);
35+
result = PyArray_SimpleNew(2, dims, NPY_FLOAT);
3636
}
3737
else {
38-
result = PyArray_SimpleNewFromData(2, dims, PyArray_FLOAT, &((*mat)[0][0]));
38+
result = PyArray_SimpleNewFromData(2, dims, NPY_FLOAT, &((*mat)[0][0]));
3939
}
4040

4141
if (result == NULL) {
4242
throw EssentiaException("MatrixReal: dang null object");
4343
}
4444

45-
PyArray_BASE(result) = TO_PYTHON_PROXY(MatrixReal, mat);
45+
if (PyArray_SetBaseObject((PyArrayObject*)result, TO_PYTHON_PROXY(MatrixReal, mat)) < 0) {
46+
Py_DECREF(result);
47+
throw EssentiaException("MatrixReal: failed to set base object");
48+
}
4649

4750
return result;
4851
}
@@ -65,11 +68,11 @@ void* MatrixReal::fromPythonCopy(PyObject* obj) {
6568
if (!PyArray_Check(obj)) {
6669
throw EssentiaException("MatrixReal::fromPythonRef: argument not a PyArray");
6770
}
68-
if (PyArray_NDIM(obj) != 2) {
71+
if (PyArray_NDIM((const PyArrayObject *) obj) != 2) {
6972
throw EssentiaException("MatrixReal::fromPythonRef: argument is not a 2-dimensional PyArray");
7073
}
7174

72-
TNT::Array2D<Real>* tntmat = new TNT::Array2D<Real>(PyArray_DIM(obj, 0), PyArray_DIM(obj, 1), 0.0);
75+
TNT::Array2D<Real>* tntmat = new TNT::Array2D<Real>(PyArray_DIM((const PyArrayObject *) obj, 0), PyArray_DIM((const PyArrayObject *) obj, 1), 0.0);
7376

7477
// copy data from numpy array to matrix
7578
PyArrayObject* numpyarr = (PyArrayObject*)obj;

src/python/pytypes/tensorreal.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ PyObject* TensorReal::toPythonCopy(const essentia::Tensor<essentia::Real>* tenso
3535
for (int i = 0; i < nd; i++)
3636
dims[i] = tensor->dimension(i);
3737

38-
result = PyArray_SimpleNew(nd, dims, PyArray_FLOAT);
38+
result = PyArray_SimpleNew(nd, dims, NPY_FLOAT);
3939

4040
Real* dest = (Real*)(((PyArrayObject*)result)->data);
4141
const Real* src = tensor->data();
@@ -55,19 +55,19 @@ void* TensorReal::fromPythonCopy(PyObject* obj) {
5555
if (!PyArray_Check(obj)) {
5656
throw EssentiaException("TensorReal::fromPythonRef: expected PyArray, received: ", strtype(obj));
5757
}
58-
if (PyArray_NDIM(obj) != TENSORRANK) {
58+
if (PyArray_NDIM((const PyArrayObject *) obj) != TENSORRANK) {
5959
throw EssentiaException("TensorReal::fromPythonCopy: argument is not a 4-dimensional PyArray");
6060
}
6161

6262
// // copy data from numpy array to matrix
6363
PyArrayObject* numpyarr = (PyArrayObject*)obj;
64-
if (numpyarr->descr->type_num != PyArray_FLOAT) {
64+
if (numpyarr->descr->type_num != NPY_FLOAT) {
6565
throw EssentiaException("TensorReal::fromPythonRef: this NumPy array doesn't contain Reals (maybe you forgot dtype='f4')");
6666
}
6767

6868
return new Tensor<Real>(TensorMap<Real>((Real *)PyArray_DATA(numpyarr),
69-
PyArray_DIM(obj, 0),
70-
PyArray_DIM(obj, 1),
71-
PyArray_DIM(obj, 2),
72-
PyArray_DIM(obj, 3)));
69+
PyArray_DIM(numpyarr, 0),
70+
PyArray_DIM(numpyarr, 1),
71+
PyArray_DIM(numpyarr, 2),
72+
PyArray_DIM(numpyarr, 3)));
7373
}

src/python/pytypes/vectorcomplex.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,19 @@ PyObject* VectorComplex::toPythonRef(RogueVector<complex<Real> >* v) {
2828
npy_intp dim = v->size();
2929
PyObject* result;
3030

31-
if (dim > 0) result = PyArray_SimpleNewFromData(1, &dim, PyArray_COMPLEX64, &((*v)[0]));
32-
else result = PyArray_SimpleNew(1, &dim, PyArray_COMPLEX64);
31+
if (dim > 0) result = PyArray_SimpleNewFromData(1, &dim, NPY_COMPLEX64, &((*v)[0]));
32+
else result = PyArray_SimpleNew(1, &dim, NPY_COMPLEX64);
3333

3434
if (result == NULL) {
35-
throw EssentiaException("VectorComplex::toPythonRef: could not create PyArray of type PyArray_COMPLEX64");
35+
throw EssentiaException("VectorComplex::toPythonRef: could not create PyArray of type NPY_COMPLEX64");
3636
}
3737

3838
// set the PyArray pointer to our vector, so it can be released when the
3939
// PyArray is released
40-
PyArray_BASE(result) = TO_PYTHON_PROXY(VectorComplex, v);
40+
if (PyArray_SetBaseObject((PyArrayObject*)result, TO_PYTHON_PROXY(VectorComplex, v)) < 0) {
41+
Py_DECREF(result);
42+
throw EssentiaException("VectorComplex: failed to set base object");
43+
}
4144

4245
return result;
4346
}
@@ -50,12 +53,12 @@ void* VectorComplex::fromPythonRef(PyObject* obj) {
5053

5154
PyArrayObject* array = (PyArrayObject*)obj;
5255

53-
if (array->descr->type_num != PyArray_CFLOAT) {
56+
if (array->descr->type_num != NPY_CFLOAT) {
5457
throw EssentiaException("VectorComplex::fromPythonRef: this NumPy array doesn't contain complex<Real> (maybe you forgot dtype='c8')");
5558
}
5659
if (array->nd != 1) {
5760
throw EssentiaException("VectorComplex::fromPythonRef: this NumPy array has dimension ", array->nd, " (expected 1)");
5861
}
5962

60-
return new RogueVector<complex<Real> >((complex<Real>*)PyArray_DATA(obj), PyArray_SIZE(obj));
63+
return new RogueVector<complex<Real> >((complex<Real>*)PyArray_DATA(array), PyArray_SIZE(array));
6164
}

src/python/pytypes/vectorinteger.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,17 @@ PyObject* VectorInteger::toPythonRef(RogueVector<int>* v) {
2727
npy_intp dim = v->size();
2828
PyObject* result;
2929

30-
if (dim > 0) result = PyArray_SimpleNewFromData(1, &dim, PyArray_INT, &((*v)[0]));
31-
else result = PyArray_SimpleNew(1, &dim, PyArray_INT);
30+
if (dim > 0) result = PyArray_SimpleNewFromData(1, &dim, NPY_INT, &((*v)[0]));
31+
else result = PyArray_SimpleNew(1, &dim, NPY_INT);
3232

3333
if (result == NULL) {
34-
throw EssentiaException("VectorInteger::toPythonRef: could not create PyArray of type PyArray_INT");
34+
throw EssentiaException("VectorInteger::toPythonRef: could not create PyArray of type NPY_INT");
3535
}
3636

37-
PyArray_BASE(result) = TO_PYTHON_PROXY(VectorInteger, v);
37+
if (PyArray_SetBaseObject((PyArrayObject*)result, TO_PYTHON_PROXY(VectorInteger, v)) < 0) {
38+
Py_DECREF(result);
39+
throw EssentiaException("VectorInteger: failed to set base object");
40+
}
3841

3942
return result;
4043
}
@@ -48,14 +51,14 @@ void* VectorInteger::fromPythonRef(PyObject* obj) {
4851

4952
PyArrayObject* array = (PyArrayObject*)obj;
5053

51-
if (array->descr->type_num != PyArray_INT32) {
54+
if (array->descr->type_num != NPY_INT32) {
5255
throw EssentiaException("VectorInteger::fromPythonRef: this NumPy array doesn't contain ints (maybe you forgot dtype='int'), type code: ", array->descr->type_num);
5356
}
5457
if (array->nd != 1) {
5558
throw EssentiaException("VectorInteger::fromPythonRef: this NumPy array has dimension ", array->nd, " (expected 1)");
5659
}
5760

58-
return new RogueVector<int>((int*)PyArray_DATA(obj), PyArray_SIZE(obj));
61+
return new RogueVector<int>((int*)PyArray_DATA(array), PyArray_SIZE(array));
5962
}
6063

6164
Parameter* VectorInteger::toParameter(PyObject* obj) {

src/python/pytypes/vectormatrixreal.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ PyObject* VectorMatrixReal::toPythonCopy(const vector<TNT::Array2D<Real> >* matV
3333
dims[0] = (*matVec)[i].dim1();
3434
dims[1] = (*matVec)[i].dim2();
3535

36-
PyArrayObject* mat = (PyArrayObject*)PyArray_SimpleNew(2, dims, PyArray_FLOAT);
36+
PyArrayObject* mat = (PyArrayObject*)PyArray_SimpleNew(2, dims, NPY_FLOAT);
3737

3838
if (mat == NULL) {
3939
throw EssentiaException("VectorMatrixReal::toPythonCopy: dang null object");

src/python/pytypes/vectorreal.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,17 @@ PyObject* VectorReal::toPythonRef(RogueVector<Real>* v) {
2727
npy_intp dim = v->size();
2828
PyObject* result;
2929

30-
if (dim > 0) result = PyArray_SimpleNewFromData(1, &dim, PyArray_FLOAT, &((*v)[0]));
31-
else result = PyArray_SimpleNew(1, &dim, PyArray_FLOAT);
30+
if (dim > 0) result = PyArray_SimpleNewFromData(1, &dim, NPY_FLOAT, &((*v)[0]));
31+
else result = PyArray_SimpleNew(1, &dim, NPY_FLOAT);
3232

3333
if (result == NULL) {
3434
throw EssentiaException("VectorReal: dang null object");
3535
}
3636

37-
PyArray_BASE(result) = TO_PYTHON_PROXY(VectorReal, v);
37+
if (PyArray_SetBaseObject((PyArrayObject*)result, TO_PYTHON_PROXY(VectorReal, v)) < 0) {
38+
Py_DECREF(result);
39+
throw EssentiaException("VectorReal: failed to set base object");
40+
}
3841

3942
return result;
4043
}
@@ -48,14 +51,14 @@ void* VectorReal::fromPythonRef(PyObject* obj) {
4851

4952
PyArrayObject* array = (PyArrayObject*)obj;
5053

51-
if (array->descr->type_num != PyArray_FLOAT) {
54+
if (array->descr->type_num != NPY_FLOAT) {
5255
throw EssentiaException("VectorReal::fromPythonRef: this NumPy array doesn't contain Reals (maybe you forgot dtype='f4')");
5356
}
5457
if (array->nd != 1) {
5558
throw EssentiaException("VectorReal::fromPythonRef: this NumPy array has dimension ", array->nd, " (expected 1)");
5659
}
5760

58-
return new RogueVector<Real>((Real*)PyArray_DATA(obj), PyArray_SIZE(obj));
61+
return new RogueVector<Real>((Real*)PyArray_DATA(array), PyArray_SIZE(array));
5962
}
6063

6164
Parameter* VectorReal::toParameter(PyObject* obj) {

src/python/pytypes/vectorstereosample.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,18 +49,19 @@ void* VectorStereoSample::fromPythonCopy(PyObject* obj) {
4949
"is not a numpy array: ", strtype(obj));
5050
}
5151

52-
if (PyArray_NDIM(obj) != 2) {
52+
PyArrayObject* arr = (PyArrayObject*)obj;
53+
54+
if (PyArray_NDIM(arr) != 2) {
5355
throw EssentiaException("VectorStereoSample::fromPythonCopy: given input "
54-
"is not a 2-dimensional numpy array: ", PyArray_NDIM(obj));
56+
"is not a 2-dimensional numpy array: ", PyArray_NDIM(arr));
5557
}
5658

57-
if (PyArray_DIM(obj, 1) != 2) {
59+
if (PyArray_DIM(arr, 1) != 2) {
5860
throw EssentiaException("VectorStereoSample::fromPythonCopy: given input's "
59-
"second dimension is not 2: ", PyArray_DIM(obj, 1));
61+
"second dimension is not 2: ", PyArray_DIM(arr, 1));
6062
}
6163

62-
Py_ssize_t total = PyArray_DIM(obj, 0);
63-
PyArrayObject* arr = (PyArrayObject*)obj;
64+
Py_ssize_t total = PyArray_DIM(arr, 0);
6465
vector<StereoSample>* result = new vector<StereoSample>(total);
6566

6667
for (int i=0; i<int(total); ++i) {

0 commit comments

Comments
 (0)