Re: ulab, or what you will - numpy on bare metal
Posted: Wed Oct 30, 2019 8:38 pm
I see this ;libiary has featured on Hackster.io https://www.hackster.io/news/zoltan-vor ... 9oOo5q-u1I
Please see the new forum at
https://forum.micropython.org/
It must have leaked from hackaday.com, or perhaps the blog of adafruit.com. Though, the reaction on hackaday was really bashing But the hackster.io article is nice. Thanks!OutoftheBOTS_ wrote: ↑Wed Oct 30, 2019 8:38 pmI see this ;libiary has featured on Hackster.io https://www.hackster.io/news/zoltan-vor ... 9oOo5q-u1I
Yes, runtime.c will do this when none of the previous options have worked and it would otherwise raise TypeError. It changes the op from FOO to REVERSE_FOO and calls your binary op method with the args reversed.
Code: Select all
make BOARD=PYBD_SF6 CROSS_COMPILE=/usr/local/bin/arm-none-eabi-
Code: Select all
make: *** No rule to make target `lib/mbedtls/library/aes.c', needed by `build-PYBD_SF6/genhdr/qstr.i.last'. Stop.
Subtractions and divisions will make life a bit difficult, that is true, but I think they are not a serious predicament. What bugs me a bit more is this comment from runtime0.hjimmo wrote: ↑Wed Oct 30, 2019 9:39 pm
Yes, runtime.c will do this when none of the previous options have worked and it would otherwise raise TypeError. It changes the op from FOO to REVERSE_FOO and calls your binary op method with the args reversed.
This means for commutative operators, your binary op can treat FOO and REVERSE_FOO the same but obviously things like subtraction or division need to be handled differently.
Code: Select all
// MP_BINARY_OP_REVERSE_* must follow immediately after MP_BINARY_OP_*
Code: Select all
switch(op) {
case MP_BINARY_OP_EQUAL:
...
break;
...
case MP_BINARY_OP_ADD:
ugly decision tree...
...
break;
case MP_BINARY_OP_REVERSE_ADD:
ugly decision tree...
...
break;
...
Code: Select all
switch(op) {
case MP_BINARY_OP_EQUAL:
...
break;
...
case MP_BINARY_OP_ADD:
case MP_BINARY_OP_REVERSE_ADD:
case MP_BINARY_OP_MULTIPLY:
case MP_BINARY_OP_REVERSE_MULTIPLY:
case MP_BINARY_OP_TRUE_DIVIDE:
case MP_BINARY_OP_REVERSE_TRUE_DIVIDE:
ugly decision tree...
...
break;
Code: Select all
mp_obj_t ndarray_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) {
if(op == MP_BINARY_OP_REVERSE_ADD) {
printf("reversed");
return ndarray_binary_op(MP_BINARY_OP_ADD, rhs, lhs);
}
...
Code: Select all
import ulab as np
a = np.array([1, 2, 3])
a + 5
Code: Select all
import ulab as np
a = np.array([1, 2, 3])
5+a
Code: Select all
import ulab as np
a = np.array([1, 2, 3])
a < 5
Code: Select all
import ulab as np
a = np.array([1, 2, 3])
5 > a
Oh, so you are trying to compile without ulab, i.e., the standard firmware, i.e., the error has nothing to do with the module. Is that right?mathieu wrote: ↑Thu Oct 31, 2019 10:21 pmI am trying to compile ulab for the PYBD_SF6 on macOS following instructions found at https://github.com/v923z/micropython-ul ... e/ulab.rst. When I run
I get the following error:Code: Select all
make BOARD=PYBD_SF6 CROSS_COMPILE=/usr/local/bin/arm-none-eabi-
Am I missing something obvious? This is my first attempt at building my own firmware and I'm obviously over my head.Code: Select all
make: *** No rule to make target `lib/mbedtls/library/aes.c', needed by `build-PYBD_SF6/genhdr/qstr.i.last'. Stop.
I agree. If I had time, I would do that, though, there are at least 20 different boards supporting micropython now, and if you want to compile for all of them, then the process has to be automatised. By that I mean compilation, and uploading to storage. You have to persuade @Damien. But I am with you. He could automatically pull the ulab repository, whenever something changes there, like the webhook of readthedocs.
I have just tried to compile for the PYBD board (though, I have none), and while I get the standard firmware without issues, with ulab, I get missing references to sqrtf, and sinf in the link step.mathieu wrote: ↑Thu Oct 31, 2019 10:21 pmI get the following error:Code: Select all
make BOARD=PYBD_SF6 CROSS_COMPILE=/usr/local/bin/arm-none-eabi-
Code: Select all
make: *** No rule to make target `lib/mbedtls/library/aes.c', needed by `build-PYBD_SF6/genhdr/qstr.i.last'. Stop.
Code: Select all
Including User C Module from ../../../ulab/code
LINK build-PYBD_SF6/firmware.elf
build-PYBD_SF6/code/linalg.o: In function `linalg_eig':
linalg.c:(.text.linalg_eig+0x100): undefined reference to `sqrtf'
linalg.c:(.text.linalg_eig+0x118): undefined reference to `sqrtf'
linalg.c:(.text.linalg_eig+0x124): undefined reference to `sqrtf'
linalg.c:(.text.linalg_eig+0x298): undefined reference to `sqrtf'
build-PYBD_SF6/code/fft.o: In function `fft_kernel':
fft.c:(.text.fft_kernel+0x9a): undefined reference to `sinf'
fft.c:(.text.fft_kernel+0xb2): undefined reference to `sinf'
build-PYBD_SF6/code/fft.o: In function `fft_fft_ifft_spectrum':
fft.c:(.text.fft_fft_ifft_spectrum+0x108): undefined reference to `sqrtf'
build-PYBD_SF6/code/numerical.o: In function `numerical_sum_mean_std_single_line':
numerical.c:(.text.numerical_sum_mean_std_single_line+0x70): undefined reference to `sqrtf'
build-PYBD_SF6/code/numerical.o: In function `numerical_sum_mean_std_array':
numerical.c:(.text.numerical_sum_mean_std_array+0x70): undefined reference to `sqrtf'
make: *** [Makefile:514: build-PYBD_SF6/firmware.elf] Error 1
By changing all occurrences of sinf, and sqrtf to sin, and sqrt, I managed to compile the firmware for PYBD:
I think one must consider various things: if you use doubles, you need twice as much RAM, and I don't know, whether that precision is really necessary in an embedded environment. But I am not dead against doubles.Damien wrote: ↑Fri Nov 01, 2019 10:51 amThe PYBD_SF6 uses double precision float, and only provides the double precision math functions (eg sin, cos, not sinf, cosf).
I see in your ulab code that you use "float" exclusively as the FP data type (at the C level). Is this a restriction or can it also work with double?
OK, thanks for the hint. But at the end of the day, one still has to cast to float, I believe: when you create the binary array, you have to set the typecode, or you would have different binary arrays for different platforms (see above). Is it generally true that, where doubles are implemented, you also have more RAM? I work mainly with the STM32F405, and that is why I can't really comment on this. But I absolutely see the problem, and I also know that a decision must be made at one point.
Code: Select all
a = np.array([1, 2, 3], dtype=float)