PyPy Project looking for sponsorship to add support for Apple Silicon
morepypy.blogspot.com
morepypy.blogspot.com
But the value of a second implementation of a language goes beyond the immediate "who uses this in practice". It can be a fertile bed for innovation and for new ideas, and provides a contrast to the nay sayers. For instance, the recent pitch to vastly improve CPython's speed has some roots in ideas that were tested out in PyPy. CFFI [1], revdb [2] and vmprof [3] all started as PyPy projects. Some of these turned out to be very popular, some less so. The next project in this line is HPy [4] (still alpha-quality), which is trying to re-think the C-API for Python to make it even easier to interface with.
RPython [5], the language behind PyPy, is also an accessible playground for dynamic language research.
[0] https://crossbar.io/about/FAQ/#python-runtime
[1] https://cffi.readthedocs.io/en/latest/
[2] https://morepypy.blogspot.com/2016/07/reverse-debugging-for-...
[3] https://vmprof.readthedocs.io/en/latest/
I wonder if sponsoring pypy instead of the PSF might be a way for people that want "a focus on performance improvements, instead of fancy features" to vote with their wallets
python.tar.gz would be exactly the same if the donations were zero.
All the more reason to switch to donating PyPy.
All of which would not exist without python.tar.gz.
As for the PyCon expenditure, it's certainly the kind of thing I'd never attend, but there can be no doubt the existence of the conference has strengthened and grown Python's user base, and it is open to everyone should they wish to attend. Meanwhile, $97k annual to operate a package registry with literally millions of downloads per month that tens of thousands of companies depend on sounds like an amazing bargain to me.
PyCon was always meant to be affordable for as many people as it could be - via low prices and financial aid for many. Those conferences helped create many of the relationships that drove key parts of the Python ecosystem. In addition, there are/were typically dedicated time for code sprints following the main conference. Important work happened there, often for key parts of the Python codebase or key libraries. While the budget numbers don’t say explicitly “development support” people shouldn’t presume PyCon does nothing for the language itself. Open Source conferences are not like commercial conferences. It’s community driven rather than marketing driven. That difference matters.
It was a smaller world when I was involved but it was and still is something special.
I was surprised it would be so low given all the Dockerfiles building in CI systems everywhere and apparently from
It looks like tens of millions per day a billions per month
edit which is ~115 downloads per second, which is nothing a beefy VM couldn’t handle.
#standardSQL
SELECT EXTRACT(HOUR FROM timestamp) hour, COUNT(*) AS num_downloads
FROM `the-psf.pypi.file_downloads`
WHERE DATE(timestamp)
BETWEEN DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
AND CURRENT_DATE()
GROUP BY hour
ORDER BY num_downloads
Gives us 6.956 billion downloads in the past 30 daysWith hour 15 clocking in at around 2,964 requests/sec -- mean. This is still not representative of peak instantaneous traffic, which I'd hazard a guess is somewhere closer to 10x that number.
Now factor in the 'usual' case where the CDN absorbs 70% of this, and you're still left with a service that is non-trivial to run and support 24/7. PyPi manages to only have a few small downtimes per year.
Total expenses for 2019 were a bit under $3.7m. "Program service expenses" were $2.6m, about 70% of total expenses. Of this $2.2m, 75.3% was spent on PyCon. So overall, around 53% of PSF spending in 2020 went to PyCon ($1.9m). In 2018, it was around 57%.
The next-biggest expense was staffing ($694k), at around 19% in 2019.
https://github.com/python/cpython/pulls?q=+label%3Asprint (and that link doesn’t capture the PEPs hashed out among other things.)
Also, why the hell make a new account for each comment?
https://codeforces.com/contests has around 20-30k participants per contest, with contests happening roughly twice a week. I would say around 10% of them use python, with the vast majority choosing pypy over cpython.
I would guesstimate at least 100k lines of pypy is written per week just from these contests. This covers virtually every textbook algorithm you can think of and were automatically graded for correctness/speed/memory. Note that there's no special time multiplier for choosing a slower language, so if you're not within 2x the speed of the equivalent C++, your solution won't pass! (hence the popularity of pypy over cpython)
The sheer volume of advanced algorithms executed in pypy gives me huge amount of confidence in it. There was only one instance where I remember a contestant running into a bug with the jit, but it was fixed within a few days after being reported: https://codeforces.com/blog/entry/82329?#comment-693711 https://foss.heptapod.net/pypy/pypy/-/issues/3297.
We were using pypy because it was better for our use case at one point but then later on we retested cpython and found the picture had changed.
We believe this was due to significant improvements in the regex engine for cpython over the period, but could also be due to our code base changing.
The point being it is not a given that pypy is faster.
For example, using CPython, if you try to make an array of a million ints, you won't get `int[1000000]` in your memory layout. Each int would actually be an object, which is huge and inefficient to reference (they are something like 24+ bytes each).
PyPy on the other hand, works as expected.
I think the more important point is that PyPy when written like C code, can actually get within 2x of the performance of C code. If it's any slower, python won't be a viable language in competitive programming at all.
(CPython is sometimes still used on other platforms like atcoder.jp, but only because they allow third party libraries like numba and numpy which can fill the same role pypy does)
PyPy shouldn't be the new default, but neither should be CPython.
I think this is the first time I've seen someone suggest that competitive programming has much bearing on “real-world use cases”.
I’ve also had great success using pypy to accelerate preprocessing steps (when they don’t rely on incompatible c libraries) for machine learning pipelines. It’s the most painless performance enhancement trick in my toolbox before I reach for concurrency (in which case I reach for joblib or Dask).
The one oddity I’ve noticed is that using tuples (including things like named tuples) often speeds up CPython by a lot, but even plain tuples can slow down pypy on the same code—in some cases pypy winds up slower than CPython.
In any case, I’m low key in love with pypy, even though I can’t use it for _everything_.
I'd love for this to be addressed. namedtuple should be lowered into a fixed sized struct, great opportunity for PyPy to show wins in both memory, memory bandwidth and compute. Add in type stability and PyPy should approach native speeds just by adding in namedtuple.
We've actually tried using some of the more traditional libs (Pandas et al) with CPython, but there's always a pure-python bottleneck (e.g. SQLAlchemy).
Performance is important to our clients and trying to keep everything performance critical in C extensions / NumPy would be kind of risky for us when adding new functionality, so pypy's guarantee of more speed pretty much across the board is awesome.
There are downsides of course - higher memory usage, longer boot times, some more obscure libraries being unsupported - but on the whole, it's a good choice for us
And of course, Apple is not investing in these ports, at least as far as I know. They just rely on what other arm64 players did in the ecosystem before Apples rolled out M1; respectively lets developers figure out the remaining porting.
As much as I hate to say this, IBM does handle porting things to ppc64 right - you can find IBM contributed code and optimizations anywhere you look. For many packages, porting to arm64 was a matter of "does it have ppc64 support? if so, it can be reused for arm64" ...
Disclaimer - used to be a contractor porting stuff to arm64 for a couple of years.
Lots of contractors and always shuffling/changing projects they work on.
You are supposed to use it through Accelerate.framework, which exposes a more traditional interface to that capability.
Apple Silicon has more than one ISA extension.
There is also the x86 memory ordering extension used by Rosetta 2.
Maybe there are yet others too.
That one isn't really a requirement either, and is handled fully in kernel mode.
Wkdm and friends are handled fully in kernel mode.
APRR? Not a strict requirement for user-mode, JIT regions are just left as RWX without it.
So apple nopes out of it. They rely on the initial boost they got from GPL software. They do some MIT/BSD licensed stuff (and publish some of it but not everything). Every year less and less happens, unless it's their own language/etc.
They do have nice gradients and round corners though. :)
I have notified my superior, that I am not able to work properly in January when I am back from a 2 months LOA were I privately switched everything over onto a WIN10 with WSL2 running Ubuntu.
I am not missing a thing currently. OK - I know at one point I will probably be missing Keynote.
PyPy is MIT licensed.
You mean BSD? That's how Darwin is licensed.
macOS ships with some GPL2 software, along with its BSD/MIT/Apache-licensed Darwin layer. (The GP is presumably implying that having this GPL2ed software "built-in", helped macOS entrench itself as a useful POSIX for developers — at least before tools like MacPorts/Homebrew came along to make acquiring this type of software "after-market" simple.)
For any GPL2 software macOS makes use of that then transitions to GPL3 licensing, Apple can't actually adopt the GPL3ed version (exactly because of the "runs anywhere" clause in the GPL3) and so instead, macOS keeps the old, GPL2ed version of the software around, left to rot. Eventually, if it's something critical, Apple removes their dependency on said software, replacing it with something that's not GPLed.
This is the story of Bash on macOS: it was regularly updated for as long as it was GPL2-licensed; then it got "stuck" on the last GPL2 version when GNU transitioned Bash to GPL3 licensing. The Bash on macOS remained on that old version for the longest time, before finally being swapped out for Zsh in Catalina.
What count as "investing in these ports"? Does submitting patches to CPython (and many other open source projects, including NumPy) for macOS 11 and Apple Silicon count? Here's a list of Apple-submitted PRs on python/cpython: https://github.com/python/cpython/pulls?q=is%3Apr+author%3Al... Also some co-authored patches excluded by the search. See https://bugs.python.org/issue41100 for more related PRs. Your subsequent comments about IBM seem to imply that these do count.
I'm also curious about who's "we" in "we reached out to the python community about wheels and arm64".
---
Edit: Forgot to say, arm wheels have been supported for many years now (not sure about the specific timeline of aarch64 support, but if 32-bit arm was supported I don't see why aarch64 wouldn't be). Maybe most famously there's https://www.piwheels.org/ for RPis. Are you talking about aarch64 support on PyPI/warehouse?
In my case, "we" referred to the working group of ARM contractors working a very specific higher level project (at the time we were doing some cloud/openstack/k8s stuff, which indirectly required some python packages). Note that the way contractors were assigned to projects at the time implied that sometimes you'd run into overlaps, e.g. some packages we needed had already been ported by a different team of contractors for a different project a while back. Sometimes multiple teams would hit the same missing port at the same time, most of the time we could sync and team up by escalating that through the right channels, but sometimes we'd just end up duplicating work items and end up with two different sets of patches/ports.
About wheels, someone else in my team handled that, so I'm not that familiar with the issue - it might have been a particular package that was lacking arm64 wheels or it might have been impractical to use a different repository only for arm64 (in general we'd try avoiding using separate resources based on architecture and we definitely did prefer the arch-agnostic approaches, e.g. debian repository URLs are arch-independent, dockerhub manifests allowed using the same container image names etc.). We were interested PyPI at the time (couple of years ago), maybe the situation has improved meanwhile, but we just accepted compilation at install time as a good enough solution.
It's not available yet but it should be a good option once they become available, you can immediately start the process of applying for the credits.
This way you would get access to the required hardware without any costs and without having to maintain it. They are designed from the ground up towards such CI/development use cases.
You can also use the same credits for getting access to Intel and ARM Linux, as well as Windows EC2 instances. This may improve your project's CI and build times.
Disclaimer: I work at AWS.
It shouldn't matter what type of instances are launched and the credits cover any other services, not just the EC2 compute, as long as the bills are less than the monthly credits.
PyPy doesn't get much love from Python community overall, too focused on CPython + C, no matter on which platform.
Hence why efforts like Julia and Chapel spring to life.
Out of curiosity, what is a ballpark, a rough estimate of the "sufficient money" for a project like this?
> I would do it myself for a small amount of money.
Protip: patrons and sponsors do not want to know all the details, and certainly not up-front. What they want is to know what you're asking for, what you offer in return and then (briefly) how one leads to the other. Thus:
We make Pypy, which does X and is used by Y people, including projects such as Z, z, and z'. We'd love to bring Pypy to Apple's exciting new M1 hardware, but that needs resources.
We're looking for $CASH_MONEY to buy some M1 hardware that we can develop, test against, and eventually run the repository on. With #NUM_MACHINES available, we believe was can have PyPy available to all M1 developers by %CALENDAR_MONTH. We also like eating and drinking and if you send us more money we will spend some of it on !GOOD_TIME(HAVING).
The whole approach of 'we're not asking for much, just x would help' is how volunteers talk to each other, minimizing their ask so that reorienting effort is not too burdensome for anyone. But how you talk to each other is not a good way to talk to external readers, because it requires effort to parse what you are getting at and then further effort to negotiate and arrange everything which is a distraction from their own concerns. Many people would rather just give you some cash and sign up for a monthly progress update.
There's a reason services Kickstarter etc. work so well: they save the donors time and entanglement. Just set up : PyPy on Mac M1 for $5000?' or similar and make it easy for people to throw money at you.
I've come to the realization that, to get more performance out of python, the most pythonic way is to simply use PyPy, rather than try and hack your way around issues like attributes requiring dict lookups, access to locals() being faster than globals(), etc.
I'd politely ask you to reconsider. You'd basically be subsidising work that benefits the World's highest-capitalised company, to whom the investment in this port would be a fraction of a second's profit.
Boycotting noncollaborating hardware vendors by FOSS is LONG overdue. In my opinion there's too much catering to companies that do not wish to be helped.
Though, we can't forget that, aarch64 support also helps other ARM vendors, open hardware, theoretically. So there's that.
Apple ships a Python.framework and a user-facing python3 installation through CLT, so I expect them to contribute to CPython. And they did. They don’t ship anything remotely related to PyPy, so I don’t expect them to do anything. A gesture would be nice, but that’s being nice.
If it takes special work, yes.
Ungrateful to just demand compatibility but provide none back, Apple hardware is increasingly hostile to 3rd party code running on it. They're not worth it.
Instead, it's better to provide that value-add on open platforms.
"Boycotting noncollaborating hardware vendors by FOSS is LONG overdue"
Is this serious. What does apple even use PyPy for?
We need to boycott APPLE because of a group making software they don't use? Huh?
I suppose we will need to boycott my home builder because they don't support my mattress company that works with the house they built me?
Apple uses python. They ship python3. They contribute to python. That get's folks into python, that get's folks interested in ARM64, so python work and golang and others start targeting ARM64 more, which in turn will probably help Microsoft and AWS whenever they inevitably release ARM products into production. That's the traditional open source cycle. We don't boycott these folks.
One issue - Apple WILL NOT ship GPLv3. Many other companies are EXTRMELY careful about shipping GPLv3 (I wouldn't be surprised if google was strict hell no on GPLv3). So there is going to be some fragmenting as the GNU folks and other put out things like Bash as GPLv3. Probably from the same folks that boycott, so it may not matter in the end.
I suppose you do need to boycott the home builder if they wish to sleep in your bed and also place demands on it.
They want 3rd party software, yet make it increasingly harder to both run and develop it on their hardware.
In the same category is Nvidia, so much effort goes into supporting their hardware but they don't really wish to play ball for more than a decade now. Why bother with such cunts? There are other vendors that are much nicer.
PyPy (claims to, at least) already supports arm64; this would just be Apple-silicon specific work.
There are many sites and services where a rewrite in a new language is just not viable, and I still would recommend Python-everywhere to startups doing things remotely associated with data. So PyPy would be a tide that would lift many boats.
We had so much less baseline load afterwards that we were able to scale down a bunch of instances. The transition only took a few hours of effort fixing one or two incompatible dependencies, so it paid for itself in savings quickly, especially vs an approach of trying to rewrite the slowest bits in a faster language.
Strictly speaking, "CPU bound" is not an adjective that can be used to describe tasks. It's one that describes a particular program solving a particular task under a particular configuration. I've done no analysis on this myself, but I would be more than willing to believe that a CPU-bound job might be only a CPython-to-MyPy's worth of speedup away from instead being memory- or disk-bound.
It can be hard to tell the difference, too, since being stalled out while waiting on the memory controller shows up as CPU activity in htop.
If you are after deep profiling, you should definitely give it a try. My recollection is totally positive.
[0] https://software.intel.com/content/www/us/en/develop/tools/o...
For me this always just consists of reading a bunch of files in and then doing some basic aggregation on them. Years ago I benchmarked Python vs. PyPy and found no real benefit to it.
Here is the link to that if you'd like to read it:
Haven't you just answered your own question? We know that people want to run CPU bound tasks in Python so much that they went to the effort of writing native modules because they couldn't do it in Python.
> python's lackluster concurrency support
This is a common misconception - Python actually has fully concurrent threads already.
This isn't true - they are fully concurrent.
The GIL prevents parallelism - not concurrency.
When a Python thread is holding on to the GIL (running Python bytecode), how many other Python threads can concurrently run in the same process?
The answer is zero.
Sure the interpreter releases the GIL every n bytecode ops, and C extensions can release the GIL before doing anything IO bound and reacquire it (i.e wait for it) afterwards, but that isn’t full concurrency, in my books.
You've been tricked by jargon. It's a common misconception. In this context, "concurrency" has a specific meaning that is different from the everyday one you're using in this sentence.
For a good introduction to what the two words mean in a software engineering context, check out this written version of Rob Pike's talk, "Concurrency is not Parallelism."
https://rakhim.org/summary-of-concurrency-is-not-parallellis...
The very tl;dr summary is:
> Concurrency is composition of independently executing things. . . Parallelism is simultaneous execution of multiple things.
When Python's threading model was implemented, parallelism just wasn't much of a concern. CPUs had a single core and could therefore only be working on one thing at a time. (In a macro sense; pipelining and supersclar architectures were still a thing, but not super relevant here.) Multithreading was not a way to do multiple things at once, it was just a way to ensure that some long-running calculation would not cause the program to lock up by, e.g., preventing it form responding to event queues in a timely manner. This was done by, not by running things in parallel, but by switching back and forth among them them very quickly.
Python's GIL was designed for this kind of situation. It's there to ensure that nothing bad happens if one of those context switches happens in the middle of a sensitive operation. Which is, strictly speaking, a concurrency concern and not a parallelism concern.
(It's also possible to have parallel work that is not concurrent, in which case locks are not necessary. But just because it's common for parallelism and concurrency to co-occur does not mean that they are the same thing.)
It's written in Python and works fine to process thousands of jobs per day. Once you start having tens of thousands of jobs in the queue, it gets slow enough that it can back things up. This compounds the problem, eventually resulting in the whole thing crashing.
By switching the interpreter to PyPy, I was able to keep the data pipeline running at that scale without having to rewrite anything.
Other languages don't have that same cycle, and Python has a LARGE amount of freely available packages that are able to help launch even quicker by not having to necessarily write everything oneself.
So at that point it comes down to what are you fastest in?
0. Because you don't have time to deal with the mess that C++ has become, and the amount of please-repeat-yourself-a-million-times crap you have to deal with (cmake files, header files, they give us a goddamn spaceship operator but not basic necessities like string split/join methods)
1. There are many use cases where faster execution time is nice to have, e.g. when results can be cached for a long time, or if it's a one-off data analysis script, but human time is far more expensive. If it costs $1000 more in engineer hours to write C++ instead of Python for that script that's only going to be run 10 times, that isn't a worthwhile tradeoff. Hell you could buy a new GPU for that money.
2. Because the same exact file can be deployed on arm32, arm64, and x86
3. Because CPU-intensive stuff is largely already optimized by numpy, numba, tensorflow, pytorch, etc.
I thought everyone who used 64-bit ARM used ARM's AAPCS64 (https://github.com/ARM-software/abi-aa/blob/master/aapcs64/a...), so the register usage and FFI calling convention should be the same as on Linux and Windows. What did Apple do differently that would affect the PyPy JIT?