From f71b4a7b32c219ecabfc1f77598823d0a40bea4b Mon Sep 17 00:00:00 2001 From: Vipul Cariappa Date: Thu, 16 May 2024 09:59:50 +0530 Subject: [PATCH 01/12] skipping function verification of Interactive ABI --- src/libasr/asr_verify.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libasr/asr_verify.cpp b/src/libasr/asr_verify.cpp index 16b255f8cc..5ad9d27391 100644 --- a/src/libasr/asr_verify.cpp +++ b/src/libasr/asr_verify.cpp @@ -420,6 +420,11 @@ class VerifyVisitor : public BaseWalkVisitor } void visit_Function(const Function_t &x) { + ASR::FunctionType_t* v_func_type = ASR::down_cast(x.m_function_signature); + if (v_func_type->m_abi == abiType::Interactive) { + // This function would have been verified in the previous interactive pass + return; + } std::vector function_dependencies_copy = function_dependencies; function_dependencies.clear(); function_dependencies.reserve(x.n_dependencies); From 36930eb333061984033ad0234da585e88cabb37d Mon Sep 17 00:00:00 2001 From: Vipul Cariappa Date: Mon, 20 May 2024 20:08:36 +0530 Subject: [PATCH 02/12] function verify checks for empty body --- src/libasr/asr_verify.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libasr/asr_verify.cpp b/src/libasr/asr_verify.cpp index 5ad9d27391..62ab9180c6 100644 --- a/src/libasr/asr_verify.cpp +++ b/src/libasr/asr_verify.cpp @@ -422,7 +422,10 @@ class VerifyVisitor : public BaseWalkVisitor void visit_Function(const Function_t &x) { ASR::FunctionType_t* v_func_type = ASR::down_cast(x.m_function_signature); if (v_func_type->m_abi == abiType::Interactive) { - // This function would have been verified in the previous interactive pass + require(x.n_body == 0, + "The Function::n_body should be 0 if abi set to Interactive"); + require(x.m_body == nullptr, + "The Function::m_body should be null if abi set to Interactive"); return; } std::vector function_dependencies_copy = function_dependencies; From 25e047e674212c8d7ef7e5c23ba788e8c7416cc0 Mon Sep 17 00:00:00 2001 From: Vipul Cariappa Date: Wed, 22 May 2024 18:42:29 +0530 Subject: [PATCH 03/12] intrinsic function's body & dependency left unchanged --- src/libasr/asr_scopes.cpp | 9 +++++++-- src/libasr/asr_verify.cpp | 8 -------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/libasr/asr_scopes.cpp b/src/libasr/asr_scopes.cpp index 4fae6739e8..a50e471c60 100644 --- a/src/libasr/asr_scopes.cpp +++ b/src/libasr/asr_scopes.cpp @@ -39,9 +39,14 @@ void SymbolTable::mark_all_variables_external(Allocator &al) { case (ASR::symbolType::Function) : { ASR::Function_t *v = ASR::down_cast(a.second); ASR::FunctionType_t* v_func_type = ASR::down_cast(v->m_function_signature); + if ((v_func_type->m_abi != ASR::abiType::Intrinsic) && + (v_func_type->m_abi != ASR::abiType::Interactive)) { + v->m_dependencies = nullptr; + v->n_dependencies = 0; + v->m_body = nullptr; + v->n_body = 0; + } v_func_type->m_abi = ASR::abiType::Interactive; - v->m_body = nullptr; - v->n_body = 0; break; } case (ASR::symbolType::Module) : { diff --git a/src/libasr/asr_verify.cpp b/src/libasr/asr_verify.cpp index 62ab9180c6..16b255f8cc 100644 --- a/src/libasr/asr_verify.cpp +++ b/src/libasr/asr_verify.cpp @@ -420,14 +420,6 @@ class VerifyVisitor : public BaseWalkVisitor } void visit_Function(const Function_t &x) { - ASR::FunctionType_t* v_func_type = ASR::down_cast(x.m_function_signature); - if (v_func_type->m_abi == abiType::Interactive) { - require(x.n_body == 0, - "The Function::n_body should be 0 if abi set to Interactive"); - require(x.m_body == nullptr, - "The Function::m_body should be null if abi set to Interactive"); - return; - } std::vector function_dependencies_copy = function_dependencies; function_dependencies.clear(); function_dependencies.reserve(x.n_dependencies); From 7cda8e36944ccd748ffb328dcebc032bbf28f486 Mon Sep 17 00:00:00 2001 From: Vipul Cariappa Date: Thu, 23 May 2024 15:45:07 +0530 Subject: [PATCH 04/12] Fix ASR verify pass error while using Interactive --- src/libasr/asr_scopes.cpp | 10 +++++----- src/libasr/asr_verify.cpp | 5 +++++ src/lpython/tests/test_llvm.cpp | 18 ++++++++++++++++++ 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/libasr/asr_scopes.cpp b/src/libasr/asr_scopes.cpp index a50e471c60..c999eaec69 100644 --- a/src/libasr/asr_scopes.cpp +++ b/src/libasr/asr_scopes.cpp @@ -3,6 +3,7 @@ #include #include +#include std::string lcompilers_unique_ID; @@ -39,14 +40,13 @@ void SymbolTable::mark_all_variables_external(Allocator &al) { case (ASR::symbolType::Function) : { ASR::Function_t *v = ASR::down_cast(a.second); ASR::FunctionType_t* v_func_type = ASR::down_cast(v->m_function_signature); - if ((v_func_type->m_abi != ASR::abiType::Intrinsic) && - (v_func_type->m_abi != ASR::abiType::Interactive)) { - v->m_dependencies = nullptr; - v->n_dependencies = 0; + if (v_func_type->m_abi != ASR::abiType::Interactive) { + v_func_type->m_abi = ASR::abiType::Interactive; v->m_body = nullptr; v->n_body = 0; + PassUtils::UpdateDependenciesVisitor ud(al); + ud.visit_Function(*v); } - v_func_type->m_abi = ASR::abiType::Interactive; break; } case (ASR::symbolType::Module) : { diff --git a/src/libasr/asr_verify.cpp b/src/libasr/asr_verify.cpp index 16b255f8cc..19adc83ae8 100644 --- a/src/libasr/asr_verify.cpp +++ b/src/libasr/asr_verify.cpp @@ -420,6 +420,11 @@ class VerifyVisitor : public BaseWalkVisitor } void visit_Function(const Function_t &x) { + ASR::FunctionType_t* x_func_type = ASR::down_cast(x.m_function_signature); + if (x_func_type->m_abi == abiType::Interactive) { + require(x.n_body == 0, + "The Function::n_body should be 0 if abi set to Interactive"); + } std::vector function_dependencies_copy = function_dependencies; function_dependencies.clear(); function_dependencies.reserve(x.n_dependencies); diff --git a/src/lpython/tests/test_llvm.cpp b/src/lpython/tests/test_llvm.cpp index 29bb414772..4a625ef045 100644 --- a/src/lpython/tests/test_llvm.cpp +++ b/src/lpython/tests/test_llvm.cpp @@ -623,6 +623,24 @@ TEST_CASE("PythonCompiler 1") { CHECK(r.result.i32 == 1); } +TEST_CASE("PythonCompiler 2") { + CompilerOptions cu; + cu.po.disable_main = true; + cu.emit_debug_line_column = false; + cu.generate_object_code = false; + cu.interactive = true; + cu.po.runtime_library_dir = LCompilers::LPython::get_runtime_library_dir(); + PythonCompiler e(cu); + LCompilers::Result + + r = e.evaluate2("i: i32 = 3 % 1"); + CHECK(r.ok); + CHECK(r.result.type == PythonCompiler::EvalResult::none); + r = e.evaluate2("i"); + CHECK(r.ok); + CHECK(r.result.type == PythonCompiler::EvalResult::none); // TODO: change to integer4 and check the value once printing top level expressions is implemented +} + TEST_CASE("PythonCompiler i32 expressions") { CompilerOptions cu; cu.po.disable_main = true; From 4a476b6fa9138683e89a6760542cdc7f71f9b952 Mon Sep 17 00:00:00 2001 From: Vipul Cariappa Date: Tue, 28 May 2024 16:18:02 +0530 Subject: [PATCH 05/12] updated tests --- src/lpython/tests/test_llvm.cpp | 110 ++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) diff --git a/src/lpython/tests/test_llvm.cpp b/src/lpython/tests/test_llvm.cpp index 4a625ef045..0855fad02f 100644 --- a/src/lpython/tests/test_llvm.cpp +++ b/src/lpython/tests/test_llvm.cpp @@ -862,6 +862,7 @@ TEST_CASE("PythonCompiler u32 declaration") { r = e.evaluate2("i: u32"); CHECK(r.ok); CHECK(r.result.type == PythonCompiler::EvalResult::none); + r = e.evaluate2("i = u32(5)"); CHECK(r.ok); CHECK(r.result.type == PythonCompiler::EvalResult::statement); @@ -1288,3 +1289,112 @@ TEST_CASE("PythonCompiler u16 declaration") { CHECK(r.result.type == PythonCompiler::EvalResult::unsignedInteger2); CHECK(r.result.u32 == 45); } + +TEST_CASE("PythonCompiler asr verify 1") { + CompilerOptions cu; + cu.po.disable_main = true; + cu.emit_debug_line_column = false; + cu.generate_object_code = false; + cu.interactive = true; + cu.po.runtime_library_dir = LCompilers::LPython::get_runtime_library_dir(); + PythonCompiler e(cu); + LCompilers::Result + r = e.evaluate2("i: i32 = 3 % 2"); + CHECK(r.ok); + CHECK(r.result.type == PythonCompiler::EvalResult::none); + r = e.evaluate2("i"); + CHECK(r.ok); + CHECK(r.result.type == PythonCompiler::EvalResult::integer4); + CHECK(r.result.i32 == 1); +} + +TEST_CASE("PythonCompiler asr verify 2") { + CompilerOptions cu; + cu.po.disable_main = true; + cu.emit_debug_line_column = false; + cu.generate_object_code = false; + cu.interactive = true; + cu.po.runtime_library_dir = LCompilers::LPython::get_runtime_library_dir(); + PythonCompiler e(cu); + LCompilers::Result + r = e.evaluate2(R"( +def is_even(x: i32) -> i32: + if x % 2 == 0: + return 1 + return 0 +)"); + CHECK(r.ok); + CHECK(r.result.type == PythonCompiler::EvalResult::none); + r = e.evaluate2("is_even(4)"); + CHECK(r.ok); + CHECK(r.result.type == PythonCompiler::EvalResult::integer4); + CHECK(r.result.i32 == 1); + r = e.evaluate2("is_even(3)"); + CHECK(r.ok); + CHECK(r.result.type == PythonCompiler::EvalResult::integer4); + CHECK(r.result.i32 == 0); +} + +TEST_CASE("PythonCompiler asr verify 3") { + CompilerOptions cu; + cu.po.disable_main = true; + cu.emit_debug_line_column = false; + cu.generate_object_code = false; + cu.interactive = true; + cu.po.runtime_library_dir = LCompilers::LPython::get_runtime_library_dir(); + PythonCompiler e(cu); + LCompilers::Result + + r = e.evaluate2(R"( +def addi(x: i32, y: i32) -> i32: + return x + y +)"); + CHECK(r.ok); + CHECK(r.result.type == PythonCompiler::EvalResult::none); + r = e.evaluate2(R"( +def subi(x: i32, y: i32) -> i32: + return addi(x, -y) +)"); + CHECK(r.ok); + CHECK(r.result.type == PythonCompiler::EvalResult::none); + r = e.evaluate2("addi(2, 3)"); + CHECK(r.ok); + CHECK(r.result.type == PythonCompiler::EvalResult::integer4); + CHECK(r.result.i32 == 5); + r = e.evaluate2("subi(2, 3)"); + CHECK(r.ok); + CHECK(r.result.type == PythonCompiler::EvalResult::integer4); + CHECK(r.result.i32 == -1); +} + +TEST_CASE("PythonCompiler asr verify 4") { + CompilerOptions cu; + cu.po.disable_main = true; + cu.emit_debug_line_column = false; + cu.generate_object_code = false; + cu.interactive = true; + cu.po.runtime_library_dir = LCompilers::LPython::get_runtime_library_dir(); + PythonCompiler e(cu); + LCompilers::Result + +r = e.evaluate2(R"( +def addr(x: f64, y: f64) -> f64: + return x + y +)"); + CHECK(r.ok); + CHECK(r.result.type == PythonCompiler::EvalResult::none); + r = e.evaluate2(R"( +def subr(x: f64, y: f64) -> f64: + return addr(x, -y) +)"); + CHECK(r.ok); + CHECK(r.result.type == PythonCompiler::EvalResult::none); + r = e.evaluate2("addr(2.5, 3.5)"); + CHECK(r.ok); + CHECK(r.result.type == PythonCompiler::EvalResult::integer4); + CHECK(r.result.i32 == 5); + r = e.evaluate2("subr(2.5, 3.5)"); + CHECK(r.ok); + CHECK(r.result.type == PythonCompiler::EvalResult::integer4); + CHECK(r.result.i32 == -1); +} From 5d1fe44bf60d7a5f9744e7cf08d8fbe0ae1649ee Mon Sep 17 00:00:00 2001 From: Vipul Cariappa Date: Tue, 28 May 2024 16:20:01 +0530 Subject: [PATCH 06/12] fix typos --- src/lpython/tests/test_llvm.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lpython/tests/test_llvm.cpp b/src/lpython/tests/test_llvm.cpp index 0855fad02f..b232ca99a6 100644 --- a/src/lpython/tests/test_llvm.cpp +++ b/src/lpython/tests/test_llvm.cpp @@ -1391,10 +1391,10 @@ def subr(x: f64, y: f64) -> f64: CHECK(r.result.type == PythonCompiler::EvalResult::none); r = e.evaluate2("addr(2.5, 3.5)"); CHECK(r.ok); - CHECK(r.result.type == PythonCompiler::EvalResult::integer4); - CHECK(r.result.i32 == 5); + CHECK(r.result.type == PythonCompiler::EvalResult::real8); + CHECK(r.result.f64 == 6); r = e.evaluate2("subr(2.5, 3.5)"); CHECK(r.ok); - CHECK(r.result.type == PythonCompiler::EvalResult::integer4); - CHECK(r.result.i32 == -1); + CHECK(r.result.type == PythonCompiler::EvalResult::real8); + CHECK(r.result.f64 == -1); } From 5469ddf974e9fe9348aaab0babe8ac344587423d Mon Sep 17 00:00:00 2001 From: Vipul Cariappa Date: Wed, 5 Jun 2024 15:43:15 +0530 Subject: [PATCH 07/12] update cmake to copy runtime python files to build dir --- CMakeLists.txt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9545f67832..4e1e2ea0b9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -120,6 +120,20 @@ if (WITH_LCOMPILERS_FAST_ALLOC) add_definitions("-DLCOMPILERS_FAST_ALLOC=1") endif() +# copy runtime files +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/runtime/lpython/lpython.py" "${CMAKE_CURRENT_BINARY_DIR}/src/runtime/lpython/lpython.py") +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/runtime/cmath.py" "${CMAKE_CURRENT_BINARY_DIR}/src/runtime/cmath.py") +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/runtime/lpython_builtin.py" "${CMAKE_CURRENT_BINARY_DIR}/src/runtime/lpython_builtin.py") +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/runtime/lpython_intrinsic_numpy.py" "${CMAKE_CURRENT_BINARY_DIR}/src/runtime/lpython_intrinsic_numpy.py") +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/runtime/lpython_parser.py" "${CMAKE_CURRENT_BINARY_DIR}/src/runtime/lpython_parser.py") +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/runtime/math.py" "${CMAKE_CURRENT_BINARY_DIR}/src/runtime/math.py") +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/runtime/os.py" "${CMAKE_CURRENT_BINARY_DIR}/src/runtime/os.py") +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/runtime/platform.py" "${CMAKE_CURRENT_BINARY_DIR}/src/runtime/platform.py") +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/runtime/random.py" "${CMAKE_CURRENT_BINARY_DIR}/src/runtime/random.py") +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/runtime/statistics.py" "${CMAKE_CURRENT_BINARY_DIR}/src/runtime/statistics.py") +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/runtime/sys.py" "${CMAKE_CURRENT_BINARY_DIR}/src/runtime/sys.py") +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/runtime/time.py" "${CMAKE_CURRENT_BINARY_DIR}/src/runtime/time.py") + # LLVM set(WITH_LLVM no CACHE BOOL "Build with LLVM support") set(WITH_TARGET_AARCH64 no CACHE BOOL "Enable target AARCH64") From d899b15459f4d5db1b2d1e7449955adc583fc519 Mon Sep 17 00:00:00 2001 From: Vipul Cariappa Date: Wed, 5 Jun 2024 16:00:28 +0530 Subject: [PATCH 08/12] fix test for the changes in main --- src/lpython/tests/test_llvm.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/lpython/tests/test_llvm.cpp b/src/lpython/tests/test_llvm.cpp index b232ca99a6..2068a2103c 100644 --- a/src/lpython/tests/test_llvm.cpp +++ b/src/lpython/tests/test_llvm.cpp @@ -633,12 +633,13 @@ TEST_CASE("PythonCompiler 2") { PythonCompiler e(cu); LCompilers::Result - r = e.evaluate2("i: i32 = 3 % 1"); + r = e.evaluate2("i: i32 = 3 % 2"); CHECK(r.ok); CHECK(r.result.type == PythonCompiler::EvalResult::none); r = e.evaluate2("i"); CHECK(r.ok); - CHECK(r.result.type == PythonCompiler::EvalResult::none); // TODO: change to integer4 and check the value once printing top level expressions is implemented + CHECK(r.result.type == PythonCompiler::EvalResult::integer4); + CHECK(r.result.i32 == 1); } TEST_CASE("PythonCompiler i32 expressions") { From 2896a235da05a4e64a944b284560efca9b80cac7 Mon Sep 17 00:00:00 2001 From: Vipul Cariappa Date: Wed, 5 Jun 2024 16:41:40 +0530 Subject: [PATCH 09/12] fix indentation for windows --- src/runtime/lpython_builtin.py | 51 ++++++++++----------- src/runtime/math.py | 26 +++++------ src/runtime/platform.py | 2 +- src/runtime/statistics.py | 82 +++++++++++++++++----------------- src/runtime/sys.py | 1 - 5 files changed, 77 insertions(+), 85 deletions(-) diff --git a/src/runtime/lpython_builtin.py b/src/runtime/lpython_builtin.py index 7678cb0de2..493b95a084 100644 --- a/src/runtime/lpython_builtin.py +++ b/src/runtime/lpython_builtin.py @@ -129,7 +129,7 @@ def pow(x: f64, y: i32) -> f64: def pow(x: bool, y: bool) -> i32: if y and not x: return 0 - + return 1 @overload @@ -146,7 +146,7 @@ def sum(arr: list[i32]) -> i32: """ sum: i32 sum = 0 - + i: i32 for i in range(len(arr)): sum += arr[i] @@ -159,7 +159,7 @@ def sum(arr: list[i64]) -> i64: """ sum: i64 sum = i64(0) - + i: i32 for i in range(len(arr)): sum += arr[i] @@ -172,7 +172,7 @@ def sum(arr: list[f32]) -> f32: """ sum: f32 sum = f32(0.0) - + i: i32 for i in range(len(arr)): sum += arr[i] @@ -185,7 +185,7 @@ def sum(arr: list[f64]) -> f64: """ sum: f64 sum = 0.0 - + i: i32 for i in range(len(arr)): sum += arr[i] @@ -618,7 +618,7 @@ def _lpython_str_capitalize(x: str) -> str: res += chr(ord(i) + 32) # Convert to lowercase using ASCII values else: res += i - + val: i32 val = ord(res[0]) if val >= ord('a') and val <= ord('z'): @@ -634,15 +634,15 @@ def _lpython_str_count(s: str, sub: str) -> i32: lps: list[i32] = [] s_len = len(s) sub_len = len(sub) - + if sub_len == 0: return s_len + 1 - + count = 0 - + for i in range(sub_len): lps.append(0) - + i = 1 _len = 0 while i < sub_len: @@ -656,7 +656,7 @@ def _lpython_str_count(s: str, sub: str) -> i32: else: lps[i] = 0 i += 1 - + j: i32 j = 0 i = 0 @@ -672,7 +672,7 @@ def _lpython_str_count(s: str, sub: str) -> i32: j = lps[j - 1] else: i = i + 1 - + return count @@ -766,15 +766,15 @@ def _lpython_str_title(s: str) -> str: else: result += ch capitalize_next = True - + return result def _lpython_str_istitle(s: str) -> bool: length: i32 = len(s) - + if length == 0: return False # Empty string is not in title case - + word_start: bool = True # Flag to track the start of a word ch: str only_whitespace: bool = True @@ -785,7 +785,6 @@ def _lpython_str_istitle(s: str) -> bool: word_start = False else: return False # Found an uppercase character in the middle of a word - elif ch.isalpha() and (ord('a') <= ord(ch) and ord(ch) <= ord('z')): only_whitespace = False if word_start: @@ -793,7 +792,6 @@ def _lpython_str_istitle(s: str) -> bool: word_start = False else: word_start = True - return True if not only_whitespace else False @overload @@ -807,10 +805,10 @@ def _lpython_str_find(s: str, sub: str) -> i32: res = -1 if s_len == 0 or sub_len == 0: return 0 if sub_len == 0 or (sub_len == s_len) else -1 - + for i in range(sub_len): lps.append(0) - + i = 1 _len = 0 while i < sub_len: @@ -824,7 +822,7 @@ def _lpython_str_find(s: str, sub: str) -> i32: else: lps[i] = 0 i += 1 - + j: i32 j = 0 i = 0 @@ -841,7 +839,6 @@ def _lpython_str_find(s: str, sub: str) -> i32: j = lps[j - 1] else: i = i + 1 - return res def _lpython_str_rstrip(x: str) -> str: @@ -886,7 +883,7 @@ def _lpython_str_split(x: str) -> list[str]: res.append(x_strip[start:start + ind]) start += ind + len(sep) return res - + @overload def _lpython_str_split(x: str, sep:str) -> list[str]: if len(sep) == 0: @@ -907,7 +904,7 @@ def _lpython_str_split(x: str, sep:str) -> list[str]: @overload def _lpython_str_replace(x: str, old:str, new:str) -> str: return _lpython_str_replace(x, old, new, len(x)) - + @overload def _lpython_str_replace(x: str, old:str, new:str, count: i32) -> str: @@ -925,7 +922,7 @@ def _lpython_str_replace(x: str, old:str, new:str, count: i32) -> str: lx: i32 = len(x) c: i32 = 0 t: i32 = -1 - + while(c bool: @overload def _lpython_str_endswith(s: str, suffix: str) -> bool: - if(len(suffix) > len(s)): return False - + i : i32 i = 0 while(i < len(suffix)): if(suffix[len(suffix) - i - 1] != s[len(s) - i - 1]): return False i += 1 - + return True @overload @@ -1143,4 +1139,3 @@ def list(s: str) -> list[str]: for i in range(len(s)): l.append(s[i]) return l - diff --git a/src/runtime/math.py b/src/runtime/math.py index 0a4f4a5c91..40e9c3fd86 100644 --- a/src/runtime/math.py +++ b/src/runtime/math.py @@ -10,7 +10,7 @@ def modf(x: f64) -> tuple[f64, f64]: """ Return fractional and integral parts of `x` as a pair. - + Both results carry the sign of x and are floats. """ return (x - f64(int(x)), float(int(x))) @@ -20,7 +20,7 @@ def factorial(x: i32) -> i32: """ Computes the factorial of `x`. """ - + result: i32 result = 0 if x < 0: @@ -104,7 +104,7 @@ def fsum(arr: list[i32]) -> f64: """ sum: f64 sum = 0.0 - + i: i32 for i in range(len(arr)): sum += float(arr[i]) @@ -117,7 +117,7 @@ def fsum(arr: list[i64]) -> f64: """ sum: f64 sum = 0.0 - + i: i32 for i in range(len(arr)): sum += float(arr[i]) @@ -130,7 +130,7 @@ def fsum(arr: list[f32]) -> f64: """ sum: f64 sum = 0.0 - + i: i32 for i in range(len(arr)): sum += float(arr[i]) @@ -143,7 +143,7 @@ def fsum(arr: list[f64]) -> f64: """ sum: f64 sum = 0.0 - + i: i32 for i in range(len(arr)): sum += arr[i] @@ -157,7 +157,7 @@ def prod(arr: list[i32]) -> f64: """ Return the product of the elements of `arr`. """ - + result: f64 result = 1.0 i: i32 @@ -170,7 +170,7 @@ def prod(arr: list[i64]) -> f64: """ Return the product of the elements of `arr`. """ - + result: f64 result = 1.0 i: i32 @@ -183,7 +183,7 @@ def prod(arr: list[f32]) -> f64: """ Return the product of the elements of `arr`. """ - + result: f64 result = 1.0 i: i32 @@ -196,7 +196,7 @@ def prod(arr: list[f64]) -> f64: """ Return the product of the elements of `arr`. """ - + result: f64 result = 1.0 i: i32 @@ -213,7 +213,7 @@ def dist(x: list[f64], y: list[f64]) -> f64: raise ValueError("Length of lists should be same") res: f64 res = 0.0 - + i: i32 for i in range(len(x)): res += (x[i] - y[i]) * (x[i] - y[i]) @@ -225,7 +225,7 @@ def comb(n: i32, k: i32) -> i32: Computes the result of `nCk`, i.e, the number of ways to choose `k` items from `n` items without repetition and without order. """ - + if n < k or n < 0: return 0 return i32(factorial(n)//(factorial(k)*factorial(n-k))) @@ -236,7 +236,7 @@ def perm(n: i32, k: i32) -> i32: Computes the result of `nPk`, i.e, the number of ways to choose `k` items from `n` items without repetition and with order. """ - + if n < k or n < 0: return 0 return i32(factorial(n)//factorial(n-k)) diff --git a/src/runtime/platform.py b/src/runtime/platform.py index 4c11b4977a..f408c53219 100644 --- a/src/runtime/platform.py +++ b/src/runtime/platform.py @@ -2,4 +2,4 @@ def python_implementation() -> str: return "LPython" def python_version() -> str: - return __LPYTHON_VERSION__ \ No newline at end of file + return __LPYTHON_VERSION__ diff --git a/src/runtime/statistics.py b/src/runtime/statistics.py index 61e1b9a9b5..66aadffd9e 100644 --- a/src/runtime/statistics.py +++ b/src/runtime/statistics.py @@ -12,7 +12,7 @@ def mean(x: list[i32]) -> f64: sum: f64 sum = 0.0 i: i32 - + for i in range(k): sum += float(x[i]) return sum/f64(k) @@ -29,10 +29,10 @@ def mean(x: list[i64]) -> f64: sum: f64 sum = 0.0 i: i32 - + for i in range(k): sum += float(x[i]) - + return sum/f64(k) @@ -47,7 +47,7 @@ def mean(x: list[f32]) -> f64: sum: f64 sum = 0.0 i: i32 - + for i in range(k): sum += float(x[i]) return sum/f64(k) @@ -64,7 +64,7 @@ def mean(x: list[f64]) -> f64: sum: f64 sum = 0.0 i: i32 - + for i in range(k): sum += x[i] return sum/f64(k) @@ -112,12 +112,12 @@ def geometric_mean(x: list[i32]) -> f64: product: f64 product = 1.0 i: i32 - + for i in range(k): if x[i] <= 0: raise Exception("geometric mean requires a non-empty dataset containing positive numbers") product *= float(x[i]) - + return product**(1/k) @overload @@ -131,7 +131,7 @@ def geometric_mean(x: list[i64]) -> f64: product: f64 product = 1.0 i: i32 - + for i in range(k): if x[i] <= i64(0): raise Exception("geometric mean requires a non-empty dataset containing positive numbers") @@ -150,7 +150,7 @@ def geometric_mean(x: list[f64]) -> f64: product: f64 product = 1.0 i: i32 - + for i in range(k): if x[i] <= 0.0: raise Exception("geometric mean requires a non-empty dataset containing positive numbers") @@ -169,14 +169,14 @@ def harmonic_mean(x: list[i32]) -> f64: sum: f64 sum = 0.0 i: i32 - + for i in range(k): if x[i] == 0: return 0.0 if x[i] < 0: raise Exception("Harmonic mean does not support negative values") sum += 1 / x[i] - + return f64(k)/sum @overload @@ -190,7 +190,7 @@ def harmonic_mean(x: list[i64]) -> f64: sum: f64 sum = 0.0 i: i32 - + for i in range(k): if x[i] == i64(0): return 0.0 @@ -210,14 +210,14 @@ def harmonic_mean(x: list[f64]) -> f64: sum: f64 sum = 0.0 i: i32 - + for i in range(k): if x[i] == 0.0: return 0.0 if x[i] < 0.0: raise Exception("Harmonic mean does not support negative values") sum += 1.0 / x[i] - + return f64(k) / sum @@ -227,15 +227,15 @@ def mode(x: list[i32]) -> i32: k: i32 = len(x) c: i32 count: dict[i32, i32] = {0: 0} - + # insert keys in the dictionary for c in range(k): count[x[c]] = 0 - + # update the frequencies for c in range(k): count[x[c]] = count[x[c]] + 1 - + max_count: i32 = 0 ans: i32 for c in range(k): @@ -249,15 +249,15 @@ def mode(x: list[i64]) -> i64: k: i32 = len(x) c: i32 count: dict[i64, i32] = {i64(0): 0} - + # insert keys in the dictionary for c in range(k): count[x[c]] = 0 - + # update the frequencies for c in range(k): count[x[c]] = count[x[c]] + 1 - + max_count: i32 = 0 ans: i64 for c in range(k): @@ -383,17 +383,17 @@ def correlation(x: list[i32], y: list[i32]) -> f64: raise Exception("correlation requires at least two data points") xmean: f64 = mean(x) ymean: f64 = mean(y) - + sxy: f64 = 0.0 i: i32 for i in range(n): sxy += (f64(x[i]) - xmean) * (f64(y[i]) - ymean) - + sxx: f64 = 0.0 j: i32 for j in range(n): sxx += (f64(x[j]) - xmean) ** 2.0 - + syy: f64 = 0.0 k: i32 for k in range(n): @@ -415,17 +415,17 @@ def correlation(x: list[f64], y: list[f64]) -> f64: raise Exception("correlation requires at least two data points") xmean: f64 = mean(x) ymean: f64 = mean(y) - + sxy: f64 = 0.0 i: i32 for i in range(n): sxy += (x[i] - xmean) * (y[i] - ymean) - + sxx: f64 = 0.0 j: i32 for j in range(n): sxx += (f64(x[j]) - xmean) ** 2.0 - + syy: f64 = 0.0 k: i32 for k in range(n): @@ -472,7 +472,6 @@ def covariance(x: list[f64], y: list[f64]) -> f64: @overload def linear_regression(x: list[i32], y: list[i32]) -> tuple[f64, f64]: - """ Returns the slope and intercept of simple linear regression parameters estimated using ordinary least squares. @@ -484,33 +483,32 @@ def linear_regression(x: list[i32], y: list[i32]) -> tuple[f64, f64]: raise Exception('linear regression requires at least two data points') xmean: f64 = mean(x) ymean: f64 = mean(y) - + sxy: f64 = 0.0 i: i32 for i in range(n): sxy += (f64(x[i]) - xmean) * (f64(y[i]) - ymean) - + sxx: f64 = 0.0 j: i32 for j in range(n): sxx += (f64(x[j]) - xmean) ** 2.0 - + slope: f64 - + if sxx == 0.0: raise Exception('x is constant') else: slope = sxy / sxx - + intercept: f64 = ymean - slope * xmean - + LinReg: tuple[f64, f64] = (slope, intercept) - + return LinReg @overload def linear_regression(x: list[f64], y: list[f64]) -> tuple[f64, f64]: - """ Returns the slope and intercept of simple linear regression parameters estimated using ordinary least squares. @@ -522,26 +520,26 @@ def linear_regression(x: list[f64], y: list[f64]) -> tuple[f64, f64]: raise Exception('linear regression requires at least two data points') xmean: f64 = mean(x) ymean: f64 = mean(y) - + sxy: f64 = 0.0 i: i32 for i in range(n): sxy += (x[i] - xmean) * (y[i] - ymean) - + sxx: f64 = 0.0 j: i32 for j in range(n): sxx += (f64(x[j]) - xmean) ** 2.0 - + slope: f64 - + if sxx == 0.0: raise Exception('x is constant') else: slope = sxy / sxx - + intercept: f64 = ymean - slope * xmean - + LinReg: tuple[f64, f64] = (slope, intercept) - + return LinReg diff --git a/src/runtime/sys.py b/src/runtime/sys.py index 505926bb2a..3dd57bc0c8 100644 --- a/src/runtime/sys.py +++ b/src/runtime/sys.py @@ -4,7 +4,6 @@ def exit(error_code: i32): """ Exits the program with an error code `error_code`. """ - quit(error_code) # >----------------------------------- argv -----------------------------------> From ef4cf7ca58a71b9f2cce7e3dd1b40a5eb7b3820d Mon Sep 17 00:00:00 2001 From: Vipul Cariappa Date: Thu, 6 Jun 2024 11:15:03 +0530 Subject: [PATCH 10/12] fix for windows --- src/libasr/codegen/KaleidoscopeJIT.h | 77 +++++++++++++++------------- src/libasr/codegen/evaluator.cpp | 6 +-- 2 files changed, 43 insertions(+), 40 deletions(-) diff --git a/src/libasr/codegen/KaleidoscopeJIT.h b/src/libasr/codegen/KaleidoscopeJIT.h index 28829bcad6..df83c850d2 100644 --- a/src/libasr/codegen/KaleidoscopeJIT.h +++ b/src/libasr/codegen/KaleidoscopeJIT.h @@ -26,6 +26,10 @@ #include "llvm/IR/LLVMContext.h" #include +#if LLVM_VERSION_MAJOR >= 13 +#include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h" +#endif + #if LLVM_VERSION_MAJOR >= 16 # define RM_OPTIONAL_TYPE std::optional #else @@ -37,77 +41,76 @@ namespace orc { class KaleidoscopeJIT { private: - ExecutionSession ES; + std::unique_ptr ES; RTDyldObjectLinkingLayer ObjectLayer; IRCompileLayer CompileLayer; DataLayout DL; MangleAndInterner Mangle; - ThreadSafeContext Ctx; JITDylib &JITDL; - TargetMachine *TM; - public: - KaleidoscopeJIT(JITTargetMachineBuilder JTMB, DataLayout DL) + KaleidoscopeJIT(std::unique_ptr ES, JITTargetMachineBuilder JTMB, DataLayout DL) : -#if LLVM_VERSION_MAJOR >= 13 - ES(cantFail(SelfExecutorProcessControl::Create())), -#endif - ObjectLayer(ES, + ES(std::move(ES)), + ObjectLayer(*this->ES, []() { return std::make_unique(); }), - CompileLayer(ES, ObjectLayer, std::make_unique(ConcurrentIRCompiler(std::move(JTMB)))), - DL(std::move(DL)), Mangle(ES, this->DL), - Ctx(std::make_unique()), + CompileLayer(*this->ES, ObjectLayer, std::make_unique(std::move(JTMB))), + DL(std::move(DL)), Mangle(*this->ES, this->DL), JITDL( #if LLVM_VERSION_MAJOR >= 11 cantFail #endif - (ES.createJITDylib("Main"))) { + (this->ES->createJITDylib("Main"))) { JITDL.addGenerator( cantFail(DynamicLibrarySearchGenerator::GetForCurrentProcess( DL.getGlobalPrefix()))); - - std::string Error; - auto TargetTriple = sys::getDefaultTargetTriple(); - auto Target = TargetRegistry::lookupTarget(TargetTriple, Error); - if (!Target) { - throw std::runtime_error("Failed to lookup the target"); + if (JTMB.getTargetTriple().isOSBinFormatCOFF()) { + ObjectLayer.setOverrideObjectFlagsWithResponsibilityFlags(true); + ObjectLayer.setAutoClaimResponsibilityForObjectSymbols(true); } - auto CPU = "generic"; - auto Features = ""; - TargetOptions opt; - auto RM = RM_OPTIONAL_TYPE(); - TM = Target->createTargetMachine(TargetTriple, CPU, Features, opt, RM); } static Expected> Create() { - auto JTMB = JITTargetMachineBuilder::detectHost(); +#if LLVM_VERSION_MAJOR >= 13 + auto EPC = SelfExecutorProcessControl::Create(); + if (!EPC) + return EPC.takeError(); - if (!JTMB) - return JTMB.takeError(); + auto ES = std::make_unique(std::move(*EPC)); - auto DL = JTMB->getDefaultDataLayoutForTarget(); + JITTargetMachineBuilder JTMB( + ES->getExecutorProcessControl().getTargetTriple()); +#else + auto ES = std::make_unique(); + + auto JTMB_P = JITTargetMachineBuilder::detectHost(); + if (!JTMB_P) + return JTMB_P.takeError(); + + auto JTMB = *JTMB_P; +#endif + + auto DL = JTMB.getDefaultDataLayoutForTarget(); if (!DL) return DL.takeError(); - return std::make_unique(std::move(*JTMB), std::move(*DL)); + return std::make_unique(std::move(ES), std::move(JTMB), + std::move(*DL)); } const DataLayout &getDataLayout() const { return DL; } - LLVMContext &getContext() { return *Ctx.getContext(); } - - Error addModule(std::unique_ptr M) { - return CompileLayer.add(JITDL, - ThreadSafeModule(std::move(M), Ctx)); + Error addModule(std::unique_ptr M, std::unique_ptr &Ctx) { + auto res = CompileLayer.add(JITDL, + ThreadSafeModule(std::move(M), std::move(Ctx))); + Ctx = std::make_unique(); + return res; } Expected lookup(StringRef Name) { - return ES.lookup({&JITDL}, Mangle(Name.str())); + return ES->lookup({&JITDL}, Mangle(Name.str())); } - - TargetMachine &getTargetMachine() { return *TM; } }; } // end namespace orc diff --git a/src/libasr/codegen/evaluator.cpp b/src/libasr/codegen/evaluator.cpp index 2e00aec308..b5cbf35285 100644 --- a/src/libasr/codegen/evaluator.cpp +++ b/src/libasr/codegen/evaluator.cpp @@ -210,7 +210,7 @@ std::unique_ptr LLVMEvaluator::parse_module(const std::string &sou throw LCompilersException("parse_module(): module failed verification."); }; module->setTargetTriple(target_triple); - module->setDataLayout(jit->getTargetMachine().createDataLayout()); + module->setDataLayout(jit->getDataLayout()); return module; } @@ -232,7 +232,7 @@ void LLVMEvaluator::add_module(std::unique_ptr mod) { // cases when the Module was constructed directly, not via parse_module(). mod->setTargetTriple(target_triple); mod->setDataLayout(jit->getDataLayout()); - llvm::Error err = jit->addModule(std::move(mod)); + llvm::Error err = jit->addModule(std::move(mod), context); if (err) { llvm::SmallVector buf; llvm::raw_svector_ostream dest(buf); @@ -346,7 +346,7 @@ std::string LLVMEvaluator::get_asm(llvm::Module &m) llvm::CodeGenFileType ft = llvm::CGFT_AssemblyFile; llvm::SmallVector buf; llvm::raw_svector_ostream dest(buf); - if (jit->getTargetMachine().addPassesToEmitFile(pass, dest, nullptr, ft)) { + if (TM->addPassesToEmitFile(pass, dest, nullptr, ft)) { throw std::runtime_error("TargetMachine can't emit a file of this type"); } pass.run(m); From 06c7dd137dc14b2af7b45122c384fe411e65f451 Mon Sep 17 00:00:00 2001 From: Vipul Cariappa Date: Fri, 7 Jun 2024 15:39:55 +0530 Subject: [PATCH 11/12] undo indentations --- src/runtime/lpython_builtin.py | 50 +++++++++++---------- src/runtime/math.py | 26 +++++------ src/runtime/statistics.py | 82 +++++++++++++++++----------------- src/runtime/sys.py | 1 + 4 files changed, 83 insertions(+), 76 deletions(-) diff --git a/src/runtime/lpython_builtin.py b/src/runtime/lpython_builtin.py index 493b95a084..6bb7920d5f 100644 --- a/src/runtime/lpython_builtin.py +++ b/src/runtime/lpython_builtin.py @@ -129,7 +129,7 @@ def pow(x: f64, y: i32) -> f64: def pow(x: bool, y: bool) -> i32: if y and not x: return 0 - + return 1 @overload @@ -146,7 +146,7 @@ def sum(arr: list[i32]) -> i32: """ sum: i32 sum = 0 - + i: i32 for i in range(len(arr)): sum += arr[i] @@ -159,7 +159,7 @@ def sum(arr: list[i64]) -> i64: """ sum: i64 sum = i64(0) - + i: i32 for i in range(len(arr)): sum += arr[i] @@ -172,7 +172,7 @@ def sum(arr: list[f32]) -> f32: """ sum: f32 sum = f32(0.0) - + i: i32 for i in range(len(arr)): sum += arr[i] @@ -185,7 +185,7 @@ def sum(arr: list[f64]) -> f64: """ sum: f64 sum = 0.0 - + i: i32 for i in range(len(arr)): sum += arr[i] @@ -618,7 +618,7 @@ def _lpython_str_capitalize(x: str) -> str: res += chr(ord(i) + 32) # Convert to lowercase using ASCII values else: res += i - + val: i32 val = ord(res[0]) if val >= ord('a') and val <= ord('z'): @@ -634,15 +634,15 @@ def _lpython_str_count(s: str, sub: str) -> i32: lps: list[i32] = [] s_len = len(s) sub_len = len(sub) - + if sub_len == 0: return s_len + 1 - + count = 0 - + for i in range(sub_len): lps.append(0) - + i = 1 _len = 0 while i < sub_len: @@ -656,7 +656,7 @@ def _lpython_str_count(s: str, sub: str) -> i32: else: lps[i] = 0 i += 1 - + j: i32 j = 0 i = 0 @@ -672,7 +672,7 @@ def _lpython_str_count(s: str, sub: str) -> i32: j = lps[j - 1] else: i = i + 1 - + return count @@ -766,15 +766,15 @@ def _lpython_str_title(s: str) -> str: else: result += ch capitalize_next = True - + return result def _lpython_str_istitle(s: str) -> bool: length: i32 = len(s) - + if length == 0: return False # Empty string is not in title case - + word_start: bool = True # Flag to track the start of a word ch: str only_whitespace: bool = True @@ -785,6 +785,7 @@ def _lpython_str_istitle(s: str) -> bool: word_start = False else: return False # Found an uppercase character in the middle of a word + elif ch.isalpha() and (ord('a') <= ord(ch) and ord(ch) <= ord('z')): only_whitespace = False if word_start: @@ -792,6 +793,7 @@ def _lpython_str_istitle(s: str) -> bool: word_start = False else: word_start = True + return True if not only_whitespace else False @overload @@ -805,10 +807,10 @@ def _lpython_str_find(s: str, sub: str) -> i32: res = -1 if s_len == 0 or sub_len == 0: return 0 if sub_len == 0 or (sub_len == s_len) else -1 - + for i in range(sub_len): lps.append(0) - + i = 1 _len = 0 while i < sub_len: @@ -822,7 +824,7 @@ def _lpython_str_find(s: str, sub: str) -> i32: else: lps[i] = 0 i += 1 - + j: i32 j = 0 i = 0 @@ -839,6 +841,7 @@ def _lpython_str_find(s: str, sub: str) -> i32: j = lps[j - 1] else: i = i + 1 + return res def _lpython_str_rstrip(x: str) -> str: @@ -883,7 +886,7 @@ def _lpython_str_split(x: str) -> list[str]: res.append(x_strip[start:start + ind]) start += ind + len(sep) return res - + @overload def _lpython_str_split(x: str, sep:str) -> list[str]: if len(sep) == 0: @@ -904,7 +907,7 @@ def _lpython_str_split(x: str, sep:str) -> list[str]: @overload def _lpython_str_replace(x: str, old:str, new:str) -> str: return _lpython_str_replace(x, old, new, len(x)) - + @overload def _lpython_str_replace(x: str, old:str, new:str, count: i32) -> str: @@ -922,7 +925,7 @@ def _lpython_str_replace(x: str, old:str, new:str, count: i32) -> str: lx: i32 = len(x) c: i32 = 0 t: i32 = -1 - + while(c bool: @overload def _lpython_str_endswith(s: str, suffix: str) -> bool: + if(len(suffix) > len(s)): return False - + i : i32 i = 0 while(i < len(suffix)): if(suffix[len(suffix) - i - 1] != s[len(s) - i - 1]): return False i += 1 - + return True @overload diff --git a/src/runtime/math.py b/src/runtime/math.py index 40e9c3fd86..0a4f4a5c91 100644 --- a/src/runtime/math.py +++ b/src/runtime/math.py @@ -10,7 +10,7 @@ def modf(x: f64) -> tuple[f64, f64]: """ Return fractional and integral parts of `x` as a pair. - + Both results carry the sign of x and are floats. """ return (x - f64(int(x)), float(int(x))) @@ -20,7 +20,7 @@ def factorial(x: i32) -> i32: """ Computes the factorial of `x`. """ - + result: i32 result = 0 if x < 0: @@ -104,7 +104,7 @@ def fsum(arr: list[i32]) -> f64: """ sum: f64 sum = 0.0 - + i: i32 for i in range(len(arr)): sum += float(arr[i]) @@ -117,7 +117,7 @@ def fsum(arr: list[i64]) -> f64: """ sum: f64 sum = 0.0 - + i: i32 for i in range(len(arr)): sum += float(arr[i]) @@ -130,7 +130,7 @@ def fsum(arr: list[f32]) -> f64: """ sum: f64 sum = 0.0 - + i: i32 for i in range(len(arr)): sum += float(arr[i]) @@ -143,7 +143,7 @@ def fsum(arr: list[f64]) -> f64: """ sum: f64 sum = 0.0 - + i: i32 for i in range(len(arr)): sum += arr[i] @@ -157,7 +157,7 @@ def prod(arr: list[i32]) -> f64: """ Return the product of the elements of `arr`. """ - + result: f64 result = 1.0 i: i32 @@ -170,7 +170,7 @@ def prod(arr: list[i64]) -> f64: """ Return the product of the elements of `arr`. """ - + result: f64 result = 1.0 i: i32 @@ -183,7 +183,7 @@ def prod(arr: list[f32]) -> f64: """ Return the product of the elements of `arr`. """ - + result: f64 result = 1.0 i: i32 @@ -196,7 +196,7 @@ def prod(arr: list[f64]) -> f64: """ Return the product of the elements of `arr`. """ - + result: f64 result = 1.0 i: i32 @@ -213,7 +213,7 @@ def dist(x: list[f64], y: list[f64]) -> f64: raise ValueError("Length of lists should be same") res: f64 res = 0.0 - + i: i32 for i in range(len(x)): res += (x[i] - y[i]) * (x[i] - y[i]) @@ -225,7 +225,7 @@ def comb(n: i32, k: i32) -> i32: Computes the result of `nCk`, i.e, the number of ways to choose `k` items from `n` items without repetition and without order. """ - + if n < k or n < 0: return 0 return i32(factorial(n)//(factorial(k)*factorial(n-k))) @@ -236,7 +236,7 @@ def perm(n: i32, k: i32) -> i32: Computes the result of `nPk`, i.e, the number of ways to choose `k` items from `n` items without repetition and with order. """ - + if n < k or n < 0: return 0 return i32(factorial(n)//factorial(n-k)) diff --git a/src/runtime/statistics.py b/src/runtime/statistics.py index 66aadffd9e..61e1b9a9b5 100644 --- a/src/runtime/statistics.py +++ b/src/runtime/statistics.py @@ -12,7 +12,7 @@ def mean(x: list[i32]) -> f64: sum: f64 sum = 0.0 i: i32 - + for i in range(k): sum += float(x[i]) return sum/f64(k) @@ -29,10 +29,10 @@ def mean(x: list[i64]) -> f64: sum: f64 sum = 0.0 i: i32 - + for i in range(k): sum += float(x[i]) - + return sum/f64(k) @@ -47,7 +47,7 @@ def mean(x: list[f32]) -> f64: sum: f64 sum = 0.0 i: i32 - + for i in range(k): sum += float(x[i]) return sum/f64(k) @@ -64,7 +64,7 @@ def mean(x: list[f64]) -> f64: sum: f64 sum = 0.0 i: i32 - + for i in range(k): sum += x[i] return sum/f64(k) @@ -112,12 +112,12 @@ def geometric_mean(x: list[i32]) -> f64: product: f64 product = 1.0 i: i32 - + for i in range(k): if x[i] <= 0: raise Exception("geometric mean requires a non-empty dataset containing positive numbers") product *= float(x[i]) - + return product**(1/k) @overload @@ -131,7 +131,7 @@ def geometric_mean(x: list[i64]) -> f64: product: f64 product = 1.0 i: i32 - + for i in range(k): if x[i] <= i64(0): raise Exception("geometric mean requires a non-empty dataset containing positive numbers") @@ -150,7 +150,7 @@ def geometric_mean(x: list[f64]) -> f64: product: f64 product = 1.0 i: i32 - + for i in range(k): if x[i] <= 0.0: raise Exception("geometric mean requires a non-empty dataset containing positive numbers") @@ -169,14 +169,14 @@ def harmonic_mean(x: list[i32]) -> f64: sum: f64 sum = 0.0 i: i32 - + for i in range(k): if x[i] == 0: return 0.0 if x[i] < 0: raise Exception("Harmonic mean does not support negative values") sum += 1 / x[i] - + return f64(k)/sum @overload @@ -190,7 +190,7 @@ def harmonic_mean(x: list[i64]) -> f64: sum: f64 sum = 0.0 i: i32 - + for i in range(k): if x[i] == i64(0): return 0.0 @@ -210,14 +210,14 @@ def harmonic_mean(x: list[f64]) -> f64: sum: f64 sum = 0.0 i: i32 - + for i in range(k): if x[i] == 0.0: return 0.0 if x[i] < 0.0: raise Exception("Harmonic mean does not support negative values") sum += 1.0 / x[i] - + return f64(k) / sum @@ -227,15 +227,15 @@ def mode(x: list[i32]) -> i32: k: i32 = len(x) c: i32 count: dict[i32, i32] = {0: 0} - + # insert keys in the dictionary for c in range(k): count[x[c]] = 0 - + # update the frequencies for c in range(k): count[x[c]] = count[x[c]] + 1 - + max_count: i32 = 0 ans: i32 for c in range(k): @@ -249,15 +249,15 @@ def mode(x: list[i64]) -> i64: k: i32 = len(x) c: i32 count: dict[i64, i32] = {i64(0): 0} - + # insert keys in the dictionary for c in range(k): count[x[c]] = 0 - + # update the frequencies for c in range(k): count[x[c]] = count[x[c]] + 1 - + max_count: i32 = 0 ans: i64 for c in range(k): @@ -383,17 +383,17 @@ def correlation(x: list[i32], y: list[i32]) -> f64: raise Exception("correlation requires at least two data points") xmean: f64 = mean(x) ymean: f64 = mean(y) - + sxy: f64 = 0.0 i: i32 for i in range(n): sxy += (f64(x[i]) - xmean) * (f64(y[i]) - ymean) - + sxx: f64 = 0.0 j: i32 for j in range(n): sxx += (f64(x[j]) - xmean) ** 2.0 - + syy: f64 = 0.0 k: i32 for k in range(n): @@ -415,17 +415,17 @@ def correlation(x: list[f64], y: list[f64]) -> f64: raise Exception("correlation requires at least two data points") xmean: f64 = mean(x) ymean: f64 = mean(y) - + sxy: f64 = 0.0 i: i32 for i in range(n): sxy += (x[i] - xmean) * (y[i] - ymean) - + sxx: f64 = 0.0 j: i32 for j in range(n): sxx += (f64(x[j]) - xmean) ** 2.0 - + syy: f64 = 0.0 k: i32 for k in range(n): @@ -472,6 +472,7 @@ def covariance(x: list[f64], y: list[f64]) -> f64: @overload def linear_regression(x: list[i32], y: list[i32]) -> tuple[f64, f64]: + """ Returns the slope and intercept of simple linear regression parameters estimated using ordinary least squares. @@ -483,32 +484,33 @@ def linear_regression(x: list[i32], y: list[i32]) -> tuple[f64, f64]: raise Exception('linear regression requires at least two data points') xmean: f64 = mean(x) ymean: f64 = mean(y) - + sxy: f64 = 0.0 i: i32 for i in range(n): sxy += (f64(x[i]) - xmean) * (f64(y[i]) - ymean) - + sxx: f64 = 0.0 j: i32 for j in range(n): sxx += (f64(x[j]) - xmean) ** 2.0 - + slope: f64 - + if sxx == 0.0: raise Exception('x is constant') else: slope = sxy / sxx - + intercept: f64 = ymean - slope * xmean - + LinReg: tuple[f64, f64] = (slope, intercept) - + return LinReg @overload def linear_regression(x: list[f64], y: list[f64]) -> tuple[f64, f64]: + """ Returns the slope and intercept of simple linear regression parameters estimated using ordinary least squares. @@ -520,26 +522,26 @@ def linear_regression(x: list[f64], y: list[f64]) -> tuple[f64, f64]: raise Exception('linear regression requires at least two data points') xmean: f64 = mean(x) ymean: f64 = mean(y) - + sxy: f64 = 0.0 i: i32 for i in range(n): sxy += (x[i] - xmean) * (y[i] - ymean) - + sxx: f64 = 0.0 j: i32 for j in range(n): sxx += (f64(x[j]) - xmean) ** 2.0 - + slope: f64 - + if sxx == 0.0: raise Exception('x is constant') else: slope = sxy / sxx - + intercept: f64 = ymean - slope * xmean - + LinReg: tuple[f64, f64] = (slope, intercept) - + return LinReg diff --git a/src/runtime/sys.py b/src/runtime/sys.py index 3dd57bc0c8..505926bb2a 100644 --- a/src/runtime/sys.py +++ b/src/runtime/sys.py @@ -4,6 +4,7 @@ def exit(error_code: i32): """ Exits the program with an error code `error_code`. """ + quit(error_code) # >----------------------------------- argv -----------------------------------> From e65cfe1206d640821bc6f2d492d2f03b416d865e Mon Sep 17 00:00:00 2001 From: Vipul Cariappa Date: Fri, 7 Jun 2024 15:48:05 +0530 Subject: [PATCH 12/12] indentation fix --- src/libasr/string_utils.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libasr/string_utils.cpp b/src/libasr/string_utils.cpp index bd496d0899..04d68033a8 100644 --- a/src/libasr/string_utils.cpp +++ b/src/libasr/string_utils.cpp @@ -116,7 +116,7 @@ std::string read_file(const std::string &filename) std::vector bytes(filesize); ifs.read(&bytes[0], filesize); - return std::string(&bytes[0], filesize); + return replace(std::string(&bytes[0], filesize), "\r\n", "\n"); } std::string parent_path(const std::string &path) {