Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#263: two modes or erroring out in lbaf #271

Merged
merged 6 commits into from
Jun 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/lbaf/Applications/LBAF_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from lbaf.IO.lbsMeshBasedVisualizer import MeshBasedVisualizer
import lbaf.IO.lbsStatistics as lbstats
from lbaf.Model.lbsPhase import Phase
from lbaf.Utils.exception_handler import exc_handler
from lbaf.Utils.logger import logger


Expand Down Expand Up @@ -79,9 +80,11 @@ def get_configuration_file(self, conf_file: str):
except yaml.MarkedYAMLError as err:
self.logger.error(f"Invalid YAML file {conf_file} in line {err.problem_mark.line} ({err.problem,} "
f"{err.context})")
sys.excepthook = exc_handler
raise SystemExit(1)
else:
self.logger.error(f"Configuration file in {conf_file} not found")
sys.excepthook = exc_handler
raise SystemExit(1)

def configuration_validation(self):
Expand All @@ -103,6 +106,7 @@ def parse_conf_file(self):
self.grid_size.append(gm.get(key))
if math.prod(self.grid_size) < self.n_ranks:
self.logger.error(f"Grid size: {self.grid_size} < {self.n_ranks}")
sys.excepthook = exc_handler
raise SystemExit(1)
self.object_jitter = gm.get("object_jitter")

Expand Down Expand Up @@ -268,6 +272,7 @@ def main(self):
objects, alpha, beta, gamma, self.params.n_ranks)
if n_a != self.params.n_ranks ** len(objects):
self.logger.error("Incorrect number of possible arrangements with repetition")
sys.excepthook = exc_handler
raise SystemExit(1)
self.logger.info(f"Minimax work: {w_min_max:.4g} for {len(a_min_max)} optimal arrangements amongst {n_a}")
else:
Expand Down
2 changes: 2 additions & 0 deletions src/lbaf/Applications/MoveCountsViewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

import vtk

from lbaf.Utils.exception_handler import exc_handler
from lbaf.Utils.logger import logger


Expand Down Expand Up @@ -423,6 +424,7 @@ def computeMoveCountsViewer(self):
# Instantiate parameters and set values from command line arguments
lgr.info("# Parsing command line arguments")
if params.parse_command_line():
sys.excepthook = exc_handler
raise SystemExit(1)

# Execute viewer
Expand Down
Empty file.
2 changes: 1 addition & 1 deletion src/lbaf/Applications/conf.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ algorithm:

# Specify output
#logging_level: debug
show_traceback: False
show_traceback: True
ppebay marked this conversation as resolved.
Show resolved Hide resolved
terminal_background: light
generate_multimedia: False
output_dir: ../../../output
Expand Down
5 changes: 5 additions & 0 deletions src/lbaf/Applications/rank_object_enumerator.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
raise SystemExit(1)

from lbaf.IO.lbsVTDataReader import LoadReader
from lbaf.Utils.exception_handler import exc_handler
from lbaf.Utils.logger import logger


Expand Down Expand Up @@ -114,9 +115,11 @@ def compute_pairwise_reachable_arrangements(objects: tuple, arrangement: tuple,
# Sanity checks regarding rank IDs
if from_id >= n_ranks:
LGR.error(f"Incorrect sender ID: {from_id} >= {n_ranks}")
sys.excepthook = exc_handler
raise SystemExit(1)
if to_id >= n_ranks:
LGR.error(f"Incorrect receiver ID: {to_id} >= {n_ranks}")
sys.excepthook = exc_handler
raise SystemExit(1)

# Provide upper bounder on transfer size when none provided
Expand Down Expand Up @@ -210,6 +213,7 @@ def recursively_compute_transitions(stack: list, visited: dict, objects: tuple,
w_a = visited.get(arrangement, -1.)
if w_a < 0.:
LGR.error(f"Arrangement {arrangement} not found in visited map")
sys.excepthook = exc_handler
raise SystemExit(1)

# Append current arrangement to trajectory stack
Expand Down Expand Up @@ -289,6 +293,7 @@ def get_conf() -> dict:
n_ranks=N_RANKS)
if n_a != N_RANKS ** len(objects):
LGR.error("Incorrect number of possible arrangements with repetition")
sys.excepthook = exc_handler
raise SystemExit(1)
LGR.info(f"Number of generated arrangements with repetition: {n_a}")
LGR.info(f"\tminimax work: {w_min_max:.4g} for {len(a_min_max)} optimal arrangements")
Expand Down
5 changes: 4 additions & 1 deletion src/lbaf/Execution/lbsAlgorithmBase.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
from logging import Logger
import sys

from ..IO.lbsStatistics import compute_function_statistics
from ..Model.lbsWorkModelBase import WorkModelBase
from ..Utils.exception_handler import exc_handler
from ..Utils.logger import logger
from ..IO.lbsStatistics import compute_function_statistics


LGR = logger
Expand All @@ -23,6 +24,7 @@ def __init__(self, work_model, parameters: dict):
# Assert that a work model base instance was passed
if not isinstance(work_model, WorkModelBase):
LGR().error("Could not create an algorithm without a work model")
sys.excepthook = exc_handler
raise SystemExit(1)
self.work_model = work_model

Expand All @@ -49,6 +51,7 @@ def factory(algorithm_name:str, parameters: dict, work_model, lgr: Logger):
except:
# Otherwise, error out
LGR().error(f"Could not create an algorithm with name {algorithm_name}")
sys.excepthook = exc_handler
raise SystemExit(1)

def update_distributions_and_statistics(self, distributions: dict, statistics: dict):
Expand Down
5 changes: 4 additions & 1 deletion src/lbaf/Execution/lbsBruteForceAlgorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
from logging import Logger

from .lbsAlgorithmBase import AlgorithmBase
from ..Model.lbsObjectCommunicator import ObjectCommunicator
from ..Model.lbsPhase import Phase
from ..Utils.exception_handler import exc_handler


class BruteForceAlgorithm(AlgorithmBase):
Expand Down Expand Up @@ -70,6 +70,7 @@ def execute(self, phases: list, distributions: dict, statistics: dict, _):
if not phases or not isinstance(phases, list) or not isinstance(
(phase := phases[0]), Phase):
self.__logger.error(f"Algorithm execution requires a Phase instance")
sys.excepthook = exc_handler
raise SystemExit(1)
self.phase = phase

Expand Down Expand Up @@ -124,9 +125,11 @@ def execute(self, phases: list, distributions: dict, statistics: dict, _):
# Sanity checks
if not len(a_min_max):
self.__logger.error("No optimal arrangements were found")
sys.excepthook = exc_handler
raise SystemExit(1)
if n_arrangements != n_ranks ** len(objects):
self.__logger.error("Incorrect number of possible arrangements with repetition")
sys.excepthook = exc_handler
raise SystemExit(1)
self.__logger.info(f"Minimax work: {w_min_max:.4g} for {len(a_min_max)} optimal arrangements amongst {n_arrangements}")

Expand Down
11 changes: 7 additions & 4 deletions src/lbaf/Execution/lbsCriterionBase.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
import sys

from ..Model.lbsWorkModelBase import WorkModelBase
from ..Utils.exception_handler import exc_handler
from ..Utils.logger import logger


LGR = logger()
LGR = logger


class CriterionBase:
Expand All @@ -21,12 +22,13 @@ def __init__(self, work_model):

# Assert that a work model base instance was passed
if not isinstance(work_model, WorkModelBase):
LGR.error("Could not create a criterion without a work model")
LGR().error("Could not create a criterion without a work model")
sys.excepthook = exc_handler
raise SystemExit(1)
self.work_model = work_model

# Criterion keeps internal references to ranks and edges
LGR.debug(f"Created base criterion with {str(type(work_model)).split('.')[-1][:-2]} work model")
LGR().debug(f"Created base criterion with {str(type(work_model)).split('.')[-1][:-2]} work model")

@staticmethod
def factory(criterion_name, work_model, lgr: Logger):
Expand All @@ -44,7 +46,8 @@ def factory(criterion_name, work_model, lgr: Logger):
return criterion(work_model, lgr=lgr)
except:
# Otherwise, error out
LGR.error(f"Could not create a criterion with name {criterion_name}")
LGR().error(f"Could not create a criterion with name {criterion_name}")
sys.excepthook = exc_handler
raise SystemExit(1)

@abc.abstractmethod
Expand Down
11 changes: 9 additions & 2 deletions src/lbaf/Execution/lbsInformAndTransferAlgorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from ..Model.lbsPhase import Phase
from ..IO.lbsStatistics import compute_function_statistics, print_function_statistics, inverse_transform_sample, \
min_Hamming_distance
from ..Utils.exception_handler import exc_handler


class InformAndTransferAlgorithm(AlgorithmBase):
Expand All @@ -33,15 +34,18 @@ def __init__(self, work_model, parameters: dict, lgr: Logger):
if not isinstance(self.__n_iterations, int) or self.__n_iterations < 0:
self.__logger.error(
f"Incorrect provided number of algorithm iterations: {self.__n_iterations}")
sys.excepthook = exc_handler
raise SystemExit(1)
self.__n_rounds = parameters.get("n_rounds")
if not isinstance(self.__n_rounds, int) or self.__n_rounds < 0:
self.__logger.error(
f"Incorrect provided number of information rounds: {self.__n_rounds}")
sys.excepthook = exc_handler
raise SystemExit(1)
self.__fanout = parameters.get("fanout")
if not isinstance(self.__fanout, int) or self.__fanout < 0:
self.__logger.error(f"Incorrect provided information fanout {self.__fanout}")
sys.excepthook = exc_handler
raise SystemExit(1)
self.__logger.info(
f"Instantiated with {self.__n_iterations} iterations, {self.__n_rounds} rounds, fanout {self.__fanout}")
Expand All @@ -59,6 +63,7 @@ def __init__(self, work_model, parameters: dict, lgr: Logger):
if o_s not in self.__strategy_mapped:
self.__logger.error(f"{o_s} does not exist in known ordering strategies: "
f"{[x for x in self.__strategy_mapped.keys()]}")
sys.excepthook = exc_handler
raise SystemExit(1)
self.__order_strategy = self.__strategy_mapped[o_s]
self.__logger.info(f"Selected {self.__order_strategy.__name__} object ordering strategy")
Expand All @@ -70,6 +75,7 @@ def __init__(self, work_model, parameters: dict, lgr: Logger):
lgr=self.__logger)
if not self.__transfer_criterion:
self.__logger.error(f"Could not instantiate a transfer criterion of type {self.__criterion_name}")
sys.excepthook = exc_handler
raise SystemExit(1)

# Assign optional parameters
Expand Down Expand Up @@ -264,6 +270,7 @@ def transfer_stage(self):
# Sanity check before transfer
if p_dst not in p_src.get_known_loads():
self.__logger.error(f"Destination rank {p_dst.get_id()} not in known ranks")
sys.excepthook = exc_handler
raise SystemExit(1)

# Transfer objects
Expand All @@ -288,9 +295,9 @@ def transfer_stage(self):
def execute(self, phases: list, distributions: dict, statistics: dict, a_min_max):
""" Execute 2-phase gossip+transfer algorithm on Phase instance."""
# Ensure that a list with at least one phase was provided
if not phases or not isinstance(phases, list) or not isinstance(
(phase := phases[0]), Phase):
if not phases or not isinstance(phases, list) or not isinstance((phase := phases[0]), Phase):
self.__logger.error(f"Algorithm execution requires a Phase instance")
sys.excepthook = exc_handler
raise SystemExit(1)
self.phase = phase

Expand Down
3 changes: 3 additions & 0 deletions src/lbaf/Execution/lbsPhaseStepperAlgorithm.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
from logging import Logger
import sys

from .lbsAlgorithmBase import AlgorithmBase
from ..Model.lbsPhase import Phase
from ..IO.lbsStatistics import print_function_statistics
from ..Utils.exception_handler import exc_handler


class PhaseStepperAlgorithm(AlgorithmBase):
Expand All @@ -27,6 +29,7 @@ def execute(self, phases: list, distributions: dict, statistics: dict, _):
if not phases or not isinstance(phases, list) or not all(
[isinstance(p, Phase) for p in phases]):
self.__logger.error(f"Algorithm execution requires a Phase instance")
sys.excepthook = exc_handler
raise SystemExit(1)

# Iterate over all phases
Expand Down
4 changes: 3 additions & 1 deletion src/lbaf/Execution/lbsRuntime.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import sys
from logging import Logger

from ..Model.lbsPhase import Phase
from ..Model.lbsWorkModelBase import WorkModelBase
from ..Execution.lbsAlgorithmBase import AlgorithmBase
from ..IO.lbsStatistics import print_function_statistics, compute_function_statistics, min_Hamming_distance
from ..Utils.exception_handler import exc_handler


class Runtime:
Expand All @@ -29,6 +29,7 @@ def __init__(self, phases: list, work_model: dict, algorithm: dict, arrangements
# If no LBS phase was provided, do not do anything
if not phases or not isinstance(phases, list):
self.__logger.error("Could not create a LBS runtime without a list of phases")
sys.excepthook = exc_handler
raise SystemExit(1)
self.__phases = phases

Expand All @@ -46,6 +47,7 @@ def __init__(self, phases: list, work_model: dict, algorithm: dict, arrangements
lgr=self.__logger)
if not self.__algorithm:
self.__logger.error(f"Could not instantiate an algorithm of type {self.__algorithm}")
sys.excepthook = exc_handler
raise SystemExit(1)

# Initialize run distributions and statistics
Expand Down
6 changes: 5 additions & 1 deletion src/lbaf/IO/lbsVTDataReader.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from ..Model.lbsObject import Object
from ..Model.lbsObjectCommunicator import ObjectCommunicator
from ..Model.lbsRank import Rank
from ..Utils.exception_handler import exc_handler


class LoadReader:
Expand Down Expand Up @@ -51,7 +52,8 @@ def read(self, node_id: int, phase_id: int = -1, comm: bool = False) -> tuple:
file_name = self.get_node_trace_file_name(node_id)
self.__logger.info(f"Reading {file_name} VT object map")
if not os.path.isfile(file_name):
raise FileNotFoundError(f"File {file_name} not found!")
sys.excepthook = exc_handler
raise FileNotFoundError(f"File {file_name} not found")

# Retrieve communications from JSON reader
iter_map = {}
Expand Down Expand Up @@ -87,6 +89,7 @@ def read_iteration(self, n_p: int, phase_id: int) -> list:
except KeyError as e:
msg_err = f"Could not retrieve information for rank {p} at time_step {phase_id}. KeyError {e}"
self.__logger.error(msg_err)
sys.excepthook = exc_handler
raise KeyError(msg_err)

# Merge rank communication with existing ones
Expand Down Expand Up @@ -136,6 +139,7 @@ def json_reader(self, returned_dict: dict, file_name: str, phase_ids, node_id: i
# Extracting type from JSON data
schema_type = decompressed_dict.get("type")
if schema_type is None:
sys.excepthook = exc_handler
raise TypeError("JSON data is missing 'type' key")

# Validate schema
Expand Down
2 changes: 2 additions & 0 deletions src/lbaf/IO/schemaValidator.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import sys

from schema import And, Optional, Schema
from ..Utils.exception_handler import exc_handler


class SchemaValidator:
Expand Down Expand Up @@ -257,6 +258,7 @@ def _get_valid_schema(self) -> Schema:
elif self.schema_type == "LBStatsfile":
return valid_schema_stats

sys.excepthook = exc_handler
raise TypeError(f"Unsupported schema type: {self.schema_type} was given")

def is_valid(self, schema_to_validate: dict) -> bool:
Expand Down
8 changes: 8 additions & 0 deletions src/lbaf/Model/lbsObject.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import sys

from .lbsObjectCommunicator import ObjectCommunicator
from ..Utils.exception_handler import exc_handler


class Object:
Expand All @@ -7,12 +10,14 @@ class Object:
def __init__(self, i: int, t: float, p: int = None, c: ObjectCommunicator = None, user_defined: dict = None):
# Object index
if not isinstance(i, int) or isinstance(i, bool):
sys.excepthook = exc_handler
raise TypeError(f"i: {i} is type of {type(i)}! Must be <class 'int'>!")
else:
self.__index = i

# Time required to perform the work of this object
if not isinstance(t, float):
sys.excepthook = exc_handler
raise TypeError(f"t: {t} is type of {type(t)}! Must be <class 'float'>!")
else:
self.__time = t
Expand All @@ -21,18 +26,21 @@ def __init__(self, i: int, t: float, p: int = None, c: ObjectCommunicator = None
if bool(isinstance(p, int) or p is None) and not isinstance(p, bool):
self.__rank_id = p
else:
sys.excepthook = exc_handler
raise TypeError(f"p: {p} is type of {type(p)}! Must be <class 'int'>!")

# Communication graph of this object if defined
if isinstance(c, ObjectCommunicator) or c is None:
self.__communicator = c
else:
sys.excepthook = exc_handler
raise TypeError(f"c: {c} is type of {type(c)}! Must be <class 'ObjectCommunicator'>!")

# User defined fields
if isinstance(user_defined, dict) or user_defined is None:
self.__user_defined = user_defined
else:
sys.excepthook = exc_handler
raise TypeError(f"user_defined: {user_defined} is type of {type(user_defined)}! Must be <class 'dict'>!")

def __repr__(self):
Expand Down
Loading