Ask Your Question
1

Sage/Cython compile embedded Cython with Sage import

asked 2012-06-28 11:04:34 -0600

daliu gravatar image

Hi,

I was wondering how you can compile a Sage .pyx file into an embedded Cython .c file and compile it with gcc to create a standalone executable?

I tried:

sage -cython --embed filename.pyx
gcc filename.c -I/path/to/python -lpython2.7

but when I run the program it gives me the following error:

from sage.all import *
ImportError: No module named sage.all

Thanks!

Dan

edit retag flag offensive close merge delete

Comments

I fear that, even if you succeed to achieve that, your binary will be huge.

tmonteil gravatar imagetmonteil ( 2016-10-16 07:27:10 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
0

answered 2016-10-15 16:42:40 -0600

updated 2016-10-17 18:57:51 -0600

This appears to work as of Sage 7.3 only to a limited extent, for reasons that will be come clear. Start with a pure Python example to highlight the changes necessary to import Sage. A file hello.pyx with the simple code

print('Hello World!')

can be converted to C with the command

sage -cython --embed hello.pyx

and then compiled for running with the command

gcc hello.c -I/usr/include/python2.7 -lpython2.7

Executing the result by typing ./a.out displays the expected greeting.

Now try a similar piece of code with a Sage numeric function in a file import.pyx:

from sage.all import *
print(bessel_J(0,1.))

Compiling with the same commands produces the reported error

ImportError: No module named sage.all

when executing the result. This error can be avoided by pointing the compiler to folders under Sage's location /path/to/sage/ so that it knows where to find Sage-specific libraries, including the version of Python that ships with Sage.

While the Cython command remains the same, the compiler command becomes

gcc import.pyx -I/path/to/sage/local/include/python2.7 -L/path/to/sage/local/lib -lpython2.7

The compiler program can now find the required module, but unfortunately another error appears upon execution:

RuntimeError: You must get the file local/bin/sage-maxima.lisp

Since that file gets installed with Sage, the source of this error is how Sage is written. The Maxima interface does an explicit check for this file when Sage starts, as can be seen in the source code, but this depends on having an environment variable set. This error can be avoided by entering

export SAGE_LOCAL=/path/to/sage/local

at the command line. Executing the compiled result now gives the output

? cannot open `standard.lib`
0.765197686558

which has the desired numeric output, but another error message. Since standard.lib is part of the Singular library, there is clearly another hard-coded path issue somewhere else in Sage.

Since the compiled program depends explicitly on setting an environment variable, it hardly qualifies as a stand-alone executable. Even worse, attempting to process symbolic manipulations as simple as

from sage.all import *
x=var('x')
print(x)

produces the C-related error

SystemError: NULL result without error in PyObject_Call

Looks like you can compile numeric parts of Sage to C to some extent, but for the symbolics would need to cythonize and compile everything.

edit flag offensive delete link more

Comments

This works for Python script, but does not seem to work when you import Sage modules.

tmonteil gravatar imagetmonteil ( 2016-10-16 07:27:55 -0600 )edit

Answer updated

paulmasson gravatar imagepaulmasson ( 2016-10-17 18:58:46 -0600 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

Stats

Asked: 2012-06-28 11:04:34 -0600

Seen: 656 times

Last updated: Oct 17 '16