Skip to content

Commit f746bd3

Browse files
authored
Merge pull request #9 from hpyproject/hpy
Update the HPy branch
2 parents 32d7bd4 + a7f23c3 commit f746bd3

18 files changed

Lines changed: 314 additions & 182 deletions

.github/workflows/tests.yml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
name: Tests
2+
3+
on: [pull_request]
4+
5+
jobs:
6+
build:
7+
runs-on: ubuntu-latest
8+
strategy:
9+
max-parallel: 5
10+
matrix:
11+
python-version: ['3.8', '3.9', '3.10']
12+
13+
steps:
14+
15+
- name: Setup Julia
16+
uses: julia-actions/setup-julia@v1
17+
18+
- name: Set up Python ${{ matrix.python-version }}
19+
uses: actions/setup-python@v4
20+
with:
21+
python-version: ${{ matrix.python-version }}
22+
23+
- name: Install dependencies
24+
run: |
25+
# install HPy from source if depending on a dev version
26+
# git clone -b master --single-branch https://github.com/hpyproject/hpy
27+
# git checkout 1234abcd
28+
# cd hpy
29+
# pip install .
30+
pip install numpy cython pytest transonic pythran 'setuptools>=60.2' 'hpy>=0.9.0rc1'
31+
32+
- name: Checkout
33+
uses: actions/checkout@v3
34+
with:
35+
fetch-depth: 0
36+
37+
- name: build
38+
run: |
39+
python setup.py develop
40+
python setup.py --hpy-abi=universal develop
41+
42+
- name: Run tests
43+
run: |
44+
pytest -s
45+
46+
- name: Run bench
47+
run: |
48+
cd bench
49+
make bench_hpy
50+
make

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
*.egg-info/*
33
*/__pycache__/*
44
build
5+
.eggs
56

67
*.so
78
.vscode

.travis.yml

Lines changed: 0 additions & 16 deletions
This file was deleted.

LICENSE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
BSD 3-Clause License
22

33
Copyright (c) 2020, Pierre Augier
4+
Copyright (c) 2021, 2023, Oracle and/or it's affiliates
45
All rights reserved.
56

67
Redistribution and use in source and binary forms, with or without

Makefile

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,27 @@ PYTHON := python
44
endif
55

66
all:
7+
make develop_universal
8+
ifeq ($(PYTHON),python)
9+
make build_ext
10+
endif
11+
12+
develop:
13+
$(PYTHON) setup.py develop
14+
15+
develop_universal:
16+
$(PYTHON) setup.py --hpy-abi=universal develop
17+
rm -f piconumpy/_piconumpy_hpy.py
18+
19+
pip:
720
$(PYTHON) -m pip install -e .[dev]
821

22+
build_ext_universal:
23+
$(PYTHON) setup.py --hpy-abi=universal build_ext -if
24+
25+
build_ext:
26+
$(PYTHON) setup.py build_ext -if
27+
928
full:
1029
$(PYTHON) -m pip install -e .[full]
1130

@@ -18,6 +37,7 @@ tests:
1837

1938
clean:
2039
rm -f piconumpy/*.so
40+
rm -rf build dist piconumpy.egg-info
2141

2242
black:
2343
black -l 82 .

README.md

Lines changed: 80 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
[![Build Status](https://travis-ci.org/paugier/piconumpy.svg?branch=master)](https://travis-ci.org/paugier/piconumpy)
44

5-
**An experiment about Numpy and pyhandle/hpy**
5+
**An experiment about Numpy and HPy**
66

77
The C API of CPython is one of the cause of the success of Python in scientific
88
computing. In particular, Numpy (and all the Python scientific stack) is built
@@ -11,7 +11,7 @@ issue for the future of scientific Python (see [1], [2], [HPy]).
1111

1212
[1]: https://faster-cpython.readthedocs.io/
1313
[2]: https://morepypy.blogspot.com/2019/12/hpy-kick-off-sprint-report.html
14-
[HPy]: https://github.com/pyhandle/hpy
14+
[HPy]: https://github.com/hpyproject/hpy
1515

1616
[HPy] is a very ambitious and promissing project to design a new and better C
1717
API for interacting with Python interpreters. It should allow people to write
@@ -60,6 +60,11 @@ such codes using Numpy).
6060

6161
## Install and run the benchmarks
6262

63+
**Warning:** PicoNumpy now depends on HPy, which still has to be installed from
64+
the [Git repository](https://github.com/hpyproject/hpy). For now, the
65+
installation is a bit more complex that what is described here (more about this
66+
[here](#more-precise-notes-on-how-to-install-and-run-the-benchmarks-with-PyPy)).
67+
6368
`make` should install the package in editable mode. `cd bench; make` should run
6469
the benchmarks. For the benchmarks, Julia is used for a good comparison point
6570
so the command `julia` has to be available.
@@ -85,106 +90,97 @@ make profile METHOD="purepy"
8590
make profile METHOD="cython"
8691
```
8792

93+
### More precise notes on how to install and run the benchmarks with PyPy
94+
95+
Download and extract a nightly PyPy build
96+
<https://buildbot.pypy.org/nightly/>. Add to the `PATH` environment variable
97+
the path of the directory containing the `pypy` executable (something like
98+
`~/opt/pypy-c-jit-101190-b661dc329618-linux64/bin`). Then, you should be able
99+
to run:
100+
101+
```bash
102+
pypy -m ensurepip
103+
pypy -m pip install pip -U
104+
pypy -m pip install numpy cython pytest transonic pythran
105+
```
106+
107+
We need to install the correct version of HPy for the version of PyPy we are using:
108+
109+
```bash
110+
pypy -c "import hpy.universal as u; print(u.get_version())"
111+
```
112+
113+
gives `('0.0.2rc2.dev12+gc9660c2', 'c9660c2')`.
114+
115+
```bash
116+
cd ~/Dev/hpy
117+
# update to the correct commit
118+
pypy setup.py develop
119+
```
120+
121+
Now we can build-install PicoNumpy:
122+
123+
```bash
124+
cd ~/Dev/piconumpy
125+
pypy setup.py --hpy-abi=universal develop
126+
```
127+
128+
And run the benchmarks with:
129+
130+
```bash
131+
export PYTHON="pypy"
132+
make clean
133+
make bench_hpy
134+
make
135+
```
136+
88137
## Few results
89138

90-
As of today (5 March 2020), HPy is not yet ready!
139+
As of today (6 July 2021), HPy is not yet ready for high performance, but at
140+
least (with HPy 0.0.2) it runs !
91141

92-
### At work (meige8pcpa79, Intel(R) Xeon(R) CPU E5-1603 v3 @ 2.80GHz)
142+
### At home (Intel(R) Core(TM) i5-8400 CPU @ 2.80GHz)
93143

94144
- With CPython
95145

96-
```raw
97-
Julia : 1 * norm = 0.00534 s
98-
Transonic-Pythran : 0.564 * norm
99-
Numpy : 18.2 * norm
100-
PicoNumpy (purepy) : 23.7 * norm
101-
PicoNumpy (purepy_array) : 21.7 * norm
102-
PicoNumpy (Cython) : 15.6 * norm
103-
PicoNumpy (CPython C-API) : 4.7 * norm
146+
```
147+
Julia : 1 * norm = 0.00196 s
148+
PicoNumpy (CPython C-API) : 9.42 * norm
149+
PicoNumpy (HPy CPy ABI) : 9.95 * norm
150+
PicoNumpy (HPy Universal) : 10.4 * norm
151+
Transonic-Pythran : 0.497 * norm
152+
Numpy : 27.5 * norm
153+
PicoNumpy (purepy) : 37.3 * norm
154+
PicoNumpy (purepy_array) : 37.7 * norm
155+
PicoNumpy (Cython) : 28.9 * norm
104156
```
105157

106158
- With PyPy3
107159

108-
```raw
109-
Julia : 1 * norm = 0.00534 s
110-
Transonic-Pythran : 0.603 * norm
111-
Numpy : 183 * norm
112-
PicoNumpy (purepy) : 2.4 * norm
113-
PicoNumpy (purepy_array) : 3.73 * norm
114-
PicoNumpy (Cython) : 135 * norm
115-
PicoNumpy (CPython C-API) : 17.8 * norm
160+
```
161+
Julia : 1 * norm = 0.00196 s
162+
PicoNumpy (CPython C-API) : 34.1 * norm
163+
PicoNumpy (HPy Universal) : 12.8 * norm
164+
Transonic-Pythran : 0.539 * norm
165+
Numpy : 232 * norm
166+
PicoNumpy (purepy) : 4.39 * norm
167+
PicoNumpy (purepy_array) : 6.33 * norm
168+
PicoNumpy (Cython) : 274 * norm
116169
```
117170

118-
### At home (Intel(R) Core(TM) i5-8400 CPU @ 2.80GHz)
171+
#### Simpler benchmarks (bench/bench_cpy_vs_hpy.py)
119172

120173
- With CPython
121174

122-
```raw
123-
Julia : 1 * norm = 0.00176 s
124-
Transonic-Pythran : 0.73 * norm
125-
Numpy : 37.6 * norm
126-
PicoNumpy (purepy) : 46.4 * norm
127-
PicoNumpy (purepy_array) : 41.9 * norm
128-
PicoNumpy (Cython) : 31.4 * norm
129-
PicoNumpy (CPython C-API) : 9.22 * norm
175+
```
176+
CPython C-API: 1.92 seconds
177+
HPy [Universal]: 2.08 seconds
178+
HPy [CPy ABI]: 2.02 seconds
130179
```
131180

132181
- With PyPy3
133182

134-
```raw
135-
Julia : 1 * norm = 0.00176 s
136-
Transonic-Pythran : 0.797 * norm
137-
Numpy : 326 * norm
138-
PicoNumpy (purepy) : 4.71 * norm
139-
PicoNumpy (purepy_array) : 7.48 * norm
140-
PicoNumpy (Cython) : 243 * norm
141-
PicoNumpy (CPython C-API) : 36.6 * norm
142183
```
143-
144-
## CPython C-API usage in PicoNumpy
145-
146-
It is the first time that I wrote a Python extension by hand (without Cython or
147-
Pythran) and moreover, there are nearly no checks and I didn't pay attention to
148-
reference counting!
149-
150-
List obtained from `grep -rwoh 'Py[_A-Z].[a-zA-Z_]*' | sort | uniq`:
151-
152-
```raw
153-
PyArg_ParseTupleAndKeywords
154-
PyCFunction
155-
Py_DECREF
156-
PyErr_NoMemory
157-
PyErr_SetString
158-
PyExc_TypeError
159-
PyFloat_AsDouble
160-
PyFloat_FromDouble
161-
PyFloatObject
162-
Py_INCREF
163-
PyList_Check
164-
PyList_GET_ITEM
165-
PyList_New
166-
PyList_SetItem
167-
PyList_Size
168-
PyLong_AsLong
169-
PyMemberDef
170-
PyMethodDef
171-
PyMODINIT_FUNC
172-
PyModule_AddObject
173-
PyModule_Create
174-
PyModuleDef
175-
PyModuleDef_HEAD_INIT
176-
PyNumber_Check
177-
PyNumberMethods
178-
PyObject
179-
PyObject_HEAD
180-
PyObject_New
181-
PySequenceMethods
182-
Py_ssize_t
183-
Py_TPFLAGS_DEFAULT
184-
Py_TYPE
185-
PyType_GenericNew
186-
PyTypeObject
187-
PyType_Ready
188-
Py_UNUSED
189-
PyVarObject_HEAD_INIT
184+
CPython C-API: 5.75 seconds
185+
HPy [Universal]: 2.11 seconds
190186
```

bench/Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,7 @@ profile: tmp.py
2424
$(PYTHON) profile_piconumpy.py $(METHOD)
2525
# with gprof2dot and graphviz (command dot)
2626
gprof2dot -f pstats tmp.pstats | dot -Tpng -o tmp_$(METHOD).png
27-
eog tmp_$(METHOD).png
27+
eog tmp_$(METHOD).png
28+
29+
bench_hpy:
30+
$(PYTHON) bench_cpy_vs_hpy.py

bench/bench.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ function board(X_0::Array, b::Float64)
1313
p = (2*π)/10.0
1414
q = (2*π)/4.0
1515

16-
H = -a*x0 - b*cos(p*x0)*cos(q*y0)
1716
H_x = -a + b*p*sin(p*x0)*cos(q*y0)
1817
H_xx = b*p^2 * cos(p*x0)*cos(q*y0)
1918
H_y = b*q*cos(p*x0)*sin(q*y0)

bench/bench_array1d.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ def runge_kutta_step(f, x0, dt, t=None):
1313
k2 = f(t, x0 + k1 / 2) * dt
1414
k3 = f(t, x0 + k2 / 2) * dt
1515
k4 = f(t, x0 + k3) * dt
16-
x_new = x0 + (k1 + 2 * k2 + 2 * k3 + k4) / 6
16+
# workaround for a pypy bug
17+
# see https://foss.heptapod.net/pypy/pypy/-/issues/3509
18+
# x_new = x0 + (k1 + 2 * k2 + 2 * k3 + k4) / 6
19+
x_new = x0 + (k1 + k2 * 2 + k3 * 2 + k4) / 6
1720
return x_new
1821

1922

0 commit comments

Comments
 (0)