From patchwork Thu Nov 10 17:31:52 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 17781 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id EBEFCBD16B for ; Thu, 10 Nov 2022 17:32:38 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id AAE8763085; Thu, 10 Nov 2022 18:32:38 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1668101558; bh=AqJwKyQZM0aJZ6Jh7VOQFZO9HCXxBT1jbI9j/OH8T+Q=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=DwPYcfnD8jbctl0Ud3ZEW0bnmeszgc1rBmz7t0MF487cy8z37iDLFLngx3sQucPsf x47JT0f+i24l5ibHVX0h/yoD6uroGbAPMBtJ7EiIpSOjMJ+TCTlFg5jsqiNw+6tYyv Q/GxHeSKYEHu3bxT5BxIN8zD8DOGxoIDkkbs3QjAKOaNqPv5WxjTD4dXlu5dZ8pVqt U3o/jpTFDCc+GuZBhieCYx8PcyNvaDETwBU7RMbMQVSMPADYVT0uSdwqxir0MHpmzx mmdnhPdeCWXoAzVMfrVt3lJwH5r3KXu0JufiYqpIZszOXPXRtHSP2ds3VfdrFluJ6R qhP4vInYUohGw== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B9B8663085 for ; Thu, 10 Nov 2022 18:32:36 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Yy9Id8K9"; dkim-atps=neutral Received: from pyrite.tail37cf.ts.net (h175-177-042-159.catv02.itscom.jp [175.177.42.159]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 4A7F1499; Thu, 10 Nov 2022 18:32:35 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1668101556; bh=AqJwKyQZM0aJZ6Jh7VOQFZO9HCXxBT1jbI9j/OH8T+Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Yy9Id8K9zHQXv9i5Jk9pYcmpCNcdHvDSGKrI/6Tbvbiq08sMJv2XAhyba3GL/Zx9w KfEgHp6cboQ57N6m+UGt3OPoCNYXvOvYSrcWS5cN2W2pGa3X1pcGK34ojg/aDRjbSd W/FfW0Nw/TbZoYUTJb7DQnzBgATdTgqMVhoo8lqo= To: libcamera-devel@lists.libcamera.org Date: Fri, 11 Nov 2022 02:31:52 +0900 Message-Id: <20221110173154.488445-11-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20221110173154.488445-1-paul.elder@ideasonboard.com> References: <20221110173154.488445-1-paul.elder@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 10/12] utils: libtuning: generators: Add yaml output X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Paul Elder via libcamera-devel From: Paul Elder Reply-To: Paul Elder Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Add a generator to libtuning for writing tuning output to a yaml file. Signed-off-by: Paul Elder Reviewed-by: Laurent Pinchart --- Changes in v3: - add file description - remove indirection from fake polymorphism New in 2 --- utils/tuning/libtuning/generators/__init__.py | 1 + .../libtuning/generators/yaml_output.py | 123 ++++++++++++++++++ 2 files changed, 124 insertions(+) create mode 100644 utils/tuning/libtuning/generators/yaml_output.py diff --git a/utils/tuning/libtuning/generators/__init__.py b/utils/tuning/libtuning/generators/__init__.py index 937aff30..f28b6149 100644 --- a/utils/tuning/libtuning/generators/__init__.py +++ b/utils/tuning/libtuning/generators/__init__.py @@ -3,3 +3,4 @@ # Copyright (C) 2022, Paul Elder from libtuning.generators.raspberrypi_output import RaspberryPiOutput +from libtuning.generators.yaml_output import YamlOutput diff --git a/utils/tuning/libtuning/generators/yaml_output.py b/utils/tuning/libtuning/generators/yaml_output.py new file mode 100644 index 00000000..6398fc59 --- /dev/null +++ b/utils/tuning/libtuning/generators/yaml_output.py @@ -0,0 +1,123 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright 2022 Paul Elder +# +# yaml_output.py - Generate tuning file in YAML format + +from .generator import Generator + +from numbers import Number +from pathlib import Path + +import libtuning.utils as utils + + +class YamlOutput(Generator): + def __init__(self): + super().__init__() + + def _stringify_number_list(self, listt: list): + line_wrap = 80 + + line = '[ ' + ', '.join([str(x) for x in listt]) + ' ]' + if len(line) <= line_wrap: + return [line] + + out_lines = ['['] + line = ' ' + for x in listt: + x_str = str(x) + # If the first number is longer than line_wrap, it'll add an extra line + if len(line) + len(x_str) > line_wrap: + out_lines.append(line) + line = f' {x_str},' + continue + line += f' {x_str},' + out_lines.append(line) + out_lines.append(']') + + return out_lines + + # @return Array of lines, and boolean of if all elements were numbers + def _stringify_list(self, listt: list): + out_lines = [] + + all_numbers = set([isinstance(x, Number) for x in listt]).issubset({True}) + + if all_numbers: + return self._stringify_number_list(listt), True + + for value in listt: + if isinstance(value, Number): + out_lines.append(f'- {str(value)}') + elif isinstance(value, str): + out_lines.append(f'- "{value}"') + elif isinstance(value, list): + lines, all_numbers = self._stringify_list(value) + + if all_numbers: + out_lines.append( f'- {lines[0]}') + out_lines += [f' {line}' for line in lines[1:]] + else: + out_lines.append( f'-') + out_lines += [f' {line}' for line in lines] + elif isinstance(value, dict): + lines = self._stringify_dict(value) + out_lines.append( f'- {lines[0]}') + out_lines += [f' {line}' for line in lines[1:]] + + return out_lines, False + + def _stringify_dict(self, dictt: dict): + out_lines = [] + + for key in dictt: + value = dictt[key] + + if isinstance(value, Number): + out_lines.append(f'{key}: {str(value)}') + elif isinstance(value, str): + out_lines.append(f'{key}: "{value}"') + elif isinstance(value, list): + lines, all_numbers = self._stringify_list(value) + + if all_numbers: + out_lines.append( f'{key}: {lines[0]}') + out_lines += [f'{" " * (len(key) + 2)}{line}' for line in lines[1:]] + else: + out_lines.append( f'{key}:') + out_lines += [f' {line}' for line in lines] + elif isinstance(value, dict): + lines = self._stringify_dict(value) + out_lines.append( f'{key}:') + out_lines += [f' {line}' for line in lines] + + return out_lines + + def write(self, output_file: Path, output_dict: dict, output_order: list): + out_lines = [ + '%YAML 1.1', + '---', + 'version: 1', + # No need to condition this, as libtuning already guarantees that + # we have at least one module. Even if the module has no output, + # its prescence is sufficient. + 'algorithms:' + ] + + for module in output_order: + out_lines.append(f' - {module.out_name}:') + + if len(output_dict[module]) == 0: + continue + + if not isinstance(output_dict[module], dict): + utils.eprint(f'Error: Output of {module.type} is not a dictionary') + continue + + lines = self._stringify_dict(output_dict[module]) + out_lines += [f' {line}' for line in lines] + + with open(output_file, 'w') as f: + for line in out_lines: + f.write(f'{line}\n')