Skip to content

Commit f733b5a

Browse files
Python update (ARM-software#191)
* Update and tests to release new wrapper on PyPI Some corrections to cholesky Tested with Numpy 2.0 (can be use with Numpy >= 1.23.5)
1 parent d7bff44 commit f733b5a

File tree

13 files changed

+75
-70
lines changed

13 files changed

+75
-70
lines changed

PythonWrapper/build_darwin/create.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ cmake -DHOST=YES \
33
-DWRAPPER=YES \
44
-DCMAKE_POSITION_INDEPENDENT_CODE=YES \
55
-DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" \
6+
-DCMAKE_OSX_DEPLOYMENT_TARGET="10.9" \
67
-DCMSISDSP="path to CMSIS-DSP folder" \
78
-DCMAKE_C_FLAGS_RELEASE="-std=c11 -Ofast -ffast-math -DNDEBUG -Wall -Wextra" \
89
-DCMAKE_CXX_FLAGS_RELEASE="-fno-rtti -std=c++11 -Ofast -ffast-math -DNDEBUG -Wall -Wextra -Wno-unused-parameter" \

PythonWrapper/cmsisdsp_pkg/src/cmsisdsp_matrix.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1908,6 +1908,15 @@ cmsis_arm_mat_cholesky_f32(PyObject *obj, PyObject *args)
19081908
uint32_t row = src_converted.numRows ;
19091909
createf32Matrix(&dst_converted,row,column);
19101910

1911+
float32_t *p=dst_converted.pData;
1912+
for(int r=0;r<row;r++)
1913+
{
1914+
for(int c =0; c < column;c++)
1915+
{
1916+
*p++=0.0f;
1917+
}
1918+
}
1919+
19111920
arm_status returnValue = arm_mat_cholesky_f32(&src_converted,&dst_converted);
19121921
PyObject* theReturnOBJ=Py_BuildValue("i",returnValue);
19131922
PyObject* dstOBJ=NumpyArrayFromf32Matrix(&dst_converted);
@@ -1939,6 +1948,16 @@ cmsis_arm_mat_cholesky_f64(PyObject *obj, PyObject *args)
19391948
uint32_t row = src_converted.numRows ;
19401949
createf64Matrix(&dst_converted,row,column);
19411950

1951+
float64_t *p=dst_converted.pData;
1952+
for(int r=0;r<row;r++)
1953+
{
1954+
for(int c =0; c < column;c++)
1955+
{
1956+
*p++=0.0f;
1957+
}
1958+
}
1959+
1960+
19421961
arm_status returnValue = arm_mat_cholesky_f64(&src_converted,&dst_converted);
19431962
PyObject* theReturnOBJ=Py_BuildValue("i",returnValue);
19441963
PyObject* dstOBJ=NumpyArrayFromf64Matrix(&dst_converted);

PythonWrapper/cmsisdsp_pkg/src/cmsisdsp_module.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,15 @@
2727
*/
2828
#ifndef CMSISMODULE_H
2929
#define CMSISMODULE_H
30-
#define NPY_NO_DEPRECATED_API NPY_1_22_API_VERSION
30+
#define NPY_NO_DEPRECATED_API NPY_1_23_API_VERSION
3131

3232
#include <numpy/numpyconfig.h>
3333

34-
// API version used on google colab
34+
// Check it is built with right version
35+
// (should be backward compatible down to 1.23.5)
3536
// https://github.com/numpy/numpy/blob/main/numpy/_core/include/numpy/numpyconfig.h
36-
#if (NPY_API_VERSION != 0x0000000F )
37-
//#error("Error building with wrong NumPy API version")
37+
#if (NPY_API_VERSION != NPY_2_0_API_VERSION )
38+
#error("Error building with wrong NumPy API version")
3839
#endif
3940

4041
#ifdef WIN

PythonWrapper/examples/debug.py

Lines changed: 14 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
1-
import cmsisdsp as dsp
2-
import cmsisdsp.fixedpoint as f
3-
1+
import cmsisdsp as dsp
42
import numpy as np
3+
from numpy.testing import assert_allclose
4+
from scipy.stats import entropy,tstd, tvar
5+
from scipy.special import logsumexp
6+
from scipy.linalg import cholesky,ldl,solve_triangular
57
from scipy import signal
6-
import matplotlib.pyplot as plt
7-
import scipy.fft
8+
89

910
import colorama
1011
from colorama import init,Fore, Back, Style
11-
from numpy.testing import assert_allclose
12-
import scipy.spatial.distance as d
1312

1413
init()
1514

@@ -20,61 +19,16 @@ def printSubTitle(s):
2019
print("\n" + Style.BRIGHT + s + Style.RESET_ALL)
2120

2221

23-
def packset(a):
24-
b = np.packbits(a)
25-
newSize = int(np.ceil(b.shape[0] / 4.0)) * 4
26-
c = np.copy(b).astype(np.uint32)
27-
c.resize(newSize)
28-
#print(c)
29-
vecSize = round(newSize/4)
30-
c=c.reshape(vecSize,4)
31-
#print(c)
32-
r = np.zeros(vecSize)
33-
result = []
34-
for i in range(0,vecSize):
35-
print(c[i,:])
36-
#print("%X %X %X %X" % (c[i,0],c[i,1],c[i,2],c[i,3]))
37-
d = (c[i,0] << 24) | (c[i,1] << 16) | (c[i,2] << 8) | c[i,3]
38-
result.append(np.uint32(d))
39-
return(result)
40-
41-
nb = 34
42-
#va = np.random.choice([0,1],nb)
43-
# Array of word32 containing all of our bits
44-
#pva = packset(va)
45-
46-
47-
#vb = np.random.choice([0,1],nb)
48-
# Array of word32 containing all of our bits
49-
#pvb = packset(vb)
50-
#
51-
va=[1, 0, 1, 0, 1, 1, 1, 0 ,0, 1, 1, 0, 1, 0, 0, 0, 0, 1,0,0,0,1,1,0,1,0,1,0,0,1,1,1,1,1]
52-
vb=[0,1,0,0,1,0,0,0,1,0,0,0,0,1,1,0,0,1,0,0,0,1,0,1,1,0,0,1,1,0,0,0,1,0]
53-
54-
va = np.array(va)
55-
vb = np.array(vb)
22+
print("Cholesky")
5623

57-
pva=packset(va)
58-
pvb=packset(vb)
59-
60-
#pva = [np.uint32(167), np.uint32(0)]
61-
#pvb = [np.uint32(152), np.uint32(0)]
62-
63-
#print(va,pva)
64-
#print(vb,pvb)
65-
66-
ctt=1.0*np.count_nonzero((va==1) & (vb==1))
67-
ctf=1.0*np.count_nonzero((va==1) & (vb==0))
68-
cft=1.0*np.count_nonzero((va==0) & (vb==1))
69-
70-
res=(cft+ctf)/(2*ctt+cft+ctf)
24+
a=np.array([[4,12,-16],[12,37,-43],[-16,-43,98]])
25+
ref=cholesky(a,lower=True)
26+
print(ref)
7127

28+
status,res=dsp.arm_mat_cholesky_f32(a)
7229
print(res)
30+
assert_allclose(ref,res,1e-6,1e-6)
7331

74-
75-
print("\nDice")
76-
ref=d.dice(va,vb)
77-
res=dsp.arm_dice_distance(pva,pvb,nb)
78-
print(ref)
32+
status,res=dsp.arm_mat_cholesky_f64(a)
7933
print(res)
80-
assert_allclose(ref,res,1e-6)
34+
assert_allclose(ref,res,1e-10,1e-10)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
numpy>=1.23.5
2+
scipy~=1.13.1
3+
scikit_learn~=1.5.0
4+
colorama~=0.4.6

PythonWrapper/examples/runall.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/usr/bin/env bash
2+
3+
set -e
4+
5+
python testdistance.py
6+
python testdsp6.py
7+
python testdsp5.py
8+
python example_1_10.py
9+
python example_1_6.py
10+
python example_1_9.py
11+

PythonWrapper_README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,8 @@ MEL filters are represented as 3 arrays to encode a sparse array.
236236

237237
## Version 1.9.9:
238238
* Supports Python 3.12
239+
* Works with Numpy 2.0
240+
* Corrections on Cholesky
239241

240242
## Version 1.9.8:
241243
* Compute graph API has been removed

Source/MatrixFunctions/arm_mat_cholesky_f16.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@
5252
* @par
5353
* If the matrix is ill conditioned or only semi-definite, then it is better using the LDL^t decomposition.
5454
* The decomposition of A is returning a lower triangular matrix U such that A = L L^t
55+
*
56+
* @par
57+
* The destination matrix should be set to 0 before calling the functions because
58+
* the function may not overwrite all output elements.
5559
*/
5660

5761
#if defined(ARM_MATH_MVE_FLOAT16) && !defined(ARM_MATH_AUTOVECTORIZE)

Source/MatrixFunctions/arm_mat_cholesky_f32.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@
6060
* @par
6161
* If the matrix is ill conditioned or only semi-definite, then it is better using the LDL^t decomposition.
6262
* The decomposition of A is returning a lower triangular matrix L such that A = L L^t
63+
*
64+
* @par
65+
* The destination matrix should be set to 0 before calling the functions because
66+
* the function may not overwrite all output elements.
6367
*/
6468

6569
#if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)

Source/MatrixFunctions/arm_mat_cholesky_f64.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@
5050
* @par
5151
* If the matrix is ill conditioned or only semi-definite, then it is better using the LDL^t decomposition.
5252
* The decomposition of A is returning a lower triangular matrix L such that A = L L^t
53+
*
54+
* @par
55+
* The destination matrix should be set to 0 before calling the functions because
56+
* the function may not overwrite all output elements.
5357
*/
5458

5559
#if defined(ARM_MATH_NEON) && !defined(ARM_MATH_AUTOVECTORIZE) && defined(__aarch64__)

0 commit comments

Comments
 (0)