From c9ef2931b1d351e833e58be3256c56919600422f Mon Sep 17 00:00:00 2001 From: Gagandeep Singh Date: Mon, 12 Dec 2022 16:30:31 +0530 Subject: [PATCH 1/6] wip --- integration_tests/CMakeLists.txt | 4 +- integration_tests/test_math.py | 496 ++++++++++---------- src/libasr/codegen/asr_to_c_cpp.h | 4 +- src/lpython/semantics/python_ast_to_asr.cpp | 19 +- src/runtime/math.py | 1 + 5 files changed, 271 insertions(+), 253 deletions(-) diff --git a/integration_tests/CMakeLists.txt b/integration_tests/CMakeLists.txt index 954a19885c..7832a6af1f 100644 --- a/integration_tests/CMakeLists.txt +++ b/integration_tests/CMakeLists.txt @@ -283,8 +283,8 @@ RUN(NAME test_import_01 LABELS cpython llvm c) RUN(NAME test_import_02 LABELS cpython llvm c) RUN(NAME test_import_03 LABELS cpython llvm c) RUN(NAME test_import_04 IMPORT_PATH .. - LABELS cpython llvm c) -RUN(NAME test_math LABELS cpython llvm) + LABELS cpython llvm) +RUN(NAME test_math LABELS cpython llvm c) RUN(NAME test_numpy_01 LABELS cpython llvm c) RUN(NAME test_numpy_02 LABELS cpython llvm c) RUN(NAME test_numpy_03 LABELS cpython llvm c) diff --git a/integration_tests/test_math.py b/integration_tests/test_math.py index 315b4efb8e..357947b65e 100644 --- a/integration_tests/test_math.py +++ b/integration_tests/test_math.py @@ -7,240 +7,240 @@ eps: f64 eps = 1e-12 -def test_factorial_1(): - i: i64 - i = factorial(i64(10)) - assert i == i64(3628800) - - -def test_comb(): - i: i32 - i = comb(10, 2) - assert i == 45 - - -def test_perm(): - i: i32 - i = perm(5, 2) - assert i == 20 +# def test_factorial_1(): +# i: i64 +# i = factorial(i64(10)) +# assert i == i64(3628800) + + +# def test_comb(): +# i: i32 +# i = comb(10, 2) +# assert i == 45 + + +# def test_perm(): +# i: i32 +# i = perm(5, 2) +# assert i == 20 -def test_isqrt(): - i: i32 - i = isqrt(15) - assert i == 3 - - -def test_degrees(): - - i: f64 - - # Check for integer - i = degrees(32) - assert abs(i - 1833.4649444186343) < eps - - # Check for float - i = degrees(32.2) - assert abs(i - 1844.924100321251) < eps - -def test_radians(): - i: f64 +# def test_isqrt(): +# i: i32 +# i = isqrt(15) +# assert i == 3 + + +# def test_degrees(): + +# i: f64 + +# # Check for integer +# i = degrees(32) +# assert abs(i - 1833.4649444186343) < eps + +# # Check for float +# i = degrees(32.2) +# assert abs(i - 1844.924100321251) < eps + +# def test_radians(): +# i: f64 - # Check for integer - i = radians(100) - assert abs(i - 1.7453292519943295) < eps +# # Check for integer +# i = radians(100) +# assert abs(i - 1.7453292519943295) < eps - # Check for float - i = radians(100.1) - assert abs(i - 1.7470745812463238) < eps +# # Check for float +# i = radians(100.1) +# assert abs(i - 1.7470745812463238) < eps -def test_exp(): - i: f64 - i = exp(2.34) - assert abs(i - 10.381236562731843) < eps +# def test_exp(): +# i: f64 +# i = exp(2.34) +# assert abs(i - 10.381236562731843) < eps -def test_pow(): - eps: f64 - eps = 1e-12 - x: f64 - x = 2.4 - y: f64 - y = 4.3 - assert abs(pow(x, y) - 43.14280115650323) < eps +# def test_pow(): +# eps: f64 +# eps = 1e-12 +# x: f64 +# x = 2.4 +# y: f64 +# y = 4.3 +# assert abs(pow(x, y) - 43.14280115650323) < eps - a: i64 - a = i64(2) - b: i64 - b = i64(4) - assert pow(a, b) == i64(16) - -def test_ldexp(): - i: f64 - i = ldexp(23.3, 2) - assert abs(i - 93.2) < eps - - -def test_fabs(): - - eps: f64 - eps = 1e-12 - i: f64 - j: f64 - i = -10.5 - j = -7.0 - assert fabs(i + fabs(j)) == 3.5 - assert abs(fabs(10) - fabs(-10)) < eps - assert abs(fabs(10.3) - fabs(-10.3)) < eps - assert fabs(0.5) == 0.5 - assert fabs(-5) == 5.0 - -def test_gcd(): - i: i32 - i = gcd(10, 4) - assert i == 2 - i = gcd(21, 14) - assert i == 7 - i = gcd(21, -12) - assert i == 3 - -def test_lcm(): - i: i32 - i = lcm(10, 4) - assert i == 20 - i = lcm(21, 14) - assert i == 42 - i = lcm(21, -12) - assert i == 84 - - -def test_floor(): - i: i64 - i = floor(10.02) - assert i == i64(10) - i = floor(-i64(13)) - assert i == -i64(13) - i = floor(-13.31) - assert i == -i64(14) - - -def test_ceil(): - i: i64 - i = ceil(10.02) - assert i == i64(11) - i = ceil(-i64(13)) - assert i == -i64(13) - i = ceil(-13.31) - assert i == -i64(13) - - -def test_remainder(): - assert remainder(9.0, 3.0) == 0.0 - assert remainder(12.0, 5.0) == 2.0 - assert remainder(13.0, 5.0) == -2.0 - -def test_fmod(): - assert fmod(20.5, 2.5) == 0.5 - assert fmod(-20.5, 2.5) == -0.5 - - -def test_log1p(): - assert log1p(1.0) - 0.69314718055994529 < eps - - -def test_expm1(): - assert expm1(1.0) - 1.71828182845904509 < eps - - -def test_trunc(): - i: i64 - i = trunc(3.5) - assert i == i64(3) - i = trunc(-4.5) - assert i == -i64(4) - i = trunc(5.5) - assert i == i64(5) - i = trunc(-4.5) - assert i == -i64(4) - -def test_fsum(): - res: f64 - eps: f64 = 1e-12 - - arr_i32: list[i32] - arr_i32 = [6, 12] - res = fsum(arr_i32) - assert abs(res - 18.0) < eps - - a: i64 = i64(12) - b: i64 = i64(6) - arr_i64: list[i64] - arr_i64 = [a, b] - res = fsum(arr_i64) - assert abs(res - 18.0) < eps - - x: f32 = f32(12.5) - y: f32 = f32(6.5) - arr_f32: list[f32] - arr_f32 = [x, y] - res = fsum(arr_f32) - assert abs(res - 19.0) < eps - - arr_f64: list[f64] - arr_f64 = [12.6, 6.4] - res = fsum(arr_f64) - assert abs(res - 19.0) < eps - -def test_prod(): - res: f64 - eps: f64 = 1e-12 - - arr_i32: list[i32] - arr_i32 = [6, 12] - res = prod(arr_i32) - assert abs(res - 72.0) < eps - - a: i64 = i64(12) - b: i64 = i64(6) - arr_i64: list[i64] - arr_i64 = [a, b] - res = prod(arr_i64) - assert abs(res - 72.0) < eps - - x: f32 = f32(12.5) - y: f32 = f32(6.5) - arr_f32: list[f32] - arr_f32 = [x, y] - res = prod(arr_f32) - assert abs(res - 81.25) < eps - - arr_f64: list[f64] - arr_f64 = [12.6, 6.4] - res = prod(arr_f64) - assert abs(res - 80.64) < eps - -def test_dist(): - x: list[f64] - y: list[f64] - eps: f64 = 1e-12 - x = [1.0, 2.2, 3.333, 4.0, 5.0] - y = [6.1, 7.2, 8.0, 9.0, 10.0] - assert abs(dist(x, y) - 11.081105044173166) < eps - -def test_modf(): - i: f64 - i = 3.14 - - res: tuple[f64, f64] - res = modf(i) - assert abs(res[0] - 0.14) <= 1e-6 - assert abs(res[1] - 3.0) <= 1e-6 - - i = -442.3 - res = modf(i) - assert abs(res[0] + 0.3) <= 1e-6 - assert abs(res[1] + 442.0) <= 1e-6 +# a: i64 +# a = i64(2) +# b: i64 +# b = i64(4) +# assert pow(a, b) == i64(16) + +# def test_ldexp(): +# i: f64 +# i = ldexp(23.3, 2) +# assert abs(i - 93.2) < eps + + +# def test_fabs(): + +# eps: f64 +# eps = 1e-12 +# i: f64 +# j: f64 +# i = -10.5 +# j = -7.0 +# assert fabs(i + fabs(j)) == 3.5 +# assert abs(fabs(10) - fabs(-10)) < eps +# assert abs(fabs(10.3) - fabs(-10.3)) < eps +# assert fabs(0.5) == 0.5 +# assert fabs(-5) == 5.0 + +# def test_gcd(): +# i: i32 +# i = gcd(10, 4) +# assert i == 2 +# i = gcd(21, 14) +# assert i == 7 +# i = gcd(21, -12) +# assert i == 3 + +# def test_lcm(): +# i: i32 +# i = lcm(10, 4) +# assert i == 20 +# i = lcm(21, 14) +# assert i == 42 +# i = lcm(21, -12) +# assert i == 84 + + +# def test_floor(): +# i: i64 +# i = floor(10.02) +# assert i == i64(10) +# i = floor(-i64(13)) +# assert i == -i64(13) +# i = floor(-13.31) +# assert i == -i64(14) + + +# def test_ceil(): +# i: i64 +# i = ceil(10.02) +# assert i == i64(11) +# i = ceil(-i64(13)) +# assert i == -i64(13) +# i = ceil(-13.31) +# assert i == -i64(13) + + +# def test_remainder(): +# assert remainder(9.0, 3.0) == 0.0 +# assert remainder(12.0, 5.0) == 2.0 +# assert remainder(13.0, 5.0) == -2.0 + +# def test_fmod(): +# assert fmod(20.5, 2.5) == 0.5 +# assert fmod(-20.5, 2.5) == -0.5 + + +# def test_log1p(): +# assert log1p(1.0) - 0.69314718055994529 < eps + + +# def test_expm1(): +# assert expm1(1.0) - 1.71828182845904509 < eps + + +# def test_trunc(): +# i: i64 +# i = trunc(3.5) +# assert i == i64(3) +# i = trunc(-4.5) +# assert i == -i64(4) +# i = trunc(5.5) +# assert i == i64(5) +# i = trunc(-4.5) +# assert i == -i64(4) + +# def test_fsum(): +# res: f64 +# eps: f64 = 1e-12 + +# arr_i32: list[i32] +# arr_i32 = [6, 12] +# res = fsum(arr_i32) +# assert abs(res - 18.0) < eps + +# a: i64 = i64(12) +# b: i64 = i64(6) +# arr_i64: list[i64] +# arr_i64 = [a, b] +# res = fsum(arr_i64) +# assert abs(res - 18.0) < eps + +# x: f32 = f32(12.5) +# y: f32 = f32(6.5) +# arr_f32: list[f32] +# arr_f32 = [x, y] +# res = fsum(arr_f32) +# assert abs(res - 19.0) < eps + +# arr_f64: list[f64] +# arr_f64 = [12.6, 6.4] +# res = fsum(arr_f64) +# assert abs(res - 19.0) < eps + +# def test_prod(): +# res: f64 +# eps: f64 = 1e-12 + +# arr_i32: list[i32] +# arr_i32 = [6, 12] +# res = prod(arr_i32) +# assert abs(res - 72.0) < eps + +# a: i64 = i64(12) +# b: i64 = i64(6) +# arr_i64: list[i64] +# arr_i64 = [a, b] +# res = prod(arr_i64) +# assert abs(res - 72.0) < eps + +# x: f32 = f32(12.5) +# y: f32 = f32(6.5) +# arr_f32: list[f32] +# arr_f32 = [x, y] +# res = prod(arr_f32) +# assert abs(res - 81.25) < eps + +# arr_f64: list[f64] +# arr_f64 = [12.6, 6.4] +# res = prod(arr_f64) +# assert abs(res - 80.64) < eps + +# def test_dist(): +# x: list[f64] +# y: list[f64] +# eps: f64 = 1e-12 +# x = [1.0, 2.2, 3.333, 4.0, 5.0] +# y = [6.1, 7.2, 8.0, 9.0, 10.0] +# assert abs(dist(x, y) - 11.081105044173166) < eps + +# def test_modf(): +# i: f64 +# i = 3.14 + +# res: tuple[f64, f64] +# res = modf(i) +# assert abs(res[0] - 0.14) <= 1e-6 +# assert abs(res[1] - 3.0) <= 1e-6 + +# i = -442.3 +# res = modf(i) +# assert abs(res[0] + 0.3) <= 1e-6 +# assert abs(res[1] + 442.0) <= 1e-6 def test_issue_1242(): @@ -255,29 +255,29 @@ def test_issue_1242(): def check(): - test_factorial_1() - test_comb() - test_isqrt() - test_perm() - test_degrees() - test_radians() - test_exp() - test_pow() - test_fabs() - test_ldexp() - test_gcd() - test_lcm() - test_floor() - test_ceil() - test_remainder() - test_fmod() - test_expm1() - test_log1p() - test_trunc() - test_fsum() - test_prod() - test_dist() - test_modf() + # test_factorial_1() + # test_comb() + # test_isqrt() + # test_perm() + # test_degrees() + # test_radians() + # test_exp() + # test_pow() + # test_fabs() + # test_ldexp() + # test_gcd() + # test_lcm() + # test_floor() + # test_ceil() + # test_remainder() + # test_fmod() + # test_expm1() + # test_log1p() + # test_trunc() + # test_fsum() + # test_prod() + # test_dist() + # test_modf() test_issue_1242() diff --git a/src/libasr/codegen/asr_to_c_cpp.h b/src/libasr/codegen/asr_to_c_cpp.h index 15cd92b70d..97c4f3a516 100644 --- a/src/libasr/codegen/asr_to_c_cpp.h +++ b/src/libasr/codegen/asr_to_c_cpp.h @@ -1099,9 +1099,9 @@ R"(#include sv->m_intent == ASRUtils::intent_inout) && is_c && ASRUtils::is_array(sv->m_type) && ASRUtils::is_pointer(sv->m_type)) { - src = "(*" + std::string(ASR::down_cast(s)->m_name) + ")"; + src = "(*" + std::string(ASRUtils::symbol_name(x.m_v)) + ")"; } else { - src = std::string(ASR::down_cast(s)->m_name); + src = std::string(ASRUtils::symbol_name(x.m_v)); } last_expr_precedence = 2; } diff --git a/src/lpython/semantics/python_ast_to_asr.cpp b/src/lpython/semantics/python_ast_to_asr.cpp index d7117131f5..1d7eb18443 100644 --- a/src/lpython/semantics/python_ast_to_asr.cpp +++ b/src/lpython/semantics/python_ast_to_asr.cpp @@ -4864,13 +4864,30 @@ class BodyVisitor : public CommonVisitor { } } else if (ASR::is_a(*t)) { ASR::Module_t *m = ASR::down_cast(t); - std::string sym_name = value + "@" + x.m_attr; + std::string sym_name = value + "_" + x.m_attr + "_external__"; ASR::symbol_t *sym = current_scope->resolve_symbol(sym_name); if (!sym) { sym = import_from_module(al, m, current_scope, value, x.m_attr, sym_name, x.base.base.loc, false); LFORTRAN_ASSERT(ASR::is_a(*sym)); current_scope->add_symbol(sym_name, sym); + } else { + if( ASR::is_a(*sym) ) { + ASR::ExternalSymbol_t* ext_sym = ASR::down_cast(sym); + if( ext_sym->m_external != m->m_symtab->resolve_symbol(std::string(x.m_attr)) ) { + sym_name = current_scope->get_unique_name(sym_name); + sym = import_from_module(al, m, current_scope, value, + x.m_attr, sym_name, x.base.base.loc, false); + LFORTRAN_ASSERT(ASR::is_a(*sym)); + current_scope->add_symbol(sym_name, sym); + } + } else { + sym_name = current_scope->get_unique_name(sym_name); + sym = import_from_module(al, m, current_scope, value, + x.m_attr, sym_name, x.base.base.loc, false); + LFORTRAN_ASSERT(ASR::is_a(*sym)); + current_scope->add_symbol(sym_name, sym); + } } tmp = ASR::make_Var_t(al, x.base.base.loc, sym); } else { diff --git a/src/runtime/math.py b/src/runtime/math.py index 379581c528..243317f6d8 100644 --- a/src/runtime/math.py +++ b/src/runtime/math.py @@ -567,6 +567,7 @@ def tan(x: f64) -> f64: def _lfortran_dlog(x: f64) -> f64: pass +@overload def log(x: f64) -> f64: return _lfortran_dlog(x) From a8ab7458650d48708cd15a700cbecdef7937c840 Mon Sep 17 00:00:00 2001 From: Gagandeep Singh Date: Fri, 16 Dec 2022 14:30:22 +0530 Subject: [PATCH 2/6] done --- integration_tests/test_math.py | 496 +++++++++++++++--------------- src/libasr/codegen/asr_to_c_cpp.h | 16 + 2 files changed, 264 insertions(+), 248 deletions(-) diff --git a/integration_tests/test_math.py b/integration_tests/test_math.py index 357947b65e..315b4efb8e 100644 --- a/integration_tests/test_math.py +++ b/integration_tests/test_math.py @@ -7,240 +7,240 @@ eps: f64 eps = 1e-12 -# def test_factorial_1(): -# i: i64 -# i = factorial(i64(10)) -# assert i == i64(3628800) - - -# def test_comb(): -# i: i32 -# i = comb(10, 2) -# assert i == 45 - - -# def test_perm(): -# i: i32 -# i = perm(5, 2) -# assert i == 20 +def test_factorial_1(): + i: i64 + i = factorial(i64(10)) + assert i == i64(3628800) + + +def test_comb(): + i: i32 + i = comb(10, 2) + assert i == 45 + + +def test_perm(): + i: i32 + i = perm(5, 2) + assert i == 20 -# def test_isqrt(): -# i: i32 -# i = isqrt(15) -# assert i == 3 - - -# def test_degrees(): - -# i: f64 - -# # Check for integer -# i = degrees(32) -# assert abs(i - 1833.4649444186343) < eps - -# # Check for float -# i = degrees(32.2) -# assert abs(i - 1844.924100321251) < eps - -# def test_radians(): -# i: f64 +def test_isqrt(): + i: i32 + i = isqrt(15) + assert i == 3 + + +def test_degrees(): + + i: f64 + + # Check for integer + i = degrees(32) + assert abs(i - 1833.4649444186343) < eps + + # Check for float + i = degrees(32.2) + assert abs(i - 1844.924100321251) < eps + +def test_radians(): + i: f64 -# # Check for integer -# i = radians(100) -# assert abs(i - 1.7453292519943295) < eps + # Check for integer + i = radians(100) + assert abs(i - 1.7453292519943295) < eps -# # Check for float -# i = radians(100.1) -# assert abs(i - 1.7470745812463238) < eps + # Check for float + i = radians(100.1) + assert abs(i - 1.7470745812463238) < eps -# def test_exp(): -# i: f64 -# i = exp(2.34) -# assert abs(i - 10.381236562731843) < eps +def test_exp(): + i: f64 + i = exp(2.34) + assert abs(i - 10.381236562731843) < eps -# def test_pow(): -# eps: f64 -# eps = 1e-12 -# x: f64 -# x = 2.4 -# y: f64 -# y = 4.3 -# assert abs(pow(x, y) - 43.14280115650323) < eps +def test_pow(): + eps: f64 + eps = 1e-12 + x: f64 + x = 2.4 + y: f64 + y = 4.3 + assert abs(pow(x, y) - 43.14280115650323) < eps -# a: i64 -# a = i64(2) -# b: i64 -# b = i64(4) -# assert pow(a, b) == i64(16) - -# def test_ldexp(): -# i: f64 -# i = ldexp(23.3, 2) -# assert abs(i - 93.2) < eps - - -# def test_fabs(): - -# eps: f64 -# eps = 1e-12 -# i: f64 -# j: f64 -# i = -10.5 -# j = -7.0 -# assert fabs(i + fabs(j)) == 3.5 -# assert abs(fabs(10) - fabs(-10)) < eps -# assert abs(fabs(10.3) - fabs(-10.3)) < eps -# assert fabs(0.5) == 0.5 -# assert fabs(-5) == 5.0 - -# def test_gcd(): -# i: i32 -# i = gcd(10, 4) -# assert i == 2 -# i = gcd(21, 14) -# assert i == 7 -# i = gcd(21, -12) -# assert i == 3 - -# def test_lcm(): -# i: i32 -# i = lcm(10, 4) -# assert i == 20 -# i = lcm(21, 14) -# assert i == 42 -# i = lcm(21, -12) -# assert i == 84 - - -# def test_floor(): -# i: i64 -# i = floor(10.02) -# assert i == i64(10) -# i = floor(-i64(13)) -# assert i == -i64(13) -# i = floor(-13.31) -# assert i == -i64(14) - - -# def test_ceil(): -# i: i64 -# i = ceil(10.02) -# assert i == i64(11) -# i = ceil(-i64(13)) -# assert i == -i64(13) -# i = ceil(-13.31) -# assert i == -i64(13) - - -# def test_remainder(): -# assert remainder(9.0, 3.0) == 0.0 -# assert remainder(12.0, 5.0) == 2.0 -# assert remainder(13.0, 5.0) == -2.0 - -# def test_fmod(): -# assert fmod(20.5, 2.5) == 0.5 -# assert fmod(-20.5, 2.5) == -0.5 - - -# def test_log1p(): -# assert log1p(1.0) - 0.69314718055994529 < eps - - -# def test_expm1(): -# assert expm1(1.0) - 1.71828182845904509 < eps - - -# def test_trunc(): -# i: i64 -# i = trunc(3.5) -# assert i == i64(3) -# i = trunc(-4.5) -# assert i == -i64(4) -# i = trunc(5.5) -# assert i == i64(5) -# i = trunc(-4.5) -# assert i == -i64(4) - -# def test_fsum(): -# res: f64 -# eps: f64 = 1e-12 - -# arr_i32: list[i32] -# arr_i32 = [6, 12] -# res = fsum(arr_i32) -# assert abs(res - 18.0) < eps - -# a: i64 = i64(12) -# b: i64 = i64(6) -# arr_i64: list[i64] -# arr_i64 = [a, b] -# res = fsum(arr_i64) -# assert abs(res - 18.0) < eps - -# x: f32 = f32(12.5) -# y: f32 = f32(6.5) -# arr_f32: list[f32] -# arr_f32 = [x, y] -# res = fsum(arr_f32) -# assert abs(res - 19.0) < eps - -# arr_f64: list[f64] -# arr_f64 = [12.6, 6.4] -# res = fsum(arr_f64) -# assert abs(res - 19.0) < eps - -# def test_prod(): -# res: f64 -# eps: f64 = 1e-12 - -# arr_i32: list[i32] -# arr_i32 = [6, 12] -# res = prod(arr_i32) -# assert abs(res - 72.0) < eps - -# a: i64 = i64(12) -# b: i64 = i64(6) -# arr_i64: list[i64] -# arr_i64 = [a, b] -# res = prod(arr_i64) -# assert abs(res - 72.0) < eps - -# x: f32 = f32(12.5) -# y: f32 = f32(6.5) -# arr_f32: list[f32] -# arr_f32 = [x, y] -# res = prod(arr_f32) -# assert abs(res - 81.25) < eps - -# arr_f64: list[f64] -# arr_f64 = [12.6, 6.4] -# res = prod(arr_f64) -# assert abs(res - 80.64) < eps - -# def test_dist(): -# x: list[f64] -# y: list[f64] -# eps: f64 = 1e-12 -# x = [1.0, 2.2, 3.333, 4.0, 5.0] -# y = [6.1, 7.2, 8.0, 9.0, 10.0] -# assert abs(dist(x, y) - 11.081105044173166) < eps - -# def test_modf(): -# i: f64 -# i = 3.14 - -# res: tuple[f64, f64] -# res = modf(i) -# assert abs(res[0] - 0.14) <= 1e-6 -# assert abs(res[1] - 3.0) <= 1e-6 - -# i = -442.3 -# res = modf(i) -# assert abs(res[0] + 0.3) <= 1e-6 -# assert abs(res[1] + 442.0) <= 1e-6 + a: i64 + a = i64(2) + b: i64 + b = i64(4) + assert pow(a, b) == i64(16) + +def test_ldexp(): + i: f64 + i = ldexp(23.3, 2) + assert abs(i - 93.2) < eps + + +def test_fabs(): + + eps: f64 + eps = 1e-12 + i: f64 + j: f64 + i = -10.5 + j = -7.0 + assert fabs(i + fabs(j)) == 3.5 + assert abs(fabs(10) - fabs(-10)) < eps + assert abs(fabs(10.3) - fabs(-10.3)) < eps + assert fabs(0.5) == 0.5 + assert fabs(-5) == 5.0 + +def test_gcd(): + i: i32 + i = gcd(10, 4) + assert i == 2 + i = gcd(21, 14) + assert i == 7 + i = gcd(21, -12) + assert i == 3 + +def test_lcm(): + i: i32 + i = lcm(10, 4) + assert i == 20 + i = lcm(21, 14) + assert i == 42 + i = lcm(21, -12) + assert i == 84 + + +def test_floor(): + i: i64 + i = floor(10.02) + assert i == i64(10) + i = floor(-i64(13)) + assert i == -i64(13) + i = floor(-13.31) + assert i == -i64(14) + + +def test_ceil(): + i: i64 + i = ceil(10.02) + assert i == i64(11) + i = ceil(-i64(13)) + assert i == -i64(13) + i = ceil(-13.31) + assert i == -i64(13) + + +def test_remainder(): + assert remainder(9.0, 3.0) == 0.0 + assert remainder(12.0, 5.0) == 2.0 + assert remainder(13.0, 5.0) == -2.0 + +def test_fmod(): + assert fmod(20.5, 2.5) == 0.5 + assert fmod(-20.5, 2.5) == -0.5 + + +def test_log1p(): + assert log1p(1.0) - 0.69314718055994529 < eps + + +def test_expm1(): + assert expm1(1.0) - 1.71828182845904509 < eps + + +def test_trunc(): + i: i64 + i = trunc(3.5) + assert i == i64(3) + i = trunc(-4.5) + assert i == -i64(4) + i = trunc(5.5) + assert i == i64(5) + i = trunc(-4.5) + assert i == -i64(4) + +def test_fsum(): + res: f64 + eps: f64 = 1e-12 + + arr_i32: list[i32] + arr_i32 = [6, 12] + res = fsum(arr_i32) + assert abs(res - 18.0) < eps + + a: i64 = i64(12) + b: i64 = i64(6) + arr_i64: list[i64] + arr_i64 = [a, b] + res = fsum(arr_i64) + assert abs(res - 18.0) < eps + + x: f32 = f32(12.5) + y: f32 = f32(6.5) + arr_f32: list[f32] + arr_f32 = [x, y] + res = fsum(arr_f32) + assert abs(res - 19.0) < eps + + arr_f64: list[f64] + arr_f64 = [12.6, 6.4] + res = fsum(arr_f64) + assert abs(res - 19.0) < eps + +def test_prod(): + res: f64 + eps: f64 = 1e-12 + + arr_i32: list[i32] + arr_i32 = [6, 12] + res = prod(arr_i32) + assert abs(res - 72.0) < eps + + a: i64 = i64(12) + b: i64 = i64(6) + arr_i64: list[i64] + arr_i64 = [a, b] + res = prod(arr_i64) + assert abs(res - 72.0) < eps + + x: f32 = f32(12.5) + y: f32 = f32(6.5) + arr_f32: list[f32] + arr_f32 = [x, y] + res = prod(arr_f32) + assert abs(res - 81.25) < eps + + arr_f64: list[f64] + arr_f64 = [12.6, 6.4] + res = prod(arr_f64) + assert abs(res - 80.64) < eps + +def test_dist(): + x: list[f64] + y: list[f64] + eps: f64 = 1e-12 + x = [1.0, 2.2, 3.333, 4.0, 5.0] + y = [6.1, 7.2, 8.0, 9.0, 10.0] + assert abs(dist(x, y) - 11.081105044173166) < eps + +def test_modf(): + i: f64 + i = 3.14 + + res: tuple[f64, f64] + res = modf(i) + assert abs(res[0] - 0.14) <= 1e-6 + assert abs(res[1] - 3.0) <= 1e-6 + + i = -442.3 + res = modf(i) + assert abs(res[0] + 0.3) <= 1e-6 + assert abs(res[1] + 442.0) <= 1e-6 def test_issue_1242(): @@ -255,29 +255,29 @@ def test_issue_1242(): def check(): - # test_factorial_1() - # test_comb() - # test_isqrt() - # test_perm() - # test_degrees() - # test_radians() - # test_exp() - # test_pow() - # test_fabs() - # test_ldexp() - # test_gcd() - # test_lcm() - # test_floor() - # test_ceil() - # test_remainder() - # test_fmod() - # test_expm1() - # test_log1p() - # test_trunc() - # test_fsum() - # test_prod() - # test_dist() - # test_modf() + test_factorial_1() + test_comb() + test_isqrt() + test_perm() + test_degrees() + test_radians() + test_exp() + test_pow() + test_fabs() + test_ldexp() + test_gcd() + test_lcm() + test_floor() + test_ceil() + test_remainder() + test_fmod() + test_expm1() + test_log1p() + test_trunc() + test_fsum() + test_prod() + test_dist() + test_modf() test_issue_1242() diff --git a/src/libasr/codegen/asr_to_c_cpp.h b/src/libasr/codegen/asr_to_c_cpp.h index 97c4f3a516..f092235d5d 100644 --- a/src/libasr/codegen/asr_to_c_cpp.h +++ b/src/libasr/codegen/asr_to_c_cpp.h @@ -458,6 +458,22 @@ R"(#include } } + for (auto &item : x.m_symtab->get_scope()) { + ASR::symbol_t* var_sym = item.second; + if( ASR::is_a(*var_sym) ) { + ASR::ExternalSymbol_t* v_ext = ASR::down_cast(var_sym); + ASR::symbol_t* v_sym = v_ext->m_external; + // std::cout<<"v_sym: "<type<<" "<m_name<(*v_sym)) { + ASR::Variable_t* v = ASR::down_cast(v_sym); + char* v_m_name = v->m_name; + v->m_name = v_ext->m_name; + decl += indent + self().convert_variable_decl(*v) + ";\n"; + v->m_name = v_m_name; + } + } + } + current_function = &x; for (size_t i=0; i Date: Fri, 16 Dec 2022 15:39:17 +0530 Subject: [PATCH 3/6] Use overload to avoid incorrect linking of symbols --- src/runtime/math.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/runtime/math.py b/src/runtime/math.py index 243317f6d8..426bdc5990 100644 --- a/src/runtime/math.py +++ b/src/runtime/math.py @@ -688,6 +688,7 @@ def log1p(x: f64) -> f64: return log(1.0 + x) +@overload def fmod(x: f64, y: f64) -> f64: if y == 0.0: raise ValueError('math domain error') From 45b1b3b9940c095d37ef21f4c0e22c8f28776468 Mon Sep 17 00:00:00 2001 From: Gagandeep Singh Date: Fri, 16 Dec 2022 16:18:37 +0530 Subject: [PATCH 4/6] done --- src/libasr/codegen/asr_to_c_cpp.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libasr/codegen/asr_to_c_cpp.h b/src/libasr/codegen/asr_to_c_cpp.h index f092235d5d..3fd5472d86 100644 --- a/src/libasr/codegen/asr_to_c_cpp.h +++ b/src/libasr/codegen/asr_to_c_cpp.h @@ -463,13 +463,13 @@ R"(#include if( ASR::is_a(*var_sym) ) { ASR::ExternalSymbol_t* v_ext = ASR::down_cast(var_sym); ASR::symbol_t* v_sym = v_ext->m_external; - // std::cout<<"v_sym: "<type<<" "<m_name<(*v_sym)) { ASR::Variable_t* v = ASR::down_cast(v_sym); - char* v_m_name = v->m_name; - v->m_name = v_ext->m_name; - decl += indent + self().convert_variable_decl(*v) + ";\n"; - v->m_name = v_m_name; + if( v->m_symbolic_value ) { + this->visit_expr(*v->m_symbolic_value); + decl += indent + "#define " + std::string(v_ext->m_name) + " " + src + "\n"; + src.clear(); + } } } } From f1b31d81509ed7273bb9d71d3b36bcec77edc1b7 Mon Sep 17 00:00:00 2001 From: Gagandeep Singh Date: Tue, 10 Jan 2023 20:31:46 +0530 Subject: [PATCH 5/6] Use constant variables to declare import constants inside a Function --- src/libasr/codegen/asr_to_c.cpp | 66 ++++++++++++++++++++++++++----- src/libasr/codegen/asr_to_c_cpp.h | 53 ++++++++++++++++++++++--- src/libasr/codegen/asr_to_cpp.cpp | 15 ++++++- 3 files changed, 117 insertions(+), 17 deletions(-) diff --git a/src/libasr/codegen/asr_to_c.cpp b/src/libasr/codegen/asr_to_c.cpp index 230b62fd49..fb5077c59a 100644 --- a/src/libasr/codegen/asr_to_c.cpp +++ b/src/libasr/codegen/asr_to_c.cpp @@ -158,7 +158,13 @@ class ASRToCVisitor : public BaseCCPPVisitor counter += 1; ASR::dimension_t* m_dims = nullptr; size_t n_dims = ASRUtils::extract_dimensions_from_ttype(mem_type, m_dims); - sub += indent + convert_variable_decl(*mem_var, true, true, true, true, mem_var_name) + ";\n"; + CDeclarationOptions c_decl_options_; + c_decl_options_.pre_initialise_derived_type = true; + c_decl_options_.use_ptr_for_derived_type = true; + c_decl_options_.use_static = true; + c_decl_options_.force_declare = true; + c_decl_options_.force_declare_name = mem_var_name; + sub += indent + convert_variable_decl(*mem_var, &c_decl_options_) + ";\n"; if( !ASRUtils::is_fixed_size_array(m_dims, n_dims) ) { sub += indent + name + "->" + itr.first + " = " + mem_var_name + ";\n"; } @@ -172,12 +178,34 @@ class ASRToCVisitor : public BaseCCPPVisitor } std::string convert_variable_decl(const ASR::Variable_t &v, - bool pre_initialise_derived_type=true, - bool use_ptr_for_derived_type=true, - bool use_static=true, - bool force_declare=false, - std::string force_declare_name="") + DeclarationOptions* decl_options=nullptr) { + bool pre_initialise_derived_type; + bool use_ptr_for_derived_type; + bool use_static; + bool force_declare; + std::string force_declare_name; + bool declare_as_constant; + std::string const_name; + + if( decl_options ) { + CDeclarationOptions* c_decl_options = reinterpret_cast(decl_options); + pre_initialise_derived_type = c_decl_options->pre_initialise_derived_type; + use_ptr_for_derived_type = c_decl_options->use_ptr_for_derived_type; + use_static = c_decl_options->use_static; + force_declare = c_decl_options->force_declare; + force_declare_name = c_decl_options->force_declare_name; + declare_as_constant = c_decl_options->declare_as_constant; + const_name = c_decl_options->const_name; + } else { + pre_initialise_derived_type = true; + use_ptr_for_derived_type = true; + use_static = true; + force_declare = false; + force_declare_name = ""; + declare_as_constant = false; + const_name = ""; + } std::string sub; bool use_ref = (v.m_intent == LFortran::ASRUtils::intent_out || v.m_intent == LFortran::ASRUtils::intent_inout); @@ -275,8 +303,13 @@ class ASRToCVisitor : public BaseCCPPVisitor } } else { bool is_fixed_size = true; + std::string v_m_name = v.m_name; + if( declare_as_constant ) { + type_name = "const " + type_name; + v_m_name = const_name; + } dims = convert_dims_c(t->n_dims, t->m_dims, v_m_type, is_fixed_size); - sub = format_type_c(dims, type_name, v.m_name, use_ref, dummy); + sub = format_type_c(dims, type_name, v_m_name, use_ref, dummy); } } else if (ASRUtils::is_real(*v_m_type)) { ASR::Real_t *t = ASR::down_cast(v_m_type); @@ -307,8 +340,13 @@ class ASRToCVisitor : public BaseCCPPVisitor } } else { bool is_fixed_size = true; + std::string v_m_name = v.m_name; + if( declare_as_constant ) { + type_name = "const " + type_name; + v_m_name = const_name; + } dims = convert_dims_c(t->n_dims, t->m_dims, v_m_type, is_fixed_size); - sub = format_type_c(dims, type_name, v.m_name, use_ref, dummy); + sub = format_type_c(dims, type_name, v_m_name, use_ref, dummy); } } else if (ASRUtils::is_complex(*v_m_type)) { headers.insert("complex"); @@ -340,8 +378,13 @@ class ASRToCVisitor : public BaseCCPPVisitor } } else { bool is_fixed_size = true; + std::string v_m_name = v.m_name; + if( declare_as_constant ) { + type_name = "const " + type_name; + v_m_name = const_name; + } dims = convert_dims_c(t->n_dims, t->m_dims, v_m_type, is_fixed_size); - sub = format_type_c(dims, type_name, v.m_name, use_ref, dummy); + sub = format_type_c(dims, type_name, v_m_name, use_ref, dummy); } } else if (ASRUtils::is_logical(*v_m_type)) { ASR::Logical_t *t = ASR::down_cast(v_m_type); @@ -731,12 +774,15 @@ R"( indentation_level += 1; std::string open_struct = indent + c_type_name + " " + std::string(x.m_name) + " {\n"; indent.push_back(' '); + CDeclarationOptions c_decl_options_; + c_decl_options_.pre_initialise_derived_type = false; + c_decl_options_.use_ptr_for_derived_type = false; for( size_t i = 0; i < x.n_members; i++ ) { ASR::symbol_t* member = x.m_symtab->get_symbol(x.m_members[i]); LFORTRAN_ASSERT(ASR::is_a(*member)); body += indent + convert_variable_decl( *ASR::down_cast(member), - false, false); + &c_decl_options_); if( !ASR::is_a(*ASRUtils::symbol_type(member)) || ASR::down_cast(member)->m_intent == ASRUtils::intent_return_var ) { body += ";\n"; diff --git a/src/libasr/codegen/asr_to_c_cpp.h b/src/libasr/codegen/asr_to_c_cpp.h index 3fd5472d86..239b93ed64 100644 --- a/src/libasr/codegen/asr_to_c_cpp.h +++ b/src/libasr/codegen/asr_to_c_cpp.h @@ -30,7 +30,6 @@ namespace LFortran { - // Platform dependent fast unique hash: static inline uint64_t get_hash(ASR::asr_t *node) { @@ -43,6 +42,38 @@ struct SymbolInfo bool intrinsic_function = false; }; +struct DeclarationOptions { +}; + +struct CDeclarationOptions: public DeclarationOptions { + bool pre_initialise_derived_type; + bool use_ptr_for_derived_type; + bool use_static; + bool force_declare; + std::string force_declare_name; + bool declare_as_constant; + std::string const_name; + + CDeclarationOptions() : + pre_initialise_derived_type{true}, + use_ptr_for_derived_type{true}, + use_static{true}, + force_declare{false}, + force_declare_name{""}, + declare_as_constant{false}, + const_name{""} { + } +}; + +struct CPPDeclarationOptions: public DeclarationOptions { + bool use_static; + bool use_templates_for_arrays; + + CPPDeclarationOptions() : + use_static{true}, + use_templates_for_arrays{false} { + } +}; template class BaseCCPPVisitor : public ASR::BaseVisitor @@ -376,9 +407,14 @@ R"(#include ASR::Variable_t *arg = LFortran::ASRUtils::EXPR2VAR(x.m_args[i]); LFORTRAN_ASSERT(LFortran::ASRUtils::is_arg_dummy(arg->m_intent)); if( is_c ) { - func += self().convert_variable_decl(*arg, false); + CDeclarationOptions c_decl_options; + c_decl_options.pre_initialise_derived_type = false; + func += self().convert_variable_decl(*arg, &c_decl_options); } else { - func += self().convert_variable_decl(*arg, false, true); + CPPDeclarationOptions cpp_decl_options; + cpp_decl_options.use_static = false; + cpp_decl_options.use_templates_for_arrays = true; + func += self().convert_variable_decl(*arg, &cpp_decl_options); } if (i < x.n_args-1) func += ", "; } @@ -466,8 +502,15 @@ R"(#include if (ASR::is_a(*v_sym)) { ASR::Variable_t* v = ASR::down_cast(v_sym); if( v->m_symbolic_value ) { - this->visit_expr(*v->m_symbolic_value); - decl += indent + "#define " + std::string(v_ext->m_name) + " " + src + "\n"; + if( is_c ) { + CDeclarationOptions c_decl_options; + c_decl_options.declare_as_constant = true; + c_decl_options.const_name = v_ext->m_name; + decl += indent + self().convert_variable_decl(*v, &c_decl_options) + ";\n"; + } else { + // TODO: Do for CPP when the use case shows up + decl += indent + self().convert_variable_decl(*v) + ";\n"; + } src.clear(); } } diff --git a/src/libasr/codegen/asr_to_cpp.cpp b/src/libasr/codegen/asr_to_cpp.cpp index da61503a49..70dda0a753 100644 --- a/src/libasr/codegen/asr_to_cpp.cpp +++ b/src/libasr/codegen/asr_to_cpp.cpp @@ -209,9 +209,20 @@ class ASRToCPPVisitor : public BaseCCPPVisitor return typename_T + "* " + v_name; } - std::string convert_variable_decl(const ASR::Variable_t &v, bool use_static=true, - bool use_templates_for_arrays=false) + std::string convert_variable_decl(const ASR::Variable_t &v, DeclarationOptions* decl_options=nullptr) { + bool use_static; + bool use_templates_for_arrays; + + if( decl_options ) { + CPPDeclarationOptions* cpp_decl_options = reinterpret_cast(decl_options); + use_static = cpp_decl_options->use_static; + use_templates_for_arrays = cpp_decl_options->use_templates_for_arrays; + } else { + use_static = true; + use_templates_for_arrays = false; + } + std::string sub; bool use_ref = (v.m_intent == LFortran::ASRUtils::intent_out || v.m_intent == LFortran::ASRUtils::intent_inout || From d5517c20cc4e75687b974fa3ec8d499ff86acdc1 Mon Sep 17 00:00:00 2001 From: Gagandeep Singh Date: Wed, 11 Jan 2023 00:26:56 +0530 Subject: [PATCH 6/6] done --- src/libasr/runtime/lfortran_intrinsics.c | 10 +++++++ src/libasr/runtime/lfortran_intrinsics.h | 2 ++ src/runtime/math.py | 35 ++++++++++++++++++++++-- 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/src/libasr/runtime/lfortran_intrinsics.c b/src/libasr/runtime/lfortran_intrinsics.c index 45ca9a931c..1c9f960f61 100644 --- a/src/libasr/runtime/lfortran_intrinsics.c +++ b/src/libasr/runtime/lfortran_intrinsics.c @@ -246,6 +246,16 @@ LFORTRAN_API double _lfortran_dlog(double x) return log(x); } +LFORTRAN_API float _lfortran_slog1p(float x) +{ + return log1pf(x); +} + +LFORTRAN_API double _lfortran_dlog1p(double x) +{ + return log1p(x); +} + LFORTRAN_API float_complex_t _lfortran_clog(float_complex_t x) { return clogf(x); diff --git a/src/libasr/runtime/lfortran_intrinsics.h b/src/libasr/runtime/lfortran_intrinsics.h index b72fcb57cc..4d71238506 100644 --- a/src/libasr/runtime/lfortran_intrinsics.h +++ b/src/libasr/runtime/lfortran_intrinsics.h @@ -76,6 +76,8 @@ LFORTRAN_API float _lfortran_slog(float x); LFORTRAN_API double _lfortran_dlog(double x); LFORTRAN_API float_complex_t _lfortran_clog(float_complex_t x); LFORTRAN_API double_complex_t _lfortran_zlog(double_complex_t x); +LFORTRAN_API float _lfortran_slog1p(float x); +LFORTRAN_API double _lfortran_dlog1p(double x); LFORTRAN_API float _lfortran_serf(float x); LFORTRAN_API double _lfortran_derf(double x); LFORTRAN_API float _lfortran_serfc(float x); diff --git a/src/runtime/math.py b/src/runtime/math.py index 426bdc5990..2a5b861144 100644 --- a/src/runtime/math.py +++ b/src/runtime/math.py @@ -563,6 +563,14 @@ def _lfortran_dtan(x: f64) -> f64: def tan(x: f64) -> f64: return _lfortran_dtan(x) +@ccall +def _lfortran_slog(x: f32) -> f32: + pass + +@overload +def log(x: f32) -> f32: + return _lfortran_slog(x) + @ccall def _lfortran_dlog(x: f64) -> f64: pass @@ -683,10 +691,26 @@ def atanh(x: f64) -> f64: def expm1(x: f64) -> f64: return exp(x) - 1.0 +@ccall +def _lfortran_slog1p(x: f32) -> f32: + pass + +@overload +def log1p(x: f32) -> f32: + return _lfortran_slog1p(x) + +@ccall +def _lfortran_dlog1p(x: f64) -> f64: + pass +@overload def log1p(x: f64) -> f64: - return log(1.0 + x) + return _lfortran_dlog1p(x) + +@ccall +def _lfortran_dfmod(x: f64, y: f64) -> f64: + pass @overload def fmod(x: f64, y: f64) -> f64: @@ -694,11 +718,16 @@ def fmod(x: f64, y: f64) -> f64: raise ValueError('math domain error') return _lfortran_dfmod(x, y) - @ccall -def _lfortran_dfmod(x: f64, y: f64) -> f64: +def _lfortran_sfmod(x: f32, y: f32) -> f32: pass +@overload +def fmod(x: f32, y: f32) -> f32: + if y == f32(0.0): + raise ValueError('math domain error') + return _lfortran_sfmod(x, y) + def remainder(x: f64, y: f64) -> f64: q: i64