diff --git a/code/ndarray.c b/code/ndarray.c index aee39e5..e592068 100644 --- a/code/ndarray.c +++ b/code/ndarray.c @@ -1981,9 +1981,3 @@ mp_obj_t ndarray_info(mp_obj_t obj_in) { MP_DEFINE_CONST_FUN_OBJ_1(ndarray_info_obj, ndarray_info); #endif - -mp_int_t ndarray_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) { - ndarray_obj_t *self = MP_OBJ_TO_PTR(self_in); - // buffer_p.get_buffer() returns zero for success, while mp_get_buffer returns true for success - return !mp_get_buffer(self->array, bufinfo, flags); -} diff --git a/code/ndarray.h b/code/ndarray.h index d56fa8f..ba24908 100644 --- a/code/ndarray.h +++ b/code/ndarray.h @@ -190,7 +190,6 @@ mp_obj_t ndarray_info(mp_obj_t ); MP_DECLARE_CONST_FUN_OBJ_1(ndarray_info_obj); #endif -mp_int_t ndarray_get_buffer(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_uint_t flags); //void ndarray_attributes(mp_obj_t , qstr , mp_obj_t *); ndarray_obj_t *ndarray_from_mp_obj(mp_obj_t ); diff --git a/code/numpy/numpy.c b/code/numpy/numpy.c index 6790f73..4ee6842 100644 --- a/code/numpy/numpy.c +++ b/code/numpy/numpy.c @@ -13,6 +13,7 @@ */ #include +#include #include "py/runtime.h" #include "numpy.h" @@ -43,9 +44,57 @@ mp_obj_float_t numpy_const_float_nan_obj = {{&mp_type_float}, NAN}; mp_obj_float_t ulab_const_float_pi_obj = {{&mp_type_float}, MP_PI}; #endif +#if ULAB_NUMPY_HAS_FROMBUFFER +static mp_obj_t numpy_frombuffer(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + static const mp_arg_t allowed_args[] = { + { MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, { .u_rom_obj = mp_const_none } }, + { MP_QSTR_dtype, MP_ARG_KW_ONLY | MP_ARG_OBJ, { .u_rom_obj = MP_ROM_INT(NDARRAY_FLOAT) } }, + { MP_QSTR_count, MP_ARG_KW_ONLY | MP_ARG_OBJ, { .u_rom_obj = MP_ROM_INT(-1) } }, + { MP_QSTR_offset, MP_ARG_KW_ONLY | MP_ARG_OBJ, { .u_rom_obj = MP_ROM_INT(0) } }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + uint8_t dtype = mp_obj_get_int(args[1].u_obj); + uint8_t _dtype = dtype == NDARRAY_BOOL ? NDARRAY_UINT8 : dtype; + size_t offset = mp_obj_get_int(args[3].u_obj); + mp_buffer_info_t bufinfo; + if(mp_get_buffer(args[0].u_obj, &bufinfo, MP_BUFFER_READ)) { + size_t sz = mp_binary_get_size('@', _dtype, NULL); + // TODO add offset here + if(bufinfo.len < offset) { + mp_raise_ValueError(translate("offset must be non-negative and no greater than buffer length")); + } + size_t len = (bufinfo.len - offset) / sz; + if((len * sz) != (bufinfo.len - offset)) { + mp_raise_ValueError(translate("buffer size must be a multiple of element size")); + } + if(mp_obj_get_int(args[2].u_obj) > 0) { + size_t count = mp_obj_get_int(args[2].u_obj); + if(len < count) { + mp_raise_ValueError(translate("buffer is smaller than requested size")); + } else { + len -= count; + } + } + ndarray_obj_t *ndarray = ndarray_new_linear_array(len, dtype); + uint8_t *buffer = bufinfo.buf; + memcpy(ndarray->array, buffer + offset, len * sz); + return MP_OBJ_FROM_PTR(ndarray); + } + return mp_const_none; +} + +MP_DEFINE_CONST_FUN_OBJ_KW(numpy_frombuffer_obj, 1, numpy_frombuffer); +#endif + static const mp_rom_map_elem_t ulab_numpy_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_numpy) }, { MP_OBJ_NEW_QSTR(MP_QSTR_array), (mp_obj_t)&ulab_ndarray_type }, + #if ULAB_NUMPY_HAS_FROMBUFFER + { MP_ROM_QSTR(MP_QSTR_frombuffer), MP_ROM_PTR(&numpy_frombuffer_obj) }, + #endif + // math constants #if ULAB_NUMPY_HAS_E { MP_ROM_QSTR(MP_QSTR_e), MP_ROM_PTR(&ulab_const_float_e_obj) }, diff --git a/code/scipy/optimize/optimize.c b/code/scipy/optimize/optimize.c index d871c47..9680eb1 100644 --- a/code/scipy/optimize/optimize.c +++ b/code/scipy/optimize/optimize.c @@ -348,16 +348,16 @@ MP_DEFINE_CONST_FUN_OBJ_KW(optimize_curve_fit_obj, 2, optimize_curve_fit); //| ... //| -STATIC mp_obj_t optimize_newton(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { +static mp_obj_t optimize_newton(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { // this is actually the secant method, as the first derivative of the function // is not accepted as an argument. The function whose root we want to solve for // must depend on a single variable without parameters, i.e., f(x) static const mp_arg_t allowed_args[] = { - { MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_rom_obj = mp_const_none } }, - { MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_rom_obj = mp_const_none } }, - { MP_QSTR_tol, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_PTR(&xtolerance)} }, - { MP_QSTR_rtol, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_PTR(&rtolerance)} }, - { MP_QSTR_maxiter, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 50} }, + { MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, { .u_rom_obj = mp_const_none } }, + { MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, { .u_rom_obj = mp_const_none } }, + { MP_QSTR_tol, MP_ARG_KW_ONLY | MP_ARG_OBJ, { .u_rom_obj = MP_ROM_PTR(&xtolerance) } }, + { MP_QSTR_rtol, MP_ARG_KW_ONLY | MP_ARG_OBJ, { .u_rom_obj = MP_ROM_PTR(&rtolerance) } }, + { MP_QSTR_maxiter, MP_ARG_KW_ONLY | MP_ARG_INT, { .u_int = 50 } }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; diff --git a/code/ulab.c b/code/ulab.c index eb177fb..274dc8b 100644 --- a/code/ulab.c +++ b/code/ulab.c @@ -34,7 +34,7 @@ #include "user/user.h" #include "vector/vectorise.h" -#define ULAB_VERSION 2.0.0 +#define ULAB_VERSION 2.1.0 #define xstr(s) str(s) #define str(s) #s #if ULAB_NUMPY_COMPATIBILITY @@ -107,7 +107,6 @@ const mp_obj_type_t ulab_ndarray_type = { #if NDARRAY_HAS_BINARY_OPS .binary_op = ndarray_binary_op, #endif - .buffer_p = { .get_buffer = ndarray_get_buffer, }, .locals_dict = (mp_obj_dict_t*)&ulab_ndarray_locals_dict, }; diff --git a/code/ulab.h b/code/ulab.h index b35b456..91e2ec3 100644 --- a/code/ulab.h +++ b/code/ulab.h @@ -137,6 +137,9 @@ // determines, whether the ndinfo function is available #define ULAB_NUMPY_HAS_NDINFO (1) +// frombuffer adds 600 bytes to the firmware +#define ULAB_NUMPY_HAS_FROMBUFFER (1) + // functions that create an array #define ULAB_NUMPY_HAS_ARANGE (1) #define ULAB_NUMPY_HAS_CONCATENATE (1) diff --git a/docs/ulab-change-log.md b/docs/ulab-change-log.md index 1653b0f..cf8bb8e 100644 --- a/docs/ulab-change-log.md +++ b/docs/ulab-change-log.md @@ -1,3 +1,9 @@ +Thu, 26 Nov 2020 + +version 2.1.0 + + implemented frombuffer + Tue, 24 Nov 2020 version 2.0.0