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 ifcreate_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, importsage.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)
wherename
is the name of the compiled module anddir
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 forvars
.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 scopeglobals()
usingsage.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'