def __create_graph(self, rank, thread, list_roots, node_dicts): graph_data = self.dict["ranks"][str(rank)]["threads"][str( thread)]["regions"] for region, data in iter(graph_data.items()): # print(region, data) frame = Frame({"type": "region", "name": data["name"]}) node = Node(frame, None) contain_read_events = [0] metrics = self.__get_metrics(data, contain_read_events) node_dict = dict({ "name": data["name"], "node": node, "rank": int(rank), "thread": int(thread), **metrics, }) node_dicts.append(node_dict) # used to find node using parent_region_id self.node_graph_dict[int(region)] = [data["name"], node] if int(data["parent_region_id"]) == -1: list_roots.append(node) else: self.__add_child_node(int(data["parent_region_id"]), node) # check if we have to create child nodes for read events if contain_read_events[0] == 1: # check how many read calls are used read_num = len(data["cycles"]) for i in range(1, read_num): node_name_read = "read_" + str(i) read_frame = Frame({ "type": "region", "name": node_name_read }) read_node = Node(read_frame, node) read_metrics = self.__get_read_metrics( data, node_name_read) node_dict = dict({ "name": node_name_read, "node": read_node, "rank": int(rank), "thread": int(thread), **read_metrics, }) node_dicts.append(node_dict) node.add_child(read_node)
def _create_parent(child_node, parent_callpath): """In TAU output, sometimes we see a node as a parent in the callpath before we see it as a leaf node. In this case, we need to create a hatchet node for the parent. We can't create a node_dict for the parent because we don't know its metric values when we first see it in a callpath. Example: a => b => c "<c_metric_values>" Here, if we haven't seen 'b' before, we should create it when we create 'c'. This function recursively creates parent nodes in a callpath until it reaches the already existing parent in that callpath. """ parent_node = self.callpath_to_node.get(parent_callpath) # Return if arrives to the parent # Else create a parent and add parent/child if parent_node is not None: parent_node.add_child(child_node) child_node.add_parent(parent_node) return else: grand_parent_callpath = parent_callpath[:-1] parent_info = parent_callpath[-1] parent_name = "" if " C " in parent_info: parent_name = _get_name_file_module( True, parent_info, " C ")[0] elif " [@] " in parent_info: parent_name = _get_name_file_module( True, parent_info, " [@] ")[0] else: parent_name = _get_name_file_module(True, parent_info, "")[0] parent_node = Node( Frame({ "type": "function", "name": parent_name }), None) self.callpath_to_node[parent_callpath] = parent_node parent_node.add_child(child_node) child_node.add_parent(parent_node) _create_parent(parent_node, grand_parent_callpath)