Skip to content

Cython extension discovery example: interface to Skycalc. - #39

Closed
phn wants to merge 1 commit into
astropy:masterfrom
phn:cython-example
Closed

phn wants to merge 1 commit into
astropy:masterfrom
phn:cython-example

Conversation

@phn

@phn phn commented Oct 31, 2011

Copy link
Copy Markdown
Contributor

Cython extension discovery should be treated the same way as the regular C extension discovery currently implemented; explicitly asking the developer and not automatic discovery. These commits implement a Cython extension discovery scheme that gives developers control over the extension building process. The scenario implemented here is probably as involved as it can be. This is an example, and not intended for direct merging.

The code adds a new sub-package astropy.skypy. This has two modules skyc and astrom, both of which are Cython extension modules. The skyc extension calls functions in an external library Skycalc. The astrom extension is a standalone extension.

The Skycalc library source code is included in cextern/skycalc. The user, one who is installing astropy, can set a few configuration options for skypy, which will determine whether astropy will build skypy.skyc using the source code in cextern, or using pre compiled library in the user's machine. Currently the setting is in skypy/setup_package.py. In production this will be in ~/.astropy/skypy.cfg or equivalent.

The developer defines one or both of get_cython_pyx_extensions() and get_cython_extensions() functions in skypy/setup_package.py. The astropy setup.py file will call the former if the condition HAVE_CYTHON and not release is True, and the latter if the condition is False. In addition, astropy setup.py will add Cython.Distutils build_ext command to cmdclass dictionary if the above condition is satisfied.

In the get_cython_pyx_extensions() function, the developer will return setuptools Extension instances that directly use Cython pyx files. In the get_cython_extensions() function, the developer will return setuptools Extension instances that use Cython generated C files only. These Extension instances will be constructed with parameters consistent with user's library option.

With the current set of files we can perform the following:

  $ python setup.py develop  # Bundle of warnings from skycalc.c.
  $ ipython
  >>> import astropy
  >>> astropy.test("skypy")
  ================================== test session starts ========
  platform linux2 -- Python 2.6.6 -- pytest-2.1.3
  collected 1 items

  astropy/skypy/tests/test_simple.py .

  =============================== 1 passed in 0.02 seconds ======
  0
 >>> from astropy import skypy
 >>> skypy.astrom.hello("d")
 Hello d!
 >>> skypy.skyc.dow(2451545.0)
 5.0

We can now clean up, set the USE_SIN_FUNC_LIB option in skypy/setup_package.py and re-run the command. This time the library in ~/lib will be used. The header file skysub.h must also be in ~/lib.

The library can be created using

gcc -c skycalc.c -o skycalc.o
ar rcs libskycalc.a skycalc.o

Note: USE_SIN_FUNC_LIB is left over from test code; forgot to rename to USE_SKYCALC_LIB or something else.

The code adds a new sub-package astropy.skypy. This has two
modules skyc and astrom, both of which are Cython extension
modules. The skyc extension calls functions in an external
library skycalc. The astrom extension is a standalone extension.

The skycalc library source code is included in cextern/skycalc.
The user, one who is installing astropy, can set a few
configuration options for skypy, which will determine whether
astropy will build skypy.skyc using the cextern source code or
using precompiled library in the user's machine. Currently the
setting is in skypy/setup_package.py. In production this will be
in ~/.astropy/skypy.cfg or equivalent.

The developer sets up one or both of get_cython_pyx_extensions()
and get_cython_extensions() functions in skypy/setup_package.py.
The astropy setup.py file will call the former if the condition
``HAVE_CYTHON and not release`` is True, and the latter if the
condition is False. In addition, astropy setup.py will add
Cython.Distutils ``build_ext`` command to ``cmdclass`` dictionary
if the above condition is satisfied.

In the get_cython_pyx_extensions() function, the developer will
return setuptools ``Extension``s that directly use Cython pyx
files. In the get_cython_extensions() function, the developer
will return setuptools ``Extension``s that use Cython generated
C files only. These Extensions will be constructed with
parameters consistent with user's library option.

With the current set of files we can perform the following:

  $ python setup.py develop  # Bundle of warnings from skycalc.c.
  $ ipython
  >>> import astropy
  >>> astropy.test("skypy")
  ================================== test session starts ========
  platform linux2 -- Python 2.6.6 -- pytest-2.1.3
  collected 1 items

  astropy/skypy/tests/test_simple.py .

  =============================== 1 passed in 0.02 seconds ======
  0
  >>> from astropy import skypy
  >>> skypy.astrom.hello("d")
  Hello d!
  >>> skypy.skyc.dow(2451545.0)
  5.0
@eteq

eteq commented Oct 31, 2011

Copy link
Copy Markdown
Member

This is definitely along the lines of something we need to be doing. You're absolutely right that the Cython compilation steps need to be fixed.

I strongly disagree that Cython should have to be explicitly compiled. The reason for C code requiring explicitness is that it has a lot more conflicting choices because it's generally intended for wrapping C-libraries. Cython, by contrast, can be easily used simply as a compiled plug-in to speed up something. So we want to make that as easy as possible by having the setup automatically do the typical use cases (e.g. numerical operations, sometimes with numpy arrays). But you're absolutely right that the option to do it explicitly needs to be present, and your solution here makes sense, I think.

Also, I'm closing this pull request because you said this is not intended to actually be merged. FYI, pull requests should be used when you actually want something pulled into master, rather than to illustrate an example. This sort of thing is ideal to post on astropy-dev, with a link like phn/astropy@astropy:master...cython-example to get something like the pull request look

@eteq eteq closed this Oct 31, 2011
@phn

phn commented Nov 1, 2011

Copy link
Copy Markdown
Contributor Author

Hello,

I strongly disagree that Cython should have to be explicitly compiled.
The reason for C code requiring explicitness is that it has a lot more
conflicting choices because it's generally intended for wrapping
C-libraries. Cython, by contrast, can be easily used simply as a compiled
plug-in to speed up something. So we want to make that as easy as possible
by having the setup automatically do the typical use cases (e.g. numerical
operations, sometimes with numpy arrays). But you're absolutely right that
the option to do it explicitly needs to be present, and your solution
here makes sense, I think.

I don't think it would be any less or any more difficult for the developer
to provide an explicit Extension instance, because creating such an
instance is first thing one does when writing Cython, unless one is doing
everything manually.

Also, I'm closing this pull request because you said this is not intended
to actually be merged. FYI, pull requests should be used when you actually
want something pulled into master, rather than to illustrate an example.
This sort of thing is ideal to post on astropy-dev, with a link like
phn/astropy@astropy:master...cython-example to
get something like the pull request look

I issued a pull request because I wasn't aware of this feature!

Thanks,
Prasanth

Reply to this email directly or view it on GitHub:
#39 (comment)

@eteq

eteq commented Nov 1, 2011

Copy link
Copy Markdown
Member

I don't think it would be any less or any more difficult for the developer
to provide an explicit Extension instance, because creating such an
instance is first thing one does when writing Cython, unless one is doing
everything manually.

I foresee plenty of people who want to write C-speed code but don't want to have to deal with the setup.py stuf. The point is to make the barrier to entry low (and we're lucky in that we can do that without really sacrificing customizability). I'm working right now on an implementation I have in mind that hopefully will incorporate what you have in mind here with what I'm saying.

I issued a pull request because I wasn't aware of this feature!

That's what I figured, so it's totally fine - just wanted to mention so you'd know about the alternative in the future.

@eteq

eteq commented Nov 1, 2011

Copy link
Copy Markdown
Member

Oh, and by the way, your example here is a perfect test as an affiliated package once we have that all up and running, given that it has a not-so-straightforward approach for setup. If we can get the automated scripts to install this correctly, they should be able to handle just about anything Cython can throw their way!

astrofrog added a commit that referenced this pull request Nov 11, 2013
embray added a commit to embray/astropy that referenced this pull request Jan 23, 2015
Refactor AstropyTest to make it easier to subclass.
jeffjennings pushed a commit to jeffjennings/astropy that referenced this pull request Jul 2, 2025
add imexam as affiliated package
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants