def test_bind_C(): if not has_fortran(): skip("No fortran compiler found.") if not cython: skip("Cython not found.") if not np: skip("NumPy not found.") a = Symbol('a', real=True) s = Symbol('s', integer=True) body = [Return((sum_(a**2)/s)**.5)] arr = array(a, dim=[s], intent='in') fd = FunctionDefinition(real, 'rms', [arr, s], body, attrs=[bind_C('rms')]) f_mod = render_as_module([fd], 'mod_rms') with TemporaryDirectory() as folder: mod, info = compile_link_import_strings([ ('rms.f90', f_mod), ('_rms.pyx', ( "cdef extern double rms(double*, int*)\n" "def py_rms(double[::1] x):\n" " cdef int s = x.size\n" " return rms(&x[0], &s)\n")) ], build_dir=folder) assert abs(mod.py_rms(np.array([2., 4., 2., 2.])) - 7**0.5) < 1e-14
def test_bind_C(): if not has_fortran(): skip("No fortran compiler found.") if not cython: skip("Cython not found.") if not np: skip("NumPy not found.") a = Symbol('a', real=True) s = Symbol('s', integer=True) body = [Return((sum_(a**2) / s)**.5)] arr = array(a, dim=[s], intent='in') fd = FunctionDefinition(real, 'rms', [arr, s], body, attrs=[bind_C('rms')]) f_mod = render_as_module([fd], 'mod_rms') with TemporaryDirectory() as folder: mod, info = compile_link_import_strings( [('rms.f90', f_mod), ('_rms.pyx', ("#cython: language_level={}\n".format("3") + "cdef extern double rms(double*, int*)\n" "def py_rms(double[::1] x):\n" " cdef int s = x.size\n" " return rms(&x[0], &s)\n"))], build_dir=folder) assert abs(mod.py_rms(np.array([2., 4., 2., 2.])) - 7**0.5) < 1e-14
def test_newtons_method_function__fcode(): x = sp.Symbol("x", real=True) expr = sp.cos(x) - x**3 func = newtons_method_function(expr, x, attrs=[bind_C(name="newton")]) if not cython: skip("cython not installed.") if not has_fortran(): skip("No Fortran compiler found.") f_mod = f_module([func], "mod_newton") with TemporaryDirectory() as folder: mod, info = compile_link_import_strings( [ ("newton.f90", f_mod), ( "_newton.pyx", ("#cython: language_level={}\n".format("3") + "cdef extern double newton(double*)\n" "def py_newton(double x):\n" " return newton(&x)\n"), ), ], build_dir=folder, ) assert abs(mod.py_newton(0.5) - 0.865474033102) < 1e-12
def test_newtons_method_function__ccode(): x = sp.Symbol("x", real=True) expr = sp.cos(x) - x**3 func = newtons_method_function(expr, x) if not cython: skip("cython not installed.") if not has_c(): skip("No C compiler found.") compile_kw = dict(std="c99") with TemporaryDirectory() as folder: mod, info = compile_link_import_strings( [ ( "newton.c", ("#include <math.h>\n" "#include <stdio.h>\n") + ccode(func), ), ( "_newton.pyx", ("#cython: language_level={}\n".format("3") + "cdef extern double newton(double)\n" "def py_newton(x):\n" " return newton(x)\n"), ), ], build_dir=folder, compile_kwargs=compile_kw, ) assert abs(mod.py_newton(0.5) - 0.865474033102) < 1e-12
def test_newtons_method_function__ccode_parameters(): args = x, A, k, p = sp.symbols("x A k p") expr = A * sp.cos(k * x) - p * x**3 raises(ValueError, lambda: newtons_method_function(expr, x)) use_wurlitzer = wurlitzer func = newtons_method_function(expr, x, args, debug=use_wurlitzer) if not has_c(): skip("No C compiler found.") if not cython: skip("cython not installed.") compile_kw = dict(std="c99") with TemporaryDirectory() as folder: mod, info = compile_link_import_strings( [ ( "newton_par.c", ("#include <math.h>\n" "#include <stdio.h>\n") + ccode(func), ), ( "_newton_par.pyx", ("#cython: language_level={}\n".format("3") + "cdef extern double newton(double, double, double, double)\n" "def py_newton(x, A=1, k=1, p=1):\n" " return newton(x, A, k, p)\n"), ), ], compile_kwargs=compile_kw, build_dir=folder, ) if use_wurlitzer: with wurlitzer.pipes() as (out, err): result = mod.py_newton(0.5) else: result = mod.py_newton(0.5) assert abs(result - 0.865474033102) < 1e-12 if not use_wurlitzer: skip( "C-level output only tested when package 'wurlitzer' is available." ) out, err = out.read(), err.read() assert err == "" assert (out == """\ x= 0.5 d_x= 0.61214 x= 1.1121 d_x= -0.20247 x= 0.90967 d_x= -0.042409 x= 0.86726 d_x= -0.0017867 x= 0.86548 d_x= -3.1022e-06 x= 0.86547 d_x= -9.3421e-12 x= 0.86547 d_x= 3.6902e-17 """) # try to run tests with LC_ALL=C if this assertion fails
def _render_compile_import(funcdef, build_dir): code_str = render_as_source_file(funcdef, settings=dict(contract=False)) declar = ccode(FunctionPrototype.from_FunctionDefinition(funcdef)) return compile_link_import_strings( [('our_test_func.c', code_str), ('_our_test_func.pyx', ("cdef extern {declar}\n" "def _{fname}({typ}[:] inp, {typ}[:] out):\n" " {fname}(inp.size, &inp[0], &out[0])").format( declar=declar, fname=funcdef.name, typ='double'))], build_dir=build_dir)
def _render_compile_import(funcdef, build_dir): code_str = render_as_source_file(funcdef, settings=dict(contract=False)) declar = ccode(FunctionPrototype.from_FunctionDefinition(funcdef)) return compile_link_import_strings([ ('our_test_func.c', code_str), ('_our_test_func.pyx', ("cdef extern {declar}\n" "def _{fname}({typ}[:] inp, {typ}[:] out):\n" " {fname}(inp.size, &inp[0], &out[0])").format( declar=declar, fname=funcdef.name, typ='double' )) ], build_dir=build_dir)
def test_compiled_ccode_with_rewriting(): if not cython: skip("cython not installed.") if not has_c(): skip("No C compiler found.") x = Symbol('x') about_two = 2**(58 / S(117)) * 3**(97 / S(117)) * 5**(4 / S(39)) * 7**( 92 / S(117)) / S(30) * pi # about_two: 1.999999999999581826 unchanged = 2 * exp(x) - about_two xval = S(10)**-11 ref = unchanged.subs(x, xval).n(19) # 2.0418173913673213e-11 rewritten = optimize(2 * exp(x) - about_two, [expm1_opt]) # Unfortunately, we need to call ``.n()`` on our expressions before we hand them # to ``ccode``, and we need to request a large number of significant digits. # In this test, results converged for double precision when the following number # of significant digits were chosen: NUMBER_OF_DIGITS = 25 # TODO: this should ideally be automatically handled. func_c = ''' #include <math.h> double func_unchanged(double x) { return %(unchanged)s; } double func_rewritten(double x) { return %(rewritten)s; } ''' % dict(unchanged=ccode(unchanged.n(NUMBER_OF_DIGITS)), rewritten=ccode(rewritten.n(NUMBER_OF_DIGITS))) func_pyx = ''' #cython: language_level=3 cdef extern double func_unchanged(double) cdef extern double func_rewritten(double) def py_unchanged(x): return func_unchanged(x) def py_rewritten(x): return func_rewritten(x) ''' with tempfile.TemporaryDirectory() as folder: mod, info = compile_link_import_strings([('func.c', func_c), ('_func.pyx', func_pyx)], build_dir=folder, compile_kwargs=dict(std='c99')) err_rewritten = abs(mod.py_rewritten(1e-11) - ref) err_unchanged = abs(mod.py_unchanged(1e-11) - ref) assert 1e-27 < err_rewritten < 1e-25 # highly accurate. assert 1e-19 < err_unchanged < 1e-16 # quite poor.
def _render_compile_import(funcdef, build_dir): code_str = render_as_source_file(funcdef, settings=dict(contract=False)) declar = ccode(FunctionPrototype.from_FunctionDefinition(funcdef)) return compile_link_import_strings( [ ("our_test_func.c", code_str), ( "_our_test_func.pyx", ("#cython: language_level={}\n".format("3") + "cdef extern {declar}\n" "def _{fname}({typ}[:] inp, {typ}[:] out):\n" " {fname}(inp.size, &inp[0], &out[0])").format( declar=declar, fname=funcdef.name, typ="double"), ), ], build_dir=build_dir, )
def test_newtons_method_function__fcode(): x = sp.Symbol('x', real=True) expr = sp.cos(x) - x**3 func = newtons_method_function(expr, x, attrs=[bind_C(name='newton')]) if not cython: skip("cython not installed.") if not has_fortran(): skip("No Fortran compiler found.") f_mod = f_module([func], 'mod_newton') with TemporaryDirectory() as folder: mod, info = compile_link_import_strings( [('newton.f90', f_mod), ('_newton.pyx', ("cdef extern double newton(double*)\n" "def py_newton(double x):\n" " return newton(&x)\n"))], build_dir=folder) assert abs(mod.py_newton(0.5) - 0.865474033102) < 1e-12
def test_newtons_method_function__fcode(): x = sp.Symbol('x', real=True) expr = sp.cos(x) - x**3 func = newtons_method_function(expr, x, attrs=[bind_C(name='newton')]) if not cython: skip("cython not installed.") if not has_fortran(): skip("No Fortran compiler found.") f_mod = f_module([func], 'mod_newton') with TemporaryDirectory() as folder: mod, info = compile_link_import_strings([ ('newton.f90', f_mod), ('_newton.pyx', ("cdef extern double newton(double*)\n" "def py_newton(double x):\n" " return newton(&x)\n")) ], build_dir=folder) assert abs(mod.py_newton(0.5) - 0.865474033102) < 1e-12
def test_newtons_method_function__ccode_parameters(): args = x, A, k, p = sp.symbols('x A k p') expr = A * sp.cos(k * x) - p * x**3 raises(ValueError, lambda: newtons_method_function(expr, x)) use_wurlitzer = wurlitzer func = newtons_method_function(expr, x, args, debug=use_wurlitzer) if not has_c(): skip("No C compiler found.") if not cython: skip("cython not installed.") compile_kw = dict(std='c99') with tempfile.TemporaryDirectory() as folder: mod, info = compile_link_import_strings( [('newton_par.c', ('#include <math.h>\n' '#include <stdio.h>\n') + ccode(func)), ('_newton_par.pyx', ("#cython: language_level={}\n".format("3") + "cdef extern double newton(double, double, double, double)\n" "def py_newton(x, A=1, k=1, p=1):\n" " return newton(x, A, k, p)\n"))], compile_kwargs=compile_kw, build_dir=folder) if use_wurlitzer: with wurlitzer.pipes() as (out, err): result = mod.py_newton(0.5) else: result = mod.py_newton(0.5) assert abs(result - 0.865474033102) < 1e-12 if not use_wurlitzer: skip( "C-level output only tested when package 'wurlitzer' is available." ) out, err = out.read(), err.read() assert err == '' assert out == """\
def test_newtons_method_function__ccode(): x = sp.Symbol('x', real=True) expr = sp.cos(x) - x**3 func = newtons_method_function(expr, x) if not cython: skip("cython not installed.") if not has_c(): skip("No C compiler found.") compile_kw = dict(std='c99') with TemporaryDirectory() as folder: mod, info = compile_link_import_strings([ ('newton.c', ('#include <math.h>\n' '#include <stdio.h>\n') + ccode(func)), ('_newton.pyx', ("cdef extern double newton(double)\n" "def py_newton(x):\n" " return newton(x)\n")) ], build_dir=folder, compile_kwargs=compile_kw) assert abs(mod.py_newton(0.5) - 0.865474033102) < 1e-12
def test_newtons_method_function__ccode(): x = sp.Symbol('x', real=True) expr = sp.cos(x) - x**3 func = newtons_method_function(expr, x) if not cython: skip("cython not installed.") if not has_c(): skip("No C compiler found.") compile_kw = dict(std='c99') with TemporaryDirectory() as folder: mod, info = compile_link_import_strings( [('newton.c', ('#include <math.h>\n' '#include <stdio.h>\n') + ccode(func)), ('_newton.pyx', ("cdef extern double newton(double)\n" "def py_newton(x):\n" " return newton(x)\n"))], build_dir=folder, compile_kwargs=compile_kw) assert abs(mod.py_newton(0.5) - 0.865474033102) < 1e-12
def test_newtons_method_function__ccode_parameters(): args = x, A, k, p = sp.symbols('x A k p') expr = A*sp.cos(k*x) - p*x**3 raises(ValueError, lambda: newtons_method_function(expr, x)) use_wurlitzer = wurlitzer func = newtons_method_function(expr, x, args, debug=use_wurlitzer) if not has_c(): skip("No C compiler found.") if not cython: skip("cython not installed.") compile_kw = dict(std='c99') with TemporaryDirectory() as folder: mod, info = compile_link_import_strings([ ('newton_par.c', ('#include <math.h>\n' '#include <stdio.h>\n') + ccode(func)), ('_newton_par.pyx', ("cdef extern double newton(double, double, double, double)\n" "def py_newton(x, A=1, k=1, p=1):\n" " return newton(x, A, k, p)\n")) ], compile_kwargs=compile_kw, build_dir=folder) if use_wurlitzer: with wurlitzer.pipes() as (out, err): result = mod.py_newton(0.5) else: result = mod.py_newton(0.5) assert abs(result - 0.865474033102) < 1e-12 if not use_wurlitzer: skip("C-level output only tested when package 'wurlitzer' is available.") out, err = out.read(), err.read() assert err == '' assert out == """\