Imported Upstream version 1.25.0
[platform/core/ml/nnfw.git] / compiler / one-cmds / onelib / CfgRunner.py
1 #!/usr/bin/env python
2
3 # Copyright (c) 2022 Samsung Electronics Co., Ltd. All Rights Reserved
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 #    http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 import configparser
18 import os
19 import warnings
20
21 import onelib.utils as oneutils
22
23
24 def _simple_warning(message, category, filename, lineno, file=None, line=None):
25     return f'{category.__name__}: {message}\n'
26
27
28 class CfgRunner:
29     driver_sequence = [
30         'one-optimize', 'one-quantize', 'one-pack', 'one-codegen', 'one-profile',
31         'one-partition', 'one-infer'
32     ]
33
34     def __init__(self, path):
35         self.path = path
36         self.optparser = None
37         self.cfgparser = configparser.ConfigParser()
38         # make option names case sensitive
39         self.cfgparser.optionxform = str
40         parsed = self.cfgparser.read(os.path.expanduser(path))
41         if not parsed:
42             raise FileNotFoundError('Not found given configuration file')
43
44         self._verify_cfg(self.cfgparser)
45         # default import drivers
46         self.import_drivers = [
47             'one-import-bcq', 'one-import-onnx', 'one-import-tf', 'one-import-tflite'
48         ]
49         # parse group option
50         GROUP_OPTION_KEY = 'include'
51         if self.cfgparser.has_option('onecc', GROUP_OPTION_KEY):
52             groups = self.cfgparser['onecc'][GROUP_OPTION_KEY].split()
53             for o in groups:
54                 if o == 'O' or not o.startswith('O'):
55                     raise ValueError('Invalid group option')
56                 # add_opt receives group name except first 'O'
57                 self.add_opt(o[1:])
58
59         self.backend = None
60
61     def _verify_cfg(self, cfgparser):
62         if not cfgparser.has_section('onecc'):
63             if cfgparser.has_section('one-build'):
64                 warnings.formatwarning = _simple_warning
65                 warnings.warn(
66                     "[one-build] section will be deprecated. Please use [onecc] section.")
67             else:
68                 raise ImportError('[onecc] section is required in configuration file')
69
70     def _is_available(self, driver):
71         # if there's no `onecc` section, it will find `one-build` section because of backward compatibility
72         return (self.cfgparser.has_option('onecc', driver) and self.cfgparser.getboolean(
73             'onecc', driver)) or (self.cfgparser.has_option('one-build', driver)
74                                   and self.cfgparser.getboolean('one-build', driver))
75
76     def add_opt(self, opt):
77         self.optparser = configparser.ConfigParser()
78         # make option names case sensitive
79         self.optparser.optionxform = str
80         opt_book = dict(
81             zip(oneutils.get_optimization_list(get_name=True),
82                 oneutils.get_optimization_list()))
83         parsed = self.optparser.read(opt_book['O' + opt])
84         if not parsed:
85             raise FileNotFoundError('Not found given optimization configuration file')
86         if len(self.optparser.sections()) != 1 or self.optparser.sections(
87         )[0] != 'one-optimize':
88             raise AssertionError(
89                 'Optimization configuration file only allowed to have a \'one-optimize\' section'
90             )
91         self.opt = opt
92
93     def set_backend(self, backend: str):
94         self.backend = backend
95
96     def detect_import_drivers(self, dir):
97         self.import_drivers = list(oneutils.detect_one_import_drivers(dir).keys())
98
99     def run(self, working_dir, verbose=False):
100         # set environment
101         CFG_ENV_SECTION = 'Environment'
102         if self.cfgparser.has_section(CFG_ENV_SECTION):
103             for key in self.cfgparser[CFG_ENV_SECTION]:
104                 os.environ[key] = self.cfgparser[CFG_ENV_SECTION][key]
105
106         section_to_run = []
107         for d in self.import_drivers + self.driver_sequence:
108             if self._is_available(d):
109                 section_to_run.append(d)
110
111         for section in section_to_run:
112             options = ['--config', self.path, '--section', section]
113             if section == 'one-optimize' and self.optparser:
114                 options += ['-O', self.opt]
115             if verbose:
116                 options.append('--verbose')
117             if (section == 'one-codegen' or section == 'one-profile') and self.backend:
118                 options += ['-b', self.backend]
119             driver_path = os.path.join(working_dir, section)
120             cmd = [driver_path] + options
121             oneutils.run(cmd)