diff --git a/ci/complexity_measurements/check_for_changes.py b/ci/complexity_measurements/check_for_changes.py
index 50deb76e08202f6b83f2f5ee2afe7499af2cc866..2048feb04451f107a63afe02bb1932defb3a6e24 100644
--- a/ci/complexity_measurements/check_for_changes.py
+++ b/ci/complexity_measurements/check_for_changes.py
@@ -5,15 +5,17 @@ import sys
THRESH = 0.01
COLS = [
- [3, 5, 7, 9], # wmops_all
- [3,5,7,8,10,12,13,15,17], # ram_all
- [3,5,7,9,11,13,15,17,19], # rom_all
+ [3, 5, 7, 9], # wmops_all
+ [3, 5, 7, 8, 10, 12, 13, 15, 17], # ram_all
+ [3, 5, 7, 9, 11, 13, 15, 17, 19], # rom_all
]
def main(args):
linewise_logfiles = [args.wmops_logfile, args.ram_logfile, args.rom_logfile]
- changes_found_linewise = any([check_linewise_logfile(f, c) for f, c in zip(linewise_logfiles, COLS)])
+ changes_found_linewise = any(
+ [check_linewise_logfile(f, c) for f, c in zip(linewise_logfiles, COLS)]
+ )
if changes_found_linewise:
print("Global max of WMOPS, RAM or ROM changed")
diff --git a/ci/complexity_measurements/genWebpageData.py b/ci/complexity_measurements/genWebpageData.py
new file mode 100644
index 0000000000000000000000000000000000000000..457ca5ba934edfe6209e2c31cda2ace25a765917
--- /dev/null
+++ b/ci/complexity_measurements/genWebpageData.py
@@ -0,0 +1,449 @@
+#!/usr/bin/env python3
+"""
+(C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
+Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+contributors to this repository. All Rights Reserved.
+
+This software is protected by copyright law and by international treaties.
+The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
+Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+contributors to this repository retain full ownership rights in their respective contributions in
+the software. This notice grants no license of any kind, including but not limited to patent
+license, nor is any license granted by implication, estoppel or otherwise.
+
+Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
+contributions.
+
+This software is provided "AS IS", without any express or implied warranties. The software is in the
+development stage. It is intended exclusively for experts who have experience with such software and
+solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
+and fitness for a particular purpose are hereby disclaimed and excluded.
+
+Any dispute, controversy or claim arising under or in relation to providing this software shall be
+submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
+accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
+the United Nations Convention on Contracts on the International Sales of Goods.
+"""
+
+import argparse
+from typing import Optional
+
+
+MAX_VALUES = 40
+
+REF_WMOPS_EVS = 88
+REF_WMOPS_3EVS = 3 * REF_WMOPS_EVS
+REF_WMOPS_6EVS = 6 * REF_WMOPS_EVS
+REF_WMOPS_10EVS = 10 * REF_WMOPS_EVS
+
+REF_COLORS = ["#000000", "#666666", "#AAAAAA"]
+
+RUNS_KEYS_COMMON = ["fullDate", "shortDate", "revision", "logFile"]
+RUNS_KEYS_WMOPS = RUNS_KEYS_COMMON + [
+ "worstCaseEnc",
+ "worstCaseDec",
+ "worstCaseCodec",
+ "worstCaseEncRs",
+ "worstCaseDecRs",
+ "worstCaseCodecRs",
+ "fixpointScalingFac",
+]
+RUNS_KEYS_WMOPS_PER_OP = [
+ "operatingPoint",
+ "mode",
+]
+RUNS_KEYS_ROM = RUNS_KEYS_COMMON + [
+ "PromEnc",
+ "PromDec",
+ "PromCom",
+ "PromRend",
+ "TromEnc",
+ "TromDec",
+ "TromCom",
+ "TromRend",
+]
+RUNS_KEYS_RAM = RUNS_KEYS_COMMON + [
+ "maxTotalRamEnc",
+ "maxTotalRamDec",
+ "maxStackEnc",
+ "maxStackDec",
+ "maxHeapEnc",
+ "maxHeapDec",
+]
+
+RUNS_KEYS = {
+ "wmops": RUNS_KEYS_WMOPS,
+ "rom": RUNS_KEYS_ROM,
+ "ram": RUNS_KEYS_RAM,
+ "wmops_per_op": RUNS_KEYS_WMOPS_PER_OP,
+}
+RUNS_LINE_IDX = {
+ "wmops": [2, 1, 0, 4, 6, 8, 12, 14, 16, 10, 18],
+ "rom": [2, 1, 0, 4, 6, 8, 10, 12, 14, 16, 18, 20],
+ "ram": [2, 1, 0, 4, 6, 9, 11, 14, 16, 18],
+ "wmops_per_op": [0, 4],
+}
+
+DISPLAY_IDS = {
+ "wmops": [
+ "3xEVS",
+ "6xEVS",
+ "10xEVS",
+ "worst case codec",
+ "worst case enc/dec",
+ "worst case enc",
+ "worst case dec",
+ ],
+ "rom": [
+ "requirementRom",
+ "TotalRomCodecScore",
+ "maxPROMEncScore",
+ "maxPROMDecScore",
+ "maxPROMComScore",
+ "maxPROMRendScore",
+ "maxTROMEncScore",
+ "maxTROMDecScore",
+ "maxTROMComScore",
+ "maxTROMRendScore",
+ ],
+ "ram": [
+ "requirementRam",
+ "maxTotalRamCodecScore",
+ "maxTotalRamEncScore",
+ "maxTotalRamDecScore",
+ "maxStackCodecScore",
+ "maxStackEncScore",
+ "maxStackDecScore",
+ "maxHeapCodecScore",
+ "maxHeapEncScore",
+ "maxHeapDecScore",
+ ],
+ "wmops_per_op": [
+ "worstCaseEnc",
+ "worstCaseDec",
+ ],
+}
+# the -1's are for reference lines
+DISPLAY_LINE_IDX = {
+ "wmops": [-1, -1, -1, 9, 3, 5, 7],
+ "rom": [-1, 3, 5, 7, 9, 11, 13, 15, 17, 19],
+ "ram": [-1, 3, 5, 7, 8, 10, 12, 13, 15, 17],
+ "wmops_per_op": [1, 2],
+}
+DISPLAY_LABELS = {
+ "wmops_per_op": ["Encoder", "Decoder"],
+}
+DISPLAY_ELEM_TEMPLATE = '{{ lines: {{ show: true }}, points: {{ show: true, fillColor: "#ffffff" }}, borderWidth: 1.5, borderColor: "#BEBEBE", markingsLineWidth: .75, hoverable: true, clickable: false, shadowSize: 0, color: "{color}", id: "{id}", data: [ {data} ] }}'
+
+REF_COLOR_FOR_COMP_BARS = dict(
+ zip(DISPLAY_LABELS["wmops_per_op"], [REF_COLORS[0], REF_COLORS[2]])
+)
+LINE_COLORS = {
+ "wmops": [
+ REF_COLORS[0],
+ REF_COLORS[1],
+ REF_COLORS[2],
+ "#0080FF",
+ "#FF8000",
+ "#CF4B4B",
+ "#008040",
+ ],
+ "rom": [
+ REF_COLORS[0],
+ "#FF0000",
+ "#FF8000",
+ "#FFFF00",
+ "#800080",
+ "#0000FF",
+ "#0080C0",
+ "#004000",
+ "#008000",
+ "#00FF00",
+ ],
+ "ram": [
+ REF_COLORS[0],
+ "#FF0000",
+ "#FF8000",
+ "#FFFF00",
+ "#004000",
+ "#008000",
+ "#00FF00",
+ "#800080",
+ "#0000FF",
+ "#0080C0",
+ ],
+ "wmops_per_op": [
+ "#CF4B4B",
+ "#008040",
+ ],
+}
+
+JS_FILE_TEMPLATE = """var {var_name} = {{
+ {elem_name}: {{
+ description: "{description}",
+ direction: -1,
+ ticks: [
+ {ticks}
+ ],
+ runs: [
+ {runs}
+ ],
+ displays: [
+ {displays}
+ ]
+ }}
+}};
+"""
+
+FILE_DATA = {
+ "wmops": {
+ "var_name": "Graphs_WMOPS",
+ "elem_name": "wmops_worstcase",
+ "description": "Worst Case WMOPS",
+ "filename": "graphs_wmops_flc.js",
+ "references": {
+ "3xEVS": REF_WMOPS_3EVS,
+ "6xEVS": REF_WMOPS_6EVS,
+ "10xEVS": REF_WMOPS_10EVS,
+ },
+ },
+ "rom": {
+ "var_name": "Graphs_ROM",
+ "elem_name": "rom_worstcase",
+ "description": "ROM",
+ "filename": "graphs_rom_flc.js",
+ "references": {
+ "requirementRom": 0,
+ },
+ },
+ "ram": {
+ "var_name": "Graphs_RAM",
+ "elem_name": "ram_worstcase",
+ "description": "Worst Case RAM",
+ "filename": "graphs_ram_flc.js",
+ "references": {
+ "requirementRam": 0,
+ },
+ },
+ "wmops_per_op": {
+ "var_name": "Graphs_WMOPS_perOP",
+ "elem_name": "wmops_worstcase_per_op",
+ "description": "Worst Case WMOPS per OP",
+ "filename": "graphs_wmops_flc_perOP.js",
+ "references": {},
+ },
+}
+
+
+def main(
+ wmops_log, wmops_per_op_log, rom_log, ram_log, wmops_per_op_log_for_comparison
+):
+ FILE_DATA["wmops"]["log_file"] = wmops_log
+ FILE_DATA["wmops_per_op"]["log_file"] = wmops_per_op_log
+ FILE_DATA["rom"]["log_file"] = rom_log
+ FILE_DATA["ram"]["log_file"] = ram_log
+
+ for x, data in FILE_DATA.items():
+ with open(data["log_file"]) as f:
+ log_lines = f.readlines()
+
+ split_char = " "
+ ticks = []
+ if x == "wmops_per_op":
+ split_char = ";"
+ log_lines, ticks = pre_proc_log_lines(
+ log_lines, wmops_per_op_log_for_comparison
+ )
+
+ else:
+ log_lines = log_lines[-MAX_VALUES:]
+
+ runs = [
+ create_runs_string(line.strip().split(split_char), x) for line in log_lines
+ ]
+ displays = create_display_strings(
+ log_lines,
+ data["references"],
+ split_char,
+ x,
+ has_comparison=x == "wmops_per_op"
+ and wmops_per_op_log_for_comparison is not None,
+ )
+
+ runs = ",\n".join(runs)
+ displays = ",\n".join(displays)
+ ticks = ",\n".join(ticks)
+
+ js_string = JS_FILE_TEMPLATE.format(
+ var_name=data["var_name"],
+ elem_name=data["elem_name"],
+ description=data["description"],
+ runs=runs,
+ displays=displays,
+ ticks=ticks,
+ )
+ with open(data["filename"], "w") as f:
+ print(js_string, file=f)
+
+
+def pre_proc_log_lines(
+ log_lines: list[str], wmops_per_op_log_for_comparison: Optional[str]
+):
+ if wmops_per_op_log_for_comparison is not None:
+ with open(wmops_per_op_log_for_comparison) as f:
+ log_lines_comp = f.readlines()
+
+ log_lines_combined = []
+ MISSING_LINE = "{};0;0;0"
+ for line in log_lines:
+ line_split = line.split(";")
+ conf = line_split[0]
+
+ # add - BASOP suffix to existing line
+ new_line_split = line_split
+ new_line_split[0] = conf + " - BASOP"
+ new_line_basop = ";".join(new_line_split)
+ log_lines_combined.append(new_line_basop)
+
+ # search for same operating point in given comparison log
+ ref_conf = conf + " - FLT REF"
+ new_line_ref = MISSING_LINE.format(ref_conf)
+ for line_comp in log_lines_comp:
+ line_comp_split = line_comp.split(";")
+ conf_comp = line_comp_split[0]
+ if conf == conf_comp:
+ new_line_ref = ";".join([ref_conf] + line_comp_split[1:])
+ break
+ log_lines_combined.append(new_line_ref)
+
+ log_lines = log_lines_combined
+
+ # some preprocessing is needed so that the later functions work as are
+ # 1. need to make sure that modes are ordered by bandwidth
+ # 2. need to add the bandwidth indicator as a column
+ wb_lines, swb_lines, fb_lines = [], [], []
+ for line in log_lines:
+ if " WB " in line:
+ wb_lines.append(line + ";WB")
+ elif " SWB " in line:
+ swb_lines.append(line + ";SWB")
+ elif " FB " in line:
+ fb_lines.append(line + ";FB")
+ log_lines = wb_lines + swb_lines + fb_lines
+
+ # generate tick positions and x axis labels from the number of lines
+ in_between_offset_size = 1
+ wb_label_pos = len(wb_lines) / 2
+ swb_label_pos = len(wb_lines) + in_between_offset_size + len(swb_lines) / 2
+ fb_label_pos = (
+ len(wb_lines)
+ + in_between_offset_size
+ + len(swb_lines)
+ + in_between_offset_size
+ + len(fb_lines) / 2
+ )
+
+ ticks = [
+ f"['{wb_label_pos}', 'WB']",
+ f"['{swb_label_pos}', 'SWB']",
+ f"['{fb_label_pos}', 'FB']",
+ ]
+
+ return log_lines, ticks
+
+
+def create_runs_string(line: list[str], which: str) -> str:
+ keys = RUNS_KEYS[which]
+
+ vals = [line[i] for i in RUNS_LINE_IDX[which]]
+ run = str(dict(zip(keys, vals)))
+
+ return run
+
+
+def create_display_strings(
+ log_lines, references, split_char, which, has_comparison=False
+):
+ display_ids = DISPLAY_IDS[which]
+ display_line_idx = DISPLAY_LINE_IDX[which]
+ line_colors = LINE_COLORS[which]
+ display_labels = DISPLAY_LABELS.get(which, [""] * len(display_ids))
+
+ displays = list()
+ for id, idx, color, label in zip(
+ display_ids, display_line_idx, line_colors, display_labels
+ ):
+ data = list()
+ for i, line in enumerate(log_lines):
+ value = line.split(split_char)[idx]
+ if id in references:
+ value = references[id]
+ data.append(f"[{i}, {value}]")
+
+ if which == "wmops_per_op" and has_comparison:
+ # de-interleave data
+ data_basop = data[::2]
+ data_flt_ref = data[1::2]
+
+ display_basop = DISPLAY_ELEM_TEMPLATE.format(
+ color=color, id=id + " - BASOP", data=", ".join(data_basop)
+ )
+ idx_data = display_basop.index("data:")
+ label_string = f"label: '{label} - BASOP', "
+ display_basop = (
+ display_basop[:idx_data] + label_string + display_basop[idx_data:]
+ )
+
+ ref_color = REF_COLOR_FOR_COMP_BARS[label]
+
+ display_flt_ref = DISPLAY_ELEM_TEMPLATE.format(
+ color=ref_color, id=id + " - FLT REF", data=", ".join(data_flt_ref)
+ )
+ idx_data = display_flt_ref.index("data:")
+ label_string = f"label: '{label} - FLT REF', "
+ display_flt_ref = (
+ display_flt_ref[:idx_data] + label_string + display_flt_ref[idx_data:]
+ )
+
+ display = display_basop + ", \n" + display_flt_ref
+ else:
+ display = DISPLAY_ELEM_TEMPLATE.format(
+ color=color, id=id, data=", ".join(data)
+ )
+
+ if which == "wmops_per_op":
+ display = display.replace("show: true", "show: false")
+
+ if not has_comparison:
+ idx_data = display.index("data:")
+ label_string = f"label: '{label}', "
+ display = display[:idx_data] + label_string + display[idx_data:]
+
+ displays.append(display)
+
+ return displays
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser(
+ description="Generate Javascript code for the complexity webpage"
+ )
+ parser.add_argument("wmops_log")
+ parser.add_argument("wmops_per_op_log")
+ parser.add_argument("rom_log")
+ parser.add_argument("ram_log")
+ parser.add_argument("--wmops_per_op_log_for_comparison", default=None)
+
+ args = parser.parse_args()
+
+ main(
+ args.wmops_log,
+ args.wmops_per_op_log,
+ args.rom_log,
+ args.ram_log,
+ args.wmops_per_op_log_for_comparison,
+ )
diff --git a/ci/complexity_measurements/genWebpageData_Ram.csh b/ci/complexity_measurements/genWebpageData_Ram.csh
deleted file mode 100755
index c0e3eab411a23ddd2b798859d71b0cd12be6008f..0000000000000000000000000000000000000000
--- a/ci/complexity_measurements/genWebpageData_Ram.csh
+++ /dev/null
@@ -1,504 +0,0 @@
-#!/bin/tcsh
-
-# (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
-# Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
-# Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
-# Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
-# contributors to this repository. All Rights Reserved.
-
-# This software is protected by copyright law and by international treaties.
-# The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
-# Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
-# Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
-# Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
-# contributors to this repository retain full ownership rights in their respective contributions in
-# the software. This notice grants no license of any kind, including but not limited to patent
-# license, nor is any license granted by implication, estoppel or otherwise.
-
-# Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
-# contributions.
-
-# This software is provided "AS IS", without any express or implied warranties. The software is in the
-# development stage. It is intended exclusively for experts who have experience with such software and
-# solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
-# and fitness for a particular purpose are hereby disclaimed and excluded.
-
-# Any dispute, controversy or claim arising under or in relation to providing this software shall be
-# submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
-# accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
-# the United Nations Convention on Contracts on the International Sales of Goods.
-
-set maxValues = 40
-
-if (${#argv} != 3) then
- echo usage: $0 \ \