Cython support functions#

AUTHORS:

  • William Stein (2006-01-18): initial version

  • William Stein (2007-07-28): update from sagex to cython

  • Martin Albrecht & William Stein (2011-08): cfile & cargs

sage.misc.cython.compile_and_load(code, **kwds)[source]#

INPUT:

  • code – string containing code that could be in a .pyx file that is attached or put in a %cython block in the notebook.

OUTPUT: a module, which results from compiling the given code and importing it

EXAMPLES:

sage: from sage.misc.cython import compile_and_load
sage: module = compile_and_load("def f(int n):\n    return n*n")
sage: module.f(10)
100
>>> from sage.all import *
>>> from sage.misc.cython import compile_and_load
>>> module = compile_and_load("def f(int n):\n    return n*n")
>>> module.f(Integer(10))
100
sage.misc.cython.cython(filename, verbose=0, compile_message=False, use_cache=False, create_local_c_file=False, annotate=True, sage_namespace=True, create_local_so_file=False)[source]#

Compile a Cython file. This converts a Cython file to a C (or C++ file), and then compiles that. The .c file and the .so file are created in a temporary directory.

INPUT:

  • filename – the name of the file to be compiled. Should end with ‘pyx’.

  • verbose (integer, default 0) – level of verbosity. A negative value ensures complete silence.

  • compile_message (bool, default: False) – if True, print 'Compiling <filename>...' to the standard error.

  • use_cache (bool, default: False) – if True, check the temporary build directory to see if there is already a corresponding .so file. If so, and if the .so file is newer than the Cython file, don’t recompile, just reuse the .so file.

  • create_local_c_file (bool, default: False) – if True, save a copy of the .c or .cpp file in the current directory.

  • annotate (bool, default: True) – if True, create an html file which annotates the conversion from .pyx to .c. By default this is only created in the temporary directory, but if create_local_c_file is also True, then save a copy of the .html file in the current directory.

  • sage_namespace (bool, default: True) – if True, import sage.all.

  • create_local_so_file (bool, default: False) – if True, save a copy of the compiled .so file in the current directory.

OUTPUT: a tuple (name, dir) where name is the name of the compiled module and dir is the directory containing the generated files.

sage.misc.cython.cython_compile(code, **kwds)[source]#

Given a block of Cython code (as a text string), this function compiles it using a C compiler, and includes it into the global namespace.

AUTHOR: William Stein, 2006-10-31

Warning

Only use this from Python code, not from extension code, since from extension code you would change the global scope (i.e., of the Sage interpreter). And it would be stupid, since you’re already writing Cython!

Also, never use this in the standard Sage library. Any code that uses this can only run on a system that has a C compiler installed, and we want to avoid making that assumption for casual Sage usage. Also, any code that uses this in the library would greatly slow down startup time, since currently there is no caching.

Todo

Need to create a clever caching system so code only gets compiled once.

sage.misc.cython.cython_import(filename, **kwds)[source]#

Compile a file containing Cython code, then import and return the module. Raises an ImportError if anything goes wrong.

INPUT:

  • filename – a string; name of a file that contains Cython code

See the function sage.misc.cython.cython() for documentation for the other inputs.

OUTPUT:

  • the module that contains the compiled Cython code.

sage.misc.cython.cython_import_all(filename, globals, **kwds)[source]#

Imports all non-private (i.e., not beginning with an underscore) attributes of the specified Cython module into the given context. This is similar to:

from module import *

Raises an ImportError exception if anything goes wrong.

INPUT:

  • filename – a string; name of a file that contains Cython code

sage.misc.cython.cython_lambda(vars, expr, verbose=0, **kwds)[source]#

Create a compiled function which evaluates expr assuming machine values for vars.

INPUT:

  • vars – list of pairs (variable name, c-data type), where the variable names and data types are strings, OR a string such as 'double x, int y, int z'

  • expr – an expression involving the vars and constants; you can access objects defined in the current module scope globals() using sage.object_name.

Warning

Accessing globals() doesn’t actually work, see Issue #12446.

EXAMPLES:

We create a Lambda function in pure Python (using the r to make sure the 3.2 is viewed as a Python float):

sage: f = lambda x,y: x*x + y*y + x + y + 17r*x + 3.2r
>>> from sage.all import *
>>> f = lambda x,y: x*x + y*y + x + y + 17*x + 3.2

We make the same Lambda function, but in a compiled form.

sage: g = cython_lambda('double x, double y', 'x*x + y*y + x + y + 17*x + 3.2')
sage: g(2,3)
55.2
sage: g(0,0)
3.2
>>> from sage.all import *
>>> g = cython_lambda('double x, double y', 'x*x + y*y + x + y + 17*x + 3.2')
>>> g(Integer(2),Integer(3))
55.2
>>> g(Integer(0),Integer(0))
3.2

In order to access Sage globals, prefix them with sage.:

sage: f = cython_lambda('double x', 'sage.sin(x) + sage.a')
sage: f(0)
Traceback (most recent call last):
...
NameError: global 'a' is not defined
sage: a = 25
sage: f(10)
24.45597888911063
sage: a = 50
sage: f(10)
49.45597888911063
>>> from sage.all import *
>>> f = cython_lambda('double x', 'sage.sin(x) + sage.a')
>>> f(Integer(0))
Traceback (most recent call last):
...
NameError: global 'a' is not defined
>>> a = Integer(25)
>>> f(Integer(10))
24.45597888911063
>>> a = Integer(50)
>>> f(Integer(10))
49.45597888911063
sage.misc.cython.sanitize(f)[source]#

Given a filename f, replace it by a filename that is a valid Python module name.

This means that the characters are all alphanumeric or _’s and doesn’t begin with a numeral.

EXAMPLES:

sage: from sage.misc.cython import sanitize
sage: sanitize('abc')
'abc'
sage: sanitize('abc/def')
'abc_def'
sage: sanitize('123/def-hij/file.py')
'_123_def_hij_file_py'
>>> from sage.all import *
>>> from sage.misc.cython import sanitize
>>> sanitize('abc')
'abc'
>>> sanitize('abc/def')
'abc_def'
>>> sanitize('123/def-hij/file.py')
'_123_def_hij_file_py'