diff --git a/dashboards/dashboard_walberla.py b/dashboards/dashboard_walberla.py index fef4cae169a8082fce2d9bb29e0a5fe0790bc3c0..433eb1033dacabd60960e58629b2f889f9a85136 100644 --- a/dashboards/dashboard_walberla.py +++ b/dashboards/dashboard_walberla.py @@ -18,10 +18,10 @@ from dashboards.dashboard_base import ( get_grid_pos, pack_in_row, ) -from dashboards.influx_queries import join_variable_and, get_variable_condition_with_tag, get_variable_tag, join_conditions, get_variable_condition, get_variable_condition_without_regex -from dashboards.legends import Units +from dashboards.influx_queries import join_variable_and, get_variable_condition_with_tag, get_variable_tag, join_conditions, get_variable_condition, get_variable_condition_without_regex, get_variable_condition_unbounded +from dashboards.legends import Units, AxisLabel from dashboards.overrides import get_color_regex_override -from dashboards.panels import PanelInfos, get_time_series_panel, get_table_panel, get_bar_chart_panel +from dashboards.panels import PanelInfos, get_time_series_panel, get_table_panel, get_bar_chart_panel, get_pie_chart_panel from dashboards.variables import ( Filter, get_dashboard_variable, @@ -321,15 +321,6 @@ def dashboard_uniformgridcpu_relativeperformance(): Filter("BandwidthBenchmark", multi=False, default_value="bw_stream"), ] - fieldConfig = { - "defaults": { - "fieldMinMax": True, - "max": 1, - "unit": "percentunit" - }, - "overrides": [] - } - fields = [ PanelInfos("Relative Performance", Units.number, absthreshold=80), PanelInfos("Bandwidth", Units.number, absthreshold=80), @@ -731,3 +722,189 @@ def dashboard_fslbmgravitywave(): return build_dashboard( options, panels=panels, templating=filter_vars, annotations=annotations ) + + + +def dashboard_percolationgpu(): + data_source = "InfluxDB-1" + arch = "GPU" + measurment_name = f"Percolation{arch}" + measurment_name2 = f"Percolation{arch}_profile" + row_repeat = "GPU" + + options = DashboardOptions( + title="Percolation GPU", + description=f"Benchmark dashboard for the Percolation {arch} Benchmark from walberla", + tags=[arch, "walberla"], + timezone="browser", + ) + + filters = [ + Filter("host", multi=False), + Filter(row_repeat), + Filter("useParticles"), + ] + + fields = [ + PanelInfos("MLUPs", Units.mlups, absthreshold=80), + PanelInfos("Time Steps per Second", absthreshold=80), + PanelInfos("Performance Flops", Units.mflop_sec, absthreshold=80), + PanelInfos("Memory Bandwidth", Units.mbytes_per_second, absthreshold=80), + PanelInfos(r"/.*_average/ useParticles=$useParticles", Units.seconds), + PanelInfos(r"/.*_average/ useParticles=$useParticles", Units.seconds), + ] + + whereVariable = join_conditions([get_variable_condition_unbounded(filters[0].name)], "AND") + groupVariable = [filters[0].name] + + filter_vars = [ + get_dashboard_variable(filter, measurment_name, data_source) + for filter in filters[2:] + ] + filter_vars = [ + get_time_dependend_dashboard_variable( + filters[0], measurment_name, data_source, inner_field_key="MLUPS" + ), + get_time_dependend_dashboard_variable( + filters[1], measurment_name, data_source, inner_field_key="MLUPS", where=whereVariable, group_by=groupVariable + ), + *filter_vars + ] + + + annotations = get_commit_annotation( + data_source, "red", "commits", measurment_name) + + groups4 = ["LBM sweep", "Boundary", "Communication"] + colors4 = ["blue", "semi-dark-yellow", "semi-dark-purple"] + overrides4 = [ + get_color_regex_override(f"/{group}.*/", color, mode="fixed") + for group, color in zip(groups4, colors4) + ] + + + where = join_conditions([get_variable_condition_with_tag(filters[i].name) for i in range(3)], "AND") + + group_by_elements01 = ["GPU", "branch", "fluidCells", "host", "numParticles", "useParticles", "communicationHidingXWidth", "communicationHidingYWidth", "communicationHidingZWidth", "cores", "numXCellsPerBlock", "numYBlocks", "particleDiameter", "sendDirectlyFromGPU"] + group_by01 = [get_variable_tag(i) for i in group_by_elements01] + group_by23 = [get_variable_tag(i.name) for i in filters] + group_by4 = [get_variable_tag(i) for i in group_by_elements01] + + + selected_columns0 = ", ".join([ + '"MLUPS"']) + selected_columns1 = ", ".join([ + '"timeStepsPerSecond"']) + selected_columns2 = ", ".join([ + '"DP [MFlop/s]"']) + selected_columns3 = ", ".join([ + '"Memory bandwidth [MByte/s]"']) + selected_columns4 = ", ".join([ + '/.*_average/']) + + + query0 = Query(select_=selected_columns0, + from_=measurment_name, + where_=where, + group_by=group_by01, + from_string=not is_regex(measurment_name), + select_string=False) + query1 = Query(select_=selected_columns1, + from_=measurment_name, + where_=where, + group_by=group_by01, + from_string=not is_regex(measurment_name), + select_string=False) + query2 = Query(select_=selected_columns2, + from_=measurment_name2, + where_=where, + group_by=group_by23, + from_string=not is_regex(measurment_name2), + select_string=False) + query3 = Query(select_=selected_columns3, + from_=measurment_name2, + where_=where, + group_by=group_by23, + from_string=not is_regex(measurment_name2), + select_string=False) + query4 = Query(select_=selected_columns4, + from_=measurment_name, + where_=where, + group_by=group_by4, + from_string=not is_regex(measurment_name), + select_string=False) + + + panels = [ + # Panel 0 + get_time_series_panel( + fields[0], + data_source, + [query0], + pointSize=5, + thresholdsStyleMode='off', + gridPos=get_grid_pos(13, 9, 0, 0), + ), + # Panel 1 + get_time_series_panel( + fields[1], + data_source, + [query1], + pointSize=5, + thresholdsStyleMode='off', + gridPos=get_grid_pos(13, 8, 9, 0), + ), + # Panel 2 + get_time_series_panel( + fields[2], + data_source, + [query2], + pointSize=5, + thresholdsStyleMode='off', + gridPos=get_grid_pos(12, 9, 0, 14), + ), + # Panel 3 + get_time_series_panel( + fields[3], + data_source, + [query3], + pointSize=5, + thresholdsStyleMode='off', + gridPos=get_grid_pos(12, 9, 9, 14), + ), + # Panel 4 + get_pie_chart_panel( + fields[4], + data_source, + [query4], + gridPos=get_grid_pos(13, 12, 0, 27), + repeat=Repeat("h", filters[2].name), + overrides=overrides4, + ), + ] + + + # Rows + row_repeat_var = [fv for fv in filter_vars if fv.name == row_repeat][0] + + row0 = pack_in_row( + title=f"MLUPS and Time Steps per Second", + panels=panels[0:2], + ) + + row1 = pack_in_row( + title="Profiling", + panels=panels[2:4], + ) + + row2 = pack_in_row( + title=f"Distribution ${row_repeat_var.name}", + panels=panels[4:5], + repeat=Repeat("v", row_repeat_var.name), + ) + + rows = [row0, row1, row2] + + return build_dashboard( + options, rows=rows, templating=filter_vars, annotations=annotations + ) \ No newline at end of file diff --git a/dashboards/deploy.py b/dashboards/deploy.py index f703d23c656b8ad9422d0d9526555b0ac77778bd..5b68f8af570ec74de3390e95ce817c79369633c1 100644 --- a/dashboards/deploy.py +++ b/dashboards/deploy.py @@ -5,7 +5,7 @@ import dashboards.dashboard_list as boards from dashboards.upload import upload_dashboard from dashboards.dashboard_fe2ti import dashboard_fe2ti from dashboard_pystencils import dashboard_pystencils_cpu, dashboard_pystencils_gpu -from dashboard_walberla import dashboard_uniformgridcpu, dashboard_uniformgridgpu, dashboard_uniformgridgpu_profile, dashboard_fslbmgravitywave +from dashboard_walberla import dashboard_uniformgridcpu, dashboard_uniformgridgpu, dashboard_uniformgridgpu_profile, dashboard_fslbmgravitywave, dashboard_uniformgridcpu_relativeperformance, dashboard_percolationgpu logger = logging.getLogger(__file__) logger.setLevel(logging.INFO) @@ -46,6 +46,8 @@ def main(): upload_dashboard(dashboard_uniformgridgpu(), folder=walberla_folder) upload_dashboard(dashboard_uniformgridgpu_profile(), folder=walberla_folder) upload_dashboard(dashboard_fslbmgravitywave(), folder=walberla_folder) + upload_dashboard(dashboard_uniformgridcpu_relativeperformance(), folder=walberla_folder) + upload_dashboard(dashboard_percolationgpu(), folder=walberla_folder) else: board = getattr(boards, board_name) upload_dashboard(board(), folder=walberla_folder) diff --git a/dashboards/influx_queries.py b/dashboards/influx_queries.py index cc7045ae35b925094a85c1875fcfafa4aa6aeb9d..59d90be43cd0243dc2c066f937ef10a83e649a4c 100644 --- a/dashboards/influx_queries.py +++ b/dashboards/influx_queries.py @@ -57,12 +57,24 @@ def show_tag_values(table: str, key_name: str) -> str: return f'{base} {from_part}WITH key = "{key_name}"' -def get_tag_values(table: str, key_name: str, *, inner_field_key="") -> str: +def get_tag_values(table: str, key_name: str, *, inner_field_key="", where="", + group_by=None) -> str: + if group_by is None: + group_by = [key_name] + + where_clause = "$timeFilter" + if where: + where_clause = where + inner_select = "*" if inner_field_key != "": inner_select = f'"{inner_field_key}", "{key_name}"' - inner_query = f'SELECT {inner_select} FROM "{table}" WHERE $timeFilter' - return f'SELECT distinct("{key_name}") FROM ({inner_query}) GROUP BY {key_name}' + + inner_query = f'SELECT {inner_select} FROM "{table}" WHERE {where_clause}' + + group_by_clause = ", ".join(group_by) + + return f'SELECT distinct("{key_name}") FROM ({inner_query}) GROUP BY {group_by_clause}' def show_field_keys(table: str) -> str: @@ -86,6 +98,17 @@ def get_variable_condition(variable_name: str, *, tag_key: str = None) -> str: return f'"{clean_lhs}" =~ /^${{{clean_rhs}:regex}}$/' +def get_variable_condition_unbounded(variable_name: str, *, tag_key: str = None) -> str: + clean_rhs = variable_name.strip() + if tag_key: + clean_lhs = tag_key.strip() + else: + clean_lhs = clean_rhs + if not clean_rhs: + raise ValueError("Empty variable name") + return f'"{clean_lhs}" =~ /${{{clean_rhs}:regex}}/' + + def get_variable_condition_with_tag(variable_name: str, *, tag_key: str = None) -> str: clean_rhs = variable_name.strip() if tag_key: diff --git a/dashboards/legends.py b/dashboards/legends.py index ddfd690ea4a1dc2293d2761cf619337574c4fe60..b71d165752cc431f3d6f034ad8cca69f1757a0fa 100644 --- a/dashboards/legends.py +++ b/dashboards/legends.py @@ -14,6 +14,8 @@ class Units(str, Enum): flop_per_byte = 'Flop/Byte' mflop_sec = 'mflops' percent = 'percentunit' + mlups = 'MLUP/s' + none = '' class AxisLabel(str, Enum): diff --git a/dashboards/panels.py b/dashboards/panels.py index 7dd6dce50c429106a17497b1c81a634b2acba90d..b6f1c3b92b89a21fda35f2c80d3cccc98e986ea3 100644 --- a/dashboards/panels.py +++ b/dashboards/panels.py @@ -1,7 +1,7 @@ from dataclasses import dataclass, field # from collections import namedtuple from dashboards.influx_queries import Query -from grafanalib.core import TimeSeries, Text, Stat, Template, Repeat, Threshold, Table, BarChart +from grafanalib.core import TimeSeries, Text, Stat, Template, Repeat, Threshold, Table, BarChart, PieChartv2 from dashboards.dashboard_base import get_influx_target from dashboards.legends import Units from numbers import Number @@ -12,7 +12,7 @@ from numbers import Number @dataclass class PanelInfos: name: str - unit: Units + unit: Units = field(default=Units.none) absthreshold: Number = field(default=None) @@ -25,23 +25,32 @@ def get_time_series_panel(panel_infos: PanelInfos, query_list: list[Query], *, overrides=None, + pointSize: int = 9, **kwargs): targets = [get_influx_target(str(query)) for query in query_list] new_kwargs = {**kwargs} if panel_infos.absthreshold is not None: - new_kwargs.update({'thresholdType': 'absolute', - 'thresholds': [Threshold('green', 0, 0.0), - Threshold('red', index=1, value=float(panel_infos.absthreshold), op='lt'), ], - 'thresholdsStyleMode': 'line', - } - ) + if 'thresholdsStyleMode' not in new_kwargs: + new_kwargs.update({ + 'thresholdType': 'absolute', + 'thresholds': [Threshold('green', 0, 0.0), + Threshold('red', index=1, value=float(panel_infos.absthreshold), op='lt')], + 'thresholdsStyleMode': 'line' + }) + else: + new_kwargs.update({ + 'thresholdType': 'absolute', + 'thresholds': [Threshold('green', 0, 0.0), + Threshold('red', index=1, value=float(panel_infos.absthreshold), op='lt')] + }) + return TimeSeries( title=panel_infos.name, dataSource=data_source, targets=targets, unit=panel_infos.unit, - pointSize=9, + pointSize=pointSize, overrides=overrides, **new_kwargs, @@ -162,3 +171,43 @@ def get_bar_chart_panel(panel_infos: PanelInfos, **new_kwargs, ) + + +def get_pie_chart_panel(panel_infos: PanelInfos, + data_source: str, + query_list: list[Query], + *, + result_format_list: list[str] = None, + alias_list: list[str] = None, + transformations=[], + overrides=[], + **kwargs): + + targets = [get_influx_target(str(query)) for query in query_list] + new_kwargs = {**kwargs} + if panel_infos.absthreshold is not None: + if 'thresholdsStyleMode' not in new_kwargs: + new_kwargs.update({ + 'thresholdType': 'absolute', + 'thresholds': [Threshold('green', 0, 0.0), + Threshold('red', index=1, value=float(panel_infos.absthreshold), op='lt')], + 'thresholdsStyleMode': 'line' + }) + else: + new_kwargs.update({ + 'thresholdType': 'absolute', + 'thresholds': [Threshold('green', 0, 0.0), + Threshold('red', index=1, value=float(panel_infos.absthreshold), op='lt')] + }) + + + return PieChartv2( + title=panel_infos.name, + dataSource=data_source, + targets=targets, + transformations=transformations, + unit=panel_infos.unit, + overrides=overrides, + **new_kwargs, + + ) diff --git a/dashboards/variables.py b/dashboards/variables.py index 088aed7e13fc3b10159a32b3f0d6758df77b038b..8883865bae47b86e7428eecfdc3cf4675f67251a 100644 --- a/dashboards/variables.py +++ b/dashboards/variables.py @@ -33,9 +33,15 @@ def get_time_dependend_dashboard_variable( data_source: str, *, inner_field_key: str = "", + where: str = "", + group_by: list[str] = None ): query = get_tag_values( - measurment_name, filter.name, inner_field_key=inner_field_key + measurment_name, + filter.name, + inner_field_key=inner_field_key, + where=where, + group_by=group_by ) kwargs = { "includeAll": filter.multi,