Skip to content

Commit

Permalink
feat(PET): parallel computation of function metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
lukasrothenberger committed Nov 22, 2023
1 parent e63898a commit 8f04e70
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 21 deletions.
48 changes: 27 additions & 21 deletions discopop_explorer/PETGraphX.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from .parser import LoopData, readlineToCUIdMap, writelineToCUIdMap, DependenceItem
from .variable import Variable

global_pet = None

# unused
# node_props = [
Expand Down Expand Up @@ -362,6 +363,7 @@ def get_exit_cu_ids(self, pet: PETGraphX) -> Set[NodeID]:
return exit_cu_ids

def calculate_reachability_pairs(self, pet: PETGraphX):
reachability_pairs: Dict[NodeID, Set[NodeID]] = dict()
# create graph copy and remove all but successor edges
copied_graph = pet.g.copy()

Expand All @@ -376,10 +378,10 @@ def calculate_reachability_pairs(self, pet: PETGraphX):

# calculate dfs successors for children CUs
for node_id in cast(List[NodeID], self.children_cu_ids):
self.reachability_pairs[node_id] = {node_id}
reachability_pairs[node_id] = {node_id}
successors = [t for s, t in nx.dfs_tree(copied_graph, node_id).edges()]
self.reachability_pairs[node_id].update(successors)
pass
reachability_pairs[node_id].update(successors)
return reachability_pairs

def get_immediate_post_dominators(self, pet: PETGraphX) -> Dict[NodeID, NodeID]:
if self.immediate_post_dominators_present:
Expand Down Expand Up @@ -724,24 +726,28 @@ def calculateFunctionMetadata(self) -> None:
# store id of parent function in each node
# and store in each function node a list of all children ids
func_nodes = self.all_nodes(FunctionNode)
print("Calculating metadata for functions: ")
with alive_bar(len(func_nodes)) as progress_bar:
for func_node in func_nodes:
stack: List[Node] = self.direct_children(func_node)
func_node.children_cu_ids = [node.id for node in stack]

while stack:
child = stack.pop()
child.parent_function_id = func_node.id
children = self.direct_children(child)
func_node.children_cu_ids.extend([node.id for node in children])
stack.extend(children)

func_node.calculate_reachability_pairs(self)
progress_bar()
print("\tDone.")

print("Metadata calculation done.")
print("Calculating local metadata results for functions...")
import tqdm # type: ignore
from multiprocessing import Pool
from .parallel_utils import pet_function_metadata_initialize_worker, pet_function_metadata_parse_func

param_list = func_nodes
with Pool(initializer=pet_function_metadata_initialize_worker, initargs=(self,)) as pool:
tmp_result = list(
tqdm.tqdm(pool.imap_unordered(pet_function_metadata_parse_func, param_list), total=len(param_list))
)
# calculate global result
print("Calculating global result...")
global_reachability_dict: Dict[NodeID, Set[NodeID]] = dict()
for local_result in tmp_result:
parsed_function_id, local_reachability_dict, local_children_ids = local_result
# set reachability values to function nodes
cast(FunctionNode, self.node_at(parsed_function_id)).reachability_pairs = local_reachability_dict
# set parent function for visited nodes
for child_id in local_children_ids:
self.node_at(child_id).parent_function_id = parsed_function_id

print("\tMetadata calculation done.")

# cleanup dependencies (remove dependencies, if it is overwritten by a more specific Intra-iteration dependency
print("Cleaning duplicated dependencies...")
Expand Down
35 changes: 35 additions & 0 deletions discopop_explorer/parallel_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# This file is part of the DiscoPoP software (http://www.discopop.tu-darmstadt.de)
#
# Copyright (c) 2020, Technische Universitaet Darmstadt, Germany
#
# This software may be modified and distributed under the terms of
# the 3-Clause BSD License. See the LICENSE file in the package base
# directory for details.

from .PETGraphX import Node, NodeID
from typing import List, Set

global_pet = None


def pet_function_metadata_initialize_worker(pet):
global global_pet
global_pet = pet


def pet_function_metadata_parse_func(param_tuple):
func_node = param_tuple
stack: List[Node] = global_pet.direct_children(func_node)
func_node.children_cu_ids = [node.id for node in stack]
local_children: Set[NodeID] = set()

while stack:
child = stack.pop()
local_children.add(child.id)
children = global_pet.direct_children(child)
func_node.children_cu_ids.extend([node.id for node in children])
stack.extend(children)

local_reachability_dict = func_node.calculate_reachability_pairs(global_pet)
local_result = func_node.id, local_reachability_dict, local_children
return local_result

0 comments on commit 8f04e70

Please sign in to comment.