Skip to content

Commit

Permalink
#386: eliminate duplicated code in BruteForceAlgorithm and LBAF_App +…
Browse files Browse the repository at this point in the history
… use loaded `Object` instances instead of dictionaries
  • Loading branch information
tlamonthezie committed Jun 6, 2023
1 parent 48b37ec commit 4256bb0
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 64 deletions.
19 changes: 1 addition & 18 deletions src/lbaf/Applications/LBAF_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -364,24 +364,7 @@ def run(self):
and self.__parameters.algorithm["name"] != "BruteForce"):
# Prepare input data for rank order enumerator
self.__logger.info("Starting brute force optimization")
objects = []

# Iterate over ranks
for rank in initial_phase.get_ranks():
for o in rank.get_objects():
entry = {
"id": o.get_id(),
"load": o.get_load(),
"to": {},
"from": {}}
comm = o.get_communicator()
if comm:
for k, v in comm.get_sent().items():
entry["to"][k.get_id()] = v
for k, v in comm.get_received().items():
entry["from"][k.get_id()] = v
objects.append(entry)
objects.sort(key=lambda x: x.get("id"))
objects = initial_phase.get_objects()

# Execute rank order enumerator and fetch optimal arrangements
alpha, beta, gamma = [
Expand Down
18 changes: 1 addition & 17 deletions src/lbaf/Applications/rank_object_enumerator.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,23 +190,7 @@ def get_conf() -> dict:

# Get objects from log files
initial_phase = phases[min(phases.keys())]
objects = []
# Iterate over ranks
for rank in initial_phase.get_ranks():
for o in rank.get_objects():
entry = {
"id": o.get_id(),
"load": o.get_load(),
"to": {},
"from": {}}
comm = o.get_communicator()
if comm:
for k, v in comm.get_sent().items():
entry["to"][k.get_id()] = v
for k, v in comm.get_received().items():
entry["from"][k.get_id()] = v
objects.append(entry)
objects.sort(key=lambda x: x.get("id"))
objects = initial_phase.get_objects()

# Print out input parameters
root_logger.info(f"alpha: {alpha_g}")
Expand Down
27 changes: 5 additions & 22 deletions src/lbaf/Execution/lbsBruteForceAlgorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,21 +40,21 @@ def compute_arrangement_works(self, objects: tuple, arrangement: tuple) -> dict:
# Compute load component for current rank
values = {
"load":
sum([objects[i].get("load") for i in rank_object_ids])}
sum([objects[i].get_load() for i in rank_object_ids])}

# Compute received communication volume
v = 0.0
for i in rank_object_ids:
v += sum([
v for k, v in objects[i].get("from", 0.).items()
v for k, v in objects[i].get_communicator().get_received().items()
if k not in rank_object_ids])
values["received volume"] = v

# Compute sent communication volume
v = 0.0
for i in rank_object_ids:
v += sum([
v for k, v in objects[i].get("to", 0.).items()
v for k, v in objects[i].get_sent().items()
if k not in rank_object_ids])
values["sent volume"] = v

Expand All @@ -73,31 +73,14 @@ def execute(self, p_id: int, phases: list, distributions: dict, statistics: dict
self._logger.info("Starting brute force optimization")
objects = []

# Iterate over ranks
initial_phase = phases[min(phases.keys())]
phase_ranks = initial_phase.get_ranks()
for rank in phase_ranks:
for o in rank.get_objects():
entry = {
"id": o.get_id(),
"rank": rank,
"load": o.get_load(),
"to": {},
"from": {}}
comm = o.get_communicator()
if comm:
for k, v in comm.get_sent().items():
entry["to"][k.get_id()] = v
for k, v in comm.get_received().items():
entry["from"][k.get_id()] = v
objects.append(entry)
objects.sort(key=lambda x: x.get("id"))
objects = initial_phase.get_objects()

# Initialize quantities of interest
n_arrangements = 0
w_min_max = math.inf
a_min_max = []
n_ranks = len(phase_ranks)
n_ranks = len(initial_phase.get_ranks())

# Compute all possible arrangements with repetition and minimax work
for arrangement in itertools.product(range(n_ranks), repeat=len(objects)):
Expand Down
8 changes: 4 additions & 4 deletions src/lbaf/IO/lbsStatistics.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ def compute_volume(objects: tuple, rank_object_ids: list, direction: str) -> flo
volume = 0.

# Iterate over all rank objects
for i in rank_object_ids:
for _ in rank_object_ids:
volume += sum(v for (k, v) in getattr(objects[0], direction, {}).items() if k not in rank_object_ids)

# Return computed volume
Expand All @@ -172,7 +172,7 @@ def compute_load(objects: tuple, rank_object_ids: list) -> float:
"""Return a load as a sum of all object loads
"""

return sum([objects[i].get('load') for i in rank_object_ids])
return sum([objects[i].get_load() for i in rank_object_ids])


def compute_arrangement_works(objects: tuple, arrangement: tuple, alpha: float, beta: float, gamma: float) -> dict:
Expand All @@ -190,8 +190,8 @@ def compute_arrangement_works(objects: tuple, arrangement: tuple, alpha: float,
works[rank] = alpha * compute_load(objects, rank_objects)

# Compute communication volumes
works[rank] += beta * max(compute_volume(objects, rank_objects, "from"),
compute_volume(objects, rank_objects, "to"))
works[rank] += beta * max(compute_volume(objects, rank_objects, "received"),
compute_volume(objects, rank_objects, "sent"))

# Add constant
works[rank] += gamma
Expand Down
27 changes: 24 additions & 3 deletions src/lbaf/Model/lbsPhase.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,34 @@ def get_number_of_objects(self):
return sum([r.get_number_of_objects() for r in self.__ranks])

def get_objects(self):

"""Return all objects belonging to phase."""

# List comprehension is not possible as we need to use set to list concatenation
objects = []
for r in self.__ranks:
objects += r.get_objects()
for rank in self.__ranks:
objects += rank.get_objects()
objects.sort(key=lambda x: x.get_id())
return objects

def get_objects_dict(self):
"""Return all objects as dictionaries with `from` and `to` values retrieved from the object communicator"""

objects = []
for o in self.get_objects():
entry = {
"id": o.get_id(),
"rank": o.get_rank_id(),
"load": o.get_load(),
"to": {},
"from": {}}
comm = o.get_communicator()
if comm:
for k, v in comm.get_sent().items():
entry["to"][k.get_id()] = v
for k, v in comm.get_received().items():
entry["from"][k.get_id()] = v
objects.append(entry)
objects.sort(key=lambda x: x.get("id"))
return objects

def get_object_ids(self):
Expand Down

0 comments on commit 4256bb0

Please sign in to comment.