Skip to content

Commit fa53fc7

Browse files
committed
cnn: Start support for building as extmod
Currently only builds int8 configuration, so tests fail
1 parent 944ee34 commit fa53fc7

5 files changed

Lines changed: 67 additions & 8 deletions

File tree

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ check_unix: $(UNIX_MICROPYTHON)
8181
$(UNIX_MICROPYTHON) tests/test_iir.py
8282
$(UNIX_MICROPYTHON) tests/test_fft.py
8383
$(UNIX_MICROPYTHON) tests/test_arrayutils.py
84+
echo SKIP $(UNIX_MICROPYTHON) tests/test_cnn.py
8485

8586
.PHONY: clean unix
8687

src/tinymaix_cnn/Makefile

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,10 @@ MPY_ABI_VERSION := 6.3
1111

1212
# Location of deps
1313
TINYMAIX_DIR := ../../dependencies/TinyMaix
14+
CONFIG_DIR := ./$(CONFIG)
1415

1516
DIST_DIR := ../../dist/$(ARCH)_$(MPY_ABI_VERSION)
1617

17-
CONFIG_DIR := ./$(CONFIG)
18-
1918
# enable linking of libm etc
2019
LINK_RUNTIME=1
2120

src/tinymaix_cnn/fp32/tm_port.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ limitations under the License.
4848

4949
// Use MicroPython for dynamic allocation
5050
#define tm_malloc(x) m_malloc(x)
51-
#define tm_free(x) m_free(x)
51+
#define tm_free(x) mod_cnn_free(x)
5252

5353
// FIXME: set theese to use MicroPython primitives
5454

src/tinymaix_cnn/int8/tm_port.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ limitations under the License.
4848

4949
// Use MicroPython for dynamic allocation
5050
#define tm_malloc(x) m_malloc(x)
51-
#define tm_free(x) m_free(x)
51+
#define tm_free(x) mod_cnn_free(x)
5252

5353
// FIXME: set theese to use MicroPython primitives
5454

src/tinymaix_cnn/mod_cnn.c

Lines changed: 63 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
// Include the header file to get access to the MicroPython API
2+
#ifdef MICROPY_ENABLE_DYNRUNTIME
23
#include "py/dynruntime.h"
4+
#else
5+
#include "py/runtime.h"
6+
#endif
7+
8+
9+
void mod_cnn_free(void *ptr);
310

411
// TinyMaix config
512
#include "./tm_port.h"
@@ -65,11 +72,27 @@ typedef struct _mp_obj_mod_cnn_t {
6572
tm_mdl_t model;
6673
tm_mat_t input;
6774
uint8_t *model_buffer;
75+
size_t model_buffer_length;
6876
uint8_t *data_buffer;
77+
size_t data_buffer_length;
6978
uint16_t out_dims[4];
7079
} mp_obj_mod_cnn_t;
7180

81+
#if MICROPY_ENABLE_DYNRUNTIME
7282
mp_obj_full_type_t mod_cnn_type;
83+
#else
84+
static const mp_obj_type_t mod_cnn_type;
85+
#endif
86+
87+
88+
void mod_cnn_free(void *ptr)
89+
{
90+
#if MICROPY_ENABLE_DYNRUNTIME
91+
return m_free(ptr);
92+
#else
93+
return m_del(void *, ptr, 0); // XXX: not sure if safe
94+
#endif
95+
}
7396

7497
// TODO: add function for getting the shape of expected input. As a tuple
7598

@@ -95,12 +118,14 @@ static mp_obj_t mod_cnn_new(mp_obj_t model_data_obj) {
95118
tm_mdl_t *model = &o->model;
96119

97120
// Copy the model data
98-
o->model_buffer = m_malloc(model_data_length);
121+
o->model_buffer_length = model_data_length;
122+
o->model_buffer = m_new(uint8_t, o->model_buffer_length);
99123
memcpy(o->model_buffer, model_data_buffer, model_data_length);
100124

101125
// Allocate temporary buffer
102126
// TODO: this can possibly be smaller? Might want to use TinyMaix internal alloc
103-
o->data_buffer = m_malloc(model_data_length);
127+
o->data_buffer_length = model_data_length;
128+
o->data_buffer = m_new(uint8_t, o->data_buffer_length);
104129

105130
// loading model
106131
// will set the dimensions of the input matrix
@@ -139,8 +164,8 @@ static mp_obj_t mod_cnn_del(mp_obj_t self_obj) {
139164
mp_obj_mod_cnn_t *o = MP_OBJ_TO_PTR(self_obj);
140165
tm_mdl_t *model = &o->model;
141166

142-
m_free(o->model_buffer);
143-
m_free(o->data_buffer);
167+
m_del(uint8_t, o->model_buffer, o->model_buffer_length);
168+
m_del(uint8_t, o->data_buffer, o->data_buffer_length);
144169
tm_unload(model);
145170

146171
return mp_const_none;
@@ -245,6 +270,7 @@ static mp_obj_t mod_cnn_output_dimensions(mp_obj_t self_obj) {
245270
static MP_DEFINE_CONST_FUN_OBJ_1(mod_cnn_output_dimensions_obj, mod_cnn_output_dimensions);
246271

247272

273+
#ifdef MICROPY_ENABLE_DYNRUNTIME // natmod
248274
mp_map_elem_t mod_locals_dict_table[3];
249275
static MP_DEFINE_CONST_DICT(mod_locals_dict, mod_locals_dict_table);
250276

@@ -268,4 +294,37 @@ mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *a
268294
// This must be last, it restores the globals dict
269295
MP_DYNRUNTIME_INIT_EXIT
270296
}
297+
#else // extmod
298+
299+
// Define a class
300+
static const mp_rom_map_elem_t mod_cnn_locals_dict_table[] = {
301+
{ MP_ROM_QSTR(MP_QSTR_run), MP_ROM_PTR(&mod_cnn_run_obj) },
302+
{ MP_ROM_QSTR(MP_QSTR_output_dimensions), MP_ROM_PTR(&mod_cnn_del_obj) },
303+
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mod_cnn_output_dimensions_obj) }
304+
};
305+
static MP_DEFINE_CONST_DICT(mod_cnn_locals_dict, mod_cnn_locals_dict_table);
306+
307+
308+
static MP_DEFINE_CONST_OBJ_TYPE(
309+
mod_cnn_type,
310+
MP_QSTR_tinymaix_cnn,
311+
MP_TYPE_FLAG_NONE,
312+
locals_dict, &mod_cnn_locals_dict
313+
);
314+
315+
// Define module object.
316+
static const mp_rom_map_elem_t mod_cnn_globals_table[] = {
317+
{ MP_ROM_QSTR(MP_QSTR_new), MP_ROM_PTR(&mod_cnn_new_obj) }
318+
};
319+
static MP_DEFINE_CONST_DICT(mod_cnn_globals, mod_cnn_globals_table);
320+
321+
const mp_obj_module_t mod_cnn_cmodule = {
322+
.base = { &mp_type_module },
323+
.globals = (mp_obj_dict_t *)&mod_cnn_globals,
324+
};
325+
326+
// FIXME: unhardcode config part of module name
327+
MP_REGISTER_MODULE(MP_QSTR_emlearn_cnn_int8, mod_cnn_cmodule);
328+
#endif
329+
271330

0 commit comments

Comments
 (0)