77from collections import OrderedDict
88import importlib .resources as importlib_resources
99
10- from typing import Any , Union , Callable
10+ from typing import Any , Union , Callable , List , Optional
1111
1212import pandas as pd
1313from mako .template import Template
@@ -124,7 +124,7 @@ def generate_fig(self):
124124 elif isinstance (fig , plot_common_access_table .DarshanReportTable ):
125125 # retrieve html table from `DarshanReportTable`
126126 self .fig_html = fig .html
127- else :
127+ elif fig is not None :
128128 err_msg = f"Figure of type { type (fig )} not supported."
129129 raise NotImplementedError (err_msg )
130130
@@ -137,21 +137,24 @@ class ReportData:
137137 ----------
138138 log_path: path to a darshan log file.
139139 enable_dxt_heatmap: flag indicating whether DXT heatmaps should be enabled
140+ filter_patterns: regex patterns for names to exclude/include
141+ filter_mode: whether to "exclude" or "include" the filter patterns
140142
141143 """
142- def __init__ (self , log_path : str , enable_dxt_heatmap : bool = False ):
144+ def __init__ (self , log_path : str , enable_dxt_heatmap : bool = False ,
145+ filter_patterns : Optional [List [str ]] = None , filter_mode : str = "exclude" ):
143146 # store the log path and use it to generate the report
144147 self .log_path = log_path
145148 self .enable_dxt_heatmap = enable_dxt_heatmap
146149 # store the report
147150 self .report = darshan .DarshanReport (log_path , read_all = False )
148151 # read only generic module data and heatmap data by default
149- self .report .read_all_generic_records ()
152+ self .report .read_all_generic_records (filter_patterns = filter_patterns , filter_mode = filter_mode )
150153 if "HEATMAP" in self .report .data ['modules' ]:
151154 self .report .read_all_heatmap_records ()
152155 # if DXT heatmaps requested, additionally read-in DXT data
153156 if self .enable_dxt_heatmap :
154- self .report .read_all_dxt_records ()
157+ self .report .read_all_dxt_records (filter_patterns = filter_patterns , filter_mode = filter_mode )
155158 # create the header/footer
156159 self .get_header ()
157160 self .get_footer ()
@@ -496,7 +499,11 @@ def register_figures(self):
496499 elif "PNETCDF_FILE" in self .report .modules :
497500 opcounts_mods .append ("PNETCDF_FILE" )
498501
499- for mod in self .report .modules :
502+ for mod in self .report .records :
503+ # skip over modules with no records -- this likely means
504+ # records in the log were filtered out via name exclusions
505+ if len (self .report .records [mod ]) == 0 :
506+ continue
500507
501508 if "H5" in mod :
502509 sect_title = "Per-Module Statistics: HDF5"
@@ -633,6 +640,12 @@ def build_sections(self):
633640 """
634641 self .sections = {}
635642 for fig in self .figures :
643+ # skip empty figures that can be generated by report sections
644+ # "Data Access by Category" and "Cross-Module Comparisons"
645+ if (fig .fig_html == None and
646+ (fig .section_title == "Data Access by Category" or
647+ fig .section_title == "Cross-Module Comparisons" )):
648+ continue
636649 # if a section title is not already in sections, add
637650 # the section title and a corresponding empty list
638651 # to store its figures
@@ -669,6 +682,16 @@ def setup_parser(parser: argparse.ArgumentParser):
669682 action = "store_true" ,
670683 help = "Enable DXT-based versions of I/O activity heatmaps."
671684 )
685+ parser .add_argument (
686+ "--exclude_names" ,
687+ action = 'append' ,
688+ help = "regex patterns for file record names to exclude in summary report"
689+ )
690+ parser .add_argument (
691+ "--include_names" ,
692+ action = 'append' ,
693+ help = "regex patterns for file record names to include in summary report"
694+ )
672695
673696
674697def main (args : Union [Any , None ] = None ):
@@ -687,6 +710,17 @@ def main(args: Union[Any, None] = None):
687710
688711 log_path = args .log_path
689712 enable_dxt_heatmap = args .enable_dxt_heatmap
713+ filter_patterns = None
714+ filter_mode = "exclude"
715+ if args .exclude_names and args .include_names :
716+ print ('Error: only one of --exclude_names and --include_names may be used.' )
717+ sys .exit (1 )
718+ elif args .exclude_names :
719+ filter_patterns = args .exclude_names
720+ filter_mode = "exclude"
721+ elif args .include_names :
722+ filter_patterns = args .include_names
723+ filter_mode = "include"
690724
691725 if args .output is None :
692726 # if no output is provided, use the log file
@@ -699,7 +733,9 @@ def main(args: Union[Any, None] = None):
699733 # collect the report data to feed into the template
700734 report_data = ReportData (
701735 log_path = log_path ,
702- enable_dxt_heatmap = enable_dxt_heatmap
736+ enable_dxt_heatmap = enable_dxt_heatmap ,
737+ filter_patterns = filter_patterns ,
738+ filter_mode = filter_mode
703739 )
704740
705741 with importlib_resources .path (darshan .cli , "base.html" ) as base_path :
0 commit comments