From 1592afe8ee7c0ebe921ad2fd822c1533489821c3 Mon Sep 17 00:00:00 2001 From: Luca Moretti Date: Tue, 27 Apr 2021 21:13:49 +0200 Subject: [PATCH] Added Processes number parameter --- .../structure_constraint_based_estimator.py | 27 +++++++++++++++---- .../structure_score_based_estimator.py | 7 ++++- ...st_structure_constraint_based_estimator.py | 2 +- .../test_structure_score_based_estimator.py | 4 ++- 4 files changed, 32 insertions(+), 8 deletions(-) diff --git a/PyCTBN/PyCTBN/estimators/structure_constraint_based_estimator.py b/PyCTBN/PyCTBN/estimators/structure_constraint_based_estimator.py index 0013d80..2fa255e 100644 --- a/PyCTBN/PyCTBN/estimators/structure_constraint_based_estimator.py +++ b/PyCTBN/PyCTBN/estimators/structure_constraint_based_estimator.py @@ -199,8 +199,14 @@ class StructureConstraintBasedEstimator(StructureEstimator): return optimizer_obj.optimize_structure() - def ctpc_algorithm(self,disable_multiprocessing:bool= False ): + def ctpc_algorithm(self, disable_multiprocessing:bool= False, processes_number:int= None): """Compute the CTPC algorithm over the entire net. + + :param disable_multiprocessing: true if you desire to disable the multiprocessing operations, default to False + :type disable_multiprocessing: Boolean, optional + :param processes_number: if disable_multiprocessing is false indicates + the maximum number of process; if None it will be automatically set, default to None + :type processes_number: int, optional """ ctpc_algo = self.one_iteration_of_CTPC_algorithm total_vars_numb = self._sample_path.total_variables_count @@ -212,8 +218,6 @@ class StructureConstraintBasedEstimator(StructureEstimator): 'get the number of CPU' cpu_count = multiprocessing.cpu_count() - - 'Remove all the edges from the structure' self._sample_path.structure.clean_structure_edges() @@ -225,6 +229,9 @@ class StructureConstraintBasedEstimator(StructureEstimator): cpu_count = 1 list_edges_partial = [ctpc_algo(n,total_vars_numb) for n in self._nodes] else: + if processes_number is not None and cpu_count < processes_number: + cpu_count = processes_number + with concurrent.futures.ProcessPoolExecutor(max_workers=cpu_count) as executor: list_edges_partial = executor.map(ctpc_algo, self._nodes, @@ -238,8 +245,18 @@ class StructureConstraintBasedEstimator(StructureEstimator): return edges - def estimate_structure(self,disable_multiprocessing:bool=False): - return self.ctpc_algorithm(disable_multiprocessing=disable_multiprocessing) + def estimate_structure(self, disable_multiprocessing:bool=False, processes_number:int= None): + """ + Compute the constraint-based algorithm to find the optimal structure + + :param disable_multiprocessing: true if you desire to disable the multiprocessing operations, default to False + :type disable_multiprocessing: Boolean, optional + :param processes_number: if disable_multiprocessing is false indicates + the maximum number of process; if None it will be automatically set, default to None + :type processes_number: int, optional + """ + return self.ctpc_algorithm(disable_multiprocessing=disable_multiprocessing, + processes_number=processes_number) diff --git a/PyCTBN/PyCTBN/estimators/structure_score_based_estimator.py b/PyCTBN/PyCTBN/estimators/structure_score_based_estimator.py index 12222f9..5763739 100644 --- a/PyCTBN/PyCTBN/estimators/structure_score_based_estimator.py +++ b/PyCTBN/PyCTBN/estimators/structure_score_based_estimator.py @@ -54,7 +54,7 @@ class StructureScoreBasedEstimator(StructureEstimator): def estimate_structure(self, max_parents:int = None, iterations_number:int= 40, patience:int = None, tabu_length:int = None, tabu_rules_duration:int = None, - optimizer: str = 'tabu',disable_multiprocessing:bool= False ): + optimizer: str = 'tabu', disable_multiprocessing:bool= False, processes_number:int= None): """ Compute the score-based algorithm to find the optimal structure @@ -72,6 +72,9 @@ class StructureScoreBasedEstimator(StructureEstimator): :type optimizer: string, optional :param disable_multiprocessing: true if you desire to disable the multiprocessing operations, default to False :type disable_multiprocessing: Boolean, optional + :param processes_number: if disable_multiprocessing is false indicates + the maximum number of process; if None it will be automatically set, default to None + :type processes_number: int, optional """ 'Save the true edges structure in tuples' true_edges = copy.deepcopy(self._sample_path.structure.edges) @@ -98,6 +101,8 @@ class StructureScoreBasedEstimator(StructureEstimator): if disable_multiprocessing: cpu_count = 1 + elif processes_number is not None and cpu_count < processes_number: + cpu_count = processes_number diff --git a/PyCTBN/tests/estimators/test_structure_constraint_based_estimator.py b/PyCTBN/tests/estimators/test_structure_constraint_based_estimator.py index b69d445..3e9d2b0 100644 --- a/PyCTBN/tests/estimators/test_structure_constraint_based_estimator.py +++ b/PyCTBN/tests/estimators/test_structure_constraint_based_estimator.py @@ -54,7 +54,7 @@ class TestStructureConstraintBasedEstimator(unittest.TestCase): true_edges = set(map(tuple, true_edges)) se1 = StructureConstraintBasedEstimator(self.s1,0.1,0.1) - edges = se1.estimate_structure(True) + edges = se1.estimate_structure(processes_number=2) self.assertFalse(se1.spurious_edges()) self.assertEqual(edges, true_edges) diff --git a/PyCTBN/tests/estimators/test_structure_score_based_estimator.py b/PyCTBN/tests/estimators/test_structure_score_based_estimator.py index 8cbbcb5..407201e 100644 --- a/PyCTBN/tests/estimators/test_structure_score_based_estimator.py +++ b/PyCTBN/tests/estimators/test_structure_score_based_estimator.py @@ -111,7 +111,8 @@ class TestStructureScoreBasedEstimator(unittest.TestCase): tabu_length = 15, tabu_rules_duration = 15, optimizer = 'hill', - disable_multiprocessing=False + disable_multiprocessing=False, + processes_number=2 ) @@ -240,6 +241,7 @@ class TestStructureScoreBasedEstimator(unittest.TestCase): self.assertGreaterEqual(recall,0.75) + if __name__ == '__main__': unittest.main()