
Hi everyone, my company has a bunch of C apps (mainly the uWSGI application server container and a scriptable DNS server) embedding CPython in their core. We would like to start using PyPy, so our need is having a workable libpypy.so implementation (we do not need it to be compatible with CPython api, we can rewrite those parts, expecially in uWSGI, without problems). I have searched for some work already done, but it looks like no one is pushing it. I apply myself for working on this area (if no-one is already doing it). So if there are no objections, i would start posting my proposals (and code) in the next few days. -- Roberto De Ioris http://unbit.it

Hi Roberto, On Mon, Jul 25, 2011 at 1:42 PM, Roberto De Ioris <roberto@unbit.it> wrote:
Indeed, there is nothing like that so far. We need to think out the kind of C-level API which makes sense for libpypy.so to expose. There are two options: either we tweak a little bit cpyext to expose the CPython C API, or we design some higher-performance PyPy-only C API... For the latter case the first issue is how to store a reference to a PyPy object in C, given that it moves around --- maybe with an indirection, which would be a bit similar to what cpyext does but can be done with much better performance if we are free to design the API. Feel free to come to our IRC channel to discuss things (#pypy on irc.freenode.net). A bientôt, Armin.

Armin Rigo, 25.07.2011 14:31:
Wouldn't it make sense to use the Cython port for PyPy here? Usually, embedding just means that there is a two-way bridge between Python and C (or a C-compatible language). Cython basically gives you this, and allows you to design your C-level API any way you want. However, this means that it has to generate a C module that exports the public C names in one way or another. That won't work with the current approach, which only "compiles" down to Python code that uses ctypes (i.e. the other side). But it shouldn't be too hard to come up with a way to pass calls from the outside C-world into some kind of PyPy API that dispatches them to the appropriate Cython backed implementation. Basically, the external C code would only see a thin generated wrapper for each exported function (or even object) which maps the incoming parameters to ctypes objects, and the complete implementation of the user provided wrapper then runs in PyPy using ctypes. That would allow the PyPy core developers to design an appropriate public convenience C-API for PyPy, and at the same time allow users to design their own specific C-API for their own code, both using the same tool. Stefan

Il giorno 25/lug/2011, alle ore 14:31, Armin Rigo ha scritto:
Sorry for the big late/silence but i spent last days working/hacking on cpyext. I have managed to have a working uWSGI+pypy inverting the initial concept (not very useful, but this is a base for benchmark) : 1) i build the whole uWSGI stack core (so, without cpython plugin) as a shared library 2) i created a uwsgi_pypy c extension: http://projects.unbit.it/hg/uwsgi_pypy/file/7bbae6efc126/uwsgi_pypy.c This extension export a bunch of functions, with the only useful one being uwsgi_pypy.init() This function calls the original main() of the uWSGI server, so effectively pypy lose the process control. 3) i have developed a very raw/minimal plugin for uWSGI that inspect a symbol in the process space. http://projects.unbit.it/uwsgi/browser/plugins/symcall/symcall_plugin.c This symbol is defined in the uwsgi_pypy.c module. So, this is the way uWSGI give control back to pypy at each request. This is an example WSGI-handler implementation (incomplete, it misses post handling, but can already execute werkzeug test app) http://projects.unbit.it/hg/uwsgi_pypy/file/7bbae6efc126/uwsgi-pypy.py Well, running it and benchmarking showed a 10% improvement in response time, so i tried with a more complex app (fibonacci's sequence and some prime number generator) and …damn it destroyed cpython :) it served the double of the connections in half of the time…. So, cpyext looks really in good shape, so (probably) the best way would be tweek it to have a libpypy.so. i will work on the current setup a bit more to have a full WSGI environment, then i will start investigating the original idea (but this time base on cpyext) Thanks for the amazing work -- Roberto De Ioris http://unbit.it JID: roberto@jabber.unbit.it

Hi, 2011/7/25 Roberto De Ioris <roberto@unbit.it>
Good idea! I suppose you already noticed the "--shared" option that already builds a libpypy-c.so. I've never tried it on Linux, but it works at least on Windows, and exposes all C API functions from cpyext. Still missing is the Py_Initialize() function... Could it be as simple as a single call to space.startup()? -- Amaury Forgeot d'Arc

Hi Roberto, On Mon, Jul 25, 2011 at 1:42 PM, Roberto De Ioris <roberto@unbit.it> wrote:
Indeed, there is nothing like that so far. We need to think out the kind of C-level API which makes sense for libpypy.so to expose. There are two options: either we tweak a little bit cpyext to expose the CPython C API, or we design some higher-performance PyPy-only C API... For the latter case the first issue is how to store a reference to a PyPy object in C, given that it moves around --- maybe with an indirection, which would be a bit similar to what cpyext does but can be done with much better performance if we are free to design the API. Feel free to come to our IRC channel to discuss things (#pypy on irc.freenode.net). A bientôt, Armin.

Armin Rigo, 25.07.2011 14:31:
Wouldn't it make sense to use the Cython port for PyPy here? Usually, embedding just means that there is a two-way bridge between Python and C (or a C-compatible language). Cython basically gives you this, and allows you to design your C-level API any way you want. However, this means that it has to generate a C module that exports the public C names in one way or another. That won't work with the current approach, which only "compiles" down to Python code that uses ctypes (i.e. the other side). But it shouldn't be too hard to come up with a way to pass calls from the outside C-world into some kind of PyPy API that dispatches them to the appropriate Cython backed implementation. Basically, the external C code would only see a thin generated wrapper for each exported function (or even object) which maps the incoming parameters to ctypes objects, and the complete implementation of the user provided wrapper then runs in PyPy using ctypes. That would allow the PyPy core developers to design an appropriate public convenience C-API for PyPy, and at the same time allow users to design their own specific C-API for their own code, both using the same tool. Stefan

Il giorno 25/lug/2011, alle ore 14:31, Armin Rigo ha scritto:
Sorry for the big late/silence but i spent last days working/hacking on cpyext. I have managed to have a working uWSGI+pypy inverting the initial concept (not very useful, but this is a base for benchmark) : 1) i build the whole uWSGI stack core (so, without cpython plugin) as a shared library 2) i created a uwsgi_pypy c extension: http://projects.unbit.it/hg/uwsgi_pypy/file/7bbae6efc126/uwsgi_pypy.c This extension export a bunch of functions, with the only useful one being uwsgi_pypy.init() This function calls the original main() of the uWSGI server, so effectively pypy lose the process control. 3) i have developed a very raw/minimal plugin for uWSGI that inspect a symbol in the process space. http://projects.unbit.it/uwsgi/browser/plugins/symcall/symcall_plugin.c This symbol is defined in the uwsgi_pypy.c module. So, this is the way uWSGI give control back to pypy at each request. This is an example WSGI-handler implementation (incomplete, it misses post handling, but can already execute werkzeug test app) http://projects.unbit.it/hg/uwsgi_pypy/file/7bbae6efc126/uwsgi-pypy.py Well, running it and benchmarking showed a 10% improvement in response time, so i tried with a more complex app (fibonacci's sequence and some prime number generator) and …damn it destroyed cpython :) it served the double of the connections in half of the time…. So, cpyext looks really in good shape, so (probably) the best way would be tweek it to have a libpypy.so. i will work on the current setup a bit more to have a full WSGI environment, then i will start investigating the original idea (but this time base on cpyext) Thanks for the amazing work -- Roberto De Ioris http://unbit.it JID: roberto@jabber.unbit.it

Hi, 2011/7/25 Roberto De Ioris <roberto@unbit.it>
Good idea! I suppose you already noticed the "--shared" option that already builds a libpypy-c.so. I've never tried it on Linux, but it works at least on Windows, and exposes all C API functions from cpyext. Still missing is the Py_Initialize() function... Could it be as simple as a single call to space.startup()? -- Amaury Forgeot d'Arc
participants (5)
-
Amaury Forgeot d'Arc
-
Armin Rigo
-
Maciej Fijalkowski
-
Roberto De Ioris
-
Stefan Behnel