From af255df5eedfd1ad4ffd157a87ea0681d3cfd19a Mon Sep 17 00:00:00 2001 From: Gibraan Rahman Date: Wed, 16 Oct 2024 18:40:22 -0700 Subject: [PATCH 1/4] Add logger to init --- src/__init__.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/__init__.py b/src/__init__.py index 64870d6..055fe99 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -1,4 +1,5 @@ """Main __init__.py for the ppopt package""" +import logging import os os.environ["OMP_NUM_THREADS"] = "1" # export OMP_NUM_THREADS=1 @@ -6,3 +7,9 @@ os.environ["MKL_NUM_THREADS"] = "1" # export MKL_NUM_THREADS=1 os.environ["VECLIB_MAXIMUM_THREADS"] = "1" # export VECLIB_MAXIMUM_THREADS=1 os.environ["NUMEXPR_NUM_THREADS"] = "1" # export NUMEXPR_NUM_THREADS=1 + +logger = logging.getLogger(__name__) +logger.setLevel(logging.INFO) + +sh = logging.StreamHandler() +logger.addHandler(sh) From 347214752743f6844d929ae325cb6c27a5622e8c Mon Sep 17 00:00:00 2001 From: Gibraan Rahman Date: Wed, 16 Oct 2024 18:50:53 -0700 Subject: [PATCH 2/4] Replace most prints with logging calls --- src/ppopt/mp_solvers/mpqp_geometric.py | 5 ++++- src/ppopt/mp_solvers/mpqp_graph.py | 7 +++++-- .../mp_solvers/mpqp_parallel_combinatorial_exp.py | 13 ++++++++----- src/ppopt/mp_solvers/mpqp_parallel_geometric.py | 11 ++++++----- src/ppopt/mp_solvers/mpqp_parallel_geometric_exp.py | 11 +++++++---- .../mp_solvers/mpqp_parrallel_combinatorial.py | 13 ++++++++----- src/ppopt/mp_solvers/mpqp_parrallel_graph.py | 4 +++- src/ppopt/mp_solvers/solve_mpmiqp.py | 4 +++- src/ppopt/mplp_program.py | 5 ++++- src/ppopt/mpmilp_program.py | 5 ++++- src/ppopt/plot.py | 6 ++++-- 11 files changed, 56 insertions(+), 28 deletions(-) diff --git a/src/ppopt/mp_solvers/mpqp_geometric.py b/src/ppopt/mp_solvers/mpqp_geometric.py index 27009bf..44e1841 100644 --- a/src/ppopt/mp_solvers/mpqp_geometric.py +++ b/src/ppopt/mp_solvers/mpqp_geometric.py @@ -1,3 +1,4 @@ +import logging from ..mpqp_program import MPQP_Program from ..solution import Solution @@ -5,6 +6,8 @@ from ..utils.mpqp_utils import gen_cr_from_active_set from .solver_utils import fathem_facet, get_facet_centers +logger = logging.getLogger(__name__) + def solve(program: MPQP_Program, active_set=None) -> Solution: """ @@ -18,7 +21,7 @@ def solve(program: MPQP_Program, active_set=None) -> Solution: """ if active_set is None: active_set = program.gen_optimal_active_set() - print(f'Using a found active set {active_set}') + logger.info(f'Using a found active set {active_set}') initial_region = gen_cr_from_active_set(program, active_set, check_full_dim=False) diff --git a/src/ppopt/mp_solvers/mpqp_graph.py b/src/ppopt/mp_solvers/mpqp_graph.py index 82420dd..1301bae 100644 --- a/src/ppopt/mp_solvers/mpqp_graph.py +++ b/src/ppopt/mp_solvers/mpqp_graph.py @@ -1,4 +1,5 @@ from typing import List, Optional +import logging from ..mpqp_program import MPQP_Program from ..solution import Solution @@ -6,6 +7,8 @@ from ..utils.mpqp_utils import gen_cr_from_active_set from .solver_utils import CombinationTester, generate_extra, generate_reduce +logger = logging.getLogger(__name__) + def graph_initialization(program, initial_active_sets): """ @@ -28,9 +31,9 @@ def graph_initialization(program, initial_active_sets): to_attempt = [tuple(a_set) for a_set in initial_active_sets] if len(to_attempt) != 0: - print(f'First region {to_attempt[0]}') + logger.info(f'First region {to_attempt[0]}') else: - print('Failed to find an initial region!') + logger.warn('Failed to find an initial region!') return attempted, solution, murder_list, to_attempt diff --git a/src/ppopt/mp_solvers/mpqp_parallel_combinatorial_exp.py b/src/ppopt/mp_solvers/mpqp_parallel_combinatorial_exp.py index 3bab2be..fa263bf 100644 --- a/src/ppopt/mp_solvers/mpqp_parallel_combinatorial_exp.py +++ b/src/ppopt/mp_solvers/mpqp_parallel_combinatorial_exp.py @@ -1,3 +1,4 @@ +import logging import time from random import shuffle from typing import List, Tuple @@ -13,6 +14,8 @@ from ..utils.mpqp_utils import gen_cr_from_active_set from .solver_utils import generate_children_sets +logger = logging.getLogger(__name__) + def full_process(program: MPQP_Program, active_set: List[int]) -> Tuple[List[List[int]], List[CriticalRegion]]: """ @@ -78,7 +81,7 @@ def solve(program: MPQP_Program, num_cores=-1) -> Solution: if num_cores == -1: num_cores = num_cpu_cores() - print(f'Spawned threads across {num_cores}') + logger.debug(f'Spawned threads across {num_cores}') pool = Pool(num_cores) @@ -100,8 +103,8 @@ def solve(program: MPQP_Program, num_cores=-1) -> Solution: to_check.append(program.equality_indices) for i in range(max_depth): - print(f'Time at depth test {i + 1}, {time.time() - start}') - print(f'Number of active sets to be considered is {len(to_check)}') + logger.debug(f'Time at depth test {i + 1}, {time.time() - start}') + logger.debug(f'Number of active sets to be considered is {len(to_check)}') depth_time = time.time() @@ -113,7 +116,7 @@ def solve(program: MPQP_Program, num_cores=-1) -> Solution: outputs = pool.map(f, to_check) - print(f'Time to run all tasks in parallel {time.time() - depth_time}') + logger.debug(f'Time to run all tasks in parallel {time.time() - depth_time}') depth_time = time.time() for output in outputs: @@ -123,7 +126,7 @@ def solve(program: MPQP_Program, num_cores=-1) -> Solution: for region in output[1]: solution.add_region(region) - print(f'Time to process all depth outputs {time.time() - depth_time}') + logger.debug(f'Time to process all depth outputs {time.time() - depth_time}') to_check = future_list diff --git a/src/ppopt/mp_solvers/mpqp_parallel_geometric.py b/src/ppopt/mp_solvers/mpqp_parallel_geometric.py index daf0bfa..b34346b 100644 --- a/src/ppopt/mp_solvers/mpqp_parallel_geometric.py +++ b/src/ppopt/mp_solvers/mpqp_parallel_geometric.py @@ -1,4 +1,4 @@ - +import logging import numpy # noinspection PyProtectedMember @@ -10,6 +10,7 @@ from ..utils.mpqp_utils import gen_cr_from_active_set from .solver_utils import fathem_facet, get_facet_centers +logger = logging.getLogger(__name__) def full_process(center: numpy.ndarray, norm: numpy.ndarray, radius: float, program: MPQP_Program, current_active_set, indexed_region_as): @@ -47,18 +48,18 @@ def solve(program: MPQP_Program, active_set=None, num_cores=-1) -> Solution: """ if active_set is None: active_set = program.gen_optimal_active_set() - print(f'Using a found active set {active_set}') + logger.info(f'Using a found active set {active_set}') initial_region = gen_cr_from_active_set(program, active_set, check_full_dim=False) if initial_region is None: - print('Could not find a valid initial region') + logger.warn('Could not find a valid initial region') return Solution(program, []) if num_cores == -1: num_cores = num_cpu_cores() - print(f'Spawned threads across {num_cores}') + logger.debug(f'Spawned threads across {num_cores}') pool = Pool(num_cores) @@ -74,7 +75,7 @@ def solve(program: MPQP_Program, active_set=None, num_cores=-1) -> Solution: while len(work_items) > 0: - print(f' Number of Facets to look at this time {len(work_items)}') + logger.debug(f' Number of Facets to look at this time {len(work_items)}') f = lambda x: full_process(x[0], x[1], x[2], program, x[3], indexed_region_as) outputs = pool.map(f, work_items) diff --git a/src/ppopt/mp_solvers/mpqp_parallel_geometric_exp.py b/src/ppopt/mp_solvers/mpqp_parallel_geometric_exp.py index 12c4fc6..cf8dc55 100644 --- a/src/ppopt/mp_solvers/mpqp_parallel_geometric_exp.py +++ b/src/ppopt/mp_solvers/mpqp_parallel_geometric_exp.py @@ -1,4 +1,5 @@ from typing import List, Optional +import logging import numpy @@ -11,6 +12,8 @@ from ..utils.mpqp_utils import gen_cr_from_active_set from .solver_utils import get_facet_centers +logger = logging.getLogger(__name__) + def fathem_facet_exp(center: numpy.ndarray, normal: numpy.ndarray, radius: float, program, current_active_set: list) -> \ Optional[List[int]]: @@ -102,12 +105,12 @@ def solve(program: MPQP_Program, initial_active_sets: Optional[List[List[int]]] if initial_active_sets[-1] is None: raise ValueError('No Active Sets Found') - print(f'Using a found active set {initial_active_sets[-1]}') + logger.info(f'Using a found active set {initial_active_sets[-1]}') if num_cores == -1: num_cores = num_cpu_cores() - print(f'Spawned threads across {num_cores}') + logger.debug(f'Spawned threads across {num_cores}') pool = Pool(num_cores) @@ -131,7 +134,7 @@ def solve(program: MPQP_Program, initial_active_sets: Optional[List[List[int]]] while len(work_items) > 0: - print(f' Number of Facets to look at this time {len(work_items)}') + logger.debug(f' Number of Facets to look at this time {len(work_items)}') f = lambda x: fathem_facet_exp(x[0], x[1], x[2], program, x[3]) found_active_sets = pool.map(f, work_items) @@ -150,7 +153,7 @@ def solve(program: MPQP_Program, initial_active_sets: Optional[List[List[int]]] work_items = [] # process the outputs filtered_outputs = [output for output in outputs if output is not None] - print(f' Number of Regions adding in this pass {len(filtered_outputs)}!') + logger.debug(f' Number of Regions adding in this pass {len(filtered_outputs)}!') for output in filtered_outputs: diff --git a/src/ppopt/mp_solvers/mpqp_parrallel_combinatorial.py b/src/ppopt/mp_solvers/mpqp_parrallel_combinatorial.py index 9d6b7f4..a8e8a0e 100644 --- a/src/ppopt/mp_solvers/mpqp_parrallel_combinatorial.py +++ b/src/ppopt/mp_solvers/mpqp_parrallel_combinatorial.py @@ -1,6 +1,7 @@ import time from random import shuffle from typing import List, Optional, Set, Tuple +import logging # noinspection PyProtectedMember from pathos.multiprocessing import ProcessingPool as Pool @@ -13,6 +14,8 @@ from ..utils.mpqp_utils import gen_cr_from_active_set from .solver_utils import CombinationTester, generate_children_sets +logger = logging.getLogger(__name__) + def full_process(program: MPQP_Program, active_set: List[int], murder_list, gen_children) -> Tuple[Optional[CriticalRegion], Set[Tuple[int,...]], List[List[int]]]: """ @@ -82,7 +85,7 @@ def solve(program: MPQP_Program, num_cores=-1) -> Solution: if num_cores == -1: num_cores = num_cpu_cores() - print(f'Spawned threads across {num_cores}') + logger.debug(f'Spawned threads across {num_cores}') pool = Pool(num_cores) @@ -100,8 +103,8 @@ def solve(program: MPQP_Program, num_cores=-1) -> Solution: to_check.extend(root_node) for i in range(max_depth): - print(f'Time at depth test {i + 1}, {time.time() - start}') - print(f'Number of active sets to be considered is {len(to_check)}') + logger.debug(f'Time at depth test {i + 1}, {time.time() - start}') + logger.debug(f'Number of active sets to be considered is {len(to_check)}') depth_time = time.time() @@ -115,7 +118,7 @@ def solve(program: MPQP_Program, num_cores=-1) -> Solution: outputs = pool.map(f, to_check) - print(f'Time to run all tasks in parallel {time.time() - depth_time}') + logger.debug(f'Time to run all tasks in parallel {time.time() - depth_time}') depth_time = time.time() if i + 1 == max_depth: @@ -130,7 +133,7 @@ def solve(program: MPQP_Program, num_cores=-1) -> Solution: if output[0] is not None: solution.add_region(output[0]) - print(f'Time to process all depth outputs {time.time() - depth_time}') + logger.debug(f'Time to process all depth outputs {time.time() - depth_time}') to_check = future_list diff --git a/src/ppopt/mp_solvers/mpqp_parrallel_graph.py b/src/ppopt/mp_solvers/mpqp_parrallel_graph.py index ecfd07b..234dc87 100644 --- a/src/ppopt/mp_solvers/mpqp_parrallel_graph.py +++ b/src/ppopt/mp_solvers/mpqp_parrallel_graph.py @@ -1,4 +1,5 @@ from typing import List, Optional, Set, Tuple +import logging # noinspection PyProtectedMember from pathos.multiprocessing import ProcessingPool as Pool @@ -14,6 +15,7 @@ manufacture_lambda, ) +logger = logging.getLogger(__name__) def full_process(program, candidate, murder_list): """ @@ -99,7 +101,7 @@ def f(x): tiered_to_attempt[cursor] = [] cursor += 1 - print(f'Processing {len(to_attempt)} in this parallel swap') + logger.debug(f'Processing {len(to_attempt)} in this parallel swap') outputs = pool.map(f, to_attempt) for candidate in to_attempt: diff --git a/src/ppopt/mp_solvers/solve_mpmiqp.py b/src/ppopt/mp_solvers/solve_mpmiqp.py index aa237d1..004a159 100644 --- a/src/ppopt/mp_solvers/solve_mpmiqp.py +++ b/src/ppopt/mp_solvers/solve_mpmiqp.py @@ -1,4 +1,5 @@ from enum import Enum +import logging from ..mpmilp_program import MPMILP_Program from ..solution import Solution @@ -9,6 +10,7 @@ from ..utils.region_overlap_utils import reduce_overlapping_critical_regions_1d +logger = logging.getLogger(__name__) class mpmiqp_algorithm(Enum): """ @@ -36,7 +38,7 @@ def solve_mpmiqp(problem: MPMILP_Program, mpmiqp_algo: mpmiqp_algorithm = mpmiqp reduce_overlap=True) -> Solution: # the case of a continuous problem just solve it and return if len(problem.binary_indices) == 0: - print("The problem does not have any binary variables, solving as a continuous problem instead.") + logger.warn("The problem does not have any binary variables, solving as a continuous problem instead.") # noinspection PyTypeChecker return solve_mpqp(problem, cont_algo) diff --git a/src/ppopt/mplp_program.py b/src/ppopt/mplp_program.py index f403ed5..c2bb7e7 100644 --- a/src/ppopt/mplp_program.py +++ b/src/ppopt/mplp_program.py @@ -1,5 +1,6 @@ from typing import List, Optional, Tuple +import logging import numpy import warnings @@ -24,6 +25,8 @@ # noinspection GrazieInspection +logger = logging.getLogger(__name__) + class MPLP_Program: r""" The standard class for multiparametric linear programming @@ -101,7 +104,7 @@ def __init__(self, A, b, c, H, A_t, b_t, F, c_c=None, c_t=None, Q_t=None, equali # print warnings if there are any for warning in problem_warning: - warnings.warn(warning, UserWarning) + logger.warn(warning) # calls constraint processing to remove redundant constraints if post_process: diff --git a/src/ppopt/mpmilp_program.py b/src/ppopt/mpmilp_program.py index cd39032..ab38197 100644 --- a/src/ppopt/mpmilp_program.py +++ b/src/ppopt/mpmilp_program.py @@ -1,4 +1,5 @@ from typing import List, Optional +import logging import numpy @@ -8,6 +9,8 @@ from .utils.constraint_utilities import detect_implicit_equalities from .utils.general_utils import ppopt_block +logger = logging.getLogger(__name__) + class MPMILP_Program(MPLP_Program): # noinspection SpellCheckingInspection @@ -64,7 +67,7 @@ def __init__(self, A: numpy.ndarray, b: numpy.ndarray, c: numpy.ndarray, H: nump self.cont_indices = [i for i in range(self.num_x()) if i not in self.binary_indices] if len(self.cont_indices) == 0: - print("Pure Integer case is not considered here only the Mixed case!!!") + logger.warn("Pure Integer case is not considered here only the Mixed case!!!") if post_process: self.post_process() diff --git a/src/ppopt/plot.py b/src/ppopt/plot.py index bcecebc..224a06e 100644 --- a/src/ppopt/plot.py +++ b/src/ppopt/plot.py @@ -1,4 +1,5 @@ import time +import logging from math import atan2 from typing import List, Optional @@ -12,6 +13,7 @@ from .solver import Solver from .utils.general_utils import make_column +logger = logging.getLogger(__name__) def vertex_enumeration_2d(A: numpy.ndarray, b: numpy.ndarray, solver: Solver) -> List[numpy.ndarray]: """ @@ -120,7 +122,7 @@ def parametric_plot(solution: Solution, save_path: Optional[str] = None, show=Tr # check if the solution is actually 2 dimensional if solution.theta_dim() != 2: - print(f"Solution is not 2D, the dimensionality of the solution is {solution.theta_dim()}") + logger.error(f"Solution is not 2D, the dimensionality of the solution is {solution.theta_dim()}") return vertex_list = gen_vertices(solution) @@ -164,7 +166,7 @@ def parametric_plot_1D(solution: Solution, save_path: Optional[str] = None, show # check if the solution is actually 1 dimensional if solution.theta_dim() != 1: - print(f"Solution is not 1D, the dimensionality of the solution is {solution.theta_dim()}") + logger.error(f"Solution is not 1D, the dimensionality of the solution is {solution.theta_dim()}") return if plot_subset is None: From 84456264ea41ac7903ce55ab0f5353bbc20d2f6d Mon Sep 17 00:00:00 2001 From: Gibraan Rahman Date: Wed, 16 Oct 2024 19:09:13 -0700 Subject: [PATCH 3/4] Update logging location --- src/__init__.py | 7 ------- src/ppopt/__init__.py | 10 ++++++++++ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/__init__.py b/src/__init__.py index 055fe99..64870d6 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -1,5 +1,4 @@ """Main __init__.py for the ppopt package""" -import logging import os os.environ["OMP_NUM_THREADS"] = "1" # export OMP_NUM_THREADS=1 @@ -7,9 +6,3 @@ os.environ["MKL_NUM_THREADS"] = "1" # export MKL_NUM_THREADS=1 os.environ["VECLIB_MAXIMUM_THREADS"] = "1" # export VECLIB_MAXIMUM_THREADS=1 os.environ["NUMEXPR_NUM_THREADS"] = "1" # export NUMEXPR_NUM_THREADS=1 - -logger = logging.getLogger(__name__) -logger.setLevel(logging.INFO) - -sh = logging.StreamHandler() -logger.addHandler(sh) diff --git a/src/ppopt/__init__.py b/src/ppopt/__init__.py index c903f8b..eb6f30f 100644 --- a/src/ppopt/__init__.py +++ b/src/ppopt/__init__.py @@ -1,3 +1,4 @@ +import logging import os os.environ["OMP_NUM_THREADS"] = "1" # export OMP_NUM_THREADS=1 @@ -5,3 +6,12 @@ os.environ["MKL_NUM_THREADS"] = "1" # export MKL_NUM_THREADS=1 os.environ["VECLIB_MAXIMUM_THREADS"] = "1" # export VECLIB_MAXIMUM_THREADS=1 os.environ["NUMEXPR_NUM_THREADS"] = "1" # export NUMEXPR_NUM_THREADS=1 + +logger = logging.getLogger(__name__) +logger.setLevel(logging.INFO) + +sh = logging.StreamHandler() +formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') +sh.setFormatter(formatter) +sh.setLevel(logging.INFO) +logger.addHandler(sh) From 171067094a15f5c35f494e16fd891d3f131ed43b Mon Sep 17 00:00:00 2001 From: Gibraan Rahman Date: Wed, 16 Oct 2024 19:10:50 -0700 Subject: [PATCH 4/4] Change logger.warn -> logger.warning --- src/ppopt/mp_solvers/mpqp_graph.py | 2 +- src/ppopt/mp_solvers/mpqp_parallel_geometric.py | 2 +- src/ppopt/mp_solvers/solve_mpmiqp.py | 2 +- src/ppopt/mplp_program.py | 2 +- src/ppopt/mpmilp_program.py | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ppopt/mp_solvers/mpqp_graph.py b/src/ppopt/mp_solvers/mpqp_graph.py index 1301bae..8dda0f7 100644 --- a/src/ppopt/mp_solvers/mpqp_graph.py +++ b/src/ppopt/mp_solvers/mpqp_graph.py @@ -33,7 +33,7 @@ def graph_initialization(program, initial_active_sets): if len(to_attempt) != 0: logger.info(f'First region {to_attempt[0]}') else: - logger.warn('Failed to find an initial region!') + logger.warning('Failed to find an initial region!') return attempted, solution, murder_list, to_attempt diff --git a/src/ppopt/mp_solvers/mpqp_parallel_geometric.py b/src/ppopt/mp_solvers/mpqp_parallel_geometric.py index b34346b..2e1545f 100644 --- a/src/ppopt/mp_solvers/mpqp_parallel_geometric.py +++ b/src/ppopt/mp_solvers/mpqp_parallel_geometric.py @@ -53,7 +53,7 @@ def solve(program: MPQP_Program, active_set=None, num_cores=-1) -> Solution: initial_region = gen_cr_from_active_set(program, active_set, check_full_dim=False) if initial_region is None: - logger.warn('Could not find a valid initial region') + logger.warning('Could not find a valid initial region') return Solution(program, []) if num_cores == -1: diff --git a/src/ppopt/mp_solvers/solve_mpmiqp.py b/src/ppopt/mp_solvers/solve_mpmiqp.py index 004a159..ba43413 100644 --- a/src/ppopt/mp_solvers/solve_mpmiqp.py +++ b/src/ppopt/mp_solvers/solve_mpmiqp.py @@ -38,7 +38,7 @@ def solve_mpmiqp(problem: MPMILP_Program, mpmiqp_algo: mpmiqp_algorithm = mpmiqp reduce_overlap=True) -> Solution: # the case of a continuous problem just solve it and return if len(problem.binary_indices) == 0: - logger.warn("The problem does not have any binary variables, solving as a continuous problem instead.") + logger.warning("The problem does not have any binary variables, solving as a continuous problem instead.") # noinspection PyTypeChecker return solve_mpqp(problem, cont_algo) diff --git a/src/ppopt/mplp_program.py b/src/ppopt/mplp_program.py index c2bb7e7..bb66c29 100644 --- a/src/ppopt/mplp_program.py +++ b/src/ppopt/mplp_program.py @@ -104,7 +104,7 @@ def __init__(self, A, b, c, H, A_t, b_t, F, c_c=None, c_t=None, Q_t=None, equali # print warnings if there are any for warning in problem_warning: - logger.warn(warning) + logger.warning(warning) # calls constraint processing to remove redundant constraints if post_process: diff --git a/src/ppopt/mpmilp_program.py b/src/ppopt/mpmilp_program.py index ab38197..182e87c 100644 --- a/src/ppopt/mpmilp_program.py +++ b/src/ppopt/mpmilp_program.py @@ -67,7 +67,7 @@ def __init__(self, A: numpy.ndarray, b: numpy.ndarray, c: numpy.ndarray, H: nump self.cont_indices = [i for i in range(self.num_x()) if i not in self.binary_indices] if len(self.cont_indices) == 0: - logger.warn("Pure Integer case is not considered here only the Mixed case!!!") + logger.warning("Pure Integer case is not considered here only the Mixed case!!!") if post_process: self.post_process()