Compiling a PIXIE library from LLVM
This notebook is building upon knowledge of Compiling a PIXIE library from C and shows how to build a PIXIE library from LLVM-IR.
PIXIE can directly ingest LLVM-IR such that any LLVM-emitting compiler frontend can build PIXIE libraries.
Let’s start with some LLVM-IR as Python strings:
llvm_add_f64 = """
define void @add_f64(double* %".1", double* %".2", double* %".out")
{
entry:
%.3 = load double, double * %.1
%.4 = load double, double * %.2
%"res" = fadd double %".3", %".4"
store double %"res", double* %".out"
ret void
}
"""
llvm_add_f32 = """
define void @add_f32(float* %".1", float* %".2", float* %".out")
{
entry:
%.3 = load float, float * %.1
%.4 = load float, float * %.2
%"res" = fadd float %".3", %".4"
store float %"res", float* %".out"
ret void
}
"""
Next, use PIXIE to compile the LLVM-IR file into a PIXIE library:
from pixie import PIXIECompiler, TranslationUnit, ExportConfiguration
from pixie.targets import get_default_configuration
src = "simple_add_llvm.ll"
tus = [
# The only difference is here.
# The TranslationUnit takes the LLVM-IR string directly.
TranslationUnit("llvm_add_f64", llvm_add_f64),
TranslationUnit("llvm_add_f32", llvm_add_f32),
]
export_config = ExportConfiguration()
export_config.add_symbol(python_name='add',
symbol_name='add_f64',
signature='void(double*, double*, double*)',)
export_config.add_symbol(python_name='add',
symbol_name='add_f32',
signature='void(float*, float*, float*)',)
compiler = PIXIECompiler(library_name='simple_add_llvm',
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_llvm as a Python C-extension library, we can import it and exercise the add() function via the ctypes.CFUNCTYPE in the __PIXIE__.
import simple_add_llvm
help(simple_add_llvm)
Output:
Help on module simple_add_llvm:
NAME
simple_add_llvm
DATA
__PIXIE__ = {'available_isas': ['v8_4a', 'v8_6a', 'baseline'], 'bitcod...
FILE
/path/to/simple_add_llvm.cpython-311-darwin.so
pixie_dict = simple_add_llvm.__PIXIE__
symbol_add = pixie_dict['symbols']['add']
signatures = list(symbol_add.keys())
signatures
Output:
['void(double*, double*, double*)', 'void(float*, float*, float*)']
from ctypes import c_double, byref
# Get the double precision definition.
add_cfunc = symbol_add[signatures[0]]['cfunc']
# Call the ctypes.CFUNCTYPE
out = c_double()
add_cfunc(byref(c_double(1.2)), byref(c_double(3.4)), byref(out))
print(out)
Output:
c_double(4.6)