Matrix library for MicroPython

Discussion about programs, libraries and tools that work with MicroPython. Mostly these are provided by a third party.
Target audience: All users and developers of MicroPython.
jickster
Posts: 629
Joined: Thu Sep 07, 2017 8:57 pm

Matrix library for MicroPython

Post by jickster » Sun Aug 19, 2018 7:07 pm

Iyassou wrote:
jickster wrote:
Sat Aug 18, 2018 8:20 pm
Write it in C and it’ll be much faster.
Out of curiosity, what do you do with the C program once you've written it to make it work with MicroPython?
I can actually program very simple things in C but don't have the same usage experience as with Python 3 and MicroPython and if this is accessible it could be the project I need to gain proficiency in it.
Once you write C code, you have use C compiler to create a firmware that you flash into the hardware.


Since you don’t know C, I would not bother with it unless you absolutely need the performance increase.

But First of all, do the viper thing and see how much of an increase gives you relative to normal `.py`.

I suspect that
normal Py -> Viper performance gain
is going to be way more than
Viper -> C performance gain.

Iyassou
Posts: 42
Joined: Sun Jun 26, 2016 9:15 am

Re: Matrix library for MicroPython

Post by Iyassou » Mon Aug 20, 2018 6:49 am

Iyassou wrote:
Sun Aug 19, 2018 5:23 pm
I'm considering merging umatrix_np into umatrix and changing the size method to shape (I'm not really a fan of the word shape in this scenario and was hanging on to prejudice, but if it's what's preferred I am flexible :) ).
I decided to merge umatrix_np into umatrix. The new umatrix, v1.1, now supports matrix slicing and has dropped "size" in favour of "shape".
jickster wrote:
Sun Aug 19, 2018 7:07 pm
But First of all, do the viper thing and see how much of an increase gives you relative to normal `.py`.

I suspect that
normal Py -> Viper performance gain
is going to be way more than
Viper -> C performance gain.
I'll report back as soon as I've done this.

User avatar
Roberthh
Posts: 3667
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: Matrix library for MicroPython

Post by Roberthh » Mon Aug 20, 2018 7:03 am

Performance gains seen in my tests:
Python Code -> Python native code : factor of 2
Python Code -> Viper code: factor of 10 (at least)
Viper code -> Assembly code: factor of 2

I expect C code performance to be between Viper and Assembly code.
For code longer than a few statements, Native, Viper and Assembly code is not available on the ESP8266, and not at all on the ESP32.

Iyassou
Posts: 42
Joined: Sun Jun 26, 2016 9:15 am

Re: Matrix library for MicroPython

Post by Iyassou » Wed Aug 22, 2018 6:55 am

Iyassou wrote:
Mon Aug 20, 2018 6:49 am
I'll report back as soon as I've done this.
Are there any fleshed-out guides for writing code for the Viper emitter? I'm not at all familiar with it and so far I've just been firing in the dark and not getting anywhere.

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Viper

Post by pythoncoder » Wed Aug 22, 2018 10:43 am

Alas it isn't well documented. You'll find some examples here (files epd.py and epdpart.py) and here (files TFT_io.py and touch.py). TFT_io.py is courtesy of @Roberthh.

You'll notice that it's often necessary to use Python type hints. IIRC there is also a limit to the number of args a function can take (4?).
Peter Hinch
Index to my micropython libraries.

Iyassou
Posts: 42
Joined: Sun Jun 26, 2016 9:15 am

Re: Matrix library for MicroPython

Post by Iyassou » Wed Aug 22, 2018 12:17 pm

pythoncoder wrote:
Wed Aug 22, 2018 10:43 am
Alas it isn't well documented.
That's unfortunate. So far I'm trying to modify "inverse" to use Viper and I'm coming across a surprising error. My code:

Code: Select all

@micropython.viper
@property
def inverse(self):
	order = int(len(self.rows))
	assert order == int(len(self.rows[0])), "Matrix must be square."
	if order == 1:
		x = int(self.rows[0][0])
		assert bool(x), "Matrix is singular."
		return matrix([1/x])
The error I'm getting:

Code: Select all

Traceback (most recent call last):
  File "main.py", line 1, in <module>
  File "umatrix.py", line 220, in inverse
ViperTypeError: binary op __truediv__ not implemented
Line 220 is the "return matrix([1/x])" line shown in the snippet above.

Is there no division in Viper or is it done differently?

I looked at the example files you linked and it seems like Viper only supports integer arithmetic and binary ops: is this the case?
I don't think a matrix library without float support would be useful.

User avatar
Roberthh
Posts: 3667
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: Matrix library for MicroPython

Post by Roberthh » Wed Aug 22, 2018 3:59 pm

Yes, it looks like floating point division is not supported, but addition, subtraction and multiplication are, as well nested lists as function arguments, just to name a few. So at least you can gain some speed with native code.
Last edited by Roberthh on Wed Aug 22, 2018 4:04 pm, edited 2 times in total.

jickster
Posts: 629
Joined: Thu Sep 07, 2017 8:57 pm

Re: Matrix library for MicroPython

Post by jickster » Wed Aug 22, 2018 4:00 pm

Roberthh wrote:
Wed Aug 22, 2018 3:59 pm
Yes, it looks like floating point division is not supported, but addition, subtraction and multiplication are, as well nested lists as function arguments, just to name a few. So at least you can gain some speed with native code.
What's the reason for that?

User avatar
Roberthh
Posts: 3667
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: Matrix library for MicroPython

Post by Roberthh » Wed Aug 22, 2018 4:04 pm

No clue. interestingly something like:
a ** (-1.0)
works.
Edit: But that might kill any performance gain.

jickster
Posts: 629
Joined: Thu Sep 07, 2017 8:57 pm

Re: Matrix library for MicroPython

Post by jickster » Wed Aug 22, 2018 4:32 pm

Iyassou wrote:
Wed Aug 22, 2018 12:17 pm

I looked at the example files you linked and it seems like Viper only supports integer arithmetic and binary ops: is this the case?
I don't think a matrix library without float support would be useful.
As with all open-source projects, the source code is the only "real" documentation.

https://github.com/micropython/micropyt ... ve.c#L1911

This is the function that implements the supported operations and a search indicates it doesn't contain MP_BINARY_OP_TRUE_DIVIDE.
So, yes for now Viper doesn't do division.

However, it doesn't mean that Viper is completely useless to you.
The Viper decorator is applied at the function level so I THINK you can choose which functions are @micropython.viper and which are not.
But what about your functions which do a ton of Viper-supported operations - mult, add, sub - followed by one unsupported op?

THE FOLLOWING IS A GUESS
You could wrap the divide in another function. I don't know if the Viper decorator will propagate but it's worth testing.
Also test the speed of `def inverse(self)` with and without @micropython.viper to make sure that calling the non-Viper function that does the divide from the Viper `def inverse(self)` doesn't cancel the Viper-ness of the caller i.e. `def inverse(self)`.

Post Reply