diff --git a/code/numpy/vector.c b/code/numpy/vector.c index 3cb1a7b9..3e042b10 100644 --- a/code/numpy/vector.c +++ b/code/numpy/vector.c @@ -87,6 +87,48 @@ static mp_obj_t vector_generic_vector(size_t n_args, const mp_obj_t *pos_args, m uint8_t *sarray = (uint8_t *)source->array; + #if ULAB_VECTORISE_USES_FUN_POINTER + + mp_float_t (*func)(void *) = ndarray_get_float_function(source->dtype); + + #if ULAB_MAX_DIMS > 3 + size_t i = 0; + do { + #endif + #if ULAB_MAX_DIMS > 2 + size_t j = 0; + do { + #endif + #if ULAB_MAX_DIMS > 1 + size_t k = 0; + do { + #endif + size_t l = 0; + do { + mp_float_t value = func(sarray); + *tarray++ = f(value); + sarray += source->strides[ULAB_MAX_DIMS - 1]; + l++; + } while(l < source->shape[ULAB_MAX_DIMS - 1]); + #if ULAB_MAX_DIMS > 1 + sarray -= source->strides[ULAB_MAX_DIMS - 1] * source->shape[ULAB_MAX_DIMS-1]; + sarray += source->strides[ULAB_MAX_DIMS - 2]; + k++; + } while(k < source->shape[ULAB_MAX_DIMS - 2]); + #endif /* ULAB_MAX_DIMS > 1 */ + #if ULAB_MAX_DIMS > 2 + sarray -= source->strides[ULAB_MAX_DIMS - 2] * source->shape[ULAB_MAX_DIMS-2]; + sarray += source->strides[ULAB_MAX_DIMS - 3]; + j++; + } while(j < source->shape[ULAB_MAX_DIMS - 3]); + #endif /* ULAB_MAX_DIMS > 2 */ + #if ULAB_MAX_DIMS > 3 + sarray -= source->strides[ULAB_MAX_DIMS - 3] * source->shape[ULAB_MAX_DIMS-3]; + sarray += source->strides[ULAB_MAX_DIMS - 4]; + i++; + } while(i < source->shape[ULAB_MAX_DIMS - 4]); + #endif /* ULAB_MAX_DIMS > 3 */ + #else if(source->dtype == NDARRAY_UINT8) { ITERATE_VECTOR(uint8_t, target, tarray, tstrides, source, sarray); } else if(source->dtype == NDARRAY_INT8) { @@ -98,6 +140,7 @@ static mp_obj_t vector_generic_vector(size_t n_args, const mp_obj_t *pos_args, m } else { ITERATE_VECTOR(mp_float_t, target, tarray, tstrides, source, sarray); } + #endif /* ULAB_VECTORISE_USES_FUN_POINTER */ } else { target = ndarray_from_mp_obj(o_in, 0); mp_float_t *tarray = (mp_float_t *)target->array; diff --git a/code/numpy/vector.h b/code/numpy/vector.h index ade12a40..2d22af8f 100644 --- a/code/numpy/vector.h +++ b/code/numpy/vector.h @@ -90,22 +90,24 @@ typedef struct _vectorized_function_obj_t { const mp_obj_type_t *type; } vectorized_function_obj_t; + +#if ULAB_MATH_FUNCTIONS_OUT_KEYWORD + #if ULAB_HAS_FUNCTION_ITERATOR -#define ITERATE_VECTOR(type, array, source, sarray, shift)\ +#define ITERATE_VECTOR(type, target, tarray, tstrides, source, sarray)\ ({\ size_t *scoords = ndarray_new_coords((source)->ndim);\ - for(size_t i=0; i < (source)->len/(source)->shape[ULAB_MAX_DIMS -1]; i++) {\ - for(size_t l=0; l < (source)->shape[ULAB_MAX_DIMS - 1]; l++) {\ - *(array) = f(*((type *)(sarray)));\ - (array) += (shift);\ + for(size_t i = 0; i < (source)->len / (source)->shape[ULAB_MAX_DIMS - 1]; i++) {\ + for(size_t l = 0; l < (source)->shape[ULAB_MAX_DIMS - 1]; l++) {\ + *(tarray) = f(*((type *)(sarray)));\ + (tarray) += (tstrides)[ULAB_MAX_DIMS - 1];\ (sarray) += (source)->strides[ULAB_MAX_DIMS - 1];\ }\ ndarray_rewind_array((source)->ndim, sarray, (source)->shape, (source)->strides, scoords);\ }\ }) -#endif /* ULAB_HAS_FUNCTION_ITERATOR */ -#if ULAB_MATH_FUNCTIONS_OUT_KEYWORD +#else #if ULAB_MAX_DIMS == 1 #define ITERATE_VECTOR(type, target, tarray, tstrides, source, sarray) do {\ @@ -202,6 +204,7 @@ typedef struct _vectorized_function_obj_t { } while(i < (source)->shape[ULAB_MAX_DIMS - 4]);\ } while(0) #endif /* ULAB_MAX_DIMS == 4 */ +#endif /* ULAB_HAS_FUNCTION_ITERATOR */ #define MATH_FUN_1(py_name, c_name) \ static mp_obj_t vector_ ## py_name(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { \ @@ -210,6 +213,22 @@ typedef struct _vectorized_function_obj_t { #else /* ULAB_MATH_FUNCTIONS_OUT_KEYWORD */ +#if ULAB_HAS_FUNCTION_ITERATOR +#define ITERATE_VECTOR(type, array, source, sarray, shift)\ +({\ + size_t *scoords = ndarray_new_coords((source)->ndim);\ + for(size_t i=0; i < (source)->len / (source)->shape[ULAB_MAX_DIMS - 1]; i++) {\ + for(size_t l = 0; l < (source)->shape[ULAB_MAX_DIMS - 1]; l++) {\ + *(array) = f(*((type *)(sarray)));\ + (array)++;\ + (sarray) += (source)->strides[ULAB_MAX_DIMS - 1];\ + }\ + ndarray_rewind_array((source)->ndim, sarray, (source)->shape, (source)->strides, scoords);\ + }\ +}) + +#else + #if ULAB_MAX_DIMS == 1 #define ITERATE_VECTOR(type, array, source, sarray) do {\ size_t l = 0;\ @@ -290,6 +309,8 @@ typedef struct _vectorized_function_obj_t { } while(0) #endif /* ULAB_MAX_DIMS == 4 */ +#endif /* ULAB_HAS_FUNCTION_ITERATOR */ + #define MATH_FUN_1(py_name, c_name) \ static mp_obj_t vector_ ## py_name(mp_obj_t x_obj) { \ return vector_generic_vector(x_obj, MICROPY_FLOAT_C_FUN(c_name)); \ diff --git a/code/ulab.c b/code/ulab.c index 5a335b3e..d731aac4 100644 --- a/code/ulab.c +++ b/code/ulab.c @@ -33,7 +33,7 @@ #include "user/user.h" #include "utils/utils.h" -#define ULAB_VERSION 6.3.4 +#define ULAB_VERSION 6.3.5 #define xstr(s) str(s) #define str(s) #s diff --git a/docs/ulab-change-log.md b/docs/ulab-change-log.md index d5993072..9dea370b 100644 --- a/docs/ulab-change-log.md +++ b/docs/ulab-change-log.md @@ -1,3 +1,9 @@ +Sat, 1 Jul 2023 + +version 6.3.5 + + allow function itertor in math functions with the out keyword + Fri, 12 May 2023 version 6.3.4