Skip to content

Commit 8cf600d

Browse files
committed
iir: Q15 matches on a simple high pass filter
1 parent 8a2dfb2 commit 8cf600d

File tree

5 files changed

+161
-71
lines changed

5 files changed

+161
-71
lines changed

benchmarks/iir/SimpleFilters.ipynb

Lines changed: 130 additions & 54 deletions
Large diffs are not rendered by default.

benchmarks/iir/iir_run.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,28 @@
11

2+
import os
23
import sys
4+
35
import npyfile
46

7+
ST_SIZE = 6
8+
59
def iir_process_file(inp, out, filters, chunksize):
610

711
coefficients_shape, coefficients = npyfile.load(filters)
812
print('c', coefficients_shape, coefficients)
13+
914

1015
# NOTE: filter shape and type checked by the C modules
1116

1217
# Processing is done by streaming, to keep RAM usage low
1318
with npyfile.Reader(inp) as reader:
1419

1520
# Check inputs and setup filters
16-
print('r', reader.shape, reader.typecode, reader.itemsize)
21+
print('r', inp, os.stat(inp)[ST_SIZE], reader.shape, reader.typecode, reader.itemsize)
22+
23+
#if reader.typecode == 'i':
24+
# reader.typecode = 'h'
25+
# coefficients = array.array('h', coefficients)
1726

1827
if len(reader.shape) != 1:
1928
raise ValueError("Input must be 1d")
@@ -26,18 +35,13 @@ def iir_process_file(inp, out, filters, chunksize):
2635
else:
2736
raise ValueError("Input must either be float32/f or int16/h")
2837

29-
30-
with npyfile.Writer(inp, reader.shape, reader.typecode) as writer:
38+
with npyfile.Writer(out, reader.shape, reader.typecode) as writer:
3139

3240
# Apply filters
3341
for chunk in reader.read_data_chunks(chunksize):
34-
print(len(chunk))
35-
3642
filter.run(chunk) # operates in-place
37-
3843
writer.write_values(chunk)
3944

40-
4145
def main():
4246

4347
args = sys.argv

benchmarks/iir/iir_run_subprocess.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ def run_iir(data : array.array,
1919

2020
with tempfile.TemporaryDirectory() as temp_dir:
2121

22+
#temp_dir = 'temp'
23+
#os.makedirs(temp_dir)
24+
2225
filter_path = os.path.join(temp_dir, 'filter.npy')
2326
input_path = os.path.join(temp_dir, 'input.npy')
2427
output_path = os.path.join(temp_dir, 'output.npy')
@@ -27,6 +30,8 @@ def run_iir(data : array.array,
2730
npyfile.save(filter_path, coefficients)
2831
npyfile.save(input_path, data)
2932

33+
input_size = os.stat(input_path).st_size
34+
3035
assert not os.path.exists(output_path), output_path
3136

3237
# run the processing function
@@ -40,9 +45,14 @@ def run_iir(data : array.array,
4045
cmd = ' '.join(args)
4146

4247
print('run: ', cmd)
43-
44-
out = subprocess.check_output(args)
45-
print(out)
48+
try:
49+
out = subprocess.check_output(args)
50+
except subprocess.CalledProcessError as e:
51+
out = e.stdout
52+
53+
print('out')
54+
for line in out.decode('utf-8').split('\n'):
55+
print(line)
4656

4757
# load the output
4858
assert os.path.exists(output_path), output_path

doc/TODO.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
- Level 0a. Run a pretrained example/demo in the browser
66
- Level 0b. Run a pretrained example/demo on a board
7-
- Level 1. Train on-device
7+
- Level 1. Train custom model on-device
88
- Level 2. Collect a dataset, do training on PC, deploy back to microcontroller
99
- Level 3. Bake the custom model into the firmware
1010

@@ -49,7 +49,7 @@ Examples
4949
Benchmarks
5050

5151
- Add FLASH and RAM usage
52-
- Test gzip compression of .csv model
52+
- Test gzip compression of .csv model for trees
5353
- Add a couple of different sized models to benchmark?
5454
- Add another application/dataset for benchmark
5555

src/eml_iir_q15/iir_filter.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ static mp_obj_t iir_filter_new(mp_obj_t array_obj) {
4747
// Extract buffer pointer and verify typecode
4848
mp_buffer_info_t bufinfo;
4949
mp_get_buffer_raise(array_obj, &bufinfo, MP_BUFFER_RW);
50-
if (bufinfo.typecode != 'i') {
51-
mp_raise_ValueError(MP_ERROR_TEXT("expecting int16/i array"));
50+
if (bufinfo.typecode != 'h') {
51+
mp_raise_ValueError(MP_ERROR_TEXT("expecting int16/h array"));
5252
}
5353
q15_t *values = bufinfo.buf;
5454
const int n_values = bufinfo.len / sizeof(*values);
@@ -57,7 +57,7 @@ static mp_obj_t iir_filter_new(mp_obj_t array_obj) {
5757
mp_raise_ValueError(MP_ERROR_TEXT("Filter coefficients must be multiple of 6"));
5858
}
5959

60-
const int post_shift = 1; // FIXME: allow to pass as argument
60+
const int post_shift = 2; // FIXME: allow to pass as argument
6161

6262
// Construct object
6363
mp_obj_iir_filter_t *o = mp_obj_malloc(mp_obj_iir_filter_t, (mp_obj_type_t *)&iir_filter_type);
@@ -103,8 +103,8 @@ static mp_obj_t iir_filter_run(mp_obj_t self_obj, mp_obj_t array_obj) {
103103
// Extract buffer pointer and verify typecode
104104
mp_buffer_info_t bufinfo;
105105
mp_get_buffer_raise(array_obj, &bufinfo, MP_BUFFER_RW);
106-
if (bufinfo.typecode != 'i') {
107-
mp_raise_ValueError(MP_ERROR_TEXT("expecting int16/i array"));
106+
if (bufinfo.typecode != 'h') {
107+
mp_raise_ValueError(MP_ERROR_TEXT("expecting int16/h array"));
108108
}
109109
q15_t *values = bufinfo.buf;
110110
const int n_values = bufinfo.len / sizeof(*values);

0 commit comments

Comments
 (0)