Skip to content

Commit

Permalink
Merge pull request #408 from v923z/attr-prop
Browse files Browse the repository at this point in the history
implement ndarray properties
  • Loading branch information
jepler authored Jun 10, 2021
2 parents 2309320 + cd3d479 commit 161a728
Show file tree
Hide file tree
Showing 32 changed files with 197 additions and 481 deletions.
2 changes: 1 addition & 1 deletion build-cp.sh
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ make -C circuitpython/mpy-cross -j$NPROC
sed -e '/MICROPY_PY_UHASHLIB/s/1/0/' < circuitpython/ports/unix/mpconfigport.h > circuitpython/ports/unix/mpconfigport_ulab.h
make -k -C circuitpython/ports/unix -j$NPROC DEBUG=1 MICROPY_PY_FFI=0 MICROPY_PY_BTREE=0 MICROPY_SSL_AXTLS=0 MICROPY_PY_USSL=0 CFLAGS_EXTRA='-DMP_CONFIGFILE="<mpconfigport_ulab.h>" -Wno-tautological-constant-out-of-range-compare -Wno-unknown-pragmas'

for dir in "circuitpy" "common"
for dir in "numpy" "scipy" "utils"
do
if ! env MICROPY_MICROPYTHON=circuitpython/ports/unix/micropython ./run-tests -d tests/"$dir"; then
for exp in *.exp; do
Expand Down
2 changes: 1 addition & 1 deletion build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ make -C micropython/ports/unix -j${NPROC} axtls
make -C micropython/ports/unix -j${NPROC} USER_C_MODULES="${HERE}" DEBUG=1 STRIP=: MICROPY_PY_FFI=0 MICROPY_PY_BTREE=0


for dir in "numpy" "scipy" "common" "utils"
for dir in "numpy" "scipy" "utils"
do
if ! env MICROPY_MICROPYTHON=micropython/ports/unix/micropython ./run-tests -d tests/"$dir"; then
for exp in *.exp; do
Expand Down
1 change: 1 addition & 0 deletions code/micropython.mk
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ SRC_USERMOD += $(USERMODULES_DIR)/scipy/special/special.c
SRC_USERMOD += $(USERMODULES_DIR)/ndarray_operators.c
SRC_USERMOD += $(USERMODULES_DIR)/ulab_tools.c
SRC_USERMOD += $(USERMODULES_DIR)/ndarray.c
SRC_USERMOD += $(USERMODULES_DIR)/ndarray_properties.c
SRC_USERMOD += $(USERMODULES_DIR)/numpy/approx/approx.c
SRC_USERMOD += $(USERMODULES_DIR)/numpy/compare/compare.c
SRC_USERMOD += $(USERMODULES_DIR)/ulab_create.c
Expand Down
30 changes: 27 additions & 3 deletions code/ndarray.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "py/binary.h"
#include "py/obj.h"
#include "py/objtuple.h"
#include "py/objint.h"

#include "ulab_tools.h"
#include "ndarray.h"
Expand Down Expand Up @@ -233,6 +234,29 @@ mp_uint_t ndarray_print_edgeitems = NDARRAY_PRINT_EDGEITEMS;
//| """alternate constructor function for `ulab.ndarray`. Mirrors numpy.array"""
//| ...


#ifdef CIRCUITPY
void ndarray_set_value(char typecode, void *p, size_t index, mp_obj_t val_in) {
switch (typecode) {
case NDARRAY_INT8:
((signed char *)p)[index] = mp_obj_get_int(val_in);
break;
case NDARRAY_UINT8:
((unsigned char *)p)[index] = mp_obj_get_int(val_in);
break;
case NDARRAY_INT16:
((short *)p)[index] = mp_obj_get_int(val_in);
break;
case NDARRAY_UINT16:
((unsigned short *)p)[index] = mp_obj_get_int(val_in);
break;
case NDARRAY_FLOAT:
((mp_float_t *)p)[index] = mp_obj_get_float(val_in);
break;
}
}
#endif

#if defined(MICROPY_VERSION_MAJOR) && MICROPY_VERSION_MAJOR == 1 && MICROPY_VERSION_MINOR == 11

void mp_obj_slice_indices(mp_obj_t self_in, mp_int_t length, mp_bound_slice_t *result) {
Expand Down Expand Up @@ -653,7 +677,7 @@ void ndarray_assign_elements(ndarray_obj_t *ndarray, mp_obj_t iterable, uint8_t
}
} else {
while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
mp_binary_set_val_array(dtype, ndarray->array, (*idx)++, item);
ndarray_set_value(dtype, ndarray->array, (*idx)++, item);
}
}
}
Expand Down Expand Up @@ -1050,7 +1074,7 @@ STATIC mp_obj_t ndarray_make_new_core(const mp_obj_type_t *type, size_t n_args,
} else {
item = mp_binary_get_val_array(source->dtype, sarray, 0);
}
mp_binary_set_val_array(dtype, tarray, 0, item);
ndarray_set_value(dtype, tarray, 0, item);
tarray += target->itemsize;
sarray += source->strides[ULAB_MAX_DIMS - 1];
l++;
Expand Down Expand Up @@ -1734,7 +1758,7 @@ ndarray_obj_t *ndarray_from_mp_obj(mp_obj_t obj, uint8_t other_type) {
}
}
ndarray = ndarray_new_linear_array(1, dtype);
mp_binary_set_val_array(dtype, ndarray->array, 0, obj);
ndarray_set_value(dtype, ndarray->array, 0, obj);
}
} else if(mp_obj_is_float(obj)) {
ndarray = ndarray_new_linear_array(1, NDARRAY_FLOAT);
Expand Down
3 changes: 3 additions & 0 deletions code/ndarray.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ typedef struct _mp_obj_slice_t {

#if !CIRCUITPY
#define translate(x) MP_ERROR_TEXT(x)
#define ndarray_set_value(a, b, c, d) mp_binary_set_val_array(a, b, c, d)
#else
void ndarray_set_value(char , void *, size_t , mp_obj_t );
#endif

#define NDARRAY_NUMERIC 0
Expand Down
83 changes: 83 additions & 0 deletions code/ndarray_properties.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@

/*
* This file is part of the micropython-ulab project,
*
* https://github.com/v923z/micropython-ulab
*
* The MIT License (MIT)
*
* Copyright (c) 2021 Zoltán Vörös
*
*/

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "py/obj.h"
#include "py/runtime.h"

#include "ulab.h"
#include "ndarray.h"

#ifndef CIRCUITPY

// a somewhat hackish implementation of property getters/setters;
// this functions is hooked into the attr member of ndarray

STATIC void call_local_method(mp_obj_t obj, qstr attr, mp_obj_t *dest) {
const mp_obj_type_t *type = mp_obj_get_type(obj);
while (type->locals_dict != NULL) {
assert(type->locals_dict->base.type == &mp_type_dict); // MicroPython restriction, for now
mp_map_t *locals_map = &type->locals_dict->map;
mp_map_elem_t *elem = mp_map_lookup(locals_map, MP_OBJ_NEW_QSTR(attr), MP_MAP_LOOKUP);
if (elem != NULL) {
mp_convert_member_lookup(obj, type, elem->value, dest);
break;
}
if (type->parent == NULL) {
break;
}
type = type->parent;
}
}


void ndarray_properties_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
if (dest[0] == MP_OBJ_NULL) {
switch(attr) {
#if NDARRAY_HAS_DTYPE
case MP_QSTR_dtype:
dest[0] = ndarray_dtype(self_in);
break;
#endif
#if NDARRAY_HAS_ITEMSIZE
case MP_QSTR_itemsize:
dest[0] = ndarray_itemsize(self_in);
break;
#endif
#if NDARRAY_HAS_SHAPE
case MP_QSTR_shape:
dest[0] = ndarray_shape(self_in);
break;
#endif
#if NDARRAY_HAS_SIZE
case MP_QSTR_size:
dest[0] = ndarray_size(self_in);
break;
#endif
#if NDARRAY_HAS_STRIDES
case MP_QSTR_strides:
dest[0] = ndarray_strides(self_in);
break;
#endif
default:
call_local_method(self_in, attr, dest);
break;
}
} else {
return;
}
}

#endif /* CIRCUITPY */
7 changes: 5 additions & 2 deletions code/ndarray_properties.h
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@

/*
* This file is part of the micropython-ulab project,
* This file is part of the micropython-ulab project,
*
* https://github.com/v923z/micropython-ulab
*
* The MIT License (MIT)
*
* Copyright (c) 2020 Jeff Epler for Adafruit Industries
* 2020 Zoltán Vörös
* 2020 Zoltán Vörös
*/

#ifndef _NDARRAY_PROPERTIES_
Expand Down Expand Up @@ -79,11 +79,14 @@ STATIC const mp_obj_property_t ndarray_strides_obj = {

#else

void ndarray_properties_attr(mp_obj_t , qstr , mp_obj_t *);

MP_DEFINE_CONST_FUN_OBJ_1(ndarray_dtype_obj, ndarray_dtype);
MP_DEFINE_CONST_FUN_OBJ_1(ndarray_itemsize_obj, ndarray_itemsize);
MP_DEFINE_CONST_FUN_OBJ_1(ndarray_shape_obj, ndarray_shape);
MP_DEFINE_CONST_FUN_OBJ_1(ndarray_size_obj, ndarray_size);
MP_DEFINE_CONST_FUN_OBJ_1(ndarray_strides_obj, ndarray_strides);

#endif /* CIRCUITPY */

#endif
6 changes: 3 additions & 3 deletions code/numpy/vector/vector.c
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,7 @@ static mp_obj_t vectorise_vectorized_function_call(mp_obj_t self_in, size_t n_ar
for(size_t i=0; i < source->len; i++) {
avalue[0] = mp_binary_get_val_array(source->dtype, source->array, i);
fvalue = self->type->call(self->fun, 1, 0, avalue);
mp_binary_set_val_array(self->otypes, ndarray->array, i, fvalue);
ndarray_set_value(self->otypes, ndarray->array, i, fvalue);
}
return MP_OBJ_FROM_PTR(ndarray);
} else if(mp_obj_is_type(args[0], &mp_type_tuple) || mp_obj_is_type(args[0], &mp_type_list) ||
Expand All @@ -562,14 +562,14 @@ static mp_obj_t vectorise_vectorized_function_call(mp_obj_t self_in, size_t n_ar
size_t i=0;
while ((avalue[0] = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
fvalue = self->type->call(self->fun, 1, 0, avalue);
mp_binary_set_val_array(self->otypes, ndarray->array, i, fvalue);
ndarray_set_value(self->otypes, ndarray->array, i, fvalue);
i++;
}
return MP_OBJ_FROM_PTR(ndarray);
} else if(mp_obj_is_int(args[0]) || mp_obj_is_float(args[0])) {
ndarray_obj_t *ndarray = ndarray_new_linear_array(1, self->otypes);
fvalue = self->type->call(self->fun, 1, 0, args);
mp_binary_set_val_array(self->otypes, ndarray->array, 0, fvalue);
ndarray_set_value(self->otypes, ndarray->array, 0, fvalue);
return MP_OBJ_FROM_PTR(ndarray);
} else {
mp_raise_ValueError(translate("wrong input type"));
Expand Down
42 changes: 23 additions & 19 deletions code/ulab.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
#include "user/user.h"
#include "utils/utils.h"

#define ULAB_VERSION 2.9.0
#define ULAB_VERSION 3.0.0
#define xstr(s) str(s)
#define str(s) #s
#define ULAB_VERSION_STRING xstr(ULAB_VERSION) xstr(-) xstr(ULAB_MAX_DIMS) xstr(D)
Expand All @@ -43,7 +43,6 @@ STATIC MP_DEFINE_STR_OBJ(ulab_version_obj, ULAB_VERSION_STRING);


STATIC const mp_rom_map_elem_t ulab_ndarray_locals_dict_table[] = {
// these are the methods and properties of an ndarray
#if ULAB_MAX_DIMS > 1
#if NDARRAY_HAS_RESHAPE
{ MP_ROM_QSTR(MP_QSTR_reshape), MP_ROM_PTR(&ndarray_reshape_obj) },
Expand All @@ -58,39 +57,41 @@ STATIC const mp_rom_map_elem_t ulab_ndarray_locals_dict_table[] = {
#if NDARRAY_HAS_COPY
{ MP_ROM_QSTR(MP_QSTR_copy), MP_ROM_PTR(&ndarray_copy_obj) },
#endif
#if NDARRAY_HAS_DTYPE
{ MP_ROM_QSTR(MP_QSTR_dtype), MP_ROM_PTR(&ndarray_dtype_obj) },
#endif
#if NDARRAY_HAS_FLATTEN
{ MP_ROM_QSTR(MP_QSTR_flatten), MP_ROM_PTR(&ndarray_flatten_obj) },
#endif
#if NDARRAY_HAS_ITEMSIZE
{ MP_ROM_QSTR(MP_QSTR_itemsize), MP_ROM_PTR(&ndarray_itemsize_obj) },
#endif
#if NDARRAY_HAS_SHAPE
{ MP_ROM_QSTR(MP_QSTR_shape), MP_ROM_PTR(&ndarray_shape_obj) },
#endif
#if NDARRAY_HAS_SIZE
{ MP_ROM_QSTR(MP_QSTR_size), MP_ROM_PTR(&ndarray_size_obj) },
#endif
#if NDARRAY_HAS_STRIDES
{ MP_ROM_QSTR(MP_QSTR_strides), MP_ROM_PTR(&ndarray_strides_obj) },
#endif
#if NDARRAY_HAS_TOBYTES
{ MP_ROM_QSTR(MP_QSTR_tobytes), MP_ROM_PTR(&ndarray_tobytes_obj) },
#endif
#if NDARRAY_HAS_SORT
{ MP_ROM_QSTR(MP_QSTR_sort), MP_ROM_PTR(&numerical_sort_inplace_obj) },
#endif
#ifdef CIRCUITPY
#if NDARRAY_HAS_DTYPE
{ MP_ROM_QSTR(MP_QSTR_dtype), MP_ROM_PTR(&ndarray_dtype_obj) },
#endif
#if NDARRAY_HAS_ITEMSIZE
{ MP_ROM_QSTR(MP_QSTR_itemsize), MP_ROM_PTR(&ndarray_itemsize_obj) },
#endif
#if NDARRAY_HAS_SHAPE
{ MP_ROM_QSTR(MP_QSTR_shape), MP_ROM_PTR(&ndarray_shape_obj) },
#endif
#if NDARRAY_HAS_SIZE
{ MP_ROM_QSTR(MP_QSTR_size), MP_ROM_PTR(&ndarray_size_obj) },
#endif
#if NDARRAY_HAS_STRIDES
{ MP_ROM_QSTR(MP_QSTR_strides), MP_ROM_PTR(&ndarray_strides_obj) },
#endif
#endif /* CIRCUITPY */
};

STATIC MP_DEFINE_CONST_DICT(ulab_ndarray_locals_dict, ulab_ndarray_locals_dict_table);

const mp_obj_type_t ulab_ndarray_type = {
{ &mp_type_type },
#if defined(MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE) && defined(MP_TYPE_FLAG_EQ_HAS_NEQ_TEST)
#if defined(MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE) && defined(MP_TYPE_FLAG_EQ_HAS_NEQ_TEST)
.flags = MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE | MP_TYPE_FLAG_EQ_HAS_NEQ_TEST,
#endif
#endif
.name = MP_QSTR_ndarray,
.print = ndarray_print,
.make_new = ndarray_make_new,
Expand All @@ -106,6 +107,9 @@ const mp_obj_type_t ulab_ndarray_type = {
#if NDARRAY_HAS_BINARY_OPS
.binary_op = ndarray_binary_op,
#endif
#ifndef CIRCUITPY
.attr = ndarray_properties_attr,
#endif
.buffer_p = { .get_buffer = ndarray_get_buffer, },
.locals_dict = (mp_obj_dict_t*)&ulab_ndarray_locals_dict,
};
Expand Down
6 changes: 3 additions & 3 deletions code/ulab_create.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ static mp_obj_t create_zeros_ones_full(mp_obj_t oshape, uint8_t dtype, mp_obj_t
}
}
for(size_t i=0; i < ndarray->len; i++) {
mp_binary_set_val_array(dtype, ndarray->array, i, value);
ndarray_set_value(dtype, ndarray->array, i, value);
}
}
// if zeros calls the function, we don't have to do anything
Expand Down Expand Up @@ -388,13 +388,13 @@ mp_obj_t create_eye(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args)
size_t i = 0;
if((args[2].u_int >= 0)) {
while(k < m) {
mp_binary_set_val_array(dtype, ndarray->array, i*m+k, one);
ndarray_set_value(dtype, ndarray->array, i*m+k, one);
k++;
i++;
}
} else {
while(k < n) {
mp_binary_set_val_array(dtype, ndarray->array, k*m+i, one);
ndarray_set_value(dtype, ndarray->array, k*m+i, one);
k++;
i++;
}
Expand Down
2 changes: 1 addition & 1 deletion docs/manual/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
author = 'Zoltán Vörös'

# The full version, including alpha/beta/rc tags
release = '2.9.0'
release = '3.0.0'


# -- General configuration ---------------------------------------------------
Expand Down
Loading

0 comments on commit 161a728

Please sign in to comment.