Skip to content

Commit 41c4363

Browse files
authored
address issue raised in #676 (#677)
* ndarrays can be created from buffer
1 parent e40a667 commit 41c4363

File tree

5 files changed

+23
-27
lines changed

5 files changed

+23
-27
lines changed

code/ndarray.c

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
* The MIT License (MIT)
88
*
9-
* Copyright (c) 2019-2022 Zoltán Vörös
9+
* Copyright (c) 2019-2024 Zoltán Vörös
1010
* 2020 Jeff Epler for Adafruit Industries
1111
* 2020 Taku Fukada
1212
*/
@@ -509,8 +509,9 @@ static size_t multiply_size(size_t a, size_t b) {
509509
return result;
510510
}
511511

512-
ndarray_obj_t *ndarray_new_ndarray(uint8_t ndim, size_t *shape, int32_t *strides, uint8_t dtype) {
512+
ndarray_obj_t *ndarray_new_ndarray(uint8_t ndim, size_t *shape, int32_t *strides, uint8_t dtype, uint8_t *buffer) {
513513
// Creates the base ndarray with shape, and initialises the values to straight 0s
514+
// optionally, values can be supplied via the last argument
514515
ndarray_obj_t *ndarray = m_new_obj(ndarray_obj_t);
515516
ndarray->base.type = &ulab_ndarray_type;
516517
ndarray->dtype = dtype == NDARRAY_BOOL ? NDARRAY_UINT8 : dtype;
@@ -536,9 +537,13 @@ ndarray_obj_t *ndarray_new_ndarray(uint8_t ndim, size_t *shape, int32_t *strides
536537

537538
// if the length is 0, still allocate a single item, so that contractions can be handled
538539
size_t len = multiply_size(ndarray->itemsize, MAX(1, ndarray->len));
539-
uint8_t *array = m_new0(byte, len);
540-
// this should set all elements to 0, irrespective of the of the dtype (all bits are zero)
541-
// we could, perhaps, leave this step out, and initialise the array only, when needed
540+
uint8_t *array;
541+
array = buffer;
542+
if(array == NULL) {
543+
// this should set all elements to 0, irrespective of the of the dtype (all bits are zero)
544+
// we could, perhaps, leave this step out, and initialise the array only, when needed
545+
array = m_new0(byte, len);
546+
}
542547
ndarray->array = array;
543548
ndarray->origin = array;
544549
return ndarray;
@@ -547,12 +552,12 @@ ndarray_obj_t *ndarray_new_ndarray(uint8_t ndim, size_t *shape, int32_t *strides
547552
ndarray_obj_t *ndarray_new_dense_ndarray(uint8_t ndim, size_t *shape, uint8_t dtype) {
548553
// creates a dense array, i.e., one, where the strides are derived directly from the shapes
549554
// the function should work in the general n-dimensional case
550-
int32_t *strides = m_new(int32_t, ULAB_MAX_DIMS);
551-
strides[ULAB_MAX_DIMS-1] = (int32_t)ulab_binary_get_size(dtype);
552-
for(size_t i=ULAB_MAX_DIMS; i > 1; i--) {
553-
strides[i-2] = strides[i-1] * MAX(1, shape[i-1]);
554-
}
555-
return ndarray_new_ndarray(ndim, shape, strides, dtype);
555+
// int32_t *strides = m_new(int32_t, ULAB_MAX_DIMS);
556+
// strides[ULAB_MAX_DIMS - 1] = (int32_t)ulab_binary_get_size(dtype);
557+
// for(size_t i = ULAB_MAX_DIMS; i > 1; i--) {
558+
// strides[i-2] = strides[i-1] * MAX(1, shape[i-1]);
559+
// }
560+
return ndarray_new_ndarray(ndim, shape, NULL, dtype, NULL);
556561
}
557562

558563
ndarray_obj_t *ndarray_new_ndarray_from_tuple(mp_obj_tuple_t *_shape, uint8_t dtype) {
@@ -650,7 +655,7 @@ ndarray_obj_t *ndarray_copy_view(ndarray_obj_t *source) {
650655
if(source->boolean) {
651656
dtype = NDARRAY_BOOL;
652657
}
653-
ndarray_obj_t *ndarray = ndarray_new_ndarray(source->ndim, source->shape, strides, dtype);
658+
ndarray_obj_t *ndarray = ndarray_new_ndarray(source->ndim, source->shape, strides, dtype, NULL);
654659
ndarray_copy_array(source, ndarray, 0);
655660
return ndarray;
656661
}
@@ -1884,7 +1889,7 @@ mp_obj_t ndarray_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
18841889
#if ULAB_SUPPORTS_COMPLEX
18851890
if(self->dtype == NDARRAY_COMPLEX) {
18861891
int32_t *strides = strides_from_shape(self->shape, NDARRAY_FLOAT);
1887-
ndarray_obj_t *target = ndarray_new_ndarray(self->ndim, self->shape, strides, NDARRAY_FLOAT);
1892+
ndarray_obj_t *target = ndarray_new_ndarray(self->ndim, self->shape, strides, NDARRAY_FLOAT, NULL);
18881893
ndarray = MP_OBJ_TO_PTR(carray_abs(self, target));
18891894
} else {
18901895
#endif

code/ndarray.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ int32_t *ndarray_contract_strides(ndarray_obj_t *, uint8_t );
188188
ndarray_obj_t *ndarray_from_iterable(mp_obj_t , uint8_t );
189189
ndarray_obj_t *ndarray_new_dense_ndarray(uint8_t , size_t *, uint8_t );
190190
ndarray_obj_t *ndarray_new_ndarray_from_tuple(mp_obj_tuple_t *, uint8_t );
191-
ndarray_obj_t *ndarray_new_ndarray(uint8_t , size_t *, int32_t *, uint8_t );
191+
ndarray_obj_t *ndarray_new_ndarray(uint8_t , size_t *, int32_t *, uint8_t , uint8_t *);
192192
ndarray_obj_t *ndarray_new_linear_array(size_t , uint8_t );
193193
ndarray_obj_t *ndarray_new_view(ndarray_obj_t *, uint8_t , size_t *, int32_t *, int32_t );
194194
bool ndarray_is_dense(ndarray_obj_t *);

code/numpy/create.c

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -838,19 +838,10 @@ mp_obj_t create_frombuffer(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw
838838
len = count;
839839
}
840840
}
841-
ndarray_obj_t *ndarray = m_new_obj(ndarray_obj_t);
842-
ndarray->base.type = &ulab_ndarray_type;
843-
ndarray->dtype = dtype == NDARRAY_BOOL ? NDARRAY_UINT8 : dtype;
844-
ndarray->boolean = dtype == NDARRAY_BOOL ? NDARRAY_BOOLEAN : NDARRAY_NUMERIC;
845-
ndarray->ndim = 1;
846-
ndarray->len = len;
847-
ndarray->itemsize = sz;
848-
ndarray->shape[ULAB_MAX_DIMS - 1] = len;
849-
ndarray->strides[ULAB_MAX_DIMS - 1] = sz;
850841

842+
size_t *shape = ndarray_shape_vector(0, 0, 0, len);
851843
uint8_t *buffer = bufinfo.buf;
852-
ndarray->array = buffer + offset;
853-
return MP_OBJ_FROM_PTR(ndarray);
844+
return ndarray_new_ndarray(1, shape, NULL, dtype, buffer + offset);
854845
}
855846
return mp_const_none;
856847
}

code/numpy/numerical.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -746,7 +746,7 @@ mp_obj_t numerical_argsort(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw
746746
numerical_reduce_axes(ndarray, ax, shape, strides);
747747

748748
// We could return an NDARRAY_UINT8 array, if all lengths are shorter than 256
749-
ndarray_obj_t *indices = ndarray_new_ndarray(ndarray->ndim, ndarray->shape, NULL, NDARRAY_UINT16);
749+
ndarray_obj_t *indices = ndarray_new_ndarray(ndarray->ndim, ndarray->shape, NULL, NDARRAY_UINT16, NULL);
750750
int32_t *istrides = m_new0(int32_t, ULAB_MAX_DIMS);
751751
numerical_reduce_axes(indices, ax, shape, istrides);
752752

code/ulab.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
#include "user/user.h"
3434
#include "utils/utils.h"
3535

36-
#define ULAB_VERSION 6.5.2
36+
#define ULAB_VERSION 6.5.3
3737
#define xstr(s) str(s)
3838
#define str(s) #s
3939

0 commit comments

Comments
 (0)