Skip to content

Commit eabda0e

Browse files
authored
[mypyc] Add experimental C extension librt.vecs (part 1/2) (#20653)
The extension defines the `vec[t]` type and associated functions. `vec` is a sequence type optimized for use in compiled code. `vec` values are immutable and represented internally as a struct with a length and buffer fields. Only the buffer object is mutable. This allows very fast access to the length field in compiled code, but any operations that change the length of a `vec` value must return a modified `vec` value (e.g. `append`). Related issue: mypyc/mypyc#840. This PR doesn't define any mypyc primitives -- only use via generic Python operations is supported at this point. I have a local branch that implements efficient mypyc primitives for vecs, and there are significant performance gains over `list` objects in benchmarks. This PR only adds support for item types `i64`, `i32`, `i16`, `u8`, `float` and `bool` (e.g. `vec[i32]`). A follow-up PR will add support for reference item types (e.g. `vec[str]`) and nested vecs. See the comment at the top of `mypyc/lib-rt/vecs/librt_vecs.c` for a more detailed description. It also documents some implementation details of reference item types and nested vec types (which are not included yet in this PR). Currently a fairly minimal API is supported. This example shows some of the supported operations: ``` from librt.vecs import vec, append, remove, pop v = vec[i32]([2, 3]) v[1] = v[0] + 2 v = append(v, 4) v = remove(v, 2) v, x = pop(v) ``` Additionally, read-only slicing and equality is supported. The `in` operator and iteration only work through the sequence API, but I will add proper support for these later on.
1 parent e711be3 commit eabda0e

17 files changed

Lines changed: 2845 additions & 0 deletions

File tree

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from typing import TypeVar, Generic, Iterable, Iterator, overload
2+
from mypy_extensions import i64
3+
4+
T = TypeVar("T")
5+
6+
class vec(Generic[T]):
7+
@overload
8+
def __init__(self) -> None: ...
9+
@overload
10+
def __init__(self, items: Iterable[T], /) -> None: ...
11+
def __len__(self) -> i64: ...
12+
@overload
13+
def __getitem__(self, i: i64, /) -> T: ...
14+
@overload
15+
def __getitem__(self, i: slice, /) -> vec[T]: ...
16+
def __setitem__(self, i: i64, o: T, /) -> None: ...
17+
def __iter__(self) -> Iterator[T]: ...
18+
19+
def append(v: vec[T], o: T, /) -> vec[T]: ...
20+
def remove(v: vec[T], o: T, /) -> vec[T]: ...
21+
def pop(v: vec[T], i: i64 = -1, /) -> tuple[vec[T], T]: ...

mypyc/build.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,20 @@ class ModDesc(NamedTuple):
104104
],
105105
["base64"],
106106
),
107+
ModDesc(
108+
"librt.vecs",
109+
[
110+
"vecs/librt_vecs.c",
111+
"vecs/vec_i64.c",
112+
"vecs/vec_i32.c",
113+
"vecs/vec_i16.c",
114+
"vecs/vec_u8.c",
115+
"vecs/vec_float.c",
116+
"vecs/vec_bool.c",
117+
],
118+
["vecs/librt_vecs.h", "vecs/vec_template.c"],
119+
["vecs"],
120+
),
107121
]
108122

109123
try:

mypyc/ir/deps.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ def get_header(self) -> str:
4848

4949
LIBRT_STRINGS: Final = Capsule("librt.strings")
5050
LIBRT_BASE64: Final = Capsule("librt.base64")
51+
LIBRT_VECS: Final = Capsule("librt.vecs")
5152

5253
BYTES_EXTRA_OPS: Final = SourceDep("bytes_extra_ops.c")
5354
BYTES_WRITER_EXTRA_OPS: Final = SourceDep("byteswriter_extra_ops.c")

mypyc/lib-rt/setup.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,5 +132,19 @@ def run(self) -> None:
132132
include_dirs=[".", "base64"],
133133
extra_compile_args=cflags,
134134
),
135+
Extension(
136+
"librt.vecs",
137+
[
138+
"vecs/librt_vecs.c",
139+
"vecs/vec_i64.c",
140+
"vecs/vec_i32.c",
141+
"vecs/vec_i16.c",
142+
"vecs/vec_u8.c",
143+
"vecs/vec_float.c",
144+
"vecs/vec_bool.c",
145+
],
146+
include_dirs=[".", "vecs"],
147+
extra_compile_args=cflags,
148+
),
135149
]
136150
)

0 commit comments

Comments
 (0)