Compiling a PIXIE library from Cython
This notebook is building upon knowledge of Compiling a PIXIE library from C
This notebook requires a working clang 14 compiler and cython. You can install them with conda install clang=14 cython.
Building on the previous C library, the simplest way to make Python binding for add_f64 is to use Cython. Here, we make cy_add() for use in Python code:
%%writefile simple_add_cython.pyx
cimport cython
cdef public void add_f64(double *x, double *y, double *out):
out[0] = x[0] + y[0]
def cy_add(x, y):
cdef cython.double out = 0.0
cdef cython.double a = x
cdef cython.double b = y
add_f64(&a, &b, &out)
return out
Next, use PIXIE to compile the Cython source file into a PIXIE library:
from pixie import PIXIECompiler, TranslationUnit, ExportConfiguration
from pixie.targets import get_default_configuration
src = "simple_add_cython.pyx"
tus = [
TranslationUnit.from_cython_source(src),
]
export_config = ExportConfiguration()
export_config.add_symbol(python_name='add_f64',
symbol_name='add_f64',
signature='void(double*, double*, double*)',)
compiler = PIXIECompiler(library_name='simple_add_cython', # name must match cython file
translation_units=tus,
export_configuration=export_config,
**get_default_configuration(),
python_cext=True,
output_dir='.')
compiler.compile()
Now that we have made a DSO with name simple_add_cython as a Python C-extension library, we can import it.
import simple_add_cython
The library is Cython module as expected with an export of cy_add:
help(simple_add_cython)
Output:
Help on module simple_add_cython:
NAME
simple_add_cython
FUNCTIONS
cy_add(x, y)
DATA
__PIXIE__ = {'available_isas': ['v8_6a', 'v8_4a', 'baseline'], 'bitcod...
__test__ = {}
FILE
/path/to/simple_add_cython.cpython-311-darwin.so
simple_add_cython.cy_add(1, 2)
Output:
3.0
It is also a PIXIE library, so it has the __PIXIE__ attribute on the module:
pixie_dict = simple_add_cython.__PIXIE__
pixie_dict
Output:
{'symbols': {'add_f64': {'void(double*, double*, double*)': {'ctypes_cfunctype': ctypes.CFUNCTYPE.<locals>.CFunctionType,
'symbol': 'add_f64',
'module': None,
'source_file': None,
'address': 4569974972,
'cfunc': <CFunctionType object at 0x1110690d0>,
'metadata': None}}},
'c_header': ['<write it>'],
'linkage': None,
'bitcode': b'...[skipped]...',
'uuid': '82506a0f-8d17-4e2a-a2db-e6760f507910',
'is_specialized': False,
'available_isas': ['v8_6a', 'v8_4a', 'baseline'],
'specialize': <function specialize.<locals>.impl(baseline_cpu='host', baseline_features=None, targets_features=None)>,
'selected_isa': 'v8_4a'}
All the exported PIXIE symbols are accessible as shown previously in the C example.
pixie_dict['symbols']
Output:
{'add_f64': {'void(double*, double*, double*)': {'ctypes_cfunctype': ctypes.CFUNCTYPE.<locals>.CFunctionType,
'symbol': 'add_f64',
'module': None,
'source_file': None,
'address': 4397500604,
'cfunc': <CFunctionType object at 0x105fc8950>,
'metadata': None}}}