Source code for gcpy.profile.vtune_utils

#!/usr/bin/env python3
"""
Utilities for displaying reports generated by the Intel VTune profiler.
"""

# Imports
import numpy as np
import pandas as pd
from gcpy.util import verify_variable_type

# Constants
DELIMITER = "\t"
LINES_PER_SCREEN = 30


[docs] def vtune_read_hotspots_csv( filename, delimiter=DELIMITER ): """ Reads a hotspot report (in CSV format) generated by Intel VTune. Parameters ---------- filename : str Hotspots report in CSV format. delimiter : str, optional Text separator. Default value: "\\t" (tab) Returns ------- report : pandas.DataFrame DataFrame with hotspot information. """ verify_variable_type(filename, str) report = pd.read_csv( filename, delimiter=delimiter, skipinitialspace=True, engine="c", dtype=str, ) if "CPU Time" in report.columns: report = report.rename(columns={"CPU Time": "CPU Time [s]"}) return report
[docs] def vtune_how_is_report_grouped( report ): """ Determines how a VTune hotspot report is grouped. Parameters ---------- report : pandas.DataFrame Hotspot report data. Returns ------- result : str Returns 'by_line' or 'by_function'. """ if "Source Line" in report.columns: return "by_line" if "Function" in report.columns: return "by_function" raise ValueError("Could not determine how report is grouped!")
[docs] def vtune_ask_user_to_continue_or_quit( header, linecount, lines_per_screen, ): """ Ask user if they wish to display more lines of VTune information to the screen, or if they wish to quit. Parameters ---------- header : str Header line for hotspot report. linecount : int Index of the line being displayed. lines_per_screen : int Pause after showing these many lines. Returns ------- result : bool True if user wishes to quit. """ if linecount % lines_per_screen == 0: result = input( "\nPress ENTER to continue, or Q/q then ENTER to quit >>> " ) # User wishes to quit if "Q" in result or "q" in result: return True # User wishes to continue print("") print(header) return False # Continue by default return False
[docs] def vtune_list_all_hotspots_by_line( report, lines_per_screen=LINES_PER_SCREEN ): """ Lists hotspots from an Intel VTune hotspot report that has been grouped by source code line. Parameters ---------- report : pandas.DataFrame Hotspot report from Intel VTune. lines_per_screen : int, optional Pause after showing these many lines. Default value: LINES_PER_SCREEN """ verify_variable_type(report, pd.DataFrame) # Crop the report to necessary columns report = report[["Source File", "Source Line", "CPU Time [s]"]] # Print column headers col = list(report.columns) header = f"Rank {col[0]:<30} {col[1]:>12} {col[2]:>20}" print(header) # Return each row of the DataFrame as a tuple for row in report.itertuples(): # Print each line linecount = row[0] + 1 cpu = float(row[3]) display = f"{linecount:<8} {row[1]:<30} {row[2]:>12} {cpu:>20.6f}" print(display) # After a certain number of lines, ask user if they want to # continue or quit. If quit, then break out of this loop # Ask user to continue/quit. If returns true, exit if vtune_ask_user_to_continue_or_quit( header, linecount, lines_per_screen ): break
[docs] def vtune_list_all_hotspots_by_function( report, lines_per_screen=LINES_PER_SCREEN ): """ Lists hotspots from an Intel VTune hotspot report that has been grouped by function. Parameters ---------- report : pandas.DataFrame Hotspot information data. lines_per_screen : int, optional Pause after showing these many lines. Default value: LINES_PER_SCREEN """ verify_variable_type(report, pd.DataFrame) # Crop the data to necessary columns report = report[["Function", "CPU Time [s]"]] # Print column headers col = list(report.columns) header = f"Rank {col[0]:<60} {col[1]:>20}" print(header) # Return each row of the DataFrame as a tuple for row in report.itertuples(): # Print each line linecount = row[0] + 1 display = f"{linecount:<8} {row[1]:<60} {float(row[2]):>20.6f}" print(display) # After a certain number of lines, ask user if they want to # continue or quit. If quit, then break out of this loop # Ask user to continue/quit. If returns true, exit if vtune_ask_user_to_continue_or_quit( header, linecount, lines_per_screen ): break
[docs] def vtune_list_all_hotspots( filename, delimiter=DELIMITER, lines_per_screen=LINES_PER_SCREEN ): """ Reads a hotspots report (in CSV format) generated by the Intel VTune profiler, and calls the proper function to display the results. Parameters ---------- filename : str File containing the hotspot report. delimiter : str, optional Text separator. Default value: "\\t" (tab) lines_per_screen : int, optional Pause after showing these many lines. Default value: LINES_PER_SCREEN """ verify_variable_type(filename, str) # Read the date into a DataFrame report= vtune_read_hotspots_csv( filename, delimiter=delimiter ) # Filename contains hotspot output by source code line if "by_line" in vtune_how_is_report_grouped(report): vtune_list_all_hotspots_by_line( report, lines_per_screen=lines_per_screen ) return # Filename contains hotspot output by functions if "by_function" in vtune_how_is_report_grouped(report): vtune_list_all_hotspots_by_function( report, lines_per_screen=lines_per_screen ) return # Throw an error msg = "Report is grouped neither by function nor by source line!" raise ValueError(msg)
[docs] def vtune_get_timing_info( ref_time, dev_time ): """ Computes timing information for a hotspot from two reports and returns a string for display. Parameters ---------- ref_time : str CPU Time [s] from the hotspot report for Ref. dev_time : str CPU Time [s] from the hotspot report for Dev. Returns ------- time_str : str String with timing information to display. """ ref_time = float(ref_time) dev_time = float(dev_time) abs_diff = dev_time - ref_time pct_diff = (abs_diff / ref_time) * 100.0 time_str = f"{ref_time:>12.5f} {dev_time:>12.5f} " time_str += f"{abs_diff:>12.5f} {pct_diff:>8.2f}" return time_str
[docs] def vtune_find_hotspot( report, column, hotspot_name ): """ Searches for a hotspot by name in a DataFrame column, Returns the relevant row of the DataFrame if found. Parameters ---------- report : pandas.DataFrame Hotspot report from Intel VTune. column : str Column to search. hotspot_name : str Name of the hotspot to look for. Returns ------- result : pandas.DataFrame Modified DataFrame object. """ verify_variable_type(report, pd.DataFrame) verify_variable_type(column, str) verify_variable_type(hotspot_name, str) index = report[column] == hotspot_name if not np.any(index): msg = f"Could not find {hotspot_name} in the '{column}' Series!" raise ValueError(msg) return report[index]
[docs] def vtune_compare_a_hotspot_by_line( ref_report, ref_label, dev_report, dev_label, hotspot_name, ref_line_number=None, dev_line_number=None, ): """ Compares a given hotspot in two different reports (grouped by source code line), and prints timing information. Parameters ---------- ref_report : pandas.DataFrame Hotspot report from the Ref model. ref_label : str Label for the Ref model. dev_report : pandas.DataFrame Hotspot report from the Dev model. dev_label : str Label for the Dev model. hotspot_name : str Name of the hotspot to search for. ref_line_number : str or int or None, optional Line number where hotspot occurs in Ref. Default value: None dev_line_number : str or int or None, optional Line number where hotspot occurs in Dev. Default value: None """ verify_variable_type(ref_report, pd.DataFrame) verify_variable_type(ref_label, str) verify_variable_type(dev_report, pd.DataFrame) verify_variable_type(dev_label, str) verify_variable_type(hotspot_name, str) def get_hotspot(report, hotspot_name, line_number): """ Returns info about a hotspot from a report (grouped by function). Parameters ---------- report : pandas.DataFrame Hotspot report from Intel VTune. hotspot_name : str Name of the hotspot to look up. line_number : str or int Line number where hotspot occurs. Returns ------- values : list [Rank, Hotspot Name, Line #, CPU Time]. """ # Error check if line_number is None: raise ValueError("Line number was not specified!") # Convert line number to string (for safety's sake) line_number = str(line_number) # Return the hotspot as a DataFrame with one row report = report[["Source File", "Source Line", "CPU Time [s]"]] report = vtune_find_hotspot(report, "Source File", hotspot_name) report = vtune_find_hotspot(report, "Source Line", line_number) # Return as list: [Rank, Hotspot Name, Source Line, CPU Time] values = report.iloc[0].tolist() return [report.index[0], values[0], values[1], values[2]] # Return hotspot info as Rank, Name, Line, CPU Time ref_hotspot = get_hotspot(ref_report, hotspot_name, ref_line_number) dev_hotspot = get_hotspot(dev_report, hotspot_name, dev_line_number) # Compute timing info and create a string for display time_str = vtune_get_timing_info(ref_hotspot[3], dev_hotspot[3]) # Print results print(f"\n{'Hotspot':<25} {ref_label[0:12]:>12} ", end="") print(f"{dev_label[0:12]:>12} {'Abs Diff':>12} {'% Diff':>8}") print(f"{ref_hotspot[1][0:25]:<25} ", end="") print(time_str)
[docs] def vtune_compare_a_hotspot_by_function( ref_report, ref_label, dev_report, dev_label, hotspot_name, ): """ Compares a given hotspot in two different reports (grouped by source code line), and prints timing information. Parameters ---------- ref_report : pandas.DataFrame Hotspot report from the Ref model. ref_label : str Label for the Ref model. dev_report : pandas.DataFrame Hotspot report from the Dev model. dev_label : str Label for the Dev model. hotspot_name : str Name of the hotspot to search for. """ verify_variable_type(ref_report, pd.DataFrame) verify_variable_type(ref_label, str) verify_variable_type(dev_report, pd.DataFrame) verify_variable_type(dev_label, str) verify_variable_type(hotspot_name, str) def get_hotspot(report, hotspot_name): """ Returns info about a hotspot from a report (grouped by function). Parameters ---------- report : pandas.DataFrame Hotspot report from Intel VTune. hotspot_name : str Name of the hotspot to look up. Returns ------- values : list [Rank, Hotspot Name, CPU Time]. """ # Return the hotspot as a DataFrame with one row report = report[["Function", "CPU Time [s]"]] report = vtune_find_hotspot(report, "Function", hotspot_name) # Return as list: [Rank, Hotspot Name, CPU Time] values = report.iloc[0].tolist() return [report.index[0], values[0], values[1]] # Return hotspot info as Rank, Name, Line, CPU Time ref_hotspot = get_hotspot(ref_report, hotspot_name) dev_hotspot = get_hotspot(dev_report, hotspot_name) # Compute timing info and create a string for display time_str = vtune_get_timing_info(ref_hotspot[2], dev_hotspot[2]) # Print results print(f"\n{'Hotspot':<25} {ref_label[0:12]:>12} ", end="") print(f"{dev_label[0:12]:>12} {'Abs Diff':>12} {'% Diff':>8}") print(f"{ref_hotspot[1][0:25]:<25} ", end="") print(time_str)
[docs] def vtune_compare_a_hotspot( ref_file, ref_label, dev_file, dev_label, hotspot_name, delimiter=DELIMITER, ref_line_number=None, dev_line_number=None, ): """ Compares a given hotspot in two different reports (grouped by source code line), and prints timing information. Parameters ---------- ref_file : str Hotspot report from the Ref model. ref_label : str Label for the Ref model. dev_file : str Hotspot report from the Dev model. dev_label : str Label for the Dev model. hotspot_name : str Name of the hotspot to search for. delimiter : str, optional Text separator. Default value: "\\t" (tab) ref_line_number : str or int or None, optional Line number where hotspot occurs in Ref. Default value: None dev_line_number : str or int or None, optional Line number where hotspot occurs in Dev. Default value: None """ verify_variable_type(ref_file, str) verify_variable_type(ref_label, str) verify_variable_type(dev_file, str) verify_variable_type(dev_label, str) verify_variable_type(hotspot_name, str) # Read Ref data and determine how it is grouped ref_report = vtune_read_hotspots_csv(ref_file, delimiter=delimiter) ref_grouped = vtune_how_is_report_grouped(ref_report) # Read Dev data and determine how it is grouped dev_report = vtune_read_hotspots_csv(dev_file, delimiter=delimiter) dev_grouped = vtune_how_is_report_grouped(dev_report) # Filename contains hotspot output by source code line if "by_line" in ref_grouped and "by_line" in dev_grouped: vtune_compare_a_hotspot_by_line( ref_report, ref_label, dev_report, dev_label, hotspot_name, ref_line_number=ref_line_number, dev_line_number=dev_line_number, ) return # Filename contains hotspot output by functions if "by_function" in ref_grouped and "by_function" in dev_grouped: vtune_compare_a_hotspot_by_function( ref_report, ref_label, dev_report, dev_label, hotspot_name, ) return # Throw an error msg = "Report is grouped neither by function nor by source line!" raise ValueError(msg)