Skip to content

Commit 3ebc686

Browse files
Updates to Python wrapper
Python 3.12 support Bug corrections Remove dependencies to compute graph (now is CMSIS-Stream on another repository).
2 parents 5f5086f + b8db1e4 commit 3ebc686

File tree

16 files changed

+146
-138
lines changed

16 files changed

+146
-138
lines changed

MANIFEST.in

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,5 @@ include PythonWrapper_README.md
22
recursive-include Include *.h
33
recursive-include PrivateInclude *.h
44
recursive-include PythonWrapper/cmsisdsp_pkg/src *.h
5-
include cmsisdsp/cg/scheduler/templates/*
65
include Source/DistanceFunctions/arm_boolean_distance_template.h
76

PythonWrapper/build_linux/create.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ cmake -DHOST=YES \
22
-DLOOPUNROLL=ON \
33
-DWRAPPER=YES \
44
-DCMAKE_POSITION_INDEPENDENT_CODE=YES \
5-
-DCMSISDSP="path to CMSIS-DSP folder" \
5+
-DCMSISDSP=".." \
66
-DCMAKE_C_FLAGS_RELEASE="-std=c11 -Ofast -ffast-math -DNDEBUG -Wall -Wextra" \
77
-DCMAKE_CXX_FLAGS_RELEASE="-fno-rtti -std=c++11 -Ofast -ffast-math -DNDEBUG -Wall -Wextra -Wno-unused-parameter" \
88
-G "Unix Makefiles" ..
99

1010
# For Mac universal lib
11-
# -arch x86_64 -arch arm64 -mmacosx-version-min=11.0
11+
# -arch x86_64 -arch arm64 -mmacosx-version-min=11.0

PythonWrapper/cmsisdsp_pkg/src/cmsisdsp_distance.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ cmsis_arm_dtw_init_window_q7(PyObject *obj,
227227
arm_matrix_instance_q7 pSrc_converted; // input
228228

229229

230-
if (PyArg_ParseTuple(args,"iiO",&winType,&winSize,&pSrc));
230+
if (PyArg_ParseTuple(args,"iiO",&winType,&winSize,&pSrc))
231231
{
232232

233233
q7MatrixFromNumpy(&pSrc_converted,pSrc);
@@ -267,7 +267,7 @@ cmsis_arm_dtw_distance_f32(PyObject *obj,
267267
arm_matrix_instance_f32 dtw_converted;
268268

269269

270-
if (PyArg_ParseTuple(args,"OO",&pDist,&pWin));
270+
if (PyArg_ParseTuple(args,"OO",&pDist,&pWin))
271271
{
272272

273273
f32MatrixFromNumpy(&pDist_converted,pDist);
@@ -348,7 +348,7 @@ cmsis_arm_dtw_path_f32(PyObject *obj,
348348
Py_DECREF(pDstOBJ);
349349
return(pythonResult);
350350
}
351-
351+
Py_RETURN_NONE;
352352
}
353353

354354
static PyMethodDef CMSISDSPMethods[] = {
@@ -450,4 +450,4 @@ void CAT(init,MODINITNAME)(void)
450450
#ifdef IS_PY3K
451451
return module;
452452
#endif
453-
}
453+
}

PythonWrapper/cmsisdsp_pkg/src/cmsisdsp_module.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@
3232
#include <numpy/numpyconfig.h>
3333

3434
// API version used on google colab
35-
// List on https://github.com/numpy/numpy/blob/main/numpy/core/include/numpy/numpyconfig.h
35+
// https://github.com/numpy/numpy/blob/main/numpy/_core/include/numpy/numpyconfig.h
3636
#if (NPY_API_VERSION != 0x0000000F )
37-
#error("Error building with wrong NumPy API version")
37+
//#error("Error building with wrong NumPy API version")
3838
#endif
3939

4040
#ifdef WIN

PythonWrapper/cmsisdsp_pkg/src/cmsisdsp_window.c

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ cmsis_arm_welch_f64(PyObject *obj, PyObject *args)
7272
{
7373

7474

75-
float32_t *pDst=NULL; // output
75+
float64_t *pDst=NULL; // output
7676
int nb; // input
7777

7878
if (PyArg_ParseTuple(args,"i",&nb))
@@ -125,7 +125,7 @@ cmsis_arm_bartlett_f64(PyObject *obj, PyObject *args)
125125
{
126126

127127

128-
float32_t *pDst=NULL; // output
128+
float64_t *pDst=NULL; // output
129129
int nb; // input
130130

131131
if (PyArg_ParseTuple(args,"i",&nb))
@@ -178,7 +178,7 @@ cmsis_arm_hamming_f64(PyObject *obj, PyObject *args)
178178
{
179179

180180

181-
float32_t *pDst=NULL; // output
181+
float64_t *pDst=NULL; // output
182182
int nb; // input
183183

184184
if (PyArg_ParseTuple(args,"i",&nb))
@@ -231,7 +231,7 @@ cmsis_arm_hanning_f64(PyObject *obj, PyObject *args)
231231
{
232232

233233

234-
float32_t *pDst=NULL; // output
234+
float64_t *pDst=NULL; // output
235235
int nb; // input
236236

237237
if (PyArg_ParseTuple(args,"i",&nb))
@@ -284,7 +284,7 @@ cmsis_arm_nuttall3_f64(PyObject *obj, PyObject *args)
284284
{
285285

286286

287-
float32_t *pDst=NULL; // output
287+
float64_t *pDst=NULL; // output
288288
int nb; // input
289289

290290
if (PyArg_ParseTuple(args,"i",&nb))
@@ -337,7 +337,7 @@ cmsis_arm_nuttall4_f64(PyObject *obj, PyObject *args)
337337
{
338338

339339

340-
float32_t *pDst=NULL; // output
340+
float64_t *pDst=NULL; // output
341341
int nb; // input
342342

343343
if (PyArg_ParseTuple(args,"i",&nb))
@@ -390,7 +390,7 @@ cmsis_arm_nuttall3a_f64(PyObject *obj, PyObject *args)
390390
{
391391

392392

393-
float32_t *pDst=NULL; // output
393+
float64_t *pDst=NULL; // output
394394
int nb; // input
395395

396396
if (PyArg_ParseTuple(args,"i",&nb))
@@ -443,7 +443,7 @@ cmsis_arm_nuttall3b_f64(PyObject *obj, PyObject *args)
443443
{
444444

445445

446-
float32_t *pDst=NULL; // output
446+
float64_t *pDst=NULL; // output
447447
int nb; // input
448448

449449
if (PyArg_ParseTuple(args,"i",&nb))
@@ -496,7 +496,7 @@ cmsis_arm_nuttall4a_f64(PyObject *obj, PyObject *args)
496496
{
497497

498498

499-
float32_t *pDst=NULL; // output
499+
float64_t *pDst=NULL; // output
500500
int nb; // input
501501

502502
if (PyArg_ParseTuple(args,"i",&nb))
@@ -549,7 +549,7 @@ cmsis_arm_blackman_harris_92db_f64(PyObject *obj, PyObject *args)
549549
{
550550

551551

552-
float32_t *pDst=NULL; // output
552+
float64_t *pDst=NULL; // output
553553
int nb; // input
554554

555555
if (PyArg_ParseTuple(args,"i",&nb))
@@ -602,7 +602,7 @@ cmsis_arm_nuttall4b_f64(PyObject *obj, PyObject *args)
602602
{
603603

604604

605-
float32_t *pDst=NULL; // output
605+
float64_t *pDst=NULL; // output
606606
int nb; // input
607607

608608
if (PyArg_ParseTuple(args,"i",&nb))
@@ -655,7 +655,7 @@ cmsis_arm_nuttall4c_f64(PyObject *obj, PyObject *args)
655655
{
656656

657657

658-
float32_t *pDst=NULL; // output
658+
float64_t *pDst=NULL; // output
659659
int nb; // input
660660

661661
if (PyArg_ParseTuple(args,"i",&nb))
@@ -708,7 +708,7 @@ cmsis_arm_hft90d_f64(PyObject *obj, PyObject *args)
708708
{
709709

710710

711-
float32_t *pDst=NULL; // output
711+
float64_t *pDst=NULL; // output
712712
int nb; // input
713713

714714
if (PyArg_ParseTuple(args,"i",&nb))
@@ -761,7 +761,7 @@ cmsis_arm_hft95_f64(PyObject *obj, PyObject *args)
761761
{
762762

763763

764-
float32_t *pDst=NULL; // output
764+
float64_t *pDst=NULL; // output
765765
int nb; // input
766766

767767
if (PyArg_ParseTuple(args,"i",&nb))
@@ -814,7 +814,7 @@ cmsis_arm_hft116d_f64(PyObject *obj, PyObject *args)
814814
{
815815

816816

817-
float32_t *pDst=NULL; // output
817+
float64_t *pDst=NULL; // output
818818
int nb; // input
819819

820820
if (PyArg_ParseTuple(args,"i",&nb))
@@ -867,7 +867,7 @@ cmsis_arm_hft144d_f64(PyObject *obj, PyObject *args)
867867
{
868868

869869

870-
float32_t *pDst=NULL; // output
870+
float64_t *pDst=NULL; // output
871871
int nb; // input
872872

873873
if (PyArg_ParseTuple(args,"i",&nb))
@@ -920,7 +920,7 @@ cmsis_arm_hft169d_f64(PyObject *obj, PyObject *args)
920920
{
921921

922922

923-
float32_t *pDst=NULL; // output
923+
float64_t *pDst=NULL; // output
924924
int nb; // input
925925

926926
if (PyArg_ParseTuple(args,"i",&nb))
@@ -973,7 +973,7 @@ cmsis_arm_hft196d_f64(PyObject *obj, PyObject *args)
973973
{
974974

975975

976-
float32_t *pDst=NULL; // output
976+
float64_t *pDst=NULL; // output
977977
int nb; // input
978978

979979
if (PyArg_ParseTuple(args,"i",&nb))
@@ -1026,7 +1026,7 @@ cmsis_arm_hft223d_f64(PyObject *obj, PyObject *args)
10261026
{
10271027

10281028

1029-
float32_t *pDst=NULL; // output
1029+
float64_t *pDst=NULL; // output
10301030
int nb; // input
10311031

10321032
if (PyArg_ParseTuple(args,"i",&nb))
@@ -1079,7 +1079,7 @@ cmsis_arm_hft248d_f64(PyObject *obj, PyObject *args)
10791079
{
10801080

10811081

1082-
float32_t *pDst=NULL; // output
1082+
float64_t *pDst=NULL; // output
10831083
int nb; // input
10841084

10851085
if (PyArg_ParseTuple(args,"i",&nb))

PythonWrapper/examples/debug.py

Lines changed: 53 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import colorama
1010
from colorama import init,Fore, Back, Style
1111
from numpy.testing import assert_allclose
12+
import scipy.spatial.distance as d
1213

1314
init()
1415

@@ -19,63 +20,61 @@ def printSubTitle(s):
1920
print("\n" + Style.BRIGHT + s + Style.RESET_ALL)
2021

2122

22-
def chop(A, eps = 1e-6):
23-
B = np.copy(A)
24-
B[np.abs(A) < eps] = 0
25-
return B
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)
2640

27-
nb = 32
28-
signal = np.cos(2 * np.pi * np.arange(nb) / nb)*np.cos(0.2*2 * np.pi * np.arange(nb) / nb)
41+
nb = 34
42+
#va = np.random.choice([0,1],nb)
43+
# Array of word32 containing all of our bits
44+
#pva = packset(va)
2945

30-
ref=scipy.fft.rfft(signal)
31-
invref = scipy.fft.irfft(ref)
3246

33-
print(f"ref length = {len(ref)}")
34-
print(ref)
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)
56+
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)
3571

36-
# Convert ref to CMSIS-DSP format
37-
referenceFloat=np.zeros(2*len(ref))
38-
print(f"referenceFloat length = {len(referenceFloat)}")
39-
# Replace complex datatype by real datatype
40-
referenceFloat[0::2] = np.real(ref)
41-
referenceFloat[1::2] = np.imag(ref)
42-
# Copy Nyquist frequency value into first
43-
# sample.This is just a storage trick so that the
44-
# output of the RFFT has same length as input
45-
# It is legacy behavior that we need to keep
46-
# for backward compatibility but it is not
47-
# very pretty
48-
#referenceFloat[1] = np.real(ref[-1])
49-
50-
rifftQ31=dsp.arm_rfft_instance_q31()
51-
status=dsp.arm_rfft_init_q31(rifftQ31,nb,1,1)
52-
# Apply CMSIS-DSP scaling
53-
referenceQ31 = f.toQ31(referenceFloat / nb)
54-
55-
resultQ31 = dsp.arm_rfft_q31(rifftQ31,referenceQ31)
56-
resultF = f.Q31toF32(resultQ31)
57-
58-
print(f"resultF length = {len(resultF)}")
59-
assert_allclose(invref/nb,resultF,atol=1e-6)
60-
61-
signalQ31 = f.toQ31(signal)
62-
rfftQ31=dsp.arm_rfft_instance_q31()
63-
status=dsp.arm_rfft_init_q31(rfftQ31,nb,0,1)
64-
resultQ31 = dsp.arm_rfft_q31(rfftQ31,signalQ31)
65-
print(len(resultQ31))
66-
print(2*nb)
67-
resultF = f.Q31toF32(resultQ31) * nb
68-
69-
def compareWithConjugatePart(r):
70-
res = r[0::2] + 1j * r[1::2]
71-
conjPart = res[nb:nb//2:-1].conj()
72-
refPart = res[1:nb//2]
73-
assert(np.equal(refPart , conjPart).all())
74-
75-
compareWithConjugatePart(resultF)
76-
77-
res = resultF[0::2] + 1j * resultF[1::2]
7872
print(res)
7973

80-
print(res[0:nb//2+1])
81-
print(res[0:nb//2+1].shape)
74+
75+
print("\nDice")
76+
ref=d.dice(va,vb)
77+
res=dsp.arm_dice_distance(pva,pvb,nb)
78+
print(ref)
79+
print(res)
80+
assert_allclose(ref,res,1e-6)

0 commit comments

Comments
 (0)