Commit 5169f917 authored by Pierre Augier's avatar Pierre Augier
Browse files


parent 66e7394a51cc
......@@ -4,5 +4,6 @@ For developers
.. toctree::
:maxdepth: 1
\ No newline at end of file
# Typing
With Transonic, we'd like to use clean and "pythonic" way to declare types. With recent versions of Python (>= 3.6), we can use type annotations.
Unfortunately, there is not yet a standard way to declare array types in
Python. Let's summarize how array types are declared in Pythran, Cython and
## Pythran
Pythran users have to write signatures. The array types can be (see
# contiguous 1d array
# stride 1d array
# contiguous 2d array
# stride 2d array
# contiguous C order 2d array
int32[:,:] order(C)
# contiguous Fortran order 2d array
int32[:,:] order(F)
## Cython
There are many ways to defined array types in Cython.
# 1d np.ndarray
np.ndarray[np.int32_t, ndim=1]
# contiguous 2d np.ndarray (C order)
np.ndarray[np.float64_t, ndim=2, mode='c']
# indirect (pointer) data access
object[np.int32_t, ndim=1]
# 1d memoryview
# contiguous 1d memoryview
# 2d memoryview
np.int32_t[:, :]
# contiguous 2d memoryview (C order)
np.int32_t[:, ::1]
# contiguous 2d memoryview (Fortran order)
np.int32_t[::1, :]
There are even more complicated notations with memoryviews:
Memoryviews are more general (and in general more efficient) but there are
useful not supported features, for example broadcasting!
Not that fused types can be used to define data and array types:
ctypedef fused number:
# memoryview of number
number[:, ::1]
ctypedef fused array2d:[:, ::1]
cython.float[:, ::1]
## Numba
See <>.
import numba
# array from numba types
# same as
numba.types.Array(numba.int32, 1, "C")
It is also possible to pass signature(s) to the `jit` (or `njit`, or
`vectorize`) decorators (the order of the signatures is meaningful).
@vectorize([int32(int32, int32),
int64(int64, int64),
float32(float32, float32),
float64(float64, float64)])
def f(x, y):
return x + y
## Transonic
To define multisignatures from fused types, we can do:
from transonic import Array, Type, NDim, boost
A = Array[Type(int, float), NDim(1, 2), "memview"]
def func(a: A, b: A):
## Issue about fused types
This works with Pythran and it should also work with other backends.
from transonic import Type, boost
T = Type(int, float)
def func(n: int, d: T):
tmp: T
tmp = type(d)(0)
_: int
for _ in range(n):
tmp += d
return tmp
result = func(100, 1)
assert result == 100
assert isinstance(result, int)
result = func(100, 0.1)
assert np.allclose(result, 10.)
assert isinstance(result, float)
Same for this other case (useful for Cython):
import numpy as np
from transonic import boost, Type, Array
A = Array[Type(np.float32, np.float64), "1d"]
def mysum(arr: A):
result: A.dtype
result = arr.dtype.type(0)
i: np.int32
for i in range(arr.shape[0]):
result += arr[i]
return result
data = np.ones(100, dtype=np.float32)
result = mysum(data)
assert np.allclose(result, 100.)
assert result.dtype == np.float32
data = np.ones(100)
result = mysum(data)
assert np.allclose(result, 100.)
assert isinstance(result, (float, np.float64))
# Pythran "bug" here!
assert result.dtype == np.float64
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment