From f24d51541b17659683ae233e8a31b5cd8e7f3508 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Sat, 1 Mar 2025 12:17:30 -0500 Subject: [PATCH 01/83] Add test to check challenger's functionality --- test.sh | 1 + test_challenger.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 test_challenger.py diff --git a/test.sh b/test.sh index 7b853ba..d6f038e 100755 --- a/test.sh +++ b/test.sh @@ -1,5 +1,6 @@ #!/bin/bash +pytest test_challenger.py rm -rf sdp/__pycache__ ./test.py > timing.csv rm -rf sdp/__pycache__ diff --git a/test_challenger.py b/test_challenger.py new file mode 100644 index 0000000..a637d60 --- /dev/null +++ b/test_challenger.py @@ -0,0 +1,29 @@ +import numpy as np +import pytest + +from numpy import testing as npt +from sdp import challenger_sdp + + +def naive_sliding_dot_product(Q, T): + m = len(Q) + l = T.shape[0] - m + 1 + out = np.empty(l) + for i in range(l): + out[i] = np.dot(Q, T[i : i + m]) + return out + + +def test_challenger(): + pmin = 2 + pmax = 10 + for q in range(pmin, pmax): + for p in range(q, pmax): + Q = np.random.rand(2 ** q) + T = np.random.rand(2 ** p) + ref = naive_sliding_dot_product(Q, T) + comp = challenger_sdp.sliding_dot_product(Q, T) + + np.testing.assert_allclose(comp, ref) + + return \ No newline at end of file From 8b494c6a87e92c941ed9c275a6889bc7fbe64ea1 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Sat, 1 Mar 2025 12:21:23 -0500 Subject: [PATCH 02/83] add warning to catch issue when function cannot be imported --- test.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/test.py b/test.py index 4d95a09..4e294bf 100755 --- a/test.py +++ b/test.py @@ -15,17 +15,21 @@ def func_exists(mod_path, func_name): try: with open(mod_path, "r") as file: module_content = file.read() - except FileNotFoundError: + except FileNotFoundError as e: + warnings.warn(f"SKIPPED: {mod_path},{func_name}: \n{e}") return False # Module file not found try: tree = ast.parse(module_content) - except SyntaxError: + except SyntaxError as e: + warnings.warn(f"SKIPPED: {mod_path},{func_name}: \n{e}") return False # Syntax error in module for node in ast.walk(tree): if isinstance(node, ast.FunctionDef) and node.name == func_name: return True + e = f"Function {func_name} not found in {mod_path}" + warnings.warn(f"SKIPPED: {mod_path},{func_name}: \n{e}") return False From 5549abf53cfd169d99d32ccd3efd674e503c69e9 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Sun, 2 Mar 2025 15:56:19 -0500 Subject: [PATCH 03/83] rename file to reflect expanded scope --- test.sh | 2 +- test_challenger.py => test_modules.py | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename test_challenger.py => test_modules.py (100%) diff --git a/test.sh b/test.sh index d6f038e..a66bdfb 100755 --- a/test.sh +++ b/test.sh @@ -1,6 +1,6 @@ #!/bin/bash -pytest test_challenger.py +pytest test_modules.py rm -rf sdp/__pycache__ ./test.py > timing.csv rm -rf sdp/__pycache__ diff --git a/test_challenger.py b/test_modules.py similarity index 100% rename from test_challenger.py rename to test_modules.py From cf79b9a7feefbc8f33c89bf0e1ee808271a78b3b Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Sun, 2 Mar 2025 16:11:53 -0500 Subject: [PATCH 04/83] move functions to utils.py --- test.py | 52 +-------------------------------------------------- utils.py | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 51 deletions(-) create mode 100644 utils.py diff --git a/test.py b/test.py index 4e294bf..1dbac8e 100755 --- a/test.py +++ b/test.py @@ -10,57 +10,7 @@ import time import warnings - -def func_exists(mod_path, func_name): - try: - with open(mod_path, "r") as file: - module_content = file.read() - except FileNotFoundError as e: - warnings.warn(f"SKIPPED: {mod_path},{func_name}: \n{e}") - return False # Module file not found - - try: - tree = ast.parse(module_content) - except SyntaxError as e: - warnings.warn(f"SKIPPED: {mod_path},{func_name}: \n{e}") - return False # Syntax error in module - - for node in ast.walk(tree): - if isinstance(node, ast.FunctionDef) and node.name == func_name: - return True - e = f"Function {func_name} not found in {mod_path}" - warnings.warn(f"SKIPPED: {mod_path},{func_name}: \n{e}") - return False - - -def import_sdp_mods(include=None, ignore=None): - mods = [] - for m in sorted(list(pkgutil.iter_modules(sdp.__path__))): - mod_path = f"sdp/{m[1]}.py" - if ( - include is not None - and len(include) - and not any(mod in mod_path for mod in include) - ): - continue - if ( - ignore is not None - and len(ignore) - and any(mod in mod_path for mod in ignore) - ): - continue - - if ( - "sdp" in m[1] - and func_exists(mod_path, "sliding_dot_product") - and func_exists(mod_path, "setup") - ): - mod_name = f"sdp.{m[1]}" - mod = importlib.import_module(mod_name) - mods.append(mod) - - return mods - +from utils import func_exists, import_sdp_mods if __name__ == "__main__": parser = argparse.ArgumentParser( diff --git a/utils.py b/utils.py new file mode 100644 index 0000000..05a83c2 --- /dev/null +++ b/utils.py @@ -0,0 +1,57 @@ +import ast +import importlib +import pkgutil +import warnings + +import sdp + + +def func_exists(mod_path, func_name): + try: + with open(mod_path, "r") as file: + module_content = file.read() + except FileNotFoundError as e: + warnings.warn(f"SKIPPED: {mod_path},{func_name}: \n{e}") + return False # Module file not found + + try: + tree = ast.parse(module_content) + except SyntaxError as e: + warnings.warn(f"SKIPPED: {mod_path},{func_name}: \n{e}") + return False # Syntax error in module + + for node in ast.walk(tree): + if isinstance(node, ast.FunctionDef) and node.name == func_name: + return True + e = f"Function {func_name} not found in {mod_path}" + warnings.warn(f"SKIPPED: {mod_path},{func_name}: \n{e}") + return False + + +def import_sdp_mods(include=None, ignore=None): + mods = [] + for m in sorted(list(pkgutil.iter_modules(sdp.__path__))): + mod_path = f"sdp/{m[1]}.py" + if ( + include is not None + and len(include) + and not any(mod in mod_path for mod in include) + ): + continue + if ( + ignore is not None + and len(ignore) + and any(mod in mod_path for mod in ignore) + ): + continue + + if ( + "sdp" in m[1] + and func_exists(mod_path, "sliding_dot_product") + and func_exists(mod_path, "setup") + ): + mod_name = f"sdp.{m[1]}" + mod = importlib.import_module(mod_name) + mods.append(mod) + + return mods \ No newline at end of file From a761bc6b693f34052b95c123e1f16f6702fa54ef Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Sun, 2 Mar 2025 16:20:20 -0500 Subject: [PATCH 05/83] testing all modules --- test_modules.py | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/test_modules.py b/test_modules.py index a637d60..bfad527 100644 --- a/test_modules.py +++ b/test_modules.py @@ -4,6 +4,8 @@ from numpy import testing as npt from sdp import challenger_sdp +from utils import import_sdp_mods + def naive_sliding_dot_product(Q, T): m = len(Q) @@ -14,16 +16,19 @@ def naive_sliding_dot_product(Q, T): return out -def test_challenger(): - pmin = 2 - pmax = 10 - for q in range(pmin, pmax): - for p in range(q, pmax): - Q = np.random.rand(2 ** q) - T = np.random.rand(2 ** p) - ref = naive_sliding_dot_product(Q, T) - comp = challenger_sdp.sliding_dot_product(Q, T) +def test_modules(): + pmin = 3 + pmax = 13 + + modules = import_sdp_mods() + for mod in modules: + for q in range(pmin, pmax): + for p in range(q, pmax): + Q = np.random.rand(2 ** q) + T = np.random.rand(2 ** p) + ref = naive_sliding_dot_product(Q, T) + comp = mod.sliding_dot_product(Q, T) - np.testing.assert_allclose(comp, ref) + np.testing.assert_allclose(comp, ref) return \ No newline at end of file From c8efd4c8a2474c6cbe4910af67f2d6f61b49ba17 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Sun, 2 Mar 2025 16:21:12 -0500 Subject: [PATCH 06/83] removed unnecssary import --- test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test.py b/test.py index 1dbac8e..d7d6b80 100755 --- a/test.py +++ b/test.py @@ -10,7 +10,7 @@ import time import warnings -from utils import func_exists, import_sdp_mods +from utils import import_sdp_mods if __name__ == "__main__": parser = argparse.ArgumentParser( From 69226bb3340986f3562eb2f4c4e64615c452827c Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Sun, 2 Mar 2025 16:28:12 -0500 Subject: [PATCH 07/83] minor fix --- test_modules.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test_modules.py b/test_modules.py index bfad527..9a03ab3 100644 --- a/test_modules.py +++ b/test_modules.py @@ -22,8 +22,8 @@ def test_modules(): modules = import_sdp_mods() for mod in modules: - for q in range(pmin, pmax): - for p in range(q, pmax): + for q in range(pmin, pmax + 1): + for p in range(q, pmax + 1): Q = np.random.rand(2 ** q) T = np.random.rand(2 ** p) ref = naive_sliding_dot_product(Q, T) From d0b3324c5759891a4294272b4e222c49f82fc160 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Sun, 2 Mar 2025 16:35:26 -0500 Subject: [PATCH 08/83] catch the name of module when there is error --- test_modules.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/test_modules.py b/test_modules.py index 9a03ab3..4c2bb1b 100644 --- a/test_modules.py +++ b/test_modules.py @@ -22,13 +22,17 @@ def test_modules(): modules = import_sdp_mods() for mod in modules: - for q in range(pmin, pmax + 1): - for p in range(q, pmax + 1): - Q = np.random.rand(2 ** q) - T = np.random.rand(2 ** p) - ref = naive_sliding_dot_product(Q, T) - comp = mod.sliding_dot_product(Q, T) - - np.testing.assert_allclose(comp, ref) + try: + for q in range(pmin, pmax + 1): + for p in range(q, pmax + 1): + Q = np.random.rand(2 ** q) + T = np.random.rand(2 ** p) + ref = naive_sliding_dot_product(Q, T) + comp = mod.sliding_dot_product(Q, T) + + np.testing.assert_allclose(comp, ref) + except Exception as e: + print(f"Error in {mod.__name__}: {str(e)}") + raise e return \ No newline at end of file From 461fdf67572ea2b3a15f8362d6ade754fc1972ee Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Wed, 5 Mar 2025 17:18:16 -0500 Subject: [PATCH 09/83] rename files --- test.py | 105 ++++++++++++------------------------------- test_modules.py | 38 ---------------- timing.py | 85 +++++++++++++++++++++++++++++++++++ test.sh => timing.sh | 4 +- 4 files changed, 116 insertions(+), 116 deletions(-) mode change 100755 => 100644 test.py delete mode 100644 test_modules.py create mode 100755 timing.py rename test.sh => timing.sh (55%) diff --git a/test.py b/test.py old mode 100755 new mode 100644 index 844ca4c..4c2bb1b --- a/test.py +++ b/test.py @@ -1,85 +1,38 @@ -#!/usr/bin/env python - -import argparse -import pkgutil -import ast -import importlib import numpy as np -import numpy.testing as npt -import sdp -import time -import warnings +import pytest + +from numpy import testing as npt +from sdp import challenger_sdp from utils import import_sdp_mods -if __name__ == "__main__": - parser = argparse.ArgumentParser( - description="./test.py -noheader -pmin 6 -pmax 23 -pdiff 3 pyfftw challenger" - ) - parser.add_argument("-noheader", default=False, action="store_true") - parser.add_argument("-timeout", default=5.0, type=float, help="Number of seconds to wait for a run before timing out") - parser.add_argument("-pequal", default=False, action="store_true", help="Compute `len(Q) == len(T)`") - parser.add_argument("-niter", default=4, type=int, help="Number of iterations to run") - parser.add_argument("-pmin", default=6, type=int, help="Minimum 2^p to use") - parser.add_argument("-pmax", default=27, type=int, help="Maximum 2^p to use") - parser.add_argument("-pdiff", default=100, type=int, help="Maximum deviation from the minimum 2^p allowed") - parser.add_argument("-ignore", default=None, nargs="*", help="Keyword of modules to match and ignore") - parser.add_argument("include", default=None, nargs="*", help="Keyword of modules to match and include") - args = parser.parse_args() - modules = import_sdp_mods(args.include, args.ignore) +def naive_sliding_dot_product(Q, T): + m = len(Q) + l = T.shape[0] - m + 1 + out = np.empty(l) + for i in range(l): + out[i] = np.dot(Q, T[i : i + m]) + return out - noheader = args.noheader - timeout = args.timeout - if args.pequal: - skip_p_equal = 0 - else: - skip_p_equal = 1 - n_iter = args.niter - p_min = args.pmin - p_max = args.pmax - p_diff = args.pdiff - if not noheader: - print(f"module,len_Q,len_T,n_iter,time", flush=True) +def test_modules(): + pmin = 3 + pmax = 13 - start_timing = time.time() + modules = import_sdp_mods() for mod in modules: - mod_name = mod.__name__.removeprefix("sdp.").removesuffix("_sdp") - for i in range(p_min, p_max + 1): - Q = np.random.rand(2**i) - break_Q = False - for j in range(i + skip_p_equal, min(i + p_diff + 1, p_max + 1)): - T = np.random.rand(2**j) - break_T = False - - mod.setup(Q, T) - - elapsed_times = [] - for _ in range(n_iter): - start = time.time() - mod.sliding_dot_product(Q, T) - diff = time.time() - start - if diff > timeout: - break_T = True - warnings.warn(f"SKIPPED: {mod_name},{len(Q)},{len(T)},{diff})") - break - else: - elapsed_times.append(diff) - - if break_T: - if j == i + 1: - break_Q = True - break - - print( - f"{mod_name},{len(Q)},{len(T)},{len(elapsed_times)},{sum(elapsed_times) / len(elapsed_times)}", - flush=True, - ) - - if break_Q: - warnings.warn(f"SKIPPED: {mod_name},{len(Q)},>{len(T)},{diff})") - break - - elapsed_timing = np.round((time.time() - start_timing) / 60.0, 2) - warnings.warn(f"Test completed in {elapsed_timing} min") + try: + for q in range(pmin, pmax + 1): + for p in range(q, pmax + 1): + Q = np.random.rand(2 ** q) + T = np.random.rand(2 ** p) + ref = naive_sliding_dot_product(Q, T) + comp = mod.sliding_dot_product(Q, T) + + np.testing.assert_allclose(comp, ref) + except Exception as e: + print(f"Error in {mod.__name__}: {str(e)}") + raise e + + return \ No newline at end of file diff --git a/test_modules.py b/test_modules.py deleted file mode 100644 index 4c2bb1b..0000000 --- a/test_modules.py +++ /dev/null @@ -1,38 +0,0 @@ -import numpy as np -import pytest - -from numpy import testing as npt -from sdp import challenger_sdp - -from utils import import_sdp_mods - - -def naive_sliding_dot_product(Q, T): - m = len(Q) - l = T.shape[0] - m + 1 - out = np.empty(l) - for i in range(l): - out[i] = np.dot(Q, T[i : i + m]) - return out - - -def test_modules(): - pmin = 3 - pmax = 13 - - modules = import_sdp_mods() - for mod in modules: - try: - for q in range(pmin, pmax + 1): - for p in range(q, pmax + 1): - Q = np.random.rand(2 ** q) - T = np.random.rand(2 ** p) - ref = naive_sliding_dot_product(Q, T) - comp = mod.sliding_dot_product(Q, T) - - np.testing.assert_allclose(comp, ref) - except Exception as e: - print(f"Error in {mod.__name__}: {str(e)}") - raise e - - return \ No newline at end of file diff --git a/timing.py b/timing.py new file mode 100755 index 0000000..844ca4c --- /dev/null +++ b/timing.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python + +import argparse +import pkgutil +import ast +import importlib +import numpy as np +import numpy.testing as npt +import sdp +import time +import warnings + +from utils import import_sdp_mods + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description="./test.py -noheader -pmin 6 -pmax 23 -pdiff 3 pyfftw challenger" + ) + parser.add_argument("-noheader", default=False, action="store_true") + parser.add_argument("-timeout", default=5.0, type=float, help="Number of seconds to wait for a run before timing out") + parser.add_argument("-pequal", default=False, action="store_true", help="Compute `len(Q) == len(T)`") + parser.add_argument("-niter", default=4, type=int, help="Number of iterations to run") + parser.add_argument("-pmin", default=6, type=int, help="Minimum 2^p to use") + parser.add_argument("-pmax", default=27, type=int, help="Maximum 2^p to use") + parser.add_argument("-pdiff", default=100, type=int, help="Maximum deviation from the minimum 2^p allowed") + parser.add_argument("-ignore", default=None, nargs="*", help="Keyword of modules to match and ignore") + parser.add_argument("include", default=None, nargs="*", help="Keyword of modules to match and include") + args = parser.parse_args() + + modules = import_sdp_mods(args.include, args.ignore) + + noheader = args.noheader + timeout = args.timeout + if args.pequal: + skip_p_equal = 0 + else: + skip_p_equal = 1 + n_iter = args.niter + p_min = args.pmin + p_max = args.pmax + p_diff = args.pdiff + + if not noheader: + print(f"module,len_Q,len_T,n_iter,time", flush=True) + + start_timing = time.time() + for mod in modules: + mod_name = mod.__name__.removeprefix("sdp.").removesuffix("_sdp") + for i in range(p_min, p_max + 1): + Q = np.random.rand(2**i) + break_Q = False + for j in range(i + skip_p_equal, min(i + p_diff + 1, p_max + 1)): + T = np.random.rand(2**j) + break_T = False + + mod.setup(Q, T) + + elapsed_times = [] + for _ in range(n_iter): + start = time.time() + mod.sliding_dot_product(Q, T) + diff = time.time() - start + if diff > timeout: + break_T = True + warnings.warn(f"SKIPPED: {mod_name},{len(Q)},{len(T)},{diff})") + break + else: + elapsed_times.append(diff) + + if break_T: + if j == i + 1: + break_Q = True + break + + print( + f"{mod_name},{len(Q)},{len(T)},{len(elapsed_times)},{sum(elapsed_times) / len(elapsed_times)}", + flush=True, + ) + + if break_Q: + warnings.warn(f"SKIPPED: {mod_name},{len(Q)},>{len(T)},{diff})") + break + + elapsed_timing = np.round((time.time() - start_timing) / 60.0, 2) + warnings.warn(f"Test completed in {elapsed_timing} min") diff --git a/test.sh b/timing.sh similarity index 55% rename from test.sh rename to timing.sh index a66bdfb..6723645 100755 --- a/test.sh +++ b/timing.sh @@ -1,6 +1,6 @@ #!/bin/bash -pytest test_modules.py +pytest test.py rm -rf sdp/__pycache__ -./test.py > timing.csv +./timing.py > timing.csv rm -rf sdp/__pycache__ From f60b215e3a9f591d3abe307064ad8e562dd101b1 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Wed, 5 Mar 2025 17:33:12 -0500 Subject: [PATCH 10/83] remove unnecessary imports and minor changes --- test.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/test.py b/test.py index 4c2bb1b..05fabff 100644 --- a/test.py +++ b/test.py @@ -1,10 +1,7 @@ import numpy as np -import pytest +import utils from numpy import testing as npt -from sdp import challenger_sdp - -from utils import import_sdp_mods def naive_sliding_dot_product(Q, T): @@ -20,19 +17,18 @@ def test_modules(): pmin = 3 pmax = 13 - modules = import_sdp_mods() + modules = utils.import_sdp_mods() for mod in modules: try: for q in range(pmin, pmax + 1): for p in range(q, pmax + 1): - Q = np.random.rand(2 ** q) - T = np.random.rand(2 ** p) + Q = np.random.rand(2**q) + T = np.random.rand(2**p) ref = naive_sliding_dot_product(Q, T) comp = mod.sliding_dot_product(Q, T) - - np.testing.assert_allclose(comp, ref) + npt.assert_allclose(comp, ref) except Exception as e: print(f"Error in {mod.__name__}: {str(e)}") raise e - return \ No newline at end of file + return From c0008cac439f298ed1b61ca399eae92cc2cdabc8 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Wed, 5 Mar 2025 18:45:29 -0500 Subject: [PATCH 11/83] enhance test functions --- test.py | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/test.py b/test.py index 05fabff..f6fb141 100644 --- a/test.py +++ b/test.py @@ -13,7 +13,7 @@ def naive_sliding_dot_product(Q, T): return out -def test_modules(): +def test_sdp_power2(): pmin = 3 pmax = 13 @@ -24,9 +24,57 @@ def test_modules(): for p in range(q, pmax + 1): Q = np.random.rand(2**q) T = np.random.rand(2**p) + + ref = naive_sliding_dot_product(Q, T) + comp = mod.sliding_dot_product(Q, T) + npt.assert_allclose(comp, ref) + + except Exception as e: + print(f"Error in {mod.__name__}: {str(e)}") + raise e + + return + + +def test_sdp_power2_plus1(): + pmin = 3 + pmax = 13 + + modules = utils.import_sdp_mods() + for mod in modules: + try: + for q in range(pmin, pmax + 1): + for p in range(q, pmax + 1): + Q = np.random.rand(2**q + 1) + T = np.random.rand(2**p + 1) + ref = naive_sliding_dot_product(Q, T) comp = mod.sliding_dot_product(Q, T) npt.assert_allclose(comp, ref) + + except Exception as e: + print(f"Error in {mod.__name__}, with q={q} and p={p}") + raise e + + return + + +def test_sdp_power2_minus1(): + pmin = 3 + pmax = 13 + + modules = utils.import_sdp_mods() + for mod in modules: + try: + for q in range(pmin, pmax + 1): + for p in range(q, pmax + 1): + Q = np.random.rand(2**q - 1) + T = np.random.rand(2**p - 1) + + ref = naive_sliding_dot_product(Q, T) + comp = mod.sliding_dot_product(Q, T) + npt.assert_allclose(comp, ref) + except Exception as e: print(f"Error in {mod.__name__}: {str(e)}") raise e From e2a097df384a9dc3d79e6f29aa119ed8941b5031 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Wed, 5 Mar 2025 18:52:15 -0500 Subject: [PATCH 12/83] minor fixes --- timing.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/timing.py b/timing.py index 844ca4c..eddfdfd 100755 --- a/timing.py +++ b/timing.py @@ -1,16 +1,15 @@ #!/usr/bin/env python import argparse -import pkgutil import ast import importlib import numpy as np -import numpy.testing as npt -import sdp +import pkgutil import time import warnings -from utils import import_sdp_mods +import sdp +import utils if __name__ == "__main__": parser = argparse.ArgumentParser( @@ -27,7 +26,7 @@ parser.add_argument("include", default=None, nargs="*", help="Keyword of modules to match and include") args = parser.parse_args() - modules = import_sdp_mods(args.include, args.ignore) + modules = utils.import_sdp_mods(args.include, args.ignore) noheader = args.noheader timeout = args.timeout From 64fc128a2981ea9c85f35cc362e39aa71fd13253 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Wed, 5 Mar 2025 19:04:58 -0500 Subject: [PATCH 13/83] Improve msg when assetion fails --- test.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/test.py b/test.py index f6fb141..22b05e2 100644 --- a/test.py +++ b/test.py @@ -30,7 +30,8 @@ def test_sdp_power2(): npt.assert_allclose(comp, ref) except Exception as e: - print(f"Error in {mod.__name__}: {str(e)}") + msg = f"Error in {mod.__name__}, with q={q} and p={p}" + print(msg) raise e return @@ -53,7 +54,8 @@ def test_sdp_power2_plus1(): npt.assert_allclose(comp, ref) except Exception as e: - print(f"Error in {mod.__name__}, with q={q} and p={p}") + msg = f"Error in {mod.__name__}, with q={q} and p={p}" + print(msg) raise e return @@ -76,7 +78,8 @@ def test_sdp_power2_minus1(): npt.assert_allclose(comp, ref) except Exception as e: - print(f"Error in {mod.__name__}: {str(e)}") + msg = f"Error in {mod.__name__}, with q={q} and p={p}" + print(msg) raise e return From 667da6cb641da406bb7ef013f9ec5b5f6d088f86 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Wed, 5 Mar 2025 22:34:40 -0500 Subject: [PATCH 14/83] add test.sh and other files and clean up scripts --- .flake8 | 15 +++++++++ .github/workflows/github-actions.yml | 0 sdp/njit_sdp.py | 1 - test.sh | 48 +++++++++++++++++++++++++++ timing.py | 49 ++++++++++++++++++++-------- timing.sh | 2 +- utils.py | 2 +- 7 files changed, 100 insertions(+), 17 deletions(-) create mode 100644 .flake8 create mode 100644 .github/workflows/github-actions.yml create mode 100644 test.sh diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..bf4ce5a --- /dev/null +++ b/.flake8 @@ -0,0 +1,15 @@ +[flake8] +ignore = + E741, + W503, + E203, + D100, + D401, + D200, + D205, + D400, + D301 +max-line-length = 88 +docstring-convention=numpy +per-file-ignores = + ./test.py:D101,D102,D103 \ No newline at end of file diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml new file mode 100644 index 0000000..e69de29 diff --git a/sdp/njit_sdp.py b/sdp/njit_sdp.py index 2b9c73b..ca88ee9 100644 --- a/sdp/njit_sdp.py +++ b/sdp/njit_sdp.py @@ -1,6 +1,5 @@ import numpy as np from numba import njit -import sdp @njit(fastmath=True) diff --git a/test.sh b/test.sh new file mode 100644 index 0000000..a7426a1 --- /dev/null +++ b/test.sh @@ -0,0 +1,48 @@ +check_errs() +{ + # Function. Parameter 1 is the return code + if [[ $1 -ne "0" && $1 -ne "5" ]]; then + echo "Error: Test execution encountered exit code $1" + # as a bonus, make our script exit with the right error code. + exit $1 + fi +} + +clean_up() +{ + echo "Cleaning Up" + rm -rf "__pycache__/" +} + + +check_black() +{ + echo "Checking Black Code Formatting" + black --check --exclude=".*\.ipynb" --extend-exclude=".venv" --diff ./ + check_errs $? +} + +check_flake() +{ + echo "Checking Flake8 Style Guide Enforcement" + flake8 --extend-exclude=.venv ./ + check_errs $? +} + + +test_unit() +{ + echo "Testing Functions" + SECONDS=0 + pytest -rsx -W ignore::RuntimeWarning -W ignore::DeprecationWarning -W ignore::UserWarning test.py + check_errs $? + duration=$SECONDS + echo "Elapsed Time: $((duration / 60)) minutes and $((duration % 60)) seconds" +} + + +clean_up +check_black +check_flake +test_unit +clean_up \ No newline at end of file diff --git a/timing.py b/timing.py index eddfdfd..200de29 100755 --- a/timing.py +++ b/timing.py @@ -1,14 +1,10 @@ #!/usr/bin/env python import argparse -import ast -import importlib import numpy as np -import pkgutil import time import warnings -import sdp import utils if __name__ == "__main__": @@ -16,14 +12,38 @@ description="./test.py -noheader -pmin 6 -pmax 23 -pdiff 3 pyfftw challenger" ) parser.add_argument("-noheader", default=False, action="store_true") - parser.add_argument("-timeout", default=5.0, type=float, help="Number of seconds to wait for a run before timing out") - parser.add_argument("-pequal", default=False, action="store_true", help="Compute `len(Q) == len(T)`") - parser.add_argument("-niter", default=4, type=int, help="Number of iterations to run") + parser.add_argument( + "-timeout", + default=5.0, + type=float, + help="Number of seconds to wait for a run before timing out", + ) + parser.add_argument( + "-pequal", default=False, action="store_true", help="Compute `len(Q) == len(T)`" + ) + parser.add_argument( + "-niter", default=4, type=int, help="Number of iterations to run" + ) parser.add_argument("-pmin", default=6, type=int, help="Minimum 2^p to use") parser.add_argument("-pmax", default=27, type=int, help="Maximum 2^p to use") - parser.add_argument("-pdiff", default=100, type=int, help="Maximum deviation from the minimum 2^p allowed") - parser.add_argument("-ignore", default=None, nargs="*", help="Keyword of modules to match and ignore") - parser.add_argument("include", default=None, nargs="*", help="Keyword of modules to match and include") + parser.add_argument( + "-pdiff", + default=100, + type=int, + help="Maximum deviation from the minimum 2^p allowed", + ) + parser.add_argument( + "-ignore", + default=None, + nargs="*", + help="Keyword of modules to match and ignore", + ) + parser.add_argument( + "include", + default=None, + nargs="*", + help="Keyword of modules to match and include", + ) args = parser.parse_args() modules = utils.import_sdp_mods(args.include, args.ignore) @@ -40,7 +60,7 @@ p_diff = args.pdiff if not noheader: - print(f"module,len_Q,len_T,n_iter,time", flush=True) + print("module,len_Q,len_T,n_iter,time", flush=True) start_timing = time.time() for mod in modules: @@ -71,10 +91,11 @@ break_Q = True break - print( - f"{mod_name},{len(Q)},{len(T)},{len(elapsed_times)},{sum(elapsed_times) / len(elapsed_times)}", - flush=True, + info = ( + f"{mod_name},{len(Q)},{len(T)},{len(elapsed_times)}" + + f",{sum(elapsed_times) / len(elapsed_times)}" ) + print(info, flush=True) if break_Q: warnings.warn(f"SKIPPED: {mod_name},{len(Q)},>{len(T)},{diff})") diff --git a/timing.sh b/timing.sh index 6723645..068b18d 100755 --- a/timing.sh +++ b/timing.sh @@ -1,6 +1,6 @@ #!/bin/bash -pytest test.py +source test.sh rm -rf sdp/__pycache__ ./timing.py > timing.csv rm -rf sdp/__pycache__ diff --git a/utils.py b/utils.py index 05a83c2..15c9e77 100644 --- a/utils.py +++ b/utils.py @@ -54,4 +54,4 @@ def import_sdp_mods(include=None, ignore=None): mod = importlib.import_module(mod_name) mods.append(mod) - return mods \ No newline at end of file + return mods From 164e06138fa18b8fc180dbcc833ccf64f766c8d5 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Wed, 5 Mar 2025 22:49:16 -0500 Subject: [PATCH 15/83] add requirements file and github-actions --- .github/workflows/github-actions.yml | 51 ++++++++++++++++++++++++++++ requirements.txt | 3 ++ 2 files changed, 54 insertions(+) create mode 100644 requirements.txt diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index e69de29..1538f16 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -0,0 +1,51 @@ +name: Tests +on: + push: + branches: main + pull_request: + branches: main +jobs: + unit-testing: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + python-version: ['3.9', '3.10', '3.11', '3.12'] + steps: + - uses: actions/checkout@v4 + - name: Set Up Python + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + - name: Display Python Version + run: python -c "import sys; print(sys.version)" + shell: bash + - name: Upgrade Pip + run: python -m pip install --upgrade pip + shell: bash + - name: Install requirements + run: python -m pip install --upgrade -r requirements.txt + shell: bash + - name: Install other dependencies + run: python -m pip install --upgrade black flake8 + shell: bash + - name: Install OpenMP + run: | + if [ "$RUNNER_OS" == "macOS" ]; then + echo "Installing OpenMP" + brew install libomp + echo "Linking OpenMP" + brew link --force libomp + echo "Find OpenMP Linking Location" + libfile=`brew list libomp --verbose | grep libomp.dylib` + echo $libfile + echo "Changing @rpath for the omppool.cpython-x-darwin.so shared object to look in $libfile" + ls "$(python -c 'import site; print(site.getsitepackages()[0])')"/numba/np/ufunc/omppool.*.so | xargs install_name_tool -change @rpath/libomp.dylib $libfile + fi + shell: bash + - name: Show Full Numba Environment + run: python -m numba -s + shell: bash + - name: Run Unit Tests + run: ./test.sh unit + shell: bash \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..636322f --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +numpy>=1.22 +scipy>=1.10 +numba>=0.59.1 \ No newline at end of file From e0788b5f253bd63bf6ecef72cfbf30e6b18292e3 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Wed, 5 Mar 2025 22:58:41 -0500 Subject: [PATCH 16/83] Empty commit From cf607dd1a74dab9fade835e06b29794a8ef63015 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Wed, 5 Mar 2025 23:01:03 -0500 Subject: [PATCH 17/83] add pytest installation to github actions --- .github/workflows/github-actions.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index 1538f16..5f3c07c 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -27,7 +27,7 @@ jobs: run: python -m pip install --upgrade -r requirements.txt shell: bash - name: Install other dependencies - run: python -m pip install --upgrade black flake8 + run: python -m pip install --upgrade pytest black flake8 shell: bash - name: Install OpenMP run: | From 03347886fe57d7a63779ff29009490ee28069438 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Wed, 5 Mar 2025 23:21:09 -0500 Subject: [PATCH 18/83] To run github actions on push on any branch --- .github/workflows/github-actions.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index 5f3c07c..b26626f 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -1,7 +1,7 @@ name: Tests on: push: - branches: main + branches: '**' pull_request: branches: main jobs: From 6c6058c388921604638f5e521f3798bb8abc97e1 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Wed, 5 Mar 2025 23:26:51 -0500 Subject: [PATCH 19/83] minor fix --- .github/workflows/github-actions.yml | 2 +- test.sh | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index b26626f..ecc3381 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -47,5 +47,5 @@ jobs: run: python -m numba -s shell: bash - name: Run Unit Tests - run: ./test.sh unit + run: source test.sh shell: bash \ No newline at end of file diff --git a/test.sh b/test.sh index a7426a1..550bbf9 100644 --- a/test.sh +++ b/test.sh @@ -1,3 +1,5 @@ +#!/bin/bash + check_errs() { # Function. Parameter 1 is the return code From 83426674e0f82b6ea7f317c1cd5cb4a99ed211dc Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Wed, 5 Mar 2025 23:35:00 -0500 Subject: [PATCH 20/83] Add pyFFTW to requirements --- requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 636322f..8175a66 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ numpy>=1.22 scipy>=1.10 -numba>=0.59.1 \ No newline at end of file +numba>=0.59.1 +pyFFTW>=0.15.0 \ No newline at end of file From ef517dd012ef2d376ea2af78134d56394f043a5c Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Wed, 5 Mar 2025 23:59:09 -0500 Subject: [PATCH 21/83] Removed python 3.9 and OpenMP --- .github/workflows/github-actions.yml | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index ecc3381..da463b9 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -10,7 +10,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] - python-version: ['3.9', '3.10', '3.11', '3.12'] + python-version: ['3.10', '3.11', '3.12'] steps: - uses: actions/checkout@v4 - name: Set Up Python @@ -29,20 +29,6 @@ jobs: - name: Install other dependencies run: python -m pip install --upgrade pytest black flake8 shell: bash - - name: Install OpenMP - run: | - if [ "$RUNNER_OS" == "macOS" ]; then - echo "Installing OpenMP" - brew install libomp - echo "Linking OpenMP" - brew link --force libomp - echo "Find OpenMP Linking Location" - libfile=`brew list libomp --verbose | grep libomp.dylib` - echo $libfile - echo "Changing @rpath for the omppool.cpython-x-darwin.so shared object to look in $libfile" - ls "$(python -c 'import site; print(site.getsitepackages()[0])')"/numba/np/ufunc/omppool.*.so | xargs install_name_tool -change @rpath/libomp.dylib $libfile - fi - shell: bash - name: Show Full Numba Environment run: python -m numba -s shell: bash From e43758a29383e7a8e98c269fe9913f8410a94a1b Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Thu, 6 Mar 2025 00:06:19 -0500 Subject: [PATCH 22/83] change file mode --- test.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 test.sh diff --git a/test.sh b/test.sh old mode 100644 new mode 100755 From 0b1f7f7e6181ad8ff04a8fa1367948e94216d0f3 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Thu, 6 Mar 2025 00:43:00 -0500 Subject: [PATCH 23/83] fix shape of irfft output --- sdp/numpy_fft_sdp.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sdp/numpy_fft_sdp.py b/sdp/numpy_fft_sdp.py index 167f8bf..ae8c560 100644 --- a/sdp/numpy_fft_sdp.py +++ b/sdp/numpy_fft_sdp.py @@ -14,7 +14,8 @@ def sliding_dot_product(Q, T, order="F"): tmp = np.empty((2, shape), order=order) tmp[0, :m] = Q[::-1] tmp[0, m:] = 0.0 - tmp[1, :] = T + tmp[1, :n] = T + tmp[1, n:] = 0.0 fft_2d = np.fft.rfft(tmp, axis=-1) - return np.fft.irfft(np.multiply(fft_2d[0], fft_2d[1]))[m - 1 : n] + return np.fft.irfft(np.multiply(fft_2d[0], fft_2d[1]), n=shape)[m - 1 : n] From 0c578d3317f1106d41134ccb16a1b51fc31c968d Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Thu, 6 Mar 2025 01:40:54 -0500 Subject: [PATCH 24/83] clean up cache in sdp/ --- test.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/test.sh b/test.sh index 550bbf9..8d7ee30 100755 --- a/test.sh +++ b/test.sh @@ -14,6 +14,7 @@ clean_up() { echo "Cleaning Up" rm -rf "__pycache__/" + rm -rf "sdp/__pycache__/" } From 1570538cf91021b8062d378d74765164726c8683 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Fri, 7 Mar 2025 22:51:19 -0500 Subject: [PATCH 25/83] change push branch in github-actions --- .github/workflows/github-actions.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index da463b9..104e277 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -1,7 +1,7 @@ name: Tests on: push: - branches: '**' + branches: main pull_request: branches: main jobs: From 34b1c933837049b1d2a977ffedfbef6a71e0ab72 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Sat, 8 Mar 2025 16:43:32 -0500 Subject: [PATCH 26/83] fix python version in Github Action --- .github/workflows/github-actions.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index 104e277..22e078a 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -10,13 +10,13 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] - python-version: ['3.10', '3.11', '3.12'] + # python-version: ['3.10', '3.11', '3.12'] steps: - uses: actions/checkout@v4 - name: Set Up Python uses: actions/setup-python@v5 with: - python-version: ${{ matrix.python-version }} + python-version: $(curl --location https://devguide.python.org/versions | xmllint --html --xpath '//section[@id="supported-versions"]//table/tbody/tr[count(//section[@id="supported-versions"]//table/tbody/tr[td[.="security"]]/preceding-sibling::*)]/td[1]/p/text()' - 2>/dev/null) - name: Display Python Version run: python -c "import sys; print(sys.version)" shell: bash From 2355ebe35022a9ab06c8bc7069a40a5f524f7f51 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Sat, 8 Mar 2025 17:01:08 -0500 Subject: [PATCH 27/83] empty commit From f6f817d875aaf54791038dda3f33bffbd3bdf108 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Sat, 8 Mar 2025 17:03:14 -0500 Subject: [PATCH 28/83] revert a change in github actions --- .github/workflows/github-actions.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index 22e078a..274d06c 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -1,7 +1,7 @@ name: Tests on: push: - branches: main + branches: '**' pull_request: branches: main jobs: From d5ae7108e01387b33483ab00bdc6690bf27fb63d Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Sat, 8 Mar 2025 19:39:35 -0500 Subject: [PATCH 29/83] Add brackets to fix bash script --- python_version.sh | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100755 python_version.sh diff --git a/python_version.sh b/python_version.sh new file mode 100755 index 0000000..f2b20b8 --- /dev/null +++ b/python_version.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +get_safe_python_version() +{ + SAFE_PYTHON=$(curl --location https://devguide.python.org/versions | xmllint --html --xpath '//section[@id="supported-versions"]//table/tbody/tr[count(//section[@id="supported-versions"]//table/tbody/tr[td[.="security"]]/preceding-sibling::*)]/td[1]/p/text()' - 2>/dev/null) +} + +get_safe_python_version +echo $SAFE_PYTHON \ No newline at end of file From aaa062ffa4f35a2f10088152ae2a7aa9675edd5b Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Sat, 8 Mar 2025 19:45:41 -0500 Subject: [PATCH 30/83] temporarily hardcoded python version --- .github/workflows/github-actions.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index 274d06c..9ccc410 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -16,7 +16,7 @@ jobs: - name: Set Up Python uses: actions/setup-python@v5 with: - python-version: $(curl --location https://devguide.python.org/versions | xmllint --html --xpath '//section[@id="supported-versions"]//table/tbody/tr[count(//section[@id="supported-versions"]//table/tbody/tr[td[.="security"]]/preceding-sibling::*)]/td[1]/p/text()' - 2>/dev/null) + python-version: '3.10' - name: Display Python Version run: python -c "import sys; print(sys.version)" shell: bash From 4f6cb91f58a90132d68cf46b7a3ab458ed640a5a Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Sat, 8 Mar 2025 19:46:53 -0500 Subject: [PATCH 31/83] temporarily --- .github/workflows/github-actions.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index 9ccc410..f1a60e9 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -10,7 +10,6 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] - # python-version: ['3.10', '3.11', '3.12'] steps: - uses: actions/checkout@v4 - name: Set Up Python From d4b0c0b882a0846892a1ff3f036535c71959bfc2 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Sat, 8 Mar 2025 20:20:12 -0500 Subject: [PATCH 32/83] set python version based on the output of a shell script --- .github/workflows/github-actions.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index f1a60e9..e59e105 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -12,10 +12,14 @@ jobs: os: [ubuntu-latest, macos-latest, windows-latest] steps: - uses: actions/checkout@v4 + + - name: Set env + - run: echo "PYTHON_VERSION=$(python_version.sh)" >> $GITHUB_ENV + - name: Set Up Python uses: actions/setup-python@v5 with: - python-version: '3.10' + python-version: $PYTHON_VERSION - name: Display Python Version run: python -c "import sys; print(sys.version)" shell: bash From f58f8ab66f41053c32a17346a5a22275f2b49a27 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Sat, 8 Mar 2025 21:03:43 -0500 Subject: [PATCH 33/83] remove leading dash for run --- .github/workflows/github-actions.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index e59e105..0285527 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -12,10 +12,9 @@ jobs: os: [ubuntu-latest, macos-latest, windows-latest] steps: - uses: actions/checkout@v4 - - name: Set env - - run: echo "PYTHON_VERSION=$(python_version.sh)" >> $GITHUB_ENV - + run: echo "PYTHON_VERSION=$(python_version.sh)" >> $GITHUB_ENV + - name: Set Up Python uses: actions/setup-python@v5 with: From 1751dc488d06ca794af48dc67e25d84c4620b3ac Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Sat, 8 Mar 2025 21:09:04 -0500 Subject: [PATCH 34/83] fixed running shell script --- .github/workflows/github-actions.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index 0285527..15a8b5f 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Set env - run: echo "PYTHON_VERSION=$(python_version.sh)" >> $GITHUB_ENV + run: echo "PYTHON_VERSION=$(./python_version.sh)" >> $GITHUB_ENV - name: Set Up Python uses: actions/setup-python@v5 @@ -35,5 +35,5 @@ jobs: run: python -m numba -s shell: bash - name: Run Unit Tests - run: source test.sh + run: ./test.sh shell: bash \ No newline at end of file From c27d50f7d78ba7e330c496a256f53d571eaad992 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Sat, 8 Mar 2025 21:29:15 -0500 Subject: [PATCH 35/83] revised flow to directly assign output to python version variable --- .github/workflows/github-actions.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index 15a8b5f..ae5fe89 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -12,13 +12,10 @@ jobs: os: [ubuntu-latest, macos-latest, windows-latest] steps: - uses: actions/checkout@v4 - - name: Set env - run: echo "PYTHON_VERSION=$(./python_version.sh)" >> $GITHUB_ENV - - name: Set Up Python uses: actions/setup-python@v5 with: - python-version: $PYTHON_VERSION + python-version: ./python_version.sh - name: Display Python Version run: python -c "import sys; print(sys.version)" shell: bash From 8e90ad54ebb8214d5c30c04b6c46feae9e5cbe53 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Sat, 8 Mar 2025 21:43:56 -0500 Subject: [PATCH 36/83] clean up output --- python_version.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python_version.sh b/python_version.sh index f2b20b8..4ce981b 100755 --- a/python_version.sh +++ b/python_version.sh @@ -2,7 +2,7 @@ get_safe_python_version() { - SAFE_PYTHON=$(curl --location https://devguide.python.org/versions | xmllint --html --xpath '//section[@id="supported-versions"]//table/tbody/tr[count(//section[@id="supported-versions"]//table/tbody/tr[td[.="security"]]/preceding-sibling::*)]/td[1]/p/text()' - 2>/dev/null) + SAFE_PYTHON=$(curl --no-progress-meter --location https://devguide.python.org/versions | xmllint --html --xpath '//section[@id="supported-versions"]//table/tbody/tr[count(//section[@id="supported-versions"]//table/tbody/tr[td[.="security"]]/preceding-sibling::*)]/td[1]/p/text()' - 2> /dev/null) } get_safe_python_version From d180987025ca7af900e2045e3d8f9b5e9411a0a2 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Sat, 8 Mar 2025 22:41:34 -0500 Subject: [PATCH 37/83] minor change --- .github/workflows/github-actions.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index ae5fe89..73cbc24 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -12,10 +12,13 @@ jobs: os: [ubuntu-latest, macos-latest, windows-latest] steps: - uses: actions/checkout@v4 + - name: Set environment variables + run: echo "PYTHON_VERSION=$(./python_version.sh)" >> $GITHUB_ENV + shell: bash - name: Set Up Python uses: actions/setup-python@v5 with: - python-version: ./python_version.sh + python-version: echo $PYTHON_VERSION - name: Display Python Version run: python -c "import sys; print(sys.version)" shell: bash From fc3516ec2d25c530f447847bb95ada3187af0a76 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Sat, 8 Mar 2025 23:12:54 -0500 Subject: [PATCH 38/83] check version in bash --- .github/workflows/github-actions.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index 73cbc24..b369263 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -15,10 +15,13 @@ jobs: - name: Set environment variables run: echo "PYTHON_VERSION=$(./python_version.sh)" >> $GITHUB_ENV shell: bash + - name: Display Python Version + run: echo ${{ env.PYTHON_VERSION }} + shell: bash - name: Set Up Python uses: actions/setup-python@v5 with: - python-version: echo $PYTHON_VERSION + python-version: echo ${{ env.PYTHON_VERSION }} - name: Display Python Version run: python -c "import sys; print(sys.version)" shell: bash From 031a49f370f7a740f6e683dcb6da8c6977ae9c33 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Sun, 9 Mar 2025 08:46:15 -0400 Subject: [PATCH 39/83] add python version to GITHUB_ENV in two steps --- .github/workflows/github-actions.yml | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index b369263..d8b840a 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -4,39 +4,52 @@ on: branches: '**' pull_request: branches: main + jobs: unit-testing: runs-on: ${{ matrix.os }} strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] + steps: - - uses: actions/checkout@v4 + - name: Checkout Repository + uses: actions/checkout@v4 + - name: Set environment variables - run: echo "PYTHON_VERSION=$(./python_version.sh)" >> $GITHUB_ENV - shell: bash + run: | + version=./python_version.sh + echo "PYTHON_VERSION=$version" >> $GITHUB_ENV + - name: Display Python Version run: echo ${{ env.PYTHON_VERSION }} shell: bash + - name: Set Up Python uses: actions/setup-python@v5 with: python-version: echo ${{ env.PYTHON_VERSION }} + - name: Display Python Version run: python -c "import sys; print(sys.version)" shell: bash + - name: Upgrade Pip run: python -m pip install --upgrade pip shell: bash + - name: Install requirements run: python -m pip install --upgrade -r requirements.txt shell: bash + - name: Install other dependencies run: python -m pip install --upgrade pytest black flake8 shell: bash + - name: Show Full Numba Environment run: python -m numba -s shell: bash + - name: Run Unit Tests run: ./test.sh shell: bash \ No newline at end of file From 35c19f5881ca2f1b5115e8784b63c33fc99eea9a Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Sun, 9 Mar 2025 09:18:04 -0400 Subject: [PATCH 40/83] fixed assigning value --- .github/workflows/github-actions.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index d8b840a..5ef7f6c 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -18,7 +18,7 @@ jobs: - name: Set environment variables run: | - version=./python_version.sh + version=$(./python_version.sh) echo "PYTHON_VERSION=$version" >> $GITHUB_ENV - name: Display Python Version From dcb8b09f0de23dbfb5a59ebac9cf37f9ed751d4c Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Sun, 9 Mar 2025 09:20:01 -0400 Subject: [PATCH 41/83] removed echo for python-version --- .github/workflows/github-actions.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index 5ef7f6c..296a810 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -28,7 +28,7 @@ jobs: - name: Set Up Python uses: actions/setup-python@v5 with: - python-version: echo ${{ env.PYTHON_VERSION }} + python-version: ${{ env.PYTHON_VERSION }} - name: Display Python Version run: python -c "import sys; print(sys.version)" From cd9fd385f5748b231097018de8caf091c85257b8 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Sun, 9 Mar 2025 09:23:58 -0400 Subject: [PATCH 42/83] directly echo using output of shell script --- .github/workflows/github-actions.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index 296a810..4e4201e 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -17,9 +17,7 @@ jobs: uses: actions/checkout@v4 - name: Set environment variables - run: | - version=$(./python_version.sh) - echo "PYTHON_VERSION=$version" >> $GITHUB_ENV + run: echo "PYTHON_VERSION=$(./python_version.sh)" >> $GITHUB_ENV - name: Display Python Version run: echo ${{ env.PYTHON_VERSION }} From ac760e33fe98aa8ca7a4c2962cf76e09ff8bdd14 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Sun, 9 Mar 2025 12:54:53 -0400 Subject: [PATCH 43/83] Revert change in github action and update python_version to make it more verbose --- python_version.sh | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/python_version.sh b/python_version.sh index 4ce981b..24617d3 100755 --- a/python_version.sh +++ b/python_version.sh @@ -1,8 +1,19 @@ #!/bin/bash +check_errs() +{ + # Function. Parameter 1 is the return code + if [[ $1 -ne "0" && $1 -ne "5" ]]; then + echo "Error: Test execution encountered exit code $1" + # as a bonus, make our script exit with the right error code. + exit $1 + fi +} + get_safe_python_version() { - SAFE_PYTHON=$(curl --no-progress-meter --location https://devguide.python.org/versions | xmllint --html --xpath '//section[@id="supported-versions"]//table/tbody/tr[count(//section[@id="supported-versions"]//table/tbody/tr[td[.="security"]]/preceding-sibling::*)]/td[1]/p/text()' - 2> /dev/null) + SAFE_PYTHON=$(curl -v --location https://devguide.python.org/versions | xmllint --html --xpath '//section[@id="supported-versions"]//table/tbody/tr[count(//section[@id="supported-versions"]//table/tbody/tr[td[.="security"]]/preceding-sibling::*)]/td[1]/p/text()' - 2> /dev/null) + check_errs $? } get_safe_python_version From 6fedc8d89070a3afb27239b5a397d249b3556d9d Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Sun, 9 Mar 2025 13:54:48 -0400 Subject: [PATCH 44/83] Removed flag verbose --- python_version.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python_version.sh b/python_version.sh index 24617d3..d4c6be4 100755 --- a/python_version.sh +++ b/python_version.sh @@ -12,7 +12,7 @@ check_errs() get_safe_python_version() { - SAFE_PYTHON=$(curl -v --location https://devguide.python.org/versions | xmllint --html --xpath '//section[@id="supported-versions"]//table/tbody/tr[count(//section[@id="supported-versions"]//table/tbody/tr[td[.="security"]]/preceding-sibling::*)]/td[1]/p/text()' - 2> /dev/null) + SAFE_PYTHON=$(curl --location https://devguide.python.org/versions | xmllint --html --xpath '//section[@id="supported-versions"]//table/tbody/tr[count(//section[@id="supported-versions"]//table/tbody/tr[td[.="security"]]/preceding-sibling::*)]/td[1]/p/text()' - 2> /dev/null) check_errs $? } From 734ba7fef733cabf18bf82688eb56710c0eb4e0e Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Sun, 9 Mar 2025 15:16:00 -0400 Subject: [PATCH 45/83] Add different cases for tests --- test.py | 141 +++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 108 insertions(+), 33 deletions(-) diff --git a/test.py b/test.py index 22b05e2..982d37b 100644 --- a/test.py +++ b/test.py @@ -1,7 +1,9 @@ import numpy as np import utils +import warnings from numpy import testing as npt +from scipy.fft import next_fast_len def naive_sliding_dot_product(Q, T): @@ -13,7 +15,8 @@ def naive_sliding_dot_product(Q, T): return out -def test_sdp_power2(): +def test_sdp_case0(): + # This tests cases where `T` is complete power of 2. pmin = 3 pmax = 13 @@ -21,9 +24,11 @@ def test_sdp_power2(): for mod in modules: try: for q in range(pmin, pmax + 1): + n_Q = 2**q for p in range(q, pmax + 1): - Q = np.random.rand(2**q) - T = np.random.rand(2**p) + n_T = 2**p + Q = np.random.rand(n_Q) + T = np.random.rand(n_T) ref = naive_sliding_dot_product(Q, T) comp = mod.sliding_dot_product(Q, T) @@ -37,49 +42,119 @@ def test_sdp_power2(): return -def test_sdp_power2_plus1(): - pmin = 3 - pmax = 13 +def test_sdp_case1(): + # This tests cases where the length of `T` is even + # and its next_fast_len is the same as the len(T). + # To this end, we choose 2, 3 and 5 + + n_T = 2 * (3**2) * (5**3) + shape = next_fast_len(n_T) + if shape != n_T: + warnings.warn(f"next_fast_len({n_T}) = {shape}") modules = utils.import_sdp_mods() for mod in modules: - try: - for q in range(pmin, pmax + 1): - for p in range(q, pmax + 1): - Q = np.random.rand(2**q + 1) - T = np.random.rand(2**p + 1) + for n_Q in range(2, n_T + 1): + try: + Q = np.random.rand(n_Q) + T = np.random.rand(n_T) - ref = naive_sliding_dot_product(Q, T) - comp = mod.sliding_dot_product(Q, T) - npt.assert_allclose(comp, ref) + ref = naive_sliding_dot_product(Q, T) + comp = mod.sliding_dot_product(Q, T) + npt.assert_allclose(comp, ref) - except Exception as e: - msg = f"Error in {mod.__name__}, with q={q} and p={p}" - print(msg) - raise e + except Exception as e: + msg = f"Error in {mod.__name__}, with n_Q={n_Q} and n_T={n_T}" + print(msg) + raise e return -def test_sdp_power2_minus1(): - pmin = 3 - pmax = 13 +def test_sdp_case2(): + # This tests cases where the length of `T` is odd + # and its next_fast_len is the same as the len(T). + # To this end, we choose 3 and 5 + + n_T = (3**2) * (5**3) + shape = next_fast_len(n_T) + if shape != n_T: + warnings.warn(f"next_fast_len({n_T}) != {shape}") modules = utils.import_sdp_mods() for mod in modules: - try: - for q in range(pmin, pmax + 1): - for p in range(q, pmax + 1): - Q = np.random.rand(2**q - 1) - T = np.random.rand(2**p - 1) + for n_Q in range(2, n_T + 1): + try: + Q = np.random.rand(n_Q) + T = np.random.rand(n_T) - ref = naive_sliding_dot_product(Q, T) - comp = mod.sliding_dot_product(Q, T) - npt.assert_allclose(comp, ref) + ref = naive_sliding_dot_product(Q, T) + comp = mod.sliding_dot_product(Q, T) + npt.assert_allclose(comp, ref) - except Exception as e: - msg = f"Error in {mod.__name__}, with q={q} and p={p}" - print(msg) - raise e + except Exception as e: + msg = f"Error in {mod.__name__}, with n_Q={n_Q} and n_T={n_T}" + print(msg) + raise e + + return + + +def test_sdp_case3(): + # This tests cases where the length of `T` is even + # and its next_fast_len is not the same as + # the len(T) but longer. To this end, we choose + # factors 2, 7, 11, 13. + + n_T = 2 * 7 * 11 * 13 + shape = next_fast_len(n_T) + if shape == n_T: + warnings.warn(f"next_fast_len({n_T}) == {shape}") + + modules = utils.import_sdp_mods() + for mod in modules: + for n_Q in range(2, n_T + 1): + try: + Q = np.random.rand(n_Q) + T = np.random.rand(n_T) + + ref = naive_sliding_dot_product(Q, T) + comp = mod.sliding_dot_product(Q, T) + npt.assert_allclose(comp, ref) + + except Exception as e: + msg = f"Error in {mod.__name__}, with n_Q={n_Q} and n_T={n_T}" + print(msg) + raise e + + return + + +def test_sdp_case4(): + # This tests cases where the length of `T` is odd + # and its next_fast_len is not the same as + # the len(T) but longer. To this end, we choose + # factors 7, 11, 13. + + n_T = 7 * 11 * 13 + shape = next_fast_len(n_T) + if shape == n_T: + warnings.warn(f"next_fast_len({n_T}) == {shape}") + + modules = utils.import_sdp_mods() + for mod in modules: + for n_Q in range(2, n_T + 1): + try: + Q = np.random.rand(n_Q) + T = np.random.rand(n_T) + + ref = naive_sliding_dot_product(Q, T) + comp = mod.sliding_dot_product(Q, T) + npt.assert_allclose(comp, ref) + + except Exception as e: + msg = f"Error in {mod.__name__}, with n_Q={n_Q} and n_T={n_T}" + print(msg) + raise e return From ac940d3785346066afd16807532545aa48256311 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Sun, 9 Mar 2025 15:29:07 -0400 Subject: [PATCH 46/83] minor changes --- test.py | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/test.py b/test.py index 982d37b..572d28d 100644 --- a/test.py +++ b/test.py @@ -1,6 +1,5 @@ import numpy as np import utils -import warnings from numpy import testing as npt from scipy.fft import next_fast_len @@ -44,13 +43,17 @@ def test_sdp_case0(): def test_sdp_case1(): # This tests cases where the length of `T` is even - # and its next_fast_len is the same as the len(T). + # and its next_fast_len is the same as the len(T). # To this end, we choose 2, 3 and 5 n_T = 2 * (3**2) * (5**3) shape = next_fast_len(n_T) if shape != n_T: - warnings.warn(f"next_fast_len({n_T}) = {shape}") + msg = ( + "In this test, n_T value should be set to an even value " + + "such that its next_fast_len must be the same" + ) + raise ValueError(msg) modules = utils.import_sdp_mods() for mod in modules: @@ -73,13 +76,17 @@ def test_sdp_case1(): def test_sdp_case2(): # This tests cases where the length of `T` is odd - # and its next_fast_len is the same as the len(T). + # and its next_fast_len is the same as the len(T). # To this end, we choose 3 and 5 - n_T = (3**2) * (5**3) + n_T = (3**2) * (5**3) shape = next_fast_len(n_T) if shape != n_T: - warnings.warn(f"next_fast_len({n_T}) != {shape}") + msg = ( + "In this test, n_T value should be set to an odd value " + + "such that its next_fast_len must be the same" + ) + raise ValueError(msg) modules = utils.import_sdp_mods() for mod in modules: @@ -108,8 +115,12 @@ def test_sdp_case3(): n_T = 2 * 7 * 11 * 13 shape = next_fast_len(n_T) - if shape == n_T: - warnings.warn(f"next_fast_len({n_T}) == {shape}") + if shape <= n_T: + msg = ( + "In this test, n_T value should be set to an even value " + + "such that its next_fast_len must be larger" + ) + raise ValueError(msg) modules = utils.import_sdp_mods() for mod in modules: @@ -138,8 +149,12 @@ def test_sdp_case4(): n_T = 7 * 11 * 13 shape = next_fast_len(n_T) - if shape == n_T: - warnings.warn(f"next_fast_len({n_T}) == {shape}") + if shape <= n_T: + msg = ( + "In this test, n_T value should be set to an odd value " + + "such that its next_fast_len must be larger" + ) + raise ValueError(msg) modules = utils.import_sdp_mods() for mod in modules: From dcad2d05d292203038b29620d41277275fe2b5f4 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Sun, 9 Mar 2025 23:31:30 -0400 Subject: [PATCH 47/83] install xmllint on linux --- .github/workflows/github-actions.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index 4e4201e..58b2e2a 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -13,6 +13,11 @@ jobs: os: [ubuntu-latest, macos-latest, windows-latest] steps: + - name: Install xmllint on Linux + if: runner.os == 'Linux' + run: sudo apt-get install libxml2-utils + shell: bash + - name: Checkout Repository uses: actions/checkout@v4 From 84837766959e989bd0589fc221be858d37b58153 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Sun, 9 Mar 2025 23:41:24 -0400 Subject: [PATCH 48/83] Add shell bash --- .github/workflows/github-actions.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index 58b2e2a..3cd92ed 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -23,6 +23,7 @@ jobs: - name: Set environment variables run: echo "PYTHON_VERSION=$(./python_version.sh)" >> $GITHUB_ENV + shell : bash - name: Display Python Version run: echo ${{ env.PYTHON_VERSION }} From 30a42fe70eda03c07716a3fdfb922953dddbbcf7 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Tue, 11 Mar 2025 09:15:53 -0400 Subject: [PATCH 49/83] improve test functions --- test.py | 193 +++++++++++++++++++------------------------------------- 1 file changed, 65 insertions(+), 128 deletions(-) diff --git a/test.py b/test.py index 572d28d..2dfbb9b 100644 --- a/test.py +++ b/test.py @@ -1,9 +1,46 @@ import numpy as np +import pytest import utils from numpy import testing as npt +from operator import eq, lt from scipy.fft import next_fast_len +# README +# Real FFT algorithm performs more efficiently when the length +# of the input array `arr` is composed of small prime factors. +# The next_fast_len(arr, real=True) function from Scipy returns +# the same length if len(arr) is composed of a subset of +# prime numbers 2, 3, 5. Therefore, these radices are +# considered as the most efficient for the real FFT algorithm. + +# To ensure that the tests cover different cases, the following cases +# are considered: +# 1. len(T) is even, and len(T) == next_fast_len(len(T)) +# 2. len(T) is odd, and len(T) == next_fast_len(len(T)) +# 3. len(T) is even, and len(T) < next_fast_len(len(T)) +# 4. len(T) is odd, and len(T) < next_fast_len(len(T)) +# And 5. a special case of 1, where len(T) is power of 2. + +# Therefore: +# 1. len(T) is composed of 2 and a subset of {3, 5} +# 2. len(T) is composed of a subset of {3, 5} +# 3. len(T) is composed of a subset of {7, 11, 13, ...} and 2 +# 4. len(T) is composed of a subset of {7, 11, 13, ...} +# 5. len(T) is power of 2 + +# In some cases, the prime factors are powered to a certain degree +# to increase the length of array to be around 1000-2000. This +# can just let us test sliding_dot_product for wider range of +# query lengths. + +test_inputs = [ + (2 * (3**2) * (5**3), 0, eq), # = 2250, Even `len(T)`, and `len(T) == next_fast_len(len(T))` + ((3**2) * (5**3), 1, eq), # = 1125, Odd `len(T)`, and `len(T) == next_fast_len(len(T))`. + (2 * 7 * 11 * 13, 0, lt), # = 2002, Even `len(T)`, and `len(T) < next_fast_len(len(T))` + (7 * 11 * 13, 1, lt) # = 1001, Odd `len(T)`, and `len(T) < next_fast_len(len(T))` +] + def naive_sliding_dot_product(Q, T): m = len(Q) @@ -14,80 +51,21 @@ def naive_sliding_dot_product(Q, T): return out -def test_sdp_case0(): - # This tests cases where `T` is complete power of 2. - pmin = 3 - pmax = 13 - - modules = utils.import_sdp_mods() - for mod in modules: - try: - for q in range(pmin, pmax + 1): - n_Q = 2**q - for p in range(q, pmax + 1): - n_T = 2**p - Q = np.random.rand(n_Q) - T = np.random.rand(n_T) - - ref = naive_sliding_dot_product(Q, T) - comp = mod.sliding_dot_product(Q, T) - npt.assert_allclose(comp, ref) - - except Exception as e: - msg = f"Error in {mod.__name__}, with q={q} and p={p}" - print(msg) - raise e - - return - +@pytest.mark.parametrize("n_T, remainder, comparator", test_inputs) +def test_remainder(n_T, remainder): + assert n_T % 2 == remainder -def test_sdp_case1(): - # This tests cases where the length of `T` is even - # and its next_fast_len is the same as the len(T). - # To this end, we choose 2, 3 and 5 - n_T = 2 * (3**2) * (5**3) +@pytest.mark.parametrize("n_T, remainder, comparator", test_inputs) +def test_comparator(n_T, comparator): shape = next_fast_len(n_T) - if shape != n_T: - msg = ( - "In this test, n_T value should be set to an even value " - + "such that its next_fast_len must be the same" - ) - raise ValueError(msg) - - modules = utils.import_sdp_mods() - for mod in modules: - for n_Q in range(2, n_T + 1): - try: - Q = np.random.rand(n_Q) - T = np.random.rand(n_T) - - ref = naive_sliding_dot_product(Q, T) - comp = mod.sliding_dot_product(Q, T) - npt.assert_allclose(comp, ref) - - except Exception as e: - msg = f"Error in {mod.__name__}, with n_Q={n_Q} and n_T={n_T}" - print(msg) - raise e - - return + assert comparator(n_T, shape) -def test_sdp_case2(): - # This tests cases where the length of `T` is odd - # and its next_fast_len is the same as the len(T). - # To this end, we choose 3 and 5 - - n_T = (3**2) * (5**3) - shape = next_fast_len(n_T) - if shape != n_T: - msg = ( - "In this test, n_T value should be set to an odd value " - + "such that its next_fast_len must be the same" - ) - raise ValueError(msg) +@pytest.mark.parametrize("n_T, remainder, comparator", test_inputs) +def test_sdp(): + # test_sdp for cases 1-4 modules = utils.import_sdp_mods() for mod in modules: for n_Q in range(2, n_T + 1): @@ -107,69 +85,28 @@ def test_sdp_case2(): return -def test_sdp_case3(): - # This tests cases where the length of `T` is even - # and its next_fast_len is not the same as - # the len(T) but longer. To this end, we choose - # factors 2, 7, 11, 13. - - n_T = 2 * 7 * 11 * 13 - shape = next_fast_len(n_T) - if shape <= n_T: - msg = ( - "In this test, n_T value should be set to an even value " - + "such that its next_fast_len must be larger" - ) - raise ValueError(msg) - - modules = utils.import_sdp_mods() - for mod in modules: - for n_Q in range(2, n_T + 1): - try: - Q = np.random.rand(n_Q) - T = np.random.rand(n_T) - - ref = naive_sliding_dot_product(Q, T) - comp = mod.sliding_dot_product(Q, T) - npt.assert_allclose(comp, ref) - - except Exception as e: - msg = f"Error in {mod.__name__}, with n_Q={n_Q} and n_T={n_T}" - print(msg) - raise e - - return - - -def test_sdp_case4(): - # This tests cases where the length of `T` is odd - # and its next_fast_len is not the same as - # the len(T) but longer. To this end, we choose - # factors 7, 11, 13. - - n_T = 7 * 11 * 13 - shape = next_fast_len(n_T) - if shape <= n_T: - msg = ( - "In this test, n_T value should be set to an odd value " - + "such that its next_fast_len must be larger" - ) - raise ValueError(msg) +def test_sdp_power2(): + # test for case 5. len(T) is power of 2 + pmin = 3 + pmax = 13 modules = utils.import_sdp_mods() for mod in modules: - for n_Q in range(2, n_T + 1): - try: - Q = np.random.rand(n_Q) - T = np.random.rand(n_T) + try: + for q in range(pmin, pmax + 1): + n_Q = 2**q + for p in range(q, pmax + 1): + n_T = 2**p + Q = np.random.rand(n_Q) + T = np.random.rand(n_T) - ref = naive_sliding_dot_product(Q, T) - comp = mod.sliding_dot_product(Q, T) - npt.assert_allclose(comp, ref) + ref = naive_sliding_dot_product(Q, T) + comp = mod.sliding_dot_product(Q, T) + npt.assert_allclose(comp, ref) - except Exception as e: - msg = f"Error in {mod.__name__}, with n_Q={n_Q} and n_T={n_T}" - print(msg) - raise e + except Exception as e: + msg = f"Error in {mod.__name__}, with q={q} and p={p}" + print(msg) + raise e - return + return \ No newline at end of file From 94f3835133db9d619864b98dcb93273a65f824bb Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Tue, 11 Mar 2025 09:18:04 -0400 Subject: [PATCH 50/83] fixed black format --- test.py | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/test.py b/test.py index 2dfbb9b..1338292 100644 --- a/test.py +++ b/test.py @@ -6,12 +6,12 @@ from operator import eq, lt from scipy.fft import next_fast_len -# README -# Real FFT algorithm performs more efficiently when the length -# of the input array `arr` is composed of small prime factors. -# The next_fast_len(arr, real=True) function from Scipy returns -# the same length if len(arr) is composed of a subset of -# prime numbers 2, 3, 5. Therefore, these radices are +# README +# Real FFT algorithm performs more efficiently when the length +# of the input array `arr` is composed of small prime factors. +# The next_fast_len(arr, real=True) function from Scipy returns +# the same length if len(arr) is composed of a subset of +# prime numbers 2, 3, 5. Therefore, these radices are # considered as the most efficient for the real FFT algorithm. # To ensure that the tests cover different cases, the following cases @@ -25,20 +25,32 @@ # Therefore: # 1. len(T) is composed of 2 and a subset of {3, 5} # 2. len(T) is composed of a subset of {3, 5} -# 3. len(T) is composed of a subset of {7, 11, 13, ...} and 2 +# 3. len(T) is composed of a subset of {7, 11, 13, ...} and 2 # 4. len(T) is composed of a subset of {7, 11, 13, ...} # 5. len(T) is power of 2 -# In some cases, the prime factors are powered to a certain degree -# to increase the length of array to be around 1000-2000. This +# In some cases, the prime factors are powered to a certain degree +# to increase the length of array to be around 1000-2000. This # can just let us test sliding_dot_product for wider range of # query lengths. test_inputs = [ - (2 * (3**2) * (5**3), 0, eq), # = 2250, Even `len(T)`, and `len(T) == next_fast_len(len(T))` - ((3**2) * (5**3), 1, eq), # = 1125, Odd `len(T)`, and `len(T) == next_fast_len(len(T))`. - (2 * 7 * 11 * 13, 0, lt), # = 2002, Even `len(T)`, and `len(T) < next_fast_len(len(T))` - (7 * 11 * 13, 1, lt) # = 1001, Odd `len(T)`, and `len(T) < next_fast_len(len(T))` + ( + 2 * (3**2) * (5**3), + 0, + eq, + ), # = 2250, Even `len(T)`, and `len(T) == next_fast_len(len(T))` + ( + (3**2) * (5**3), + 1, + eq, + ), # = 1125, Odd `len(T)`, and `len(T) == next_fast_len(len(T))`. + ( + 2 * 7 * 11 * 13, + 0, + lt, + ), # = 2002, Even `len(T)`, and `len(T) < next_fast_len(len(T))` + (7 * 11 * 13, 1, lt), # = 1001, Odd `len(T)`, and `len(T) < next_fast_len(len(T))` ] @@ -62,7 +74,6 @@ def test_comparator(n_T, comparator): assert comparator(n_T, shape) - @pytest.mark.parametrize("n_T, remainder, comparator", test_inputs) def test_sdp(): # test_sdp for cases 1-4 @@ -109,4 +120,4 @@ def test_sdp_power2(): print(msg) raise e - return \ No newline at end of file + return From 595841fe8c7d15e7bca09e42cf6a4fd988dd42af Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Tue, 11 Mar 2025 09:21:00 -0400 Subject: [PATCH 51/83] minor fix --- test.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test.py b/test.py index 1338292..9ef27b0 100644 --- a/test.py +++ b/test.py @@ -64,18 +64,18 @@ def naive_sliding_dot_product(Q, T): @pytest.mark.parametrize("n_T, remainder, comparator", test_inputs) -def test_remainder(n_T, remainder): +def test_remainder(n_T, remainder, comparator): assert n_T % 2 == remainder @pytest.mark.parametrize("n_T, remainder, comparator", test_inputs) -def test_comparator(n_T, comparator): +def test_comparator(n_T, remainder, comparator): shape = next_fast_len(n_T) assert comparator(n_T, shape) @pytest.mark.parametrize("n_T, remainder, comparator", test_inputs) -def test_sdp(): +def test_sdp(n_T, remainder, comparator): # test_sdp for cases 1-4 modules = utils.import_sdp_mods() for mod in modules: From 45cb28faceee38bacfc8608b3d5f943acb1ef939 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Tue, 11 Mar 2025 09:29:37 -0400 Subject: [PATCH 52/83] set push-to-branch to main --- .github/workflows/github-actions.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index 3cd92ed..6f8e1b2 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -1,7 +1,7 @@ name: Tests on: push: - branches: '**' + branches: main pull_request: branches: main From 8818cbd21c68fe84365617559d3bb6f313b8432c Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Tue, 11 Mar 2025 09:30:50 -0400 Subject: [PATCH 53/83] empty commit From 70eb9dfee96a71680e49f9d18befa565787ba4f7 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Tue, 11 Mar 2025 09:31:58 -0400 Subject: [PATCH 54/83] revert change in github-action --- .github/workflows/github-actions.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index 6f8e1b2..3cd92ed 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -1,7 +1,7 @@ name: Tests on: push: - branches: main + branches: '**' pull_request: branches: main From 789a0a34e7293888a9bfda99ee84cf411b8b2f9d Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Tue, 11 Mar 2025 10:15:16 -0400 Subject: [PATCH 55/83] minor fix --- test.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/test.py b/test.py index 9ef27b0..956ffd1 100644 --- a/test.py +++ b/test.py @@ -16,10 +16,10 @@ # To ensure that the tests cover different cases, the following cases # are considered: -# 1. len(T) is even, and len(T) == next_fast_len(len(T)) -# 2. len(T) is odd, and len(T) == next_fast_len(len(T)) -# 3. len(T) is even, and len(T) < next_fast_len(len(T)) -# 4. len(T) is odd, and len(T) < next_fast_len(len(T)) +# 1. len(T) is even, and len(T) == next_fast_len(len(T), real=True) +# 2. len(T) is odd, and len(T) == next_fast_len(len(T), real=True) +# 3. len(T) is even, and len(T) < next_fast_len(len(T), real=True) +# 4. len(T) is odd, and len(T) < next_fast_len(len(T), real=True) # And 5. a special case of 1, where len(T) is power of 2. # Therefore: @@ -39,18 +39,18 @@ 2 * (3**2) * (5**3), 0, eq, - ), # = 2250, Even `len(T)`, and `len(T) == next_fast_len(len(T))` + ), # = 2250, Even `len(T)`, and `len(T) == next_fast_len(len(T), real=True)` ( (3**2) * (5**3), 1, eq, - ), # = 1125, Odd `len(T)`, and `len(T) == next_fast_len(len(T))`. + ), # = 1125, Odd `len(T)`, and `len(T) == next_fast_len(len(T), real=True)`. ( 2 * 7 * 11 * 13, 0, lt, - ), # = 2002, Even `len(T)`, and `len(T) < next_fast_len(len(T))` - (7 * 11 * 13, 1, lt), # = 1001, Odd `len(T)`, and `len(T) < next_fast_len(len(T))` + ), # = 2002, Even `len(T)`, and `len(T) < next_fast_len(len(T), real=True)` + (7 * 11 * 13, 1, lt), # = 1001, Odd `len(T)`, and `len(T) < next_fast_len(len(T), real=True)` ] @@ -70,7 +70,7 @@ def test_remainder(n_T, remainder, comparator): @pytest.mark.parametrize("n_T, remainder, comparator", test_inputs) def test_comparator(n_T, remainder, comparator): - shape = next_fast_len(n_T) + shape = next_fast_len(n_T, real=True) assert comparator(n_T, shape) From c246a703e6f7424b6b3fab9f0529fb1d26aaf069 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Tue, 11 Mar 2025 10:17:22 -0400 Subject: [PATCH 56/83] add coverage check --- test.sh | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/test.sh b/test.sh index 8d7ee30..cfd0940 100755 --- a/test.sh +++ b/test.sh @@ -43,9 +43,32 @@ test_unit() echo "Elapsed Time: $((duration / 60)) minutes and $((duration % 60)) seconds" } +test_coverage() +{ + echo "Disabling Numba JIT and CUDA Compiled Functions" + export NUMBA_DISABLE_JIT=1 + export NUMBA_ENABLE_CUDASIM=1 + + echo "Testing Code Coverage" + coverage erase + + SECONDS=0 + coverage run --append --source=. -m pytest -rsx -W ignore::RuntimeWarning -W ignore::DeprecationWarning -W ignore::UserWarning test.py + check_errs $? + duration=$SECONDS + + echo "Elapsed Time: $((duration / 60)) minutes and $((duration % 60)) seconds" + coverage report -m --fail-under=100 --skip-covered --omit=timing.py,utils.py +} + clean_up check_black check_flake test_unit -clean_up \ No newline at end of file + +clean_up +test_coverage + +clean_up +echo $NUMBA_DISABLE_JIT \ No newline at end of file From 1e030daa5eb398ba9f1ecc2cda5a67ac06583f50 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Tue, 11 Mar 2025 21:11:26 -0400 Subject: [PATCH 57/83] only test for some n_Q --- test.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/test.py b/test.py index 956ffd1..cd7d59a 100644 --- a/test.py +++ b/test.py @@ -50,7 +50,11 @@ 0, lt, ), # = 2002, Even `len(T)`, and `len(T) < next_fast_len(len(T), real=True)` - (7 * 11 * 13, 1, lt), # = 1001, Odd `len(T)`, and `len(T) < next_fast_len(len(T), real=True)` + ( + 7 * 11 * 13, + 1, + lt, + ), # = 1001, Odd `len(T)`, and `len(T) < next_fast_len(len(T), real=True)` ] @@ -79,7 +83,7 @@ def test_sdp(n_T, remainder, comparator): # test_sdp for cases 1-4 modules = utils.import_sdp_mods() for mod in modules: - for n_Q in range(2, n_T + 1): + for n_Q in [2, n_T // 2, n_T]: try: Q = np.random.rand(n_Q) T = np.random.rand(n_T) From 90da515835cb75880579a5f796075b0bc9a95ef8 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Tue, 11 Mar 2025 21:14:41 -0400 Subject: [PATCH 58/83] improve docstring --- test.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test.py b/test.py index cd7d59a..b9b20f4 100644 --- a/test.py +++ b/test.py @@ -29,10 +29,10 @@ # 4. len(T) is composed of a subset of {7, 11, 13, ...} # 5. len(T) is power of 2 -# In some cases, the prime factors are powered to a certain degree -# to increase the length of array to be around 1000-2000. This -# can just let us test sliding_dot_product for wider range of -# query lengths. +# In some cases, the prime factors are raised to a power of +# certain degree to increase the length of array to be around +# 1000-2000. This allows us to test sliding_dot_product for +# wider range of query lengths. test_inputs = [ ( From 9c08d09c2ca2ecdbbb998d6b9423be3846b3a845 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Tue, 11 Mar 2025 21:17:40 -0400 Subject: [PATCH 59/83] fix black formatting --- test.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test.py b/test.py index b9b20f4..62a7847 100644 --- a/test.py +++ b/test.py @@ -29,9 +29,9 @@ # 4. len(T) is composed of a subset of {7, 11, 13, ...} # 5. len(T) is power of 2 -# In some cases, the prime factors are raised to a power of -# certain degree to increase the length of array to be around -# 1000-2000. This allows us to test sliding_dot_product for +# In some cases, the prime factors are raised to a power of +# certain degree to increase the length of array to be around +# 1000-2000. This allows us to test sliding_dot_product for # wider range of query lengths. test_inputs = [ From 17c12cd41ca482e7a90d8307d82afd2fcfcc5515 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Tue, 11 Mar 2025 21:31:02 -0400 Subject: [PATCH 60/83] remove shell script and move code to Github-Actions --- .github/workflows/github-actions.yml | 2 +- python_version.sh | 20 -------------------- 2 files changed, 1 insertion(+), 21 deletions(-) delete mode 100755 python_version.sh diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index 3cd92ed..145b25a 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -22,7 +22,7 @@ jobs: uses: actions/checkout@v4 - name: Set environment variables - run: echo "PYTHON_VERSION=$(./python_version.sh)" >> $GITHUB_ENV + run: echo "PYTHON_VERSION=$(curl --location https://devguide.python.org/versions | xmllint --html --xpath '//section[@id="supported-versions"]//table/tbody/tr[count(//section[@id="supported-versions"]//table/tbody/tr[td[.="security"]]/preceding-sibling::*)]/td[1]/p/text()' - 2> /dev/null)" >> $GITHUB_ENV shell : bash - name: Display Python Version diff --git a/python_version.sh b/python_version.sh deleted file mode 100755 index d4c6be4..0000000 --- a/python_version.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash - -check_errs() -{ - # Function. Parameter 1 is the return code - if [[ $1 -ne "0" && $1 -ne "5" ]]; then - echo "Error: Test execution encountered exit code $1" - # as a bonus, make our script exit with the right error code. - exit $1 - fi -} - -get_safe_python_version() -{ - SAFE_PYTHON=$(curl --location https://devguide.python.org/versions | xmllint --html --xpath '//section[@id="supported-versions"]//table/tbody/tr[count(//section[@id="supported-versions"]//table/tbody/tr[td[.="security"]]/preceding-sibling::*)]/td[1]/p/text()' - 2> /dev/null) - check_errs $? -} - -get_safe_python_version -echo $SAFE_PYTHON \ No newline at end of file From a570f87d2d6e0d81fb57a8bcb1ee1f24c5534807 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Tue, 11 Mar 2025 21:31:37 -0400 Subject: [PATCH 61/83] Add coverage installation to workflow --- .github/workflows/github-actions.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index 145b25a..00832c0 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -47,7 +47,7 @@ jobs: shell: bash - name: Install other dependencies - run: python -m pip install --upgrade pytest black flake8 + run: python -m pip install --upgrade pytest coverage black flake8 shell: bash - name: Show Full Numba Environment From 948f7e8e331141d5e8e4a0e2a961cfc2253ae37d Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Wed, 12 Mar 2025 22:32:07 -0400 Subject: [PATCH 62/83] ignore untested lines in coverage --- sdp/challenger_sdp.py | 2 +- sdp/njit_sdp.py | 2 +- sdp/numpy_fft_sdp.py | 2 +- sdp/pyfftw_sdp.py | 2 +- sdp/scipy_oaconvolve_sdp.py | 2 +- test.py | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/sdp/challenger_sdp.py b/sdp/challenger_sdp.py index ce60e8d..9e7dfcd 100644 --- a/sdp/challenger_sdp.py +++ b/sdp/challenger_sdp.py @@ -1,7 +1,7 @@ import numpy as np -def setup(Q, T): +def setup(Q, T): # pragma: no cover return diff --git a/sdp/njit_sdp.py b/sdp/njit_sdp.py index ca88ee9..89e5534 100644 --- a/sdp/njit_sdp.py +++ b/sdp/njit_sdp.py @@ -16,7 +16,7 @@ def _sliding_dot_product(Q, T): return out -def setup(Q, T): +def setup(Q, T): # pragma: no cover _sliding_dot_product(np.random.rand(50), np.random.rand(100)) return diff --git a/sdp/numpy_fft_sdp.py b/sdp/numpy_fft_sdp.py index ae8c560..0208d71 100644 --- a/sdp/numpy_fft_sdp.py +++ b/sdp/numpy_fft_sdp.py @@ -2,7 +2,7 @@ from scipy.fft import next_fast_len -def setup(Q, T): +def setup(Q, T): # pragma: no cover return diff --git a/sdp/pyfftw_sdp.py b/sdp/pyfftw_sdp.py index bd0a0e9..05140b8 100644 --- a/sdp/pyfftw_sdp.py +++ b/sdp/pyfftw_sdp.py @@ -42,7 +42,7 @@ def __call__(self, Q, T): _sliding_dot_product = SLIDING_DOT_PRODUCT() -def setup(Q, T): +def setup(Q, T): # pragma: no cover _sliding_dot_product(Q, T) return diff --git a/sdp/scipy_oaconvolve_sdp.py b/sdp/scipy_oaconvolve_sdp.py index 85f0a1f..1d484a0 100644 --- a/sdp/scipy_oaconvolve_sdp.py +++ b/sdp/scipy_oaconvolve_sdp.py @@ -2,7 +2,7 @@ import numpy as np -def setup(Q, T): +def setup(Q, T): # pragma: no cover return diff --git a/test.py b/test.py index 62a7847..1f4cc8e 100644 --- a/test.py +++ b/test.py @@ -92,7 +92,7 @@ def test_sdp(n_T, remainder, comparator): comp = mod.sliding_dot_product(Q, T) npt.assert_allclose(comp, ref) - except Exception as e: + except Exception as e: # pragma: no cover msg = f"Error in {mod.__name__}, with n_Q={n_Q} and n_T={n_T}" print(msg) raise e @@ -119,7 +119,7 @@ def test_sdp_power2(): comp = mod.sliding_dot_product(Q, T) npt.assert_allclose(comp, ref) - except Exception as e: + except Exception as e: # pragma: no cover msg = f"Error in {mod.__name__}, with q={q} and p={p}" print(msg) raise e From f0ec4718ad1c9d0575630b3bcf270c5ed275d5cd Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Wed, 12 Mar 2025 22:49:30 -0400 Subject: [PATCH 63/83] testing for more values of n_Q --- test.py | 44 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/test.py b/test.py index 1f4cc8e..8ec3b02 100644 --- a/test.py +++ b/test.py @@ -81,17 +81,47 @@ def test_comparator(n_T, remainder, comparator): @pytest.mark.parametrize("n_T, remainder, comparator", test_inputs) def test_sdp(n_T, remainder, comparator): # test_sdp for cases 1-4 + + n_Q_prime = [ + 2, + 3, + 5, + 7, + 11, + 13, + 17, + 19, + 23, + 29, + 31, + 37, + 41, + 43, + 47, + 53, + 59, + 61, + 67, + 71, + 73, + 79, + 83, + 89, + 97, + ] + n_Q_power2 = [2, 4, 8, 16, 32, 64] + n_Q_values = n_Q_prime + n_Q_power2 + [n_T] + n_Q_values = sorted(n_Q for n_Q in set(n_Q_values) if n_Q <= n_T) + modules = utils.import_sdp_mods() - for mod in modules: - for n_Q in [2, n_T // 2, n_T]: + for n_Q in n_Q_values: + Q = np.random.rand(n_Q) + T = np.random.rand(n_T) + ref = naive_sliding_dot_product(Q, T) + for mod in modules: try: - Q = np.random.rand(n_Q) - T = np.random.rand(n_T) - - ref = naive_sliding_dot_product(Q, T) comp = mod.sliding_dot_product(Q, T) npt.assert_allclose(comp, ref) - except Exception as e: # pragma: no cover msg = f"Error in {mod.__name__}, with n_Q={n_Q} and n_T={n_T}" print(msg) From 53de511d83278997c44c5c7151eefa896cd75412 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Sat, 15 Mar 2025 22:38:30 -0400 Subject: [PATCH 64/83] use conda to install dependencies on Github Actions --- .github/workflows/github-actions.yml | 70 +++++++++++++++------------- 1 file changed, 38 insertions(+), 32 deletions(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index 00832c0..727cbc0 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -7,6 +7,10 @@ on: jobs: unit-testing: + defaults: + run: + shell: bash -el {0} + runs-on: ${{ matrix.os }} strategy: matrix: @@ -16,44 +20,46 @@ jobs: - name: Install xmllint on Linux if: runner.os == 'Linux' run: sudo apt-get install libxml2-utils - shell: bash - + + - name: Get safe PYTHON_VERSION + run: echo "PYTHON_VERSION=$(curl --location https://devguide.python.org/versions | xmllint --html --xpath '//section[@id="supported-versions"]//table/tbody/tr[count(//section[@id="supported-versions"]//table/tbody/tr[td[.="security"]]/preceding-sibling::*)]/td[1]/p/text()' - 2> /dev/null)" >> $GITHUB_ENV + - name: Checkout Repository uses: actions/checkout@v4 - - - name: Set environment variables - run: echo "PYTHON_VERSION=$(curl --location https://devguide.python.org/versions | xmllint --html --xpath '//section[@id="supported-versions"]//table/tbody/tr[count(//section[@id="supported-versions"]//table/tbody/tr[td[.="security"]]/preceding-sibling::*)]/td[1]/p/text()' - 2> /dev/null)" >> $GITHUB_ENV - shell : bash - - name: Display Python Version - run: echo ${{ env.PYTHON_VERSION }} - shell: bash - - - name: Set Up Python - uses: actions/setup-python@v5 + - name: Update environment.yml with PYTHON_VERSION + run: sed 's/python.*/python==${{ env.PYTHON_VERSION }}/' environment.yml > environment_new.yml + + - name: Display environment_new.yml + run: cat environment_new.yml + + - name: set up conda and install dependencies + uses: conda-incubator/setup-miniconda@v3 with: - python-version: ${{ env.PYTHON_VERSION }} - + environment-file: environment_new.yml + + - name : Remove environment_new.yml + run: rm -rf environment_new.yml + + - name: install pytest and coverage + run: | + conda install conda-forge::pytest + conda install conda-forge::coverage + + - name : Display Conda Environments + run: conda env list + + - name: Display conda info + run: conda info + + - name: Display conda list + run: conda list + - name: Display Python Version run: python -c "import sys; print(sys.version)" - shell: bash - - - name: Upgrade Pip - run: python -m pip install --upgrade pip - shell: bash - - - name: Install requirements - run: python -m pip install --upgrade -r requirements.txt - shell: bash - - - name: Install other dependencies - run: python -m pip install --upgrade pytest coverage black flake8 - shell: bash - + - name: Show Full Numba Environment run: python -m numba -s - shell: bash - + - name: Run Unit Tests - run: ./test.sh - shell: bash \ No newline at end of file + run: ./test.sh \ No newline at end of file From 37a024b1fdacb83d3bc2ef7e28ef02282f230455 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Mon, 17 Mar 2025 00:05:05 -0400 Subject: [PATCH 65/83] update environment.yml and workflow --- .github/workflows/github-actions.yml | 8 +++----- environment.yml | 4 ++-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index 727cbc0..eb06507 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -9,6 +9,9 @@ jobs: unit-testing: defaults: run: + # Set default shell to login-bash + # This is required to properly activate the conda environment + # https://github.com/conda-incubator/setup-miniconda?tab=readme-ov-file#use-a-default-shell shell: bash -el {0} runs-on: ${{ matrix.os }} @@ -41,11 +44,6 @@ jobs: - name : Remove environment_new.yml run: rm -rf environment_new.yml - - name: install pytest and coverage - run: | - conda install conda-forge::pytest - conda install conda-forge::coverage - - name : Display Conda Environments run: conda env list diff --git a/environment.yml b/environment.yml index b720b8d..c5d39d9 100644 --- a/environment.yml +++ b/environment.yml @@ -8,11 +8,11 @@ dependencies: - numba>=0.59.1 - fftw - pyfftw - - jax - panel - pandas>=0.20.0 - flake8>=3.7.7 - black>=22.1.0 - jupyterlab>=3.0 - matplotlib>=3.3.0 - - isort>=5.11.0 + - pytest>=4.4.1 + - coverage>=4.5.3 From afc2eb2a95f1e9ae0e32f4457e57a93dfb943444 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Mon, 17 Mar 2025 00:53:49 -0400 Subject: [PATCH 66/83] Removed requirements.txt --- requirements.txt | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 requirements.txt diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 8175a66..0000000 --- a/requirements.txt +++ /dev/null @@ -1,4 +0,0 @@ -numpy>=1.22 -scipy>=1.10 -numba>=0.59.1 -pyFFTW>=0.15.0 \ No newline at end of file From 8671d1dc93251d90647447cc20d4c70799fbd7d8 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Mon, 17 Mar 2025 07:27:22 -0400 Subject: [PATCH 67/83] add test for setup function --- test.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/test.py b/test.py index 8ec3b02..244939d 100644 --- a/test.py +++ b/test.py @@ -155,3 +155,23 @@ def test_sdp_power2(): raise e return + + +def test_setup(): + Q = np.random.rand(3) + T = np.random.rand(10) + + modules = utils.import_sdp_mods() + for mod in modules: + # test if setup function exists and runs without error + try: + out = mod.setup(Q, T) + except Exception as e: # pragma: no cover + msg = f"Error in {mod.__name__}" + print(msg) + raise e + + # test if setup function returns None + assert out is None + + return From 9a67f19319034bcce4716bb01d5b66d220d02a3e Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Mon, 17 Mar 2025 07:29:00 -0400 Subject: [PATCH 68/83] including setup for coverage --- sdp/challenger_sdp.py | 2 +- sdp/njit_sdp.py | 2 +- sdp/numpy_fft_sdp.py | 2 +- sdp/pyfftw_sdp.py | 2 +- sdp/scipy_oaconvolve_sdp.py | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sdp/challenger_sdp.py b/sdp/challenger_sdp.py index 9e7dfcd..ce60e8d 100644 --- a/sdp/challenger_sdp.py +++ b/sdp/challenger_sdp.py @@ -1,7 +1,7 @@ import numpy as np -def setup(Q, T): # pragma: no cover +def setup(Q, T): return diff --git a/sdp/njit_sdp.py b/sdp/njit_sdp.py index 89e5534..ca88ee9 100644 --- a/sdp/njit_sdp.py +++ b/sdp/njit_sdp.py @@ -16,7 +16,7 @@ def _sliding_dot_product(Q, T): return out -def setup(Q, T): # pragma: no cover +def setup(Q, T): _sliding_dot_product(np.random.rand(50), np.random.rand(100)) return diff --git a/sdp/numpy_fft_sdp.py b/sdp/numpy_fft_sdp.py index 0208d71..ae8c560 100644 --- a/sdp/numpy_fft_sdp.py +++ b/sdp/numpy_fft_sdp.py @@ -2,7 +2,7 @@ from scipy.fft import next_fast_len -def setup(Q, T): # pragma: no cover +def setup(Q, T): return diff --git a/sdp/pyfftw_sdp.py b/sdp/pyfftw_sdp.py index 05140b8..bd0a0e9 100644 --- a/sdp/pyfftw_sdp.py +++ b/sdp/pyfftw_sdp.py @@ -42,7 +42,7 @@ def __call__(self, Q, T): _sliding_dot_product = SLIDING_DOT_PRODUCT() -def setup(Q, T): # pragma: no cover +def setup(Q, T): _sliding_dot_product(Q, T) return diff --git a/sdp/scipy_oaconvolve_sdp.py b/sdp/scipy_oaconvolve_sdp.py index 1d484a0..85f0a1f 100644 --- a/sdp/scipy_oaconvolve_sdp.py +++ b/sdp/scipy_oaconvolve_sdp.py @@ -2,7 +2,7 @@ import numpy as np -def setup(Q, T): # pragma: no cover +def setup(Q, T): return From 4077e08e100155d577a21baa7ee2d8ecd36ed3e9 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Mon, 17 Mar 2025 07:29:57 -0400 Subject: [PATCH 69/83] update gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 0473167..6f5d8ae 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ __pycache__ *csv .ipynb_checkpoints +.coverage \ No newline at end of file From 092a03380b3ed9d095c926aa68f34164c34d8067 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Mon, 17 Mar 2025 07:36:06 -0400 Subject: [PATCH 70/83] change push branch --- .github/workflows/github-actions.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index eb06507..bfa4100 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -1,7 +1,7 @@ name: Tests on: push: - branches: '**' + branches: add_test pull_request: branches: main From b14b43d8a424cc8434712cb1f3fccae269ea8f60 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Mon, 17 Mar 2025 08:11:27 -0400 Subject: [PATCH 71/83] Removed unnecessary check for ENV VAR --- test.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test.sh b/test.sh index cfd0940..fa8704f 100755 --- a/test.sh +++ b/test.sh @@ -70,5 +70,4 @@ test_unit clean_up test_coverage -clean_up -echo $NUMBA_DISABLE_JIT \ No newline at end of file +clean_up \ No newline at end of file From 72f74f4098509337a4ecb44878b2d1f978185c39 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Mon, 17 Mar 2025 08:13:51 -0400 Subject: [PATCH 72/83] Removed manipulation of unnecessary env var --- test.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/test.sh b/test.sh index fa8704f..de3ad46 100755 --- a/test.sh +++ b/test.sh @@ -47,7 +47,6 @@ test_coverage() { echo "Disabling Numba JIT and CUDA Compiled Functions" export NUMBA_DISABLE_JIT=1 - export NUMBA_ENABLE_CUDASIM=1 echo "Testing Code Coverage" coverage erase From aac2bc3c765b8e5c00a387d17839f0c6fc7d1cb1 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Mon, 17 Mar 2025 08:33:01 -0400 Subject: [PATCH 73/83] execute instead of sourcing --- timing.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/timing.sh b/timing.sh index 068b18d..77fdaec 100755 --- a/timing.sh +++ b/timing.sh @@ -1,6 +1,6 @@ #!/bin/bash -source test.sh +./test.sh rm -rf sdp/__pycache__ ./timing.py > timing.csv rm -rf sdp/__pycache__ From 93432db01c52e46e298554cfd287909fc636eeb4 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Mon, 17 Mar 2025 22:53:31 -0400 Subject: [PATCH 74/83] remove test from timing --- timing.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/timing.sh b/timing.sh index 77fdaec..2e125c6 100755 --- a/timing.sh +++ b/timing.sh @@ -1,6 +1,5 @@ #!/bin/bash -./test.sh rm -rf sdp/__pycache__ ./timing.py > timing.csv rm -rf sdp/__pycache__ From 7cf868bfa19f2e85341fc71ae44b6ac7b5e8bafd Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Mon, 17 Mar 2025 22:56:28 -0400 Subject: [PATCH 75/83] minor fix --- timing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/timing.py b/timing.py index 200de29..701e1c5 100755 --- a/timing.py +++ b/timing.py @@ -9,7 +9,7 @@ if __name__ == "__main__": parser = argparse.ArgumentParser( - description="./test.py -noheader -pmin 6 -pmax 23 -pdiff 3 pyfftw challenger" + description="./timing.py -noheader -pmin 6 -pmax 23 -pdiff 3 pyfftw challenger" ) parser.add_argument("-noheader", default=False, action="store_true") parser.add_argument( From 279f4ad3364e23288c0def0a3583d6dc6bfc2a0b Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Mon, 17 Mar 2025 23:19:07 -0400 Subject: [PATCH 76/83] revise test_setup --- test.py | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/test.py b/test.py index 244939d..7b5c2f3 100644 --- a/test.py +++ b/test.py @@ -1,5 +1,8 @@ +import importlib import numpy as np +import pkgutil import pytest +import sdp import utils from numpy import testing as npt @@ -161,17 +164,25 @@ def test_setup(): Q = np.random.rand(3) T = np.random.rand(10) - modules = utils.import_sdp_mods() - for mod in modules: - # test if setup function exists and runs without error - try: - out = mod.setup(Q, T) - except Exception as e: # pragma: no cover - msg = f"Error in {mod.__name__}" - print(msg) - raise e + for m in sorted(list(pkgutil.iter_modules(sdp.__path__))): + if m[1].endswith("_sdp"): + # test if the module has the setup function + mod_path = f"sdp/{m[1]}.py" + try: + assert utils.func_exists(mod_path, "setup") + except AssertionError as e: # pragma: no cover + msg = f"Error in {mod_path}" + print(msg) + raise e - # test if setup function returns None - assert out is None + # test if setup function returns None + mod_name = f"sdp.{m[1]}" + mod = importlib.import_module(mod_name) + try: + assert mod.setup(Q, T) is None + except AssertionError as e: # pragma: no cover + msg = f"Error in {mod_name}" + print(msg) + raise e return From 74e811844f56a8b343f96d9a50a7073af761ca6c Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Wed, 19 Mar 2025 00:30:49 -0400 Subject: [PATCH 77/83] addressed comments --- .github/workflows/github-actions.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index bfa4100..e51c695 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -24,19 +24,19 @@ jobs: if: runner.os == 'Linux' run: sudo apt-get install libxml2-utils - - name: Get safe PYTHON_VERSION + - name: Get Safe PYTHON_VERSION run: echo "PYTHON_VERSION=$(curl --location https://devguide.python.org/versions | xmllint --html --xpath '//section[@id="supported-versions"]//table/tbody/tr[count(//section[@id="supported-versions"]//table/tbody/tr[td[.="security"]]/preceding-sibling::*)]/td[1]/p/text()' - 2> /dev/null)" >> $GITHUB_ENV - name: Checkout Repository uses: actions/checkout@v4 - name: Update environment.yml with PYTHON_VERSION - run: sed 's/python.*/python==${{ env.PYTHON_VERSION }}/' environment.yml > environment_new.yml + run: sed -r 's/- python[>=]+[0-9]+\.[0-9]+/- python==${{ env.PYTHON_VERSION }}/' environment.yml > environment_new.yml - name: Display environment_new.yml run: cat environment_new.yml - - name: set up conda and install dependencies + - name: Set up Miniconda and Install New Dependencies uses: conda-incubator/setup-miniconda@v3 with: environment-file: environment_new.yml @@ -47,10 +47,10 @@ jobs: - name : Display Conda Environments run: conda env list - - name: Display conda info + - name: Display Conda Info run: conda info - - name: Display conda list + - name: Display All Installed Packages run: conda list - name: Display Python Version From f8da7e72f4e40c42919346b37c82b29d7b01014c Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Wed, 19 Mar 2025 00:36:01 -0400 Subject: [PATCH 78/83] add comment to describe test_inputs --- test.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test.py b/test.py index 7b5c2f3..6ac5ed6 100644 --- a/test.py +++ b/test.py @@ -38,6 +38,12 @@ # wider range of query lengths. test_inputs = [ + # Input format: + # ( + # len(T), + # remainder, # from `len(T) % 2` + # comparator, # for len(T) comparator next_fast_len(len(T), real=True) + # ) ( 2 * (3**2) * (5**3), 0, From 2c5c631c5d7ee5108ae5ed640b4f12f9f0858aef Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Wed, 19 Mar 2025 00:40:32 -0400 Subject: [PATCH 79/83] fix format --- test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test.py b/test.py index 6ac5ed6..fba9807 100644 --- a/test.py +++ b/test.py @@ -41,7 +41,7 @@ # Input format: # ( # len(T), - # remainder, # from `len(T) % 2` + # remainder, # from `len(T) % 2` # comparator, # for len(T) comparator next_fast_len(len(T), real=True) # ) ( From 47bcaf17c88bcf9bee141182afbe09fe70c902eb Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Wed, 19 Mar 2025 00:48:46 -0400 Subject: [PATCH 80/83] change push branches to main --- .github/workflows/github-actions.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index e51c695..3748acd 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -1,7 +1,7 @@ name: Tests on: push: - branches: add_test + branches: main pull_request: branches: main From a568ff429eaee3411f43950be64b2c7cada58d81 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Wed, 19 Mar 2025 01:03:54 -0400 Subject: [PATCH 81/83] Removed unnecessary step in Github Action --- .github/workflows/github-actions.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index 3748acd..2fb9392 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -47,9 +47,6 @@ jobs: - name : Display Conda Environments run: conda env list - - name: Display Conda Info - run: conda info - - name: Display All Installed Packages run: conda list From 1ff353a9956a83f2add3df78aa5cf5e4f8695c77 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Wed, 19 Mar 2025 19:23:19 -0400 Subject: [PATCH 82/83] minor change --- test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test.py b/test.py index fba9807..c72a6b3 100644 --- a/test.py +++ b/test.py @@ -171,7 +171,7 @@ def test_setup(): T = np.random.rand(10) for m in sorted(list(pkgutil.iter_modules(sdp.__path__))): - if m[1].endswith("_sdp"): + if "sdp" in m[1]: # test if the module has the setup function mod_path = f"sdp/{m[1]}.py" try: From 6720f8014617c53db420460b40a8fe4c9bbb279b Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Wed, 19 Mar 2025 19:25:14 -0400 Subject: [PATCH 83/83] improve description of step --- .github/workflows/github-actions.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index 2fb9392..abcccff 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -56,5 +56,5 @@ jobs: - name: Show Full Numba Environment run: python -m numba -s - - name: Run Unit Tests + - name: Run Unit Tests and Coverage run: ./test.sh \ No newline at end of file