blob: b5f9f9860d4ed2335b37309e864daf2f335fae81 [file] [log] [blame]
erik.andersson@arm.comad45f792021-02-03 10:20:16 +01001# Copyright (C) 2020-2021 Arm Limited or its affiliates. All rights reserved.
Tim Hall79d07d22020-04-27 18:20:16 +01002#
3# SPDX-License-Identifier: Apache-2.0
4#
5# Licensed under the Apache License, Version 2.0 (the License); you may
6# not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# 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, WITHOUT
13# 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.
Tim Hall79d07d22020-04-27 18:20:16 +010016# Description:
17# Main entry point for the Vela compiler.
18#
19# Provides command line interface, options parsing, and network loading. Before calling the compiler driver.
Diego Russoe8a10452020-04-21 17:39:10 +010020import argparse
Rickard Bolin1538dce2022-04-25 11:07:56 +000021import glob
Tim Hall1bd531d2020-11-01 20:59:36 +000022import os
Diego Russoea6111a2020-04-14 18:41:58 +010023import sys
Tim Hall79d07d22020-04-27 18:20:16 +010024import time
Tim Hall79d07d22020-04-27 18:20:16 +010025
erik.andersson@arm.comad45f792021-02-03 10:20:16 +010026import flatbuffers
27
Tim Hall79d07d22020-04-27 18:20:16 +010028from . import architecture_features
Diego Russoe8a10452020-04-21 17:39:10 +010029from . import compiler_driver
30from . import model_reader
Diqing Zhong5e5a7842021-08-16 17:24:09 +020031from . import rawdata_writer
Diego Russoe8a10452020-04-21 17:39:10 +010032from . import scheduler
Tim Hall79d07d22020-04-27 18:20:16 +010033from . import stats_writer
34from . import tflite_writer
Tim Hall79d07d22020-04-27 18:20:16 +010035from ._version import __version__
Louis Verhaard11831ce2020-11-18 18:53:24 +010036from .api import API_VERSION
Tim Halle6ccd872020-11-09 16:46:37 +000037from .debug_database import DebugDatabase
Louis Verhaard7db78962020-05-25 15:05:26 +020038from .errors import InputFileError
Henrik G Olssonea9b23c2021-03-23 17:34:49 +010039from .errors import VelaError
Jonas Ohlsson45e653d2021-07-26 16:13:12 +020040from .nn_graph import NetworkType
Diego Russoe8a10452020-04-21 17:39:10 +010041from .nn_graph import TensorAllocator
Diego Russoea6111a2020-04-14 18:41:58 +010042from .tensor import MemArea
Jacob Bohlin0628a8c2020-08-28 13:25:14 +020043from .tensor import Tensor
erik.andersson@arm.comad45f792021-02-03 10:20:16 +010044from .tflite.Model import Model
Michael McGeagh837dc1b2020-11-10 12:38:25 +000045from .tflite_mapping import builtin_operator_map
Tim Halla3fe6652022-03-03 17:43:16 +000046from .tflite_mapping import builtin_operator_name_map
Jonas Ohlsson45e653d2021-07-26 16:13:12 +020047from .tflite_model_semantic import TFLiteSemantic
48from .tflite_supported_operators import TFLiteSupportedOperators
49from .tosa_model_semantic import TosaSemantic
50from .tosa_supported_operators import TosaSupportedOperators
Louis Verhaard52078302020-11-18 13:35:06 +010051from ethosu.vela.architecture_features import ArchitectureFeatures
Tim Hall79d07d22020-04-27 18:20:16 +010052
Rickard Bolin1538dce2022-04-25 11:07:56 +000053CONFIG_FILES_PATH = os.path.abspath(f"{__file__}/../../config_files")
54
Tim Hall79d07d22020-04-27 18:20:16 +010055
Tim Halle6ccd872020-11-09 16:46:37 +000056def process(input_name, enable_debug_db, arch, model_reader_options, compiler_options, scheduler_options):
Tim Hall79d07d22020-04-27 18:20:16 +010057 if compiler_options.timing:
58 start = time.time()
59
Tim Halle6ccd872020-11-09 16:46:37 +000060 os.makedirs(compiler_options.output_dir, exist_ok=True)
61 output_basename = os.path.join(compiler_options.output_dir, os.path.splitext(os.path.basename(input_name))[0])
62 DebugDatabase.show_warnings = enable_debug_db
63
Patrik Gustavsson8f1f9aa2021-06-28 07:41:58 +020064 nng, network_type = model_reader.read_model(input_name, model_reader_options)
Tim Hall79d07d22020-04-27 18:20:16 +010065
66 if not nng:
Michael McGeagh7a6f8432020-12-02 15:29:22 +000067 raise InputFileError(input_name, "Input file could not be read")
Tim Hall79d07d22020-04-27 18:20:16 +010068
69 if compiler_options.verbose_operators:
70 nng.print_operators()
71
72 if compiler_options.timing:
73 stop = time.time()
74 print("Model reading took %f s" % (stop - start))
75 start = time.time()
76
Patrik Gustavsson8f1f9aa2021-06-28 07:41:58 +020077 compiler_driver.compiler_driver(nng, arch, compiler_options, scheduler_options, network_type)
Tim Hall79d07d22020-04-27 18:20:16 +010078
Tim Halle6ccd872020-11-09 16:46:37 +000079 summary_csv_file = "{0}_summary_{1}.csv".format(output_basename, arch.system_config)
Tim Hall79d07d22020-04-27 18:20:16 +010080 stats_writer.write_summary_metrics_csv(nng, summary_csv_file, arch)
81
Fredrik Svedbergf5c07c42021-04-23 14:36:42 +020082 stats_writer.print_performance_metrics(
83 nng,
84 show_cpu_operations=compiler_options.show_cpu_operations,
85 verbose_weights=compiler_options.verbose_weights,
86 arch=arch,
87 )
Tim Hall79d07d22020-04-27 18:20:16 +010088
Diqing Zhong5e5a7842021-08-16 17:24:09 +020089 output_tfl_filename = output_basename + "_vela.tflite"
Patrik Gustavssonb081d672021-08-25 13:49:25 +020090 if input_name.endswith(".tflite"):
Diqing Zhong5e5a7842021-08-16 17:24:09 +020091 tflite_writer.write_tflite(nng, output_tfl_filename)
Patrik Gustavssonc74682c2021-08-17 14:26:38 +020092 if input_name.endswith(".tosa"):
Diqing Zhong5e5a7842021-08-16 17:24:09 +020093 rawdata_writer.write_rawdata_output(nng, arch, output_basename)
Tim Halle6ccd872020-11-09 16:46:37 +000094
95 if enable_debug_db:
Diqing Zhong5e5a7842021-08-16 17:24:09 +020096 file_offsets = calculate_operator_file_offsets(output_tfl_filename)
erik.andersson@arm.comad45f792021-02-03 10:20:16 +010097 for idx, offset in enumerate(sorted(file_offsets)):
98 sg = find_subgraph_with_command_stream_order(nng, idx)
99 if sg is not None:
100 DebugDatabase.set_stream_offset(sg, offset)
Tim Halle6ccd872020-11-09 16:46:37 +0000101 debug_filename = output_basename + "_debug.xml"
Diqing Zhong5e5a7842021-08-16 17:24:09 +0200102 DebugDatabase.write(debug_filename, input_name, output_tfl_filename)
Tim Hall79d07d22020-04-27 18:20:16 +0100103
104 if compiler_options.timing:
105 stop = time.time()
106 print("Compiler driver took %f s" % (stop - start))
107
108 return nng
109
110
erik.andersson@arm.comad45f792021-02-03 10:20:16 +0100111def find_subgraph_with_command_stream_order(nng, idx):
112 for sg in nng.subgraphs:
113 if sg.generated_stream_id == idx:
114 return sg
115 return None
116
117
118def calculate_operator_file_offsets(name: str):
119 # Read the vela optimized tflite file
120 with open(name, "rb") as f:
121 buf = bytearray(f.read())
122 # Calculate the file offsets for each custom operator
123 file_offsets = []
124 model = Model.GetRootAsModel(buf, 0)
125 for idx in range(model.SubgraphsLength()): # However only one subgraph is supported as of now
126 sg = model.Subgraphs(idx)
127 for idx in range(sg.OperatorsLength()):
128 operator = sg.Operators(idx)
129 if model.OperatorCodes(operator.OpcodeIndex()).CustomCode() is not None:
130 tensor_idx = operator.Inputs(0)
131 tensor = sg.Tensors(tensor_idx)
132 buffer = model.Buffers(tensor.Buffer())
133 offset = flatbuffers.number_types.UOffsetTFlags.py_type(buffer._tab.Offset(4))
134 file_offsets.append(buffer._tab.Vector(offset))
135 return file_offsets
136
137
Tim Hall79d07d22020-04-27 18:20:16 +0100138def print_subgraph_io_summary(nng):
139 """Print a summary of all the input and output tensor sizes for all subgraphs.
140 Also displays the total tensor size and the memory used area for sram.
141 """
142
143 print("Subgraph IO Summary")
144 print("-------------------")
James Ward93389782021-10-14 12:58:02 +0100145 print(f"NNG: {nng.name}")
Tim Hall79d07d22020-04-27 18:20:16 +0100146 max_sg_size = 0
147 for sg in reversed(nng.subgraphs):
James Ward93389782021-10-14 12:58:02 +0100148 print(f" NNG Subgraph: {sg.name} = {sg.placement}")
Tim Hall79d07d22020-04-27 18:20:16 +0100149 sg_size = 0
150
James Ward93389782021-10-14 12:58:02 +0100151 if hasattr(sg, "scratch_tensor") and sg.scratch_tensor is not None:
152 sg_tensors = sg.input_tensors + [sg.scratch_tensor] + sg.output_tensors
153 else:
154 sg_tensors = sg.input_tensors + sg.output_tensors
Tim Hall79d07d22020-04-27 18:20:16 +0100155
James Ward93389782021-10-14 12:58:02 +0100156 for tens in sg_tensors:
157 if tens in sg.input_tensors:
158 tens_dir = "In"
159 elif tens in sg.output_tensors:
160 tens_dir = "Out"
161 else:
162 tens_dir = "In/Out"
Tim Hall79d07d22020-04-27 18:20:16 +0100163
James Ward93389782021-10-14 12:58:02 +0100164 size = tens.elements() * tens.element_size() / 1024.0
165 sg_size = sg_size + size
166 print(f" Tensor [{tens_dir}]: {tens.name} = {size} KiB")
167
168 print(f" Total Size = {sg_size} KiB")
169 print(f" SRAM Memory Used = {sg.memory_used.get(MemArea.Sram, 0) / 1024.0} KiB")
Tim Hall79d07d22020-04-27 18:20:16 +0100170 max_sg_size = max(sg_size, max_sg_size)
171
James Ward93389782021-10-14 12:58:02 +0100172 print(f" Maximum NNG Subgraph Size = {max_sg_size} KiB")
Tim Hall79d07d22020-04-27 18:20:16 +0100173
174
Michael McGeagh837dc1b2020-11-10 12:38:25 +0000175def generate_supported_ops():
Jonas Ohlsson0957e3e2021-09-01 15:57:21 +0200176 # Exclude network type from generation by adding value to exclude list.
177 # To easily exclude NetworkType from generated documentation.
178 exclude_generation_network_type_value = [NetworkType.TOSA.value]
179
Michael McGeagh837dc1b2020-11-10 12:38:25 +0000180 lines = [
181 "# Supported Ops",
182 "",
183 "This file was automatically generated by Vela using the `--supported-ops-report` parameter. ",
184 f"Vela version: `{__version__}`",
185 "",
Michael McGeagh54a61112020-11-24 14:58:51 +0000186 "This file complies with",
187 "[**Gitiles Markdown syntax**](https://github.com/google/gitiles/blob/master/Documentation/markdown.md)",
Michael McGeagh837dc1b2020-11-10 12:38:25 +0000188 "",
Jonas Ohlsson45e653d2021-07-26 16:13:12 +0200189 "Summary table of constraints for:",
Michael McGeagh837dc1b2020-11-10 12:38:25 +0000190 ]
Jonas Ohlsson45e653d2021-07-26 16:13:12 +0200191
192 for network_type in NetworkType:
Jonas Ohlsson0957e3e2021-09-01 15:57:21 +0200193 if network_type.value in exclude_generation_network_type_value:
194 continue
195
Jonas Ohlsson45e653d2021-07-26 16:13:12 +0200196 lines += [
197 f"- [{network_type.name}](#{network_type.name.lower()}-summary-table)",
198 ]
199
200 for network_type in NetworkType:
Jonas Ohlsson0957e3e2021-09-01 15:57:21 +0200201 if network_type.value in exclude_generation_network_type_value:
202 continue
203
Michael McGeagh837dc1b2020-11-10 12:38:25 +0000204 lines += [
205 "",
Jonas Ohlsson45e653d2021-07-26 16:13:12 +0200206 f"## {network_type.name} Summary Table",
Michael McGeagh837dc1b2020-11-10 12:38:25 +0000207 "",
208 ]
Jonas Ohlsson45e653d2021-07-26 16:13:12 +0200209 if network_type == NetworkType.TFLite:
210 lines += [
211 "The table below contains TFLite operators that can be placed on the Ethos-U NPU. ",
212 "If the constraints are not met, then that operator will be scheduled on the CPU instead. ",
213 "For any other TFLite operator not listed, will be left untouched and scheduled on the CPU. ",
214 "Please check the supported operator list for your chosen runtime for further information.",
215 "",
216 "| Operator | TFLite Constraints |",
217 "| --- | --- |",
218 ]
219 semantic_checker = TFLiteSemantic()
220 supported = TFLiteSupportedOperators()
221 elif network_type == NetworkType.TOSA:
222 lines += [
223 "The table below contains TOSA operators that can be placed on the Ethos-U NPU. ",
224 "Note: There is limited support for compiling a TOSA neural network (EXPERIMENTAL). ",
225 "The related constraints have not yet been populated in the list.",
226 "",
227 "| Operator | TOSA Constraints |",
228 "| --- | --- |",
229 ]
230 semantic_checker = TosaSemantic()
231 supported = TosaSupportedOperators()
232 else:
233 raise ValueError
234
235 op_constraint_links = []
Tim Halla3fe6652022-03-03 17:43:16 +0000236 op_list = sorted(((op, builtin_operator_name_map[op]) for op in builtin_operator_map), key=lambda x: x[1])
Jonas Ohlsson45e653d2021-07-26 16:13:12 +0200237 for op, name in op_list:
238 internal_op = builtin_operator_map[op][0]
239 if internal_op in TFLiteSupportedOperators.supported_operators:
240 links = f"[Generic](#{network_type.name.lower()}-generic-constraints)"
241 if (
242 internal_op in supported.specific_constraints
243 or internal_op in semantic_checker.specific_constraints
244 ):
245 links += f", [Specific](#{network_type.name.lower()}-{name.lower()}-constraints)"
246 op_constraint_links.append((internal_op, name))
247 lines.append(f"| {name} | {links} |")
248 lines += [
249 "",
250 f"### {network_type.name} Generic Constraints",
251 "",
252 "This is a list of constraints that all NPU operators must satisfy in order to be scheduled on the NPU.",
253 "",
254 ]
255 for constraint in semantic_checker.generic_constraints:
Michael McGeagh837dc1b2020-11-10 12:38:25 +0000256 # Markdown needs two spaces at the end of a line to render it as a separate line
257 reason = constraint.__doc__.replace("\n", " \n")
258 lines.append(f"- {reason}")
Jonas Ohlsson45e653d2021-07-26 16:13:12 +0200259 for constraint in supported.generic_constraints:
260 # Markdown needs two spaces at the end of a line to render it as a separate line
261 reason = constraint.__doc__.replace("\n", " \n")
262 lines.append(f"- {reason}")
263 for op, name in op_constraint_links:
264 lines += [
265 "",
266 f"### {network_type.name} {name} Constraints",
267 "",
268 f"This is a list of constraints that the {name} operator must satisfy in order to be scheduled on the"
269 " NPU.",
270 "",
271 ]
272 for constraint in semantic_checker.specific_constraints[op]:
273 # Markdown needs two spaces at the end of a line to render it as a separate line
274 reason = constraint.__doc__.replace("\n", " \n")
275 lines.append(f"- {reason}")
276 for constraint in supported.specific_constraints[op]:
277 # Markdown needs two spaces at the end of a line to render it as a separate line
278 reason = constraint.__doc__.replace("\n", " \n")
279 lines.append(f"- {reason}")
Michael McGeagh837dc1b2020-11-10 12:38:25 +0000280
281 # Note. this will generate the file in the CWD
282 filepath = os.path.join(os.getcwd(), "SUPPORTED_OPS.md")
283 with open(filepath, "wt") as md:
284 md.writelines(line + "\n" for line in lines)
285 print(f"Report file: {filepath}")
286
287
Rickard Bolin1538dce2022-04-25 11:07:56 +0000288def list_config_files():
289 print("\nAvailable config files:\n")
290 for config in glob.glob(os.path.join(CONFIG_FILES_PATH, "*", "*.ini")):
291 print(config.lstrip(CONFIG_FILES_PATH + os.path.sep))
292
293
Tim Hall79d07d22020-04-27 18:20:16 +0100294def main(args=None):
Henrik G Olssonea9b23c2021-03-23 17:34:49 +0100295 try:
296 if args is None:
297 args = sys.argv[1:]
Tim Hall79d07d22020-04-27 18:20:16 +0100298
Henrik G Olssonea9b23c2021-03-23 17:34:49 +0100299 parser = argparse.ArgumentParser(prog="vela", description="Neural network model compiler for Arm Ethos-U NPUs")
300 parser.add_argument("--version", action="version", version=__version__)
301 parser.add_argument(
302 "--api-version", action="version", version=API_VERSION, help="Displays the version of the external API."
303 )
304 parser.add_argument(
305 "--supported-ops-report",
306 action="store_true",
307 help="Generate the SUPPORTED_OPS.md file in the current working directory and exit",
Tim Hallb9b515c2020-11-01 21:27:19 +0000308 )
Jacob Bohlin0628a8c2020-08-28 13:25:14 +0200309
Rickard Bolin1538dce2022-04-25 11:07:56 +0000310 parser.add_argument(
311 "--list-config-files",
312 action="store_true",
313 help=(
314 "Display all available configurations in the `config_files` folder and exit. To select config file, "
315 "use the --config argument with one of the listed config files (For example: --config Arm/vela.ini )"
316 ),
317 )
318
Henrik G Olssonea9b23c2021-03-23 17:34:49 +0100319 # set network nargs to be optional to allow the support-ops-report CLI option to be used standalone
320 parser.add_argument(
321 "network",
322 metavar="NETWORK",
323 type=str,
324 default=None,
325 nargs="?",
326 help="Filename of the input TensorFlow Lite for Microcontrollers network",
327 )
328 parser.add_argument(
329 "--output-dir", type=str, default="output", help="Output directory to write files to (default: %(default)s)"
330 )
331 parser.add_argument(
332 "--enable-debug-db",
333 action="store_true",
334 default=None,
335 help="Enables the calculation and writing of a network debug database to output directory",
336 )
337 parser.add_argument(
338 "--config",
339 type=str,
340 action="append",
341 help="Vela configuration file(s) in Python ConfigParser .ini file format",
342 )
343 parser.add_argument("--verbose-all", action="store_true", help="Enable all verbose options")
344 parser.add_argument(
345 "--verbose-config", action="store_true", help="Verbose system configuration and memory mode"
346 )
347 parser.add_argument("--verbose-graph", action="store_true", help="Verbose graph rewriter")
348 parser.add_argument("--verbose-quantization", action="store_true", help="Verbose quantization")
349 parser.add_argument("--verbose-packing", action="store_true", help="Verbose pass packing")
350 parser.add_argument("--verbose-tensor-purpose", action="store_true", help="Verbose tensor purpose")
351 parser.add_argument("--verbose-tensor-format", action="store_true", help="Verbose tensor format")
352 parser.add_argument("--verbose-schedule", action="store_true", help="Verbose schedule")
Henrik G Olssonea9b23c2021-03-23 17:34:49 +0100353 parser.add_argument("--verbose-allocation", action="store_true", help="Verbose tensor allocation")
354 parser.add_argument(
355 "--verbose-high-level-command-stream", action="store_true", help="Verbose high level command stream"
356 )
357 parser.add_argument(
358 "--verbose-register-command-stream", action="store_true", help="Verbose register command stream"
359 )
360 parser.add_argument("--verbose-operators", action="store_true", help="Verbose operator list")
Fredrik Svedbergf5c07c42021-04-23 14:36:42 +0200361 parser.add_argument("--verbose-weights", action="store_true", help="Verbose weights information")
Tim Hallc1be0872022-03-03 17:50:52 +0000362 parser.add_argument("--verbose-performance", action="store_true", help="Verbose performance information")
Henrik G Olssonea9b23c2021-03-23 17:34:49 +0100363 parser.add_argument(
364 "--show-cpu-operations", action="store_true", help="Show the operations that fall back to the CPU"
365 )
Henrik G Olssonea9b23c2021-03-23 17:34:49 +0100366 parser.add_argument("--timing", action="store_true", help="Time the compiler doing operations")
367 parser.add_argument(
368 "--accelerator-config",
369 type=str,
370 default="ethos-u55-256",
371 choices=list(architecture_features.Accelerator.member_list()),
372 help="Accelerator configuration to use (default: %(default)s)",
373 )
374 parser.add_argument(
375 "--system-config",
376 type=str,
377 default=architecture_features.ArchitectureFeatures.DEFAULT_CONFIG,
378 help="System configuration to select from the Vela configuration file (default: %(default)s)",
379 )
380 parser.add_argument(
381 "--memory-mode",
382 type=str,
383 default=architecture_features.ArchitectureFeatures.DEFAULT_CONFIG,
384 help="Memory mode to select from the Vela configuration file (default: %(default)s)",
385 )
386 parser.add_argument(
387 "--tensor-allocator",
388 default=TensorAllocator.HillClimb,
389 type=lambda s: TensorAllocator[s],
390 choices=list(TensorAllocator),
391 help="Tensor Allocator algorithm (default: %(default)s)",
392 )
393 parser.add_argument(
394 "--show-subgraph-io-summary",
395 action="store_true",
396 help="Shows a summary of all the subgraphs and their inputs and outputs",
397 )
398 parser.add_argument(
Henrik G Olssonea9b23c2021-03-23 17:34:49 +0100399 "--max-block-dependency",
400 type=int,
401 default=architecture_features.ArchitectureFeatures.MAX_BLOCKDEP,
402 choices=range(0, architecture_features.ArchitectureFeatures.MAX_BLOCKDEP + 1),
403 help=(
404 "Set the maximum value that can be used for the block dependency between npu kernel operations"
405 " (default: %(default)s)"
406 ),
407 )
408 parser.add_argument(
Tim Halld8339a72021-05-27 18:49:40 +0100409 "--optimise",
410 type=lambda s: scheduler.OptimizationStrategy[s],
411 default=scheduler.OptimizationStrategy.Performance,
412 choices=list(scheduler.OptimizationStrategy),
413 help=(
414 "Set the optimisation strategy. The Size strategy results in minimal SRAM usage (does not use"
415 " arena-cache-size). The Performance strategy results in maximal performance (uses the arena-cache-size"
416 " if specified) (default: %(default)s)"
417 ),
Henrik G Olssonea9b23c2021-03-23 17:34:49 +0100418 )
419 parser.add_argument(
Tim Halld8339a72021-05-27 18:49:40 +0100420 "--arena-cache-size",
421 type=int,
422 help=(
423 "Set the size of the arena cache memory area, in bytes. If specified, this option overrides the memory"
424 " mode attribute with the same name in a Vela configuration file"
425 ),
Henrik G Olssonea9b23c2021-03-23 17:34:49 +0100426 )
427 parser.add_argument(
428 "--cpu-tensor-alignment",
429 type=int,
430 default=Tensor.AllocationQuantum,
431 help=(
432 "Controls the allocation byte alignment of cpu tensors including Ethos-U Custom"
433 " operator inputs and outputs (default: %(default)s)"
434 ),
435 )
Dwight Lidmanb9c95422021-08-18 19:24:14 +0200436 parser.add_argument(
437 "--recursion-limit",
438 type=int,
439 default=1000,
440 help="Set the recursion depth limit, may result in RecursionError if too low (default: %(default)s)",
441 )
Henrik G Olssonea9b23c2021-03-23 17:34:49 +0100442 args = parser.parse_args(args=args)
Louis Verhaard52078302020-11-18 13:35:06 +0100443
Henrik G Olssonea9b23c2021-03-23 17:34:49 +0100444 # Generate the supported ops report and exit
445 if args.supported_ops_report:
446 generate_supported_ops()
447 return 0
Louis Verhaard52078302020-11-18 13:35:06 +0100448
Rickard Bolin1538dce2022-04-25 11:07:56 +0000449 if args.list_config_files:
450 list_config_files()
451 return 0
452
Henrik G Olssonea9b23c2021-03-23 17:34:49 +0100453 if args.network is None:
454 parser.error("the following argument is required: NETWORK")
Michael McGeagh2fa40ae2020-12-02 10:55:04 +0000455
Rickard Bolin1538dce2022-04-25 11:07:56 +0000456 def _parse_config(config):
457 if not config.endswith(".ini"):
458 raise InputFileError(config, "Configuration files must use the .ini extension")
459
460 if len(config.split(os.path.sep)) == 2 and not config.startswith(os.path.sep):
461 config_path = os.path.join(CONFIG_FILES_PATH, config)
462 else:
463 print(
464 f"Warning: Configuration file `{config}` not located in a folder directly under the "
465 "`config_files` directory. Note that the file depth from the `config_files` directory must be "
466 "exactly 2 to be discovered via the --list-config-files mechanism "
467 "(e.g. `config_files/directory_name/my_config_file.ini`). This config file will still be "
468 "parsed however, and treated as an absolute path config instead."
469 )
470 config_path = config
471
472 if not os.access(config_path, os.R_OK):
473 raise InputFileError(config_path, "File not found or is not readable")
474
475 return config_path
476
Henrik G Olssonea9b23c2021-03-23 17:34:49 +0100477 # check all config files exist because they will be read as a group
Rickard Bolin1538dce2022-04-25 11:07:56 +0000478 config_files = [_parse_config(cfg) for cfg in args.config] if args.config else None
Tim Hall79d07d22020-04-27 18:20:16 +0100479
Henrik G Olssonea9b23c2021-03-23 17:34:49 +0100480 if args.cpu_tensor_alignment < 16 or args.cpu_tensor_alignment & (args.cpu_tensor_alignment - 1) != 0:
481 parser.error(
482 "Invalid argument to --cpu-tensor-alignment = {} (must be greater than or equal to 16 and a power of 2)"
483 "".format(args.cpu_tensor_alignment)
484 )
Tim Hall79d07d22020-04-27 18:20:16 +0100485
Henrik G Olssonea9b23c2021-03-23 17:34:49 +0100486 if args.system_config == ArchitectureFeatures.DEFAULT_CONFIG:
487 print(f"Warning: Using {ArchitectureFeatures.DEFAULT_CONFIG} values for system configuration")
Tim Hall79d07d22020-04-27 18:20:16 +0100488
Henrik G Olssonea9b23c2021-03-23 17:34:49 +0100489 if args.memory_mode == ArchitectureFeatures.DEFAULT_CONFIG:
490 print(f"Warning: Using {ArchitectureFeatures.DEFAULT_CONFIG} values for memory mode")
Tim Hall79d07d22020-04-27 18:20:16 +0100491
Henrik G Olssonea9b23c2021-03-23 17:34:49 +0100492 if args.verbose_all:
493 for v in vars(args):
494 if v.startswith("verbose") and v != "verbose_all":
495 setattr(args, v, True)
496
Dwight Lidmanb9c95422021-08-18 19:24:14 +0200497 sys.setrecursionlimit(args.recursion_limit)
498
Henrik G Olssonea9b23c2021-03-23 17:34:49 +0100499 arch = architecture_features.ArchitectureFeatures(
Rickard Bolin1538dce2022-04-25 11:07:56 +0000500 vela_config_files=config_files,
Henrik G Olssonea9b23c2021-03-23 17:34:49 +0100501 system_config=args.system_config,
502 memory_mode=args.memory_mode,
503 accelerator_config=args.accelerator_config,
Henrik G Olssonea9b23c2021-03-23 17:34:49 +0100504 max_blockdep=args.max_block_dependency,
Henrik G Olssonea9b23c2021-03-23 17:34:49 +0100505 verbose_config=args.verbose_config,
Tim Halld8339a72021-05-27 18:49:40 +0100506 arena_cache_size=args.arena_cache_size,
Henrik G Olssonea9b23c2021-03-23 17:34:49 +0100507 )
508
509 compiler_options = compiler_driver.CompilerOptions(
510 verbose_graph=args.verbose_graph,
511 verbose_quantization=args.verbose_quantization,
512 verbose_packing=args.verbose_packing,
513 verbose_tensor_purpose=args.verbose_tensor_purpose,
514 verbose_tensor_format=args.verbose_tensor_format,
515 verbose_allocation=args.verbose_allocation,
516 verbose_high_level_command_stream=args.verbose_high_level_command_stream,
517 verbose_register_command_stream=args.verbose_register_command_stream,
518 verbose_operators=args.verbose_operators,
Fredrik Svedbergf5c07c42021-04-23 14:36:42 +0200519 verbose_weights=args.verbose_weights,
Tim Hallc1be0872022-03-03 17:50:52 +0000520 verbose_performance=args.verbose_performance,
Henrik G Olssonea9b23c2021-03-23 17:34:49 +0100521 show_cpu_operations=args.show_cpu_operations,
522 tensor_allocator=args.tensor_allocator,
523 timing=args.timing,
524 output_dir=args.output_dir,
525 cpu_tensor_alignment=args.cpu_tensor_alignment,
526 )
527
528 scheduler_options = scheduler.SchedulerOptions(
Tim Halld8339a72021-05-27 18:49:40 +0100529 optimization_strategy=args.optimise,
530 sram_target=arch.arena_cache_size,
Henrik G Olssonea9b23c2021-03-23 17:34:49 +0100531 verbose_schedule=args.verbose_schedule,
Henrik G Olssonea9b23c2021-03-23 17:34:49 +0100532 )
533
534 model_reader_options = model_reader.ModelReaderOptions()
535
536 nng = process(
537 args.network, args.enable_debug_db, arch, model_reader_options, compiler_options, scheduler_options
538 )
539
540 if args.show_subgraph_io_summary:
541 print_subgraph_io_summary(nng)
542
543 return 0
544 except VelaError as e:
545 print(e.data)
546 return 1