Object oriented programming!
OOP is not natively supported by Pythran so it is not a pleasure to use Pythran in Python classes. One needs to rewrite functions in another modules and call these functions in the methods: boring, bad in terms of readability and good to introduce bugs…
With Transonic, one can easily use Pythran for methods:
import numpy as np from transonic import boost @boost class Transmitter: freq: float def __init__(self, freq): self.freq = float(freq) @boost def __call__(self, inp: "float"): """My docstring""" return inp * np.exp(np.arange(len(inp)) * self.freq * 1j) if __name__ == "__main__": inp = np.ones(2) freq = 1.0 trans = Transmitter(freq) def for_check(freq, inp): return inp * np.exp(np.arange(len(inp)) * freq * 1j) assert np.allclose(trans(inp), for_check(freq, inp))
For implementation reasons, we need to decorate the methods (with
@jit) and the classes (with
One has to be very careful with assignments in methods. For example,
self.attr = 1 does not work but
self.myarray[:] = 1 should
work (because it is not a real assignment).
Calling another method in a transonified method is not yet supported!
Function calls in methods are supported!
from transonic import boost def add(a, b): return a + b @boost class MyClass: attr0: float attr1: float def __init__(self, arg): self.attr0 = self.attr1 = 2 * float(arg) @boost def compute(self, number: int): result = 0.0 for _ in range(number): result += add(self.attr0, self.attr1)
We can also use the
jit decorator for methods!
from transonic import boost, jit @boost class OtherClass: """Note that there is no type annotations at all! The Pythran signature is created at run time with the types of the attributes and the arguments. """ def __init__(self, arg): self.attr0 = self.attr1 = 2 * arg @jit def calcul(self, a, b): return a * self.attr0 + b * self.attr1