From cd6041a9d713c220921ea975f7acbde3f10e51d6 Mon Sep 17 00:00:00 2001 From: jist <95856749+george0st@users.noreply.github.com> Date: Tue, 22 Oct 2024 10:38:19 +0200 Subject: [PATCH 1/6] Tune garbage collection usage --- qgate_perf/parallel_executor.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/qgate_perf/parallel_executor.py b/qgate_perf/parallel_executor.py index 9d18094..bc958ee 100644 --- a/qgate_perf/parallel_executor.py +++ b/qgate_perf/parallel_executor.py @@ -361,7 +361,7 @@ def run_bulk_executor(self, performance.add_state(bulk_performance.state) # memory clean - gc.collect() + gc.collect(generation = 2) return performance @@ -415,7 +415,7 @@ def run_executor(self, executor_list = ExecutorHelper.PROCESS_2_8_THREAD_1_4_SHO performance.add_state(state) # memory clean - gc.collect(generation = 1) + gc.collect(generation = 2) self._print_footer(file, performance.state) @@ -470,6 +470,7 @@ def run(self, processes = 2, threads = 2, run_setup: RunSetup = None, performanc else: performance.add_state(state) + gc.collect(generation = 2) self._print_footer(file, performance.state) except Exception as e: @@ -631,6 +632,8 @@ def create_graph_static(input_file, output_graph_dir = "output", scope: GraphSco for file in graph.generate_from_file(input_file, os.path.join(output_graph_dir,"graph-exec"), suppress_error): output_file.append(file) + # clean GC + gc.collect(generation = 2) return output_file def create_graph(self, output_graph_dir = "output", scope: GraphScope = GraphScope.all_no_raw, picture_dpi = 100, suppress_error = False) -> list[str]: From c96cc8eb842f04f4144ff8a11f782157b4a862f2 Mon Sep 17 00:00:00 2001 From: jist <95856749+george0st@users.noreply.github.com> Date: Tue, 22 Oct 2024 14:11:10 +0200 Subject: [PATCH 2/6] bump qgate-graph --- dev-requirements.txt | 2 +- qgate_perf/parallel_executor.py | 48 +++++++++++++++++++++------------ requirements.txt | 2 +- 3 files changed, 33 insertions(+), 19 deletions(-) diff --git a/dev-requirements.txt b/dev-requirements.txt index e9ee458..8e9a734 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -9,7 +9,7 @@ numpy>=1.26.4,<=2.1.2 psutil>=5.9.0,<=6.0.0 packaging>=21.0,<=24.1 -qgate_graph==1.4.26 +qgate_graph==1.4.27 coverage>=7 coverage-badge>=1 diff --git a/qgate_perf/parallel_executor.py b/qgate_perf/parallel_executor.py index bc958ee..865c55e 100644 --- a/qgate_perf/parallel_executor.py +++ b/qgate_perf/parallel_executor.py @@ -560,7 +560,12 @@ def test_run(self, run_setup: RunSetup=None, print_output=False) -> bool: # region GRAPH's @staticmethod - def create_graph_static(input_file, output_graph_dir = "output", scope: GraphScope = GraphScope.all_no_raw, picture_dpi = 100, suppress_error = False) -> list[str]: + def create_graph_static(input_file, + output_graph_dir = "output", + scope: GraphScope = GraphScope.all_no_raw, + picture_dpi = 100, + suppress_error = False, + only_new = False) -> list[str]: """ Generate graph(s) based on output from performance tests @@ -569,6 +574,7 @@ def create_graph_static(input_file, output_graph_dir = "output", scope: GraphSco :param scope: definition of scope generation (default ExecutorGraph.all) :param picture_dpi: quality of picture (default is 100 DPI) :param suppress_error: suppress error (default is False) + :param only_new: generate only new outputs (default is False, regenerate all) :return: list of generated files """ output_file=[] @@ -578,7 +584,7 @@ def create_graph_static(input_file, output_graph_dir = "output", scope: GraphSco from qgate_graph.graph_performance import GraphPerformance # raw format False - graph = GraphPerformance(picture_dpi, raw_format = False) + graph = GraphPerformance(picture_dpi, raw_format = False, only_new = only_new) for file in graph.generate_from_file(input_file, os.path.join(output_graph_dir,"graph-perf"), suppress_error): output_file.append(file) @@ -586,7 +592,7 @@ def create_graph_static(input_file, output_graph_dir = "output", scope: GraphSco from qgate_graph.graph_performance import GraphPerformance # raw format True - graph = GraphPerformance(picture_dpi, raw_format = True) + graph = GraphPerformance(picture_dpi, raw_format = True, only_new = only_new) for file in graph.generate_from_file(input_file, os.path.join(output_graph_dir,"graph-perf"), suppress_error): output_file.append(file) @@ -595,7 +601,7 @@ def create_graph_static(input_file, output_graph_dir = "output", scope: GraphSco from qgate_graph.graph_performance_csv import GraphPerformanceCsv # raw format False - graph = GraphPerformanceCsv(raw_format = False) + graph = GraphPerformanceCsv(raw_format = False, only_new = only_new) for file in graph.generate_from_file(input_file, os.path.join(output_graph_dir,"graph-perf"), suppress_error): output_file.append(file) @@ -603,7 +609,7 @@ def create_graph_static(input_file, output_graph_dir = "output", scope: GraphSco from qgate_graph.graph_performance_csv import GraphPerformanceCsv # raw format True - graph = GraphPerformanceCsv(raw_format = True) + graph = GraphPerformanceCsv(raw_format = True, only_new = only_new) for file in graph.generate_from_file(input_file, os.path.join(output_graph_dir,"graph-perf"), suppress_error): output_file.append(file) @@ -612,7 +618,7 @@ def create_graph_static(input_file, output_graph_dir = "output", scope: GraphSco from qgate_graph.graph_performance_txt import GraphPerformanceTxt # raw format False - graph = GraphPerformanceTxt(raw_format=False) + graph = GraphPerformanceTxt(raw_format=False, only_new = only_new) for file in graph.generate_from_file(input_file, os.path.join(output_graph_dir, "graph-perf"), suppress_error): output_file.append(file) @@ -620,7 +626,7 @@ def create_graph_static(input_file, output_graph_dir = "output", scope: GraphSco from qgate_graph.graph_performance_txt import GraphPerformanceTxt # raw format True - graph = GraphPerformanceTxt(raw_format=True) + graph = GraphPerformanceTxt(raw_format=True, only_new = only_new) for file in graph.generate_from_file(input_file, os.path.join(output_graph_dir, "graph-perf"), suppress_error): output_file.append(file) @@ -628,7 +634,7 @@ def create_graph_static(input_file, output_graph_dir = "output", scope: GraphSco if GraphScope.exe in scope: from qgate_graph.graph_executor import GraphExecutor - graph = GraphExecutor(picture_dpi) + graph = GraphExecutor(picture_dpi, only_new = only_new) for file in graph.generate_from_file(input_file, os.path.join(output_graph_dir,"graph-exec"), suppress_error): output_file.append(file) @@ -636,7 +642,12 @@ def create_graph_static(input_file, output_graph_dir = "output", scope: GraphSco gc.collect(generation = 2) return output_file - def create_graph(self, output_graph_dir = "output", scope: GraphScope = GraphScope.all_no_raw, picture_dpi = 100, suppress_error = False) -> list[str]: + def create_graph(self, + output_graph_dir = "output", + scope: GraphScope = GraphScope.all_no_raw, + picture_dpi = 100, + suppress_error = False, + only_new = False) -> list[str]: """ Generate graph(s) based on output from performance tests. The outputs will be in subdirectories 'graph-perf' and 'graph-exec'. @@ -645,13 +656,15 @@ def create_graph(self, output_graph_dir = "output", scope: GraphScope = GraphSco :param scope: definition of scope generation (default ExecutorGraph.all) :param picture_dpi: quality of picture (default is 100 DPI) :param suppress_error: suppress error (default is False) + :param only_new: generate only new outputs (default is False, regenerate all) :return: list of generated files """ return ParallelExecutor.create_graph_static(self._output_file, - output_graph_dir, - scope, - picture_dpi, - suppress_error) + output_graph_dir, + scope, + picture_dpi, + suppress_error, + only_new) def create_graph_perf(self, output_graph_dir = "output", picture_dpi = 100, suppress_error = False) -> list[str]: """ @@ -664,10 +677,11 @@ def create_graph_perf(self, output_graph_dir = "output", picture_dpi = 100, supp :return: list of generated files """ return ParallelExecutor.create_graph_static(self._output_file, - output_graph_dir, - GraphScope.perf, - picture_dpi, - suppress_error) + output_graph_dir, + GraphScope.perf, + picture_dpi, + suppress_error, + only_new) def create_graph_exec(self, output_graph_dir = "output", picture_dpi = 100, suppress_error = False) -> list[str]: """ diff --git a/requirements.txt b/requirements.txt index d16570c..13810e9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,4 +6,4 @@ numpy>=1.26.4,<=2.1.2 psutil>=5.9.0,<=6.0.0 packaging>=21.0,<=24.1 -qgate_graph==1.4.26 +qgate_graph==1.4.27 From d1da7a63d2376067eb8eeb99cf2d778355e8f891 Mon Sep 17 00:00:00 2001 From: jist <95856749+george0st@users.noreply.github.com> Date: Tue, 22 Oct 2024 14:14:14 +0200 Subject: [PATCH 3/6] Update parallel_executor.py --- qgate_perf/parallel_executor.py | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/qgate_perf/parallel_executor.py b/qgate_perf/parallel_executor.py index 865c55e..13a1c2c 100644 --- a/qgate_perf/parallel_executor.py +++ b/qgate_perf/parallel_executor.py @@ -571,7 +571,7 @@ def create_graph_static(input_file, :param input_file: source file with detail of outputs from performance tests :param output_graph_dir: directory for graph outputs (with subdirectory 'graph-perf' and 'graph-exec') - :param scope: definition of scope generation (default ExecutorGraph.all) + :param scope: definition of scope generation (default ExecutorGraph.all_no_raw) :param picture_dpi: quality of picture (default is 100 DPI) :param suppress_error: suppress error (default is False) :param only_new: generate only new outputs (default is False, regenerate all) @@ -653,7 +653,7 @@ def create_graph(self, The outputs will be in subdirectories 'graph-perf' and 'graph-exec'. :param output_graph_dir: directory for graph outputs (with subdirectory 'graph-perf' and 'graph-exec') - :param scope: definition of scope generation (default ExecutorGraph.all) + :param scope: definition of scope generation (default ExecutorGraph.all_no_raw) :param picture_dpi: quality of picture (default is 100 DPI) :param suppress_error: suppress error (default is False) :param only_new: generate only new outputs (default is False, regenerate all) @@ -666,7 +666,11 @@ def create_graph(self, suppress_error, only_new) - def create_graph_perf(self, output_graph_dir = "output", picture_dpi = 100, suppress_error = False) -> list[str]: + def create_graph_perf(self, + output_graph_dir = "output", + picture_dpi = 100, + suppress_error = False, + only_new = False) -> list[str]: """ Generate performance graph(s) based on output from performance tests. The outputs will be in subdirectory 'graph-perf'. @@ -674,16 +678,21 @@ def create_graph_perf(self, output_graph_dir = "output", picture_dpi = 100, supp :param output_graph_dir: directory for graph outputs (with subdirectory 'graph-perf') :param picture_dpi: quality of picture (default is 100 DPI) :param suppress_error: suppress error (default is False) + :param only_new: generate only new outputs (default is False, regenerate all) :return: list of generated files """ return ParallelExecutor.create_graph_static(self._output_file, output_graph_dir, GraphScope.perf, picture_dpi, - suppress_error, + suppress_error, only_new) - def create_graph_exec(self, output_graph_dir = "output", picture_dpi = 100, suppress_error = False) -> list[str]: + def create_graph_exec(self, + output_graph_dir = "output", + picture_dpi = 100, + suppress_error = False, + only_new = False) -> list[str]: """ Generate executors graph(s) based on output from performance tests. The outputs will be in subdirectory 'graph-exec'. @@ -691,12 +700,14 @@ def create_graph_exec(self, output_graph_dir = "output", picture_dpi = 100, supp :param output_graph_dir: directory for graph outputs (with subdirectory 'graph-exec') :param picture_dpi: quality of picture (default is 100 DPI) :param suppress_error: suppress error (default is False) + :param only_new: generate only new outputs (default is False, regenerate all) :return: list of generated files """ return ParallelExecutor.create_graph_static(self._output_file, - output_graph_dir, - GraphScope.exe, - picture_dpi, - suppress_error) + output_graph_dir, + GraphScope.exe, + picture_dpi, + suppress_error, + only_new) # endregion GRAPHS \ No newline at end of file From 883794ca1a17858040d988ef1173b62f57779530 Mon Sep 17 00:00:00 2001 From: jist <95856749+george0st@users.noreply.github.com> Date: Tue, 22 Oct 2024 14:24:15 +0200 Subject: [PATCH 4/6] Update test_perf_partly.py --- tests/test_perf_partly.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_perf_partly.py b/tests/test_perf_partly.py index f9fd12c..9f8023e 100644 --- a/tests/test_perf_partly.py +++ b/tests/test_perf_partly.py @@ -56,6 +56,7 @@ def prf_partly(run_setup: RunSetup) -> ParallelProbe: class TestCasePerfPartly(unittest.TestCase): + """Performance measurement in more code segments (not in one block START and STOP) """ OUTPUT_ADR = "../output/test_perf/" @classmethod From b0b61b82c2c8ddc4524cbf3d61955ad404a4c1ed Mon Sep 17 00:00:00 2001 From: jist <95856749+george0st@users.noreply.github.com> Date: Tue, 22 Oct 2024 14:24:46 +0200 Subject: [PATCH 5/6] Update version.py --- qgate_perf/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qgate_perf/version.py b/qgate_perf/version.py index 6364bed..a33d23a 100644 --- a/qgate_perf/version.py +++ b/qgate_perf/version.py @@ -1,3 +1,3 @@ # Store the version here so: -__version__ = '0.4.40' \ No newline at end of file +__version__ = '0.4.41' \ No newline at end of file From 7706aebe7a5c835418263a1880780895d953ee7b Mon Sep 17 00:00:00 2001 From: jist <95856749+george0st@users.noreply.github.com> Date: Tue, 22 Oct 2024 14:35:26 +0200 Subject: [PATCH 6/6] Add unit test --- tests/test_graph.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/tests/test_graph.py b/tests/test_graph.py index 396bbd4..b51d9e5 100644 --- a/tests/test_graph.py +++ b/tests/test_graph.py @@ -16,7 +16,7 @@ def prf_test(run_setup: RunSetup) -> ParallelProbe: generator = numpy.random.default_rng() - # init (contain executor synchonization, if needed) + # init (contain executor synchronization, if needed) probe = ParallelProbe(run_setup) if run_setup.is_init: @@ -215,3 +215,19 @@ def test_graph_percentile(self): self.assertTrue(len(file)==2) print(file[0]) + def test_graph_onlynew(self): + + generator = ParallelExecutor(prf_test, + label="test_percentile", + detail_output=True, + output_file=path.join(self.OUTPUT_ADR, "only_new", "perf_test_percentile.txt")) + + setup=RunSetup(duration_second=2, start_delay=0, parameters={"percentile": 0.95}) + generator.run_bulk_executor([[1,1]], [[1,1]], setup) + + output=generator.create_graph_perf(self.OUTPUT_ADR, only_new = True) + self.assertTrue(len(output) == 1) + + output=generator.create_graph_perf(self.OUTPUT_ADR, only_new = True) + self.assertTrue(len(output) == 0) +