def __init__(self, module, opt_level=3, loop_vectorize=True): # opt_level is used for both module level (opt) and # instruction level optimization (cg) for TargetMachine # and PassManager if not detect_avx_support(): tm = le.TargetMachine.new( opt = opt_level, cm = le.CM_JITDEFAULT, features='-avx', ) else: tm = le.TargetMachine.new( opt = opt_level, cm = le.CM_JITDEFAULT, features='' , ) pass_opts = dict( fpm = False, mod = module, opt = opt_level, vectorize = False, loop_vectorize = loop_vectorize, inline_threshold=self.inline_threshold, ) pms = lp.build_pass_managers(tm = tm, **pass_opts) pms.pm.run(module)
def __init__(self, env, libs=None): self.destroyed = False libs = libs or ['prelude'] for lib in libs: if 'darwin' in sys.platform: prelude = join(dirname(realpath(__file__)), lib + '.dylib') elif 'linux' in sys.platform: prelude = join(dirname(realpath(__file__)), lib+ '.so') else: raise NotImplementedError # XXX: yeah, don't do this ctypes._dlopen(prelude, ctypes.RTLD_GLOBAL) cgen = env['cgen'] self.__namespace = cgen.globals self.__llmodule = cgen.module.clone() if not detect_avx_support(): tc = le.TargetMachine.new(features='-avx', cm=le.CM_JITDEFAULT) else: tc = le.TargetMachine.new(features='', cm=le.CM_JITDEFAULT) eb = le.EngineBuilder.new(self.__llmodule) self.__engine = eb.create(tc) #self.__engine.run_function(cgen.globals['__module'], []) mod = ModuleType('blir_wrapper') wrap_llvm_module(cgen.module, self.__engine, mod) self.__mod = mod
def __initialize(self, opt, cg, inline): assert self.__singleton is None m = self.__module = lc.Module.new("numba_executable_module") # Create the TargetMachine features = '' try: from llvm.workaround.avx_support import detect_avx_support if not detect_avx_support(): features = '-avx' except ImportError: # Old llvm, disable AVX for all features = '-avx' tm = self.__machine = le.TargetMachine.new(opt=cg, cm=le.CM_JITDEFAULT, features=features) # Create the ExceutionEngine self.__engine = le.EngineBuilder.new(m).create(tm) # Build a PassManager which will be used for every module/ has_loop_vectorizer = llvm.version >= (3, 2) passmanagers = lp.build_pass_managers(tm, opt=opt, inline_threshold=inline, loop_vectorize=has_loop_vectorizer, fpm=False) self.__pm = passmanagers.pm self.__string_constants = {}
def test_basicvectorize_generic(self): module = Module.new(__name__) exe = CExecutor(module) tyslist = [ (C.double, C.double), (C.float, C.float), (C.int64, C.int64), (C.int32, C.int32), ] tynumslist = [] for tys in tyslist: tynumslist.append(list(map(_llvm_ty_to_dtype, tys))) oneone_defs = [OneOne(*tys)(module) for tys in tyslist] ufunc = basic_vectorize_from_func(oneone_defs, tynumslist, exe.engine) # print(module) module.verify() asm = module.to_native_assembly() from llvm.workaround.avx_support import detect_avx_support if not detect_avx_support() and 'vmovsd' in asm: print('SKIP! LLVM incorrectly uses AVX on machine without AVX') return self.check(ufunc, np.double) self.check(ufunc, np.float32) self.check(ufunc, np.int64) self.check(ufunc, np.int32)
def test_basicvectorize_generic(self): module = Module.new(__name__) exe = CExecutor(module) tyslist = [ (C.double, C.double), (C.float, C.float), (C.int64, C.int64), (C.int32, C.int32), ] tynumslist = [] for tys in tyslist: tynumslist.append(list(map(_llvm_ty_to_dtype, tys))) oneone_defs = [OneOne(*tys)(module) for tys in tyslist] ufunc = basic_vectorize_from_func(oneone_defs, tynumslist, exe.engine) # print(module) module.verify() asm = module.to_native_assembly() from llvm.workaround.avx_support import detect_avx_support if not detect_avx_support() and 'vmovsd' in asm: print('SKIP! LLVM incorrectly uses AVX on machine without AVX') return self.check(ufunc, np.double) self.check(ufunc, np.float32) self.check(ufunc, np.int64) self.check(ufunc, np.int32)
def test_cpu_support6(self): features = [] from llvm.workaround.avx_support import detect_avx_support if not detect_avx_support(): print('Skipping: no AVX') else: mattrs = ','.join(map(lambda s: '-%s' % s, features)) print('disable mattrs', mattrs) self._template(mattrs)
def test_cpu_support6(self): features = [] from llvm.workaround.avx_support import detect_avx_support if not detect_avx_support(): print('Skipping: no AVX') else: mattrs = ','.join(map(lambda s: '-%s' % s, features)) print('disable mattrs', mattrs) self._template(mattrs)
def test_cpu_support6(self): features = [] from llvm.workaround.avx_support import detect_avx_support if not detect_avx_support(): print("Skipping: no AVX") else: mattrs = ",".join(map(lambda s: "-%s" % s, features)) print("disable mattrs", mattrs) self._template(mattrs)
def _template(self, mod, func, pyfunc): float = func.type.pointee.return_type from llvm.workaround.avx_support import detect_avx_support if not detect_avx_support(): ee = le.EngineBuilder.new(mod).mattrs("-avx").create() else: ee = le.EngineBuilder.new(mod).create() arg = le.GenericValue.real(float, 1.234) retval = ee.run_function(func, [arg]) golden = pyfunc(1.234) answer = retval.as_real(float) self.assertTrue(abs(answer - golden) / golden < 1e-7)
def _template(self, mod, func, pyfunc): float = func.type.pointee.return_type from llvm.workaround.avx_support import detect_avx_support if not detect_avx_support(): ee = le.EngineBuilder.new(mod).mattrs("-avx").create() else: ee = le.EngineBuilder.new(mod).create() arg = le.GenericValue.real(float, 1.234) retval = ee.run_function(func, [arg]) golden = pyfunc(1.234) answer = retval.as_real(float) self.assertTrue(abs(answer - golden) / golden < 1e-7)
def init(self): self.execmodule = lc.Module.new("numba.exec") eb = le.EngineBuilder.new(self.execmodule).opt(3) if not avx_support.detect_avx_support(): eb.mattrs("-avx") self.tm = tm = eb.select_target() self.engine = eb.create(tm) self.pm = self.build_pass_manager() self.native_funcs = utils.UniqueDict() self.cmath_provider = {} self.is32bit = (tuple.__itemsize__ == 4) # map math functions self.map_math_functions() # Add target specific implementations self.insert_func_defn(mathimpl.functions) self.insert_func_defn(npyimpl.functions)
def init(self): self.execmodule = lc.Module.new("numba.exec") eb = le.EngineBuilder.new(self.execmodule).opt(3) if not avx_support.detect_avx_support(): eb.mattrs("-avx") self.tm = tm = eb.select_target() self.engine = eb.create(tm) self.pm = self.build_pass_manager() self.native_funcs = utils.UniqueDict() self.cmath_provider = {} self.is32bit = (tuple.__itemsize__ == 4) # map math functions self.map_math_functions() # Add target specific implementations self.insert_func_defn(mathimpl.functions) self.insert_func_defn(npyimpl.functions)
def template(self, itype, otype): module = Module.new(__name__) exe = CExecutor(module) def_oneone = OneOne(itype, otype) oneone = def_oneone(module) tyslist = [list(map(_llvm_ty_to_dtype, [itype, otype]))] ufunc = basic_vectorize_from_func(oneone, tyslist, exe.engine) print(module) module.verify() asm = module.to_native_assembly() print(asm) from llvm.workaround.avx_support import detect_avx_support if not detect_avx_support() and 'vmovsd' in asm: print('SKIP! LLVM incorrectly uses AVX on machine without AVX') return self.check(ufunc, np.double)
def template(self, itype, otype): module = Module.new(__name__) exe = CExecutor(module) def_oneone = OneOne(itype, otype) oneone = def_oneone(module) tyslist = [[_llvm_ty_to_dtype(itype), _llvm_ty_to_dtype(otype)]] ufunc = basic_vectorize_from_func(oneone, tyslist, exe.engine) print(module) module.verify() asm = module.to_native_assembly() print(asm) from llvm.workaround.avx_support import detect_avx_support if not detect_avx_support() and 'vmovsd' in asm: print('SKIP! LLVM incorrectly uses AVX on machine without AVX') return self.check(ufunc, np.double)
def test_mysin(self): if sys.platform == "win32" and BITS == 32: # float32 support is known to fail on 32-bit Windows return # mysin(x) = sqrt(1.0 - pow(cos(x), 2)) mod = Module.new("test") float = Type.float() mysinty = Type.function(float, [float]) mysin = mod.add_function(mysinty, "mysin") block = mysin.append_basic_block("entry") b = Builder.new(block) sqrt = Function.intrinsic(mod, lc.INTR_SQRT, [float]) pow = Function.intrinsic(mod, lc.INTR_POWI, [float]) cos = Function.intrinsic(mod, lc.INTR_COS, [float]) mysin.args[0].name = "x" x = mysin.args[0] one = Constant.real(float, "1") cosx = b.call(cos, [x], "cosx") cos2 = b.call(pow, [cosx, Constant.int(Type.int(), 2)], "cos2") onemc2 = b.fsub(one, cos2, "onemc2") # Should use fsub sin = b.call(sqrt, [onemc2], "sin") b.ret(sin) # logging.debug(mod) # ; ModuleID = 'test' # # define void @showme() { # entry: # call i32 @llvm.bswap.i32( i32 42 ) ; <i32>:0 [#uses # } # # declare i32 @llvm.bswap.i32(i32) nounwind readnone # # define float @mysin(float %x) { # entry: # %cosx = call float @llvm.cos.f32( float %x ) ; <float # %cos2 = call float @llvm.powi.f32( float %cosx, i32 2 ) # %onemc2 = sub float 1.000000e+00, %cos2 ; <float> [#uses # %sin = call float @llvm.sqrt.f32( float %onemc2 ) # ret float %sin # } # # declare float @llvm.sqrt.f32(float) nounwind readnone # # declare float @llvm.powi.f32(float, i32) nounwind readnone # # declare float @llvm.cos.f32(float) nounwind readnone # let's run the function from llvm.workaround.avx_support import detect_avx_support if not detect_avx_support(): ee = le.EngineBuilder.new(mod).mattrs("-avx").create() else: ee = le.EngineBuilder.new(mod).create() arg = le.GenericValue.real(Type.float(), 1.234) retval = ee.run_function(mysin, [arg]) golden = math.sin(1.234) answer = retval.as_real(Type.float()) self.assertTrue(abs(answer - golden) / golden < 1e-5)
class TestCPUSupport(TestCase): def _build_test_module(self): mod = Module.new('test') float = Type.double() mysinty = Type.function(float, [float]) mysin = mod.add_function(mysinty, "mysin") block = mysin.append_basic_block("entry") b = Builder.new(block) sqrt = Function.intrinsic(mod, lc.INTR_SQRT, [float]) pow = Function.intrinsic(mod, lc.INTR_POWI, [float]) cos = Function.intrinsic(mod, lc.INTR_COS, [float]) mysin.args[0].name = "x" x = mysin.args[0] one = Constant.real(float, "1") cosx = b.call(cos, [x], "cosx") cos2 = b.call(pow, [cosx, Constant.int(Type.int(), 2)], "cos2") onemc2 = b.fsub(one, cos2, "onemc2") # Should use fsub sin = b.call(sqrt, [onemc2], "sin") b.ret(sin) return mod, mysin def _template(self, mattrs): mod, func = self._build_test_module() ee = self._build_engine(mod, mattrs=mattrs) arg = le.GenericValue.real(Type.double(), 1.234) retval = ee.run_function(func, [arg]) golden = math.sin(1.234) answer = retval.as_real(Type.double()) self.assertTrue(abs(answer - golden) / golden < 1e-5) def _build_engine(self, mod, mattrs): if mattrs: return EngineBuilder.new(mod).mattrs(mattrs).create() else: return EngineBuilder.new(mod).create() def test_cpu_support2(self): features = 'sse3', 'sse41', 'sse42', 'avx' mattrs = ','.join(map(lambda s: '-%s' % s, features)) print('disable mattrs', mattrs) self._template(mattrs) def test_cpu_support3(self): features = 'sse41', 'sse42', 'avx' mattrs = ','.join(map(lambda s: '-%s' % s, features)) print('disable mattrs', mattrs) self._template(mattrs) def test_cpu_support4(self): features = 'sse42', 'avx' mattrs = ','.join(map(lambda s: '-%s' % s, features)) print('disable mattrs', mattrs) self._template(mattrs) def test_cpu_support5(self): features = 'avx', mattrs = ','.join(map(lambda s: '-%s' % s, features)) print('disable mattrs', mattrs) self._template(mattrs) @skip_if(not detect_avx_support(), msg="no AVX support") def test_cpu_support6(self): features = [] mattrs = ','.join(map(lambda s: '-%s' % s, features)) print('disable mattrs', mattrs) self._template(mattrs)
def test_mysin(self): if sys.platform == 'win32' and BITS == 32: # float32 support is known to fail on 32-bit Windows return # mysin(x) = sqrt(1.0 - pow(cos(x), 2)) mod = Module.new('test') float = Type.float() mysinty = Type.function(float, [float]) mysin = mod.add_function(mysinty, "mysin") block = mysin.append_basic_block("entry") b = Builder.new(block) sqrt = Function.intrinsic(mod, lc.INTR_SQRT, [float]) pow = Function.intrinsic(mod, lc.INTR_POWI, [float]) cos = Function.intrinsic(mod, lc.INTR_COS, [float]) mysin.args[0].name = "x" x = mysin.args[0] one = Constant.real(float, "1") cosx = b.call(cos, [x], "cosx") cos2 = b.call(pow, [cosx, Constant.int(Type.int(), 2)], "cos2") onemc2 = b.fsub(one, cos2, "onemc2") # Should use fsub sin = b.call(sqrt, [onemc2], "sin") b.ret(sin) #logging.debug(mod) # ; ModuleID = 'test' # # define void @showme() { # entry: # call i32 @llvm.bswap.i32( i32 42 ) ; <i32>:0 [#uses # } # # declare i32 @llvm.bswap.i32(i32) nounwind readnone # # define float @mysin(float %x) { # entry: # %cosx = call float @llvm.cos.f32( float %x ) ; <float # %cos2 = call float @llvm.powi.f32( float %cosx, i32 2 ) # %onemc2 = sub float 1.000000e+00, %cos2 ; <float> [#uses # %sin = call float @llvm.sqrt.f32( float %onemc2 ) # ret float %sin # } # # declare float @llvm.sqrt.f32(float) nounwind readnone # # declare float @llvm.powi.f32(float, i32) nounwind readnone # # declare float @llvm.cos.f32(float) nounwind readnone # let's run the function from llvm.workaround.avx_support import detect_avx_support if not detect_avx_support(): ee = le.EngineBuilder.new(mod).mattrs("-avx").create() else: ee = le.EngineBuilder.new(mod).create() arg = le.GenericValue.real(Type.float(), 1.234) retval = ee.run_function(mysin, [arg]) golden = math.sin(1.234) answer = retval.as_real(Type.float()) self.assertTrue(abs(answer - golden) / golden < 1e-5)