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
7282mp_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) {
245270static MP_DEFINE_CONST_FUN_OBJ_1 (mod_cnn_output_dimensions_obj , mod_cnn_output_dimensions ) ;
246271
247272
273+ #ifdef MICROPY_ENABLE_DYNRUNTIME // natmod
248274mp_map_elem_t mod_locals_dict_table [3 ];
249275static 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