Skip to content

Commit a0999ab

Browse files
authored
add modulo operator (#733)
* add modulo operator * fix modulo loops * add in-place modulo operator * update readme
1 parent 8eb8eaf commit a0999ab

7 files changed

Lines changed: 320 additions & 3 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ detected and handled.
3636
## ndarray methods
3737

3838
`ulab` implements `numpy`'s `ndarray` with the `==`, `!=`, `<`, `<=`, `>`, `>=`, `+`, `-`, `/`, `*`, `**`,
39-
`+=`, `-=`, `*=`, `/=`, `**=` binary operators, and the `len`, `~`, `-`, `+`, `abs` unary operators that
39+
`%`, `+=`, `-=`, `*=`, `/=`, `**=`, `%=` binary operators, and the `len`, `~`, `-`, `+`, `abs` unary operators that
4040
operate element-wise. Type-aware `ndarray`s can be initialised from any `micropython` iterable, lists of
4141
iterables via the `array` constructor, or by means of the `arange`, `concatenate`, `diag`, `eye`,
4242
`frombuffer`, `full`, `linspace`, `logspace`, `ones`, or `zeros` functions.

code/ndarray.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1648,6 +1648,12 @@ mp_obj_t ndarray_binary_op(mp_binary_op_t _op, mp_obj_t lobj, mp_obj_t robj) {
16481648
return ndarray_inplace_ams(lhs, rhs, rstrides, op);
16491649
break;
16501650
#endif
1651+
#if NDARRAY_HAS_INPLACE_MODULO
1652+
case MP_BINARY_OP_INPLACE_MODULO:
1653+
COMPLEX_DTYPE_NOT_IMPLEMENTED(lhs->dtype);
1654+
return ndarray_inplace_modulo(lhs, rhs, rstrides);
1655+
break;
1656+
#endif
16511657
#if NDARRAY_HAS_INPLACE_MULTIPLY
16521658
case MP_BINARY_OP_INPLACE_MULTIPLY:
16531659
COMPLEX_DTYPE_NOT_IMPLEMENTED(lhs->dtype);
@@ -1703,6 +1709,12 @@ mp_obj_t ndarray_binary_op(mp_binary_op_t _op, mp_obj_t lobj, mp_obj_t robj) {
17031709
return ndarray_binary_add(lhs, rhs, ndim, shape, lstrides, rstrides);
17041710
break;
17051711
#endif
1712+
#if NDARRAY_HAS_BINARY_OP_MODULO
1713+
case MP_BINARY_OP_MODULO:
1714+
COMPLEX_DTYPE_NOT_IMPLEMENTED(lhs->dtype);
1715+
return ndarray_binary_modulo(lhs, rhs, ndim, shape, lstrides, rstrides);
1716+
break;
1717+
#endif
17061718
#if NDARRAY_HAS_BINARY_OP_MULTIPLY
17071719
case MP_BINARY_OP_MULTIPLY:
17081720
return ndarray_binary_multiply(lhs, rhs, ndim, shape, lstrides, rstrides);

code/ndarray_operators.c

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,105 @@ mp_obj_t ndarray_binary_add(ndarray_obj_t *lhs, ndarray_obj_t *rhs,
248248
}
249249
#endif /* NDARRAY_HAS_BINARY_OP_ADD */
250250

251+
#if NDARRAY_HAS_BINARY_OP_MODULO
252+
mp_obj_t ndarray_binary_modulo(ndarray_obj_t *lhs, ndarray_obj_t *rhs,
253+
uint8_t ndim, size_t *shape, int32_t *lstrides, int32_t *rstrides) {
254+
255+
ndarray_obj_t *results = NULL;
256+
uint8_t *larray = (uint8_t *)lhs->array;
257+
uint8_t *rarray = (uint8_t *)rhs->array;
258+
259+
if(lhs->dtype == NDARRAY_UINT8) {
260+
if(rhs->dtype == NDARRAY_UINT8) {
261+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_UINT8);
262+
BINARY_LOOP(results, uint8_t, uint8_t, uint8_t, larray, lstrides, rarray, rstrides, %);
263+
} else if(rhs->dtype == NDARRAY_INT8) {
264+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
265+
BINARY_LOOP(results, int16_t, uint8_t, int8_t, larray, lstrides, rarray, rstrides, %);
266+
} else if(rhs->dtype == NDARRAY_UINT16) {
267+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_UINT16);
268+
BINARY_LOOP(results, uint16_t, uint8_t, uint16_t, larray, lstrides, rarray, rstrides, %);
269+
} else if(rhs->dtype == NDARRAY_INT16) {
270+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
271+
BINARY_LOOP(results, int16_t, uint8_t, int16_t, larray, lstrides, rarray, rstrides, %);
272+
} else if(rhs->dtype == NDARRAY_FLOAT) {
273+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_FLOAT);
274+
MODULO_FLOAT_LOOP(results, mp_float_t, uint8_t, mp_float_t, larray, lstrides, rarray, rstrides);
275+
}
276+
} else if(lhs->dtype == NDARRAY_INT8) {
277+
if(rhs->dtype == NDARRAY_UINT8) {
278+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
279+
BINARY_LOOP(results, int16_t, int8_t, uint8_t, larray, lstrides, rarray, rstrides, %);
280+
} else if(rhs->dtype == NDARRAY_INT8) {
281+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT8);
282+
BINARY_LOOP(results, int8_t, int8_t, int8_t, larray, lstrides, rarray, rstrides, %);
283+
} else if(rhs->dtype == NDARRAY_UINT16) {
284+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
285+
BINARY_LOOP(results, int16_t, int8_t, int16_t, larray, lstrides, rarray, rstrides, %);
286+
} else if(rhs->dtype == NDARRAY_INT16) {
287+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
288+
BINARY_LOOP(results, int16_t, int8_t, int16_t, larray, lstrides, rarray, rstrides, %);
289+
} else if(rhs->dtype == NDARRAY_FLOAT) {
290+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_FLOAT);
291+
MODULO_FLOAT_LOOP(results, mp_float_t, int8_t, mp_float_t, larray, lstrides, rarray, rstrides);
292+
}
293+
} else if(lhs->dtype == NDARRAY_UINT16) {
294+
if(rhs->dtype == NDARRAY_UINT8) {
295+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_UINT8);
296+
BINARY_LOOP(results, uint16_t, uint16_t, uint8_t, larray, lstrides, rarray, rstrides, %);
297+
} else if(rhs->dtype == NDARRAY_INT8) {
298+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_FLOAT);
299+
BINARY_LOOP(results, mp_float_t, uint16_t, int8_t, larray, lstrides, rarray, rstrides, %);
300+
} else if(rhs->dtype == NDARRAY_UINT16) {
301+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_UINT16);
302+
BINARY_LOOP(results, uint16_t, uint16_t, uint16_t, larray, lstrides, rarray, rstrides, %);
303+
} else if(rhs->dtype == NDARRAY_INT16) {
304+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_FLOAT);
305+
BINARY_LOOP(results, mp_float_t, uint16_t, int16_t, larray, lstrides, rarray, rstrides, %);
306+
} else if(rhs->dtype == NDARRAY_FLOAT) {
307+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_FLOAT);
308+
MODULO_FLOAT_LOOP(results, mp_float_t, uint16_t, mp_float_t, larray, lstrides, rarray, rstrides);
309+
}
310+
} else if(lhs->dtype == NDARRAY_INT16) {
311+
if(rhs->dtype == NDARRAY_UINT8) {
312+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
313+
BINARY_LOOP(results, int16_t, int16_t, uint8_t, larray, lstrides, rarray, rstrides, %);
314+
} else if(rhs->dtype == NDARRAY_INT8) {
315+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
316+
BINARY_LOOP(results, int16_t, int16_t, int8_t, larray, lstrides, rarray, rstrides, %);
317+
} else if(rhs->dtype == NDARRAY_UINT16) {
318+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_FLOAT);
319+
BINARY_LOOP(results, mp_float_t, int16_t, uint16_t, larray, lstrides, rarray, rstrides, %);
320+
} else if(rhs->dtype == NDARRAY_INT16) {
321+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_INT16);
322+
BINARY_LOOP(results, int16_t, int16_t, int16_t, larray, lstrides, rarray, rstrides, %);
323+
} else if(rhs->dtype == NDARRAY_FLOAT) {
324+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_FLOAT);
325+
MODULO_FLOAT_LOOP(results, mp_float_t, int16_t, mp_float_t, larray, lstrides, rarray, rstrides);
326+
}
327+
} else if(lhs->dtype == NDARRAY_FLOAT) {
328+
if(rhs->dtype == NDARRAY_UINT8) {
329+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_FLOAT);
330+
MODULO_FLOAT_LOOP(results, mp_float_t, mp_float_t, uint8_t, larray, lstrides, rarray, rstrides);
331+
} else if(rhs->dtype == NDARRAY_INT8) {
332+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_FLOAT);
333+
MODULO_FLOAT_LOOP(results, mp_float_t, mp_float_t, int8_t, larray, lstrides, rarray, rstrides);
334+
} else if(rhs->dtype == NDARRAY_UINT16) {
335+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_FLOAT);
336+
MODULO_FLOAT_LOOP(results, mp_float_t, mp_float_t, uint16_t, larray, lstrides, rarray, rstrides);
337+
} else if(rhs->dtype == NDARRAY_INT16) {
338+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_FLOAT);
339+
MODULO_FLOAT_LOOP(results, mp_float_t, mp_float_t, int16_t, larray, lstrides, rarray, rstrides);
340+
} else if(rhs->dtype == NDARRAY_FLOAT) {
341+
results = ndarray_new_dense_ndarray(ndim, shape, NDARRAY_FLOAT);
342+
MODULO_FLOAT_LOOP(results, mp_float_t, mp_float_t, mp_float_t, larray, lstrides, rarray, rstrides);
343+
}
344+
}
345+
346+
return MP_OBJ_FROM_PTR(results);
347+
}
348+
#endif /* NDARRAY_HAS_BINARY_OP_MODULO */
349+
251350
#if NDARRAY_HAS_BINARY_OP_MULTIPLY
252351
mp_obj_t ndarray_binary_multiply(ndarray_obj_t *lhs, ndarray_obj_t *rhs,
253352
uint8_t ndim, size_t *shape, int32_t *lstrides, int32_t *rstrides) {
@@ -1074,6 +1173,29 @@ mp_obj_t ndarray_inplace_ams(ndarray_obj_t *lhs, ndarray_obj_t *rhs, int32_t *rs
10741173
}
10751174
#endif /* NDARRAY_HAS_INPLACE_ADD || NDARRAY_HAS_INPLACE_MULTIPLY || NDARRAY_HAS_INPLACE_SUBTRACT */
10761175

1176+
1177+
#if NDARRAY_HAS_INPLACE_MODULO
1178+
mp_obj_t ndarray_inplace_modulo(ndarray_obj_t *lhs, ndarray_obj_t *rhs, int32_t *rstrides) {
1179+
if((lhs->dtype != NDARRAY_FLOAT) && (rhs->dtype == NDARRAY_FLOAT)) {
1180+
mp_raise_TypeError(MP_ERROR_TEXT("results cannot be cast to specified type"));
1181+
}
1182+
if(lhs->dtype == NDARRAY_FLOAT) {
1183+
if(rhs->dtype == NDARRAY_UINT8) {
1184+
INLINE_MODULO_FLOAT_LOOP(lhs, uint8_t, larray, rarray, rstrides);
1185+
} else if(rhs->dtype == NDARRAY_UINT8) {
1186+
INLINE_MODULO_FLOAT_LOOP(lhs, int8_t, larray, rarray, rstrides);
1187+
} else if(rhs->dtype == NDARRAY_UINT16) {
1188+
INLINE_MODULO_FLOAT_LOOP(lhs, uint16_t, larray, rarray, rstrides);
1189+
} else if(rhs->dtype == NDARRAY_INT16) {
1190+
INLINE_MODULO_FLOAT_LOOP(lhs, int16_t, larray, rarray, rstrides);
1191+
} else {
1192+
INLINE_MODULO_FLOAT_LOOP(lhs, mp_float_t, larray, rarray, rstrides);
1193+
}
1194+
}
1195+
return MP_OBJ_FROM_PTR(lhs);
1196+
}
1197+
#endif /* NDARRAY_HAS_INPLACE_MODULO */
1198+
10771199
#if NDARRAY_HAS_INPLACE_TRUE_DIVIDE
10781200
mp_obj_t ndarray_inplace_divide(ndarray_obj_t *lhs, ndarray_obj_t *rhs, int32_t *rstrides) {
10791201

code/ndarray_operators.h

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
mp_obj_t ndarray_binary_equality(ndarray_obj_t *, ndarray_obj_t *, uint8_t , size_t *, int32_t *, int32_t *, mp_binary_op_t );
1414
mp_obj_t ndarray_binary_add(ndarray_obj_t *, ndarray_obj_t *, uint8_t , size_t *, int32_t *, int32_t *);
15+
mp_obj_t ndarray_binary_modulo(ndarray_obj_t *, ndarray_obj_t *, uint8_t , size_t *, int32_t *, int32_t *);
1516
mp_obj_t ndarray_binary_multiply(ndarray_obj_t *, ndarray_obj_t *, uint8_t , size_t *, int32_t *, int32_t *);
1617
mp_obj_t ndarray_binary_more(ndarray_obj_t *, ndarray_obj_t *, uint8_t , size_t *, int32_t *, int32_t *, mp_binary_op_t );
1718
mp_obj_t ndarray_binary_power(ndarray_obj_t *, ndarray_obj_t *, uint8_t , size_t *, int32_t *, int32_t *);
@@ -21,6 +22,7 @@ mp_obj_t ndarray_binary_logical(ndarray_obj_t *, ndarray_obj_t *, uint8_t , size
2122
mp_obj_t ndarray_binary_floor_divide(ndarray_obj_t *, ndarray_obj_t *, uint8_t , size_t *, int32_t *, int32_t *);
2223

2324
mp_obj_t ndarray_inplace_ams(ndarray_obj_t *, ndarray_obj_t *, int32_t *, uint8_t );
25+
mp_obj_t ndarray_inplace_modulo(ndarray_obj_t *, ndarray_obj_t *, int32_t *);
2426
mp_obj_t ndarray_inplace_power(ndarray_obj_t *, ndarray_obj_t *, int32_t *);
2527
mp_obj_t ndarray_inplace_divide(ndarray_obj_t *, ndarray_obj_t *, int32_t *);
2628

@@ -537,3 +539,176 @@ mp_obj_t ndarray_inplace_divide(ndarray_obj_t *, ndarray_obj_t *, int32_t *);
537539
} while(0)
538540

539541
#endif /* ULAB_MAX_DIMS == 4 */
542+
543+
#define MODULO_FLOAT1(results, array, type_left, type_right, larray, lstrides, rarray, rstrides)\
544+
({\
545+
size_t l = 0;\
546+
do {\
547+
*(array)++ = MICROPY_FLOAT_C_FUN(fmod)(*((type_left *)(larray)), *((type_right *)(rarray)));\
548+
(larray) += (lstrides)[ULAB_MAX_DIMS - 1];\
549+
(rarray) += (rstrides)[ULAB_MAX_DIMS - 1];\
550+
l++;\
551+
} while(l < (results)->shape[ULAB_MAX_DIMS - 1]);\
552+
})
553+
554+
#if ULAB_MAX_DIMS == 1
555+
#define MODULO_FLOAT_LOOP(results, type_out, type_left, type_right, larray, lstrides, rarray, rstrides) do {\
556+
type_out *array = (type_out *)(results)->array;\
557+
MODULO_FLOAT1((results), (array), type_left, type_right, (larray), (lstrides), (rarray), (rstrides));\
558+
} while(0)
559+
#endif /* ULAB_MAX_DIMS == 1 */
560+
561+
#if ULAB_MAX_DIMS == 2
562+
#define MODULO_FLOAT_LOOP(results, type_out, type_left, type_right, larray, lstrides, rarray, rstrides) do {\
563+
type_out *array = (type_out *)(results)->array;\
564+
size_t l = 0;\
565+
do {\
566+
MODULO_FLOAT1((results), (array), type_left, type_right, (larray), (lstrides), (rarray), (rstrides));\
567+
(larray) -= (lstrides)[ULAB_MAX_DIMS - 1] * (results)->shape[ULAB_MAX_DIMS - 1];\
568+
(larray) += (lstrides)[ULAB_MAX_DIMS - 2];\
569+
(rarray) -= (rstrides)[ULAB_MAX_DIMS - 1] * (results)->shape[ULAB_MAX_DIMS - 1];\
570+
(rarray) += (rstrides)[ULAB_MAX_DIMS - 2];\
571+
l++;\
572+
} while(l < (results)->shape[ULAB_MAX_DIMS - 2]);\
573+
} while(0)
574+
#endif /* ULAB_MAX_DIMS == 2 */
575+
576+
#if ULAB_MAX_DIMS == 3
577+
#define MODULO_FLOAT_LOOP(results, type_out, type_left, type_right, larray, lstrides, rarray, rstrides) do {\
578+
type_out *array = (type_out *)(results)->array;\
579+
size_t k = 0;\
580+
do {\
581+
size_t l = 0;\
582+
do {\
583+
MODULO_FLOAT1((results), (array), type_left, type_right, (larray), (lstrides), (rarray), (rstrides));\
584+
(larray) -= (lstrides)[ULAB_MAX_DIMS - 1] * (results)->shape[ULAB_MAX_DIMS - 1];\
585+
(larray) += (lstrides)[ULAB_MAX_DIMS - 2];\
586+
(rarray) -= (rstrides)[ULAB_MAX_DIMS - 1] * (results)->shape[ULAB_MAX_DIMS - 1];\
587+
(rarray) += (rstrides)[ULAB_MAX_DIMS - 2];\
588+
l++;\
589+
} while(l < (results)->shape[ULAB_MAX_DIMS - 2]);\
590+
(larray) -= (lstrides)[ULAB_MAX_DIMS - 2] * (results)->shape[ULAB_MAX_DIMS - 2];\
591+
(larray) += (lstrides)[ULAB_MAX_DIMS - 3];\
592+
(rarray) -= (rstrides)[ULAB_MAX_DIMS - 2] * (results)->shape[ULAB_MAX_DIMS - 2];\
593+
(rarray) += (rstrides)[ULAB_MAX_DIMS - 3];\
594+
k++;\
595+
} while(k < (results)->shape[ULAB_MAX_DIMS - 3]);\
596+
} while(0)
597+
#endif /* ULAB_MAX_DIMS == 3 */
598+
599+
#if ULAB_MAX_DIMS == 4
600+
#define MODULO_FLOAT_LOOP(results, type_out, type_left, type_right, larray, lstrides, rarray, rstrides) do {\
601+
type_out *array = (type_out *)(results)->array;\
602+
size_t j = 0;\
603+
do {\
604+
size_t k = 0;\
605+
do {\
606+
size_t l = 0;\
607+
do {\
608+
MODULO_FLOAT1((results), (array), type_left, type_right, (larray), (lstrides), (rarray), (rstrides));\
609+
(larray) -= (lstrides)[ULAB_MAX_DIMS - 1] * (results)->shape[ULAB_MAX_DIMS - 1];\
610+
(larray) += (lstrides)[ULAB_MAX_DIMS - 2];\
611+
(rarray) -= (rstrides)[ULAB_MAX_DIMS - 1] * (results)->shape[ULAB_MAX_DIMS - 1];\
612+
(rarray) += (rstrides)[ULAB_MAX_DIMS - 2];\
613+
l++;\
614+
} while(l < (results)->shape[ULAB_MAX_DIMS - 2]);\
615+
(larray) -= (lstrides)[ULAB_MAX_DIMS - 2] * (results)->shape[ULAB_MAX_DIMS - 2];\
616+
(larray) += (lstrides)[ULAB_MAX_DIMS - 3];\
617+
(rarray) -= (rstrides)[ULAB_MAX_DIMS - 2] * (results)->shape[ULAB_MAX_DIMS - 2];\
618+
(rarray) += (rstrides)[ULAB_MAX_DIMS - 3];\
619+
k++;\
620+
} while(k < (results)->shape[ULAB_MAX_DIMS - 3]);\
621+
(larray) -= (lstrides)[ULAB_MAX_DIMS - 3] * (results)->shape[ULAB_MAX_DIMS - 3];\
622+
(larray) += (lstrides)[ULAB_MAX_DIMS - 4];\
623+
(rarray) -= (rstrides)[ULAB_MAX_DIMS - 3] * (results)->shape[ULAB_MAX_DIMS - 3];\
624+
(rarray) += (rstrides)[ULAB_MAX_DIMS - 4];\
625+
j++;\
626+
} while(j < (results)->shape[ULAB_MAX_DIMS - 4]);\
627+
} while(0)
628+
#endif /* ULAB_MAX_DIMS == 4 */
629+
630+
631+
#define INPLACE_MODULO_FLOAT1(results, type_right, larray, rarray, rstrides)\
632+
({\
633+
size_t l = 0;\
634+
do {\
635+
*((mp_float_t *)larray) = MICROPY_FLOAT_C_FUN(fmod)(*((mp_float_t *)(larray)), *((type_right *)(rarray)));\
636+
(larray) += (results)->strides[ULAB_MAX_DIMS - 1];\
637+
(rarray) += (rstrides)[ULAB_MAX_DIMS - 1];\
638+
l++;\
639+
} while(l < (results)->shape[ULAB_MAX_DIMS - 1]);\
640+
})
641+
642+
643+
#if ULAB_MAX_DIMS == 1
644+
#define INPLACE_MODULO_FLOAT_LOOP(results, type_right, larray, rarray, rstrides) do {\
645+
INPLACE_MODULO_FLOAT1((results), type_right, (larray), (rarray), (rstrides));\
646+
} while(0)
647+
#endif /* ULAB_MAX_DIMS == 1 */
648+
649+
650+
#if ULAB_MAX_DIMS == 2
651+
#define INLINE_MODULO_FLOAT_LOOP(results, type_right, larray, rarray, rstrides) do {\
652+
size_t l = 0;\
653+
do {\
654+
INPLACE_MODULO_FLOAT1((results), type_right, (larray), (rarray), (rstrides));\
655+
(larray) -= (results)->strides[ULAB_MAX_DIMS - 1] * (results)->shape[ULAB_MAX_DIMS - 1];\
656+
(larray) += (results)->strides[ULAB_MAX_DIMS - 2];\
657+
(rarray) -= (rstrides)[ULAB_MAX_DIMS - 1] * (results)->shape[ULAB_MAX_DIMS - 1];\
658+
(rarray) += (rstrides)[ULAB_MAX_DIMS - 2];\
659+
l++;\
660+
} while(l < (results)->shape[ULAB_MAX_DIMS - 2]);\
661+
} while(0)
662+
#endif /* ULAB_MAX_DIMS == 2 */
663+
664+
#if ULAB_MAX_DIMS == 3
665+
#define INLINE_MODULO_FLOAT_LOOP(results, type_right, larray, rarray, rstrides) do {\
666+
size_t k = 0;\
667+
do {\
668+
size_t l = 0;\
669+
do {\
670+
INPLACE_MODULO_FLOAT1((results), type_right, (larray), (rarray), (rstrides));\
671+
(larray) -= (results)->strides[ULAB_MAX_DIMS - 1] * (results)->shape[ULAB_MAX_DIMS - 1];\
672+
(larray) += (results)->strides[ULAB_MAX_DIMS - 2];\
673+
(rarray) -= (rstrides)[ULAB_MAX_DIMS - 1] * (results)->shape[ULAB_MAX_DIMS - 1];\
674+
(rarray) += (rstrides)[ULAB_MAX_DIMS - 2];\
675+
l++;\
676+
} while(l < (results)->shape[ULAB_MAX_DIMS - 2]);\
677+
(larray) -= (results)->strides[ULAB_MAX_DIMS - 2] * (results)->shape[ULAB_MAX_DIMS - 2];\
678+
(larray) += (results)->strides[ULAB_MAX_DIMS - 3];\
679+
(rarray) -= (rstrides)[ULAB_MAX_DIMS - 2] * (results)->shape[ULAB_MAX_DIMS - 2];\
680+
(rarray) += (rstrides)[ULAB_MAX_DIMS - 3];\
681+
k++;\
682+
} while(k < (results)->shape[ULAB_MAX_DIMS - 3]);\
683+
} while(0)
684+
#endif /* ULAB_MAX_DIMS == 3 */
685+
686+
#if ULAB_MAX_DIMS == 4
687+
#define INLINE_MODULO_FLOAT_LOOP(results, type_right, larray, rarray, rstrides) do {\
688+
size_t j = 0;\
689+
do {\
690+
size_t k = 0;\
691+
do {\
692+
size_t l = 0;\
693+
do {\
694+
INPLACE_MODULO_FLOAT1((results), type_right, (larray), (rarray), (rstrides));\
695+
(larray) -= (results)->strides[ULAB_MAX_DIMS - 1] * (results)->shape[ULAB_MAX_DIMS - 1];\
696+
(larray) += (results)->strides[ULAB_MAX_DIMS - 2];\
697+
(rarray) -= (rstrides)[ULAB_MAX_DIMS - 1] * (results)->shape[ULAB_MAX_DIMS - 1];\
698+
(rarray) += (rstrides)[ULAB_MAX_DIMS - 2];\
699+
l++;\
700+
} while(l < (results)->shape[ULAB_MAX_DIMS - 2]);\
701+
(larray) -= (results)->strides[ULAB_MAX_DIMS - 2] * (results)->shape[ULAB_MAX_DIMS - 2];\
702+
(larray) += (results)->strides[ULAB_MAX_DIMS - 3];\
703+
(rarray) -= (rstrides)[ULAB_MAX_DIMS - 2] * (results)->shape[ULAB_MAX_DIMS - 2];\
704+
(rarray) += (rstrides)[ULAB_MAX_DIMS - 3];\
705+
k++;\
706+
} while(k < (results)->shape[ULAB_MAX_DIMS - 3]);\
707+
(larray) -= (results)->strides[ULAB_MAX_DIMS - 3] * (results)->shape[ULAB_MAX_DIMS - 3];\
708+
(larray) += (results)->strides[ULAB_MAX_DIMS - 4];\
709+
(rarray) -= (rstrides)[ULAB_MAX_DIMS - 3] * (results)->shape[ULAB_MAX_DIMS - 3];\
710+
(rarray) += (rstrides)[ULAB_MAX_DIMS - 4];\
711+
j++;\
712+
} while(j < (results)->shape[ULAB_MAX_DIMS - 4]);\
713+
} while(0)
714+
#endif /* ULAB_MAX_DIMS == 4 */

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.8.0
36+
#define ULAB_VERSION 6.9.0
3737
#define xstr(s) str(s)
3838
#define str(s) #s
3939

0 commit comments

Comments
 (0)