def prepare_for_call(self, func, fndesc): wrapper, api = PyCallWrapper(self, func.module, func, fndesc).build() self.optimize(func.module) if config.DUMP_OPTIMIZED: print(("OPTIMIZED DUMP %s" % fndesc.qualified_name).center(80, "-")) print(func.module) print("=" * 80) if config.DUMP_ASSEMBLY: print(("ASSEMBLY %s" % fndesc.qualified_name).center(80, "-")) print(self.tm.emit_assembly(func.module)) print("=" * 80) # Map module.__dict__ le.dylib_add_symbol(".pymodule.dict." + fndesc.pymod.__name__, id(fndesc.pymod.__dict__)) # Code gen self.engine.add_module(func.module) baseptr = self.engine.get_pointer_to_function(func) fnptr = self.engine.get_pointer_to_function(wrapper) cfunc = _dynfunc.make_function(fndesc.pymod, fndesc.name, fndesc.doc, fnptr) if fndesc.native: self.native_funcs[cfunc] = fndesc.mangled_name, baseptr return cfunc, fnptr
def prepare_for_call(self, func, fndesc): wrapper, api = PyCallWrapper(self, func.module, func, fndesc, exceptions=self.exceptions).build() self.optimize(func.module) if config.DUMP_OPTIMIZED: print(("OPTIMIZED DUMP %s" % fndesc).center(80,'-')) print(func.module) print('=' * 80) if config.DUMP_ASSEMBLY: print(("ASSEMBLY %s" % fndesc).center(80, '-')) print(self.tm.emit_assembly(func.module)) print('=' * 80) # Map module.__dict__ le.dylib_add_symbol(".pymodule.dict." + fndesc.modname, id(fndesc.globals)) # Code gen self.engine.add_module(func.module) baseptr = self.engine.get_pointer_to_function(func) fnptr = self.engine.get_pointer_to_function(wrapper) cfunc = _dynfunc.make_function(fndesc.lookup_module(), fndesc.qualname.split('.')[-1], fndesc.doc, fnptr) if fndesc.native: self.native_funcs[cfunc] = fndesc.mangled_name, baseptr return cfunc, fnptr
def test_multi_module_linking(self): # generate external library module m = Module.new('external-library-module') fnty = Type.function(Type.int(), [Type.int(), Type.int()]) libfname = 'myadd' func = m.add_function(fnty, libfname) bb = func.append_basic_block('') bldr = Builder.new(bb) bldr.ret(bldr.add(*func.args)) func.verify() # JIT the lib module and bind dynamic symbol libengine = EngineBuilder.new(m).mcjit(True).create() myadd_ptr = libengine.get_pointer_to_function(func) le.dylib_add_symbol(libfname, myadd_ptr) # reference external library m = Module.new('user') fnty = Type.function(Type.int(), [Type.int(), Type.int()]) func = m.add_function(fnty, 'foo') bb = func.append_basic_block('') bldr = Builder.new(bb) extadd = m.get_or_insert_function(fnty, name=libfname) bldr.ret(bldr.call(extadd, func.args)) func.verify() # JIT the user module engine = EngineBuilder.new(m).mcjit(True).create() ptr = engine.get_pointer_to_function(func) self.assertEqual(myadd_ptr, engine.get_pointer_to_named_function(libfname)) from ctypes import c_int, CFUNCTYPE callee = CFUNCTYPE(c_int, c_int, c_int)(ptr) self.assertEqual(321 + 123, callee(321, 123))
def prepare_for_call(self, func, fndesc): wrapper, api = PyCallWrapper(self, func.module, func, fndesc).build() self.optimize(func.module) if config.DUMP_OPTIMIZED: print( ("OPTIMIZED DUMP %s" % fndesc.qualified_name).center(80, '-')) print(func.module) print('=' * 80) if config.DUMP_ASSEMBLY: print(("ASSEMBLY %s" % fndesc.qualified_name).center(80, '-')) print(self.tm.emit_assembly(func.module)) print('=' * 80) # Map module.__dict__ le.dylib_add_symbol(".pymodule.dict." + fndesc.pymod.__name__, id(fndesc.pymod.__dict__)) # Code gen self.engine.add_module(func.module) baseptr = self.engine.get_pointer_to_function(func) fnptr = self.engine.get_pointer_to_function(wrapper) cfunc = _dynfunc.make_function(fndesc.pymod, fndesc.name, fndesc.doc, fnptr) if fndesc.native: self.native_funcs[cfunc] = fndesc.mangled_name, baseptr return cfunc, fnptr
def _windows_symbol_hacks_32bits(): # if we don't have _ftol2, bind _ftol as _ftol2 ftol2 = le.dylib_address_of_symbol("_ftol2") if not ftol2: ftol = le.dylib_address_of_symbol("_ftol") assert ftol le.dylib_add_symbol("_ftol2", ftol)
def fix_python_api(): """ Execute once to install special symbols into the LLVM symbol table """ le.dylib_add_symbol("Py_None", ctypes.addressof(_PyNone)) le.dylib_add_symbol("NumbaArrayAdaptor", _numpyadapt.get_ndarray_adaptor()) le.dylib_add_symbol("NumbaComplexAdaptor", _helperlib.get_complex_adaptor()) le.dylib_add_symbol("NumbaNativeError", id(NativeError)) le.dylib_add_symbol("PyExc_NameError", id(NameError))
def remove_native_function(self, func): """ Remove internal references to nonpython mode function *func*. KeyError is raised if the function isn't known to us. """ name, ptr = self.native_funcs.pop(func) # If the symbol wasn't redefined, NULL it out. # (otherwise, it means the corresponding Python function was # re-compiled, and the new target is still alive) if le.dylib_address_of_symbol(name) == ptr: le.dylib_add_symbol(name, 0)
def install_symbols(self): '''Bind all the external symbols to the global symbol map. Any future reference to these symbols will be automatically resolved by LLVM. ''' for lfunc in self.module.functions: if lfunc.linkage == lc.LINKAGE_EXTERNAL: mangled = '__llrt_' + lfunc.name self.installed_symbols.add(mangled) ptr = self.engine.get_pointer_to_function(lfunc) le.dylib_add_symbol(mangled, ptr)
def map_math_functions(self): c_helpers = _helperlib.c_helpers for name in ['cpow', 'sdiv', 'srem', 'udiv', 'urem']: le.dylib_add_symbol("numba.math.%s" % name, c_helpers[name]) if sys.platform.startswith('win32') and self.is32bit: # This may still be necessary for windows XP _add_missing_symbol("__ftol2", c_helpers["fptoui"]) elif sys.platform.startswith('linux') and self.is32bit: _add_missing_symbol("__fixunsdfdi", c_helpers["fptoui"]) _add_missing_symbol("__fixunssfdi", c_helpers["fptouif"]) # Necessary for Python3 le.dylib_add_symbol("numba.round", c_helpers["round_even"]) le.dylib_add_symbol("numba.roundf", c_helpers["roundf_even"]) # List available C-math for fname in intrinsics.INTR_MATH: if le.dylib_address_of_symbol(fname): # Exist self.cmath_provider[fname] = 'builtin' else: # Non-exist # Bind from C code le.dylib_add_symbol(fname, c_helpers[fname]) self.cmath_provider[fname] = 'indirect'
def map_math_functions(self): c_helpers = _helperlib.c_helpers for name in ['cpow', 'sdiv', 'srem', 'udiv', 'urem']: le.dylib_add_symbol("numba.math.%s" % name, c_helpers[name]) if sys.platform.startswith('win32') and self.is32bit: # For Windows XP __ftol2 is not defined, we will just use # __ftol as a replacement. # On Windows 7, this is not necessary but will work anyway. ftol = le.dylib_address_of_symbol('_ftol') _add_missing_symbol("_ftol2", ftol) elif sys.platform.startswith('linux') and self.is32bit: _add_missing_symbol("__fixunsdfdi", c_helpers["fptoui"]) _add_missing_symbol("__fixunssfdi", c_helpers["fptouif"]) # Necessary for Python3 le.dylib_add_symbol("numba.round", c_helpers["round_even"]) le.dylib_add_symbol("numba.roundf", c_helpers["roundf_even"]) # List available C-math for fname in intrinsics.INTR_MATH: if le.dylib_address_of_symbol(fname): # Exist self.cmath_provider[fname] = 'builtin' else: # Non-exist # Bind from C code le.dylib_add_symbol(fname, c_helpers[fname]) self.cmath_provider[fname] = 'indirect'
def fix_python_api(): """ Execute once to install special symbols into the LLVM symbol table """ le.dylib_add_symbol("Py_None", ctypes.addressof(_PyNone)) le.dylib_add_symbol("numba_native_error", id(NativeError)) # Add C helper functions c_helpers = _helperlib.c_helpers for py_name in c_helpers: c_name = "numba_" + py_name c_address = c_helpers[py_name] le.dylib_add_symbol(c_name, c_address) # Add all built-in exception classes for obj in utils.builtins.__dict__.values(): if isinstance(obj, type) and issubclass(obj, BaseException): le.dylib_add_symbol("PyExc_%s" % (obj.__name__), id(obj))
def fix_python_api(): """ Execute once to install special symbols into the LLVM symbol table """ le.dylib_add_symbol("Py_None", ctypes.addressof(_PyNone)) le.dylib_add_symbol("NumbaArrayAdaptor", _numpyadapt.get_ndarray_adaptor()) le.dylib_add_symbol("NumbaComplexAdaptor", _helperlib.get_complex_adaptor()) le.dylib_add_symbol("NumbaNativeError", id(NativeError)) le.dylib_add_symbol("NumbaExtractRecordData", _helperlib.get_extract_record_data()) le.dylib_add_symbol("NumbaReleaseRecordBuffer", _helperlib.get_release_record_buffer()) le.dylib_add_symbol("NumbaRecreateRecord", _helperlib.get_recreate_record()) le.dylib_add_symbol("PyExc_NameError", id(NameError))
def map_math_functions(self): le.dylib_add_symbol("numba.math.cpow", _helperlib.get_cpow()) le.dylib_add_symbol("numba.math.sdiv", _helperlib.get_sdiv()) le.dylib_add_symbol("numba.math.srem", _helperlib.get_srem()) le.dylib_add_symbol("numba.math.udiv", _helperlib.get_udiv()) le.dylib_add_symbol("numba.math.urem", _helperlib.get_urem()) # Necessary for Python3 le.dylib_add_symbol("numba.round", _helperlib.get_round_even()) le.dylib_add_symbol("numba.roundf", _helperlib.get_roundf_even()) # windows symbol hacks if sys.platform.startswith('win32') and self.is32bit: _windows_symbol_hacks_32bits() # List available C-math for fname in intrinsics.INTR_MATH: if le.dylib_address_of_symbol(fname): # Exist self.cmath_provider[fname] = 'builtin' else: # Non-exist # Bind from C code imp = getattr(_helperlib, "get_%s" % fname) le.dylib_add_symbol(fname, imp()) self.cmath_provider[fname] = 'indirect'
def map_numpy_math_functions(self): # add the symbols for numpy math to the execution environment. import numba._npymath_exports as npymath for sym in npymath.symbols: le.dylib_add_symbol(*sym)
def _add_missing_symbol(symbol, addr): """Add missing symbol into LLVM internal symtab """ if not le.dylib_address_of_symbol(symbol): le.dylib_add_symbol(symbol, addr)
def uninstall(symbol): del DYLIB[symbol] dylib_add_symbol(symbol, 0) # insert poison value
def dynamic_map_function(self, func): name, ptr = self.native_funcs[func] le.dylib_add_symbol(name, ptr)
def install(symbol, address): if symbol in DYLIB: raise KeyError("Duplicated symbol '%s'" % symbol) DYLIB[symbol] = address dylib_add_symbol(symbol, address)
def fix_python_api(): """ Execute once to install special symbols into the LLVM symbol table """ c_helpers = _helperlib.c_helpers le.dylib_add_symbol("Py_None", ctypes.addressof(_PyNone)) le.dylib_add_symbol("NumbaArrayAdaptor", _numpyadapt.get_ndarray_adaptor()) le.dylib_add_symbol("NumbaComplexAdaptor", c_helpers["complex_adaptor"]) le.dylib_add_symbol("NumbaNativeError", id(NativeError)) le.dylib_add_symbol("NumbaExtractRecordData", c_helpers["extract_record_data"]) le.dylib_add_symbol("NumbaReleaseRecordBuffer", c_helpers["release_record_buffer"]) le.dylib_add_symbol("NumbaRecreateRecord", c_helpers["recreate_record"]) le.dylib_add_symbol("PyExc_NameError", id(NameError))
def map_math_functions(self): c_helpers = _helperlib.c_helpers for name in ['cpow', 'sdiv', 'srem', 'udiv', 'urem']: le.dylib_add_symbol("numba.math.%s" % name, c_helpers[name]) if sys.platform.startswith( 'win32') and not le.dylib_address_of_symbol('__ftol2'): le.dylib_add_symbol("__ftol2", c_helpers["fptoui"]) elif sys.platform.startswith( 'linux') and not le.dylib_address_of_symbol('__fixunsdfdi'): le.dylib_add_symbol("__fixunsdfdi", c_helpers["fptoui"]) # Necessary for Python3 le.dylib_add_symbol("numba.round", c_helpers["round_even"]) le.dylib_add_symbol("numba.roundf", c_helpers["roundf_even"]) # windows symbol hacks if sys.platform.startswith('win32') and self.is32bit: _windows_symbol_hacks_32bits() # List available C-math for fname in intrinsics.INTR_MATH: if le.dylib_address_of_symbol(fname): # Exist self.cmath_provider[fname] = 'builtin' else: # Non-exist # Bind from C code le.dylib_add_symbol(fname, c_helpers[fname]) self.cmath_provider[fname] = 'indirect'
def map_math_functions(self): le.dylib_add_symbol("numba.math.cpow", _helperlib.get_cpow()) le.dylib_add_symbol("numba.math.sdiv", _helperlib.get_sdiv()) le.dylib_add_symbol("numba.math.srem", _helperlib.get_srem()) le.dylib_add_symbol("numba.math.udiv", _helperlib.get_udiv()) le.dylib_add_symbol("numba.math.urem", _helperlib.get_urem()) if sys.platform.startswith('win32') and not le.dylib_address_of_symbol('__ftol2'): le.dylib_add_symbol("__ftol2", _helperlib.get_fptoui()) elif sys.platform.startswith('linux') and not le.dylib_address_of_symbol('__fixunsdfdi'): le.dylib_add_symbol("__fixunsdfdi", _helperlib.get_fptoui()) # Necessary for Python3 le.dylib_add_symbol("numba.round", _helperlib.get_round_even()) le.dylib_add_symbol("numba.roundf", _helperlib.get_roundf_even()) # windows symbol hacks if sys.platform.startswith('win32') and self.is32bit: _windows_symbol_hacks_32bits() # List available C-math for fname in intrinsics.INTR_MATH: if le.dylib_address_of_symbol(fname): # Exist self.cmath_provider[fname] = 'builtin' else: # Non-exist # Bind from C code imp = getattr(_helperlib, "get_%s" % fname) le.dylib_add_symbol(fname, imp()) self.cmath_provider[fname] = 'indirect'
def uninstall_symbols(self): for sym in self.installed_symbols: le.dylib_add_symbol(sym, 0)
def fix_python_api(): """ Execute once to install special symbols into the LLVM symbol table """ c_helpers = _helperlib.c_helpers le.dylib_add_symbol("Py_None", ctypes.addressof(_PyNone)) le.dylib_add_symbol("NumbaArrayAdaptor", _numpyadapt.get_ndarray_adaptor()) le.dylib_add_symbol("NumbaComplexAdaptor", c_helpers["complex_adaptor"]) le.dylib_add_symbol("NumbaNativeError", id(NativeError)) le.dylib_add_symbol("NumbaExtractRecordData", c_helpers["extract_record_data"]) le.dylib_add_symbol("NumbaReleaseRecordBuffer", c_helpers["release_record_buffer"]) le.dylib_add_symbol("NumbaRecreateRecord", c_helpers["recreate_record"]) # Add all built-in exception classes for obj in utils.builtins.__dict__.values(): if isinstance(obj, type) and issubclass(obj, BaseException): le.dylib_add_symbol("PyExc_%s" % (obj.__name__), id(obj))