From ffcebf4ddcbe4541597ce471418bdb6d962f726b Mon Sep 17 00:00:00 2001 From: Arne Symons Date: Thu, 24 Oct 2024 13:10:19 +0200 Subject: [PATCH] allow salsa engine in api call; remove old main files; update documentation --- docs/source/getting-started.rst | 17 +++---- docs/source/workload.rst | 2 +- main.py | 1 + main_onnx.py | 54 --------------------- main_onnx_salsa.py | 86 --------------------------------- zigzag/api.py | 8 ++- 6 files changed, 16 insertions(+), 152 deletions(-) delete mode 100644 main_onnx.py delete mode 100644 main_onnx_salsa.py diff --git a/docs/source/getting-started.rst b/docs/source/getting-started.rst index 1fa074545..66c38f351 100644 --- a/docs/source/getting-started.rst +++ b/docs/source/getting-started.rst @@ -29,7 +29,9 @@ The following command starts the execution using the provided inputs: .. code:: sh - python main_onnx.py --model zigzag/inputs/workload/resnet18.onnx --accelerator zigzag/inputs/hardware/tpu_like.yaml --mapping zigzag/inputs/mapping/tpu_like.yaml + python main.py --model zigzag/inputs/workload/resnet18.onnx --accelerator zigzag/inputs/hardware/tpu_like.yaml --mapping zigzag/inputs/mapping/tpu_like.yaml + +Below you can see the terminal outputs of this run: .. raw:: html @@ -37,21 +39,18 @@ The following command starts the execution using the provided inputs: Other ZigZag runs examples: -- The directory contains a directly runnable ``example.py`` file. +- The directory contains a directly runnable ``example.py`` file. This file directly defines the model, accelerator and mapping as Python variables, and thus doesn't require command line arguments. -- ZigZag can also run with user-defined workload (see section manual layer definition section in :doc:`workload`): +- ZigZag can also run with user-defined workloads as follows (see section manual layer definition section in :doc:`workload` for more information): .. code:: sh - python main_onnx.py --model zigzag/inputs/workload/resnet18.yaml --accelerator zigzag/inputs/hardware/tpu_like.yaml --mapping zigzag/inputs/mapping/tpu_like.yaml - -- ZigZag can also run with `SALSA temporal mapping search engine `_ which utilizes a different scheduler than the `LOMA scheduler `_: + python main.py --model zigzag/inputs/workload/resnet18.yaml --accelerator zigzag/inputs/hardware/tpu_like.yaml --mapping zigzag/inputs/mapping/tpu_like.yaml -.. code:: sh +ZigZag can also run with the `SALSA `_ temporal mapping search engine which utilizes a different optimizer than `LOMA `_. This can be done by setting the ``temporal_mapping_search_engine`` to 'salsa' in the api call in ``main.py``. - python main_onnx_salsa.py --model zigzag/inputs/workload/resnet18.onnx --accelerator zigzag/inputs/hardware/tpu_like.yaml --mapping zigzag/inputs/mapping/tpu_like.yaml Analyzing results ================= -During the run, results will be saved in the ``dump_folder`` provided in the ``main_onnx.py`` file, or as argument to the API function call. In total, five result files are saved, one for each supported onnx node the ``ONNXModelParserStage`` parsed (supported meaning it can be accelerated on one of the accelerator cores). Each result file contains the optimal energy and latency of running the onnx node on the core to which it was mapped through the ``mapping`` input file. Optimality is defined through the ``MinimalLatencyStage``, for more information we refer you to :doc:`stages`. The chosen loop ordering (spatial and temporal) and memory allocation are also saved in ``loop_ordering.txt``, as well as a graph of the hardware architecture's memory hierarchy and a bar plot of the results. +During the run, results will be saved in the ``dump_folder`` provided in the ``main.py`` file, or as argument to the API function call. In total, five result files are saved, one for each supported onnx node the ``ONNXModelParserStage`` parsed (supported meaning it can be accelerated on one of the accelerator cores). Each result file contains the optimal energy and latency of running the onnx node on the core to which it was mapped through the ``mapping`` input file. Optimality is defined through the ``MinimalLatencyStage``, for more information we refer you to :doc:`stages`. The chosen loop ordering (spatial and temporal) and memory allocation are also saved in ``loop_ordering.txt``, as well as a graph of the hardware architecture's memory hierarchy and a bar plot of the results. diff --git a/docs/source/workload.rst b/docs/source/workload.rst index 6169cddaa..c3ba74819 100644 --- a/docs/source/workload.rst +++ b/docs/source/workload.rst @@ -63,7 +63,7 @@ ZigZag requires an inferred onnx model, as it needs to know the shapes of all in Manual layer definition ======================= -It is also possible to manually define your own workload layers. In that case, the ``main.py`` file should be executed instead of ``main_onnx.py``. Moreover, the workload file should be provided as input together with the accelerator, and there is no onnx model loaded. +It is also possible to manually define your own workload layers. Each layer definition is represented as a YAML entry, which should have the following attributes: diff --git a/main.py b/main.py index b63968cc2..8456bb164 100644 --- a/main.py +++ b/main.py @@ -28,6 +28,7 @@ accelerator=args.accelerator, workload=args.model, mapping=args.mapping, + temporal_mapping_search_engine="loma", opt="latency", dump_folder=f"outputs/{experiment_id}", pickle_filename=f"outputs/{pickle_name}.pickle", diff --git a/main_onnx.py b/main_onnx.py deleted file mode 100644 index 0833337a0..000000000 --- a/main_onnx.py +++ /dev/null @@ -1,54 +0,0 @@ -import logging -import re - -from zigzag.parser.arguments import get_arg_parser -from zigzag.stages.AcceleratorParserStage import AcceleratorParserStage -from zigzag.stages.CostModelStage import CostModelStage -from zigzag.stages.MainStage import MainStage -from zigzag.stages.ONNXModelParserStage import ONNXModelParserStage -from zigzag.stages.reduce_stages import MinimalLatencyStage -from zigzag.stages.save_stages import SimpleSaveStage -from zigzag.stages.SpatialMappingGeneratorStage import SpatialMappingGeneratorStage -from zigzag.stages.temporal_mapping_generator_stage import TemporalMappingGeneratorStage -from zigzag.stages.WorkloadStage import WorkloadStage - -parser = get_arg_parser() -args = parser.parse_args() - -# Initialize the logger - -logging_level = logging.INFO -logging_format = "%(asctime)s - %(funcName)s +%(lineno)s - %(levelname)s - %(message)s" -logging.basicConfig(level=logging_level, format=logging_format) - -hw_name = args.accelerator.split(".")[-1] -wl_name = re.split(r"/|\.", args.model)[-1] -if wl_name == "onnx": - wl_name = re.split(r"/|\.", args.model)[-2] -experiment_id = f"{hw_name}-{wl_name}" -pkl_name = f"{experiment_id}-saved_list_of_cmes" - -# Initialize the MainStage which will start execution. -# The first argument of this init is the list of stages that will be executed in sequence. -# The second argument of this init are the arguments required for these different stages. -mainstage = MainStage( - [ # Initializes the MainStage as entry point - ONNXModelParserStage, # Parses the ONNX Model into the workload - AcceleratorParserStage, # Parses the accelerator - SimpleSaveStage, # Saves all received CMEs information to a json - WorkloadStage, # Iterates through the different layers in the workload - SpatialMappingGeneratorStage, # Generates multiple spatial mappings (SM) - MinimalLatencyStage, # Reduces all CMEs, returning minimal latency one - TemporalMappingGeneratorStage, # Generates multiple temporal mappings (TM) - CostModelStage, # Evaluates generated SM and TM through cost model - ], - accelerator=args.accelerator, # required by AcceleratorParserStage - workload=args.model, # required by ONNXModelParserStage - mapping=args.mapping, # required by ONNXModelParserStage - dump_folder=f"outputs/{experiment_id}", # output folder - loma_lpf_limit=6, # required by TemporalMappingGeneratorStage - loma_show_progress_bar=True, # shows a progress bar while iterating over temporal mappings -) - -# Launch the MainStage -mainstage.run() diff --git a/main_onnx_salsa.py b/main_onnx_salsa.py deleted file mode 100644 index 02da6d210..000000000 --- a/main_onnx_salsa.py +++ /dev/null @@ -1,86 +0,0 @@ -""" -===================================================================== -Title: main_onnx_salsa.py -Description: - -Date: 02.01.2023 - -===================================================================== - -Copyright (C) 2020 ETH Zurich and University of Bologna. - -Author: Victor Jung, ETH Zurich - -SPDX-License-Identifier: Apache-2.0 - -Licensed under the Apache License, Version 2.0 (the License); you may -not use this file except in compliance with the License. -You may obtain a copy of the License at - -www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an AS IS BASIS, WITHOUT -WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -""" - -import logging -import re - -from zigzag.parser.arguments import get_arg_parser -from zigzag.stages.AcceleratorParserStage import AcceleratorParserStage -from zigzag.stages.CostModelStage import CostModelStage -from zigzag.stages.MainStage import MainStage -from zigzag.stages.ONNXModelParserStage import ONNXModelParserStage -from zigzag.stages.reduce_stages import MinimalLatencyStage -from zigzag.stages.SalsaStage import SalsaStage -from zigzag.stages.save_stages import SimpleSaveStage -from zigzag.stages.SpatialMappingGeneratorStage import SpatialMappingGeneratorStage -from zigzag.stages.WorkloadStage import WorkloadStage - -parser = get_arg_parser() -args = parser.parse_args() - -# Initialize the logger - -logging_level = logging.INFO -logging_format = "%(asctime)s - %(funcName)s +%(lineno)s - %(levelname)s - %(message)s" -logging.basicConfig(level=logging_level, format=logging_format) - -hw_name = args.accelerator.split(".")[-1] -wl_name = re.split(r"/|\.", args.model)[-1] -if wl_name == "onnx": - wl_name = re.split(r"/|\.", args.model)[-2] -experiment_id = f"{hw_name}-{wl_name}" -pkl_name = f"{experiment_id}-saved_list_of_cmes" - -# Initialize the MainStage which will start execution. -# The first argument of this init is the list of stages that will be executed in sequence. -# The second argument of this init are the arguments required for these different stages. -mainstage = MainStage( - [ # Initializes the MainStage as entry point - ONNXModelParserStage, # Parses the ONNX Model into the workload - AcceleratorParserStage, # Parses the accelerator - SimpleSaveStage, # Saves all received CMEs information to a json - WorkloadStage, # Iterates through the different layers in the workload - SpatialMappingGeneratorStage, # Generates multiple spatial mappings (SM) - MinimalLatencyStage, # Reduces all CMEs, returning minimal latency one - SalsaStage, # Find pseudo-optimal temporal mapping - CostModelStage, # Evaluates generated SM and TM through cost model - ], - accelerator=args.accelerator, # required by AcceleratorParserStage - workload=args.model, # required by ONNXModelParserStage - mapping=args.mapping, # required by ONNXModelParserStage - dump_folder=f"outputs/{experiment_id}", # Output folder - loma_lpf_limit=6, # required by TemporalMappingGeneratorStage - loma_show_progress_bar=True, # shows a progress bar while iterating over temporal mappings - salsa_iteration_number=1000, - salsa_start_temperature=0.05, - salsa_opt_criterion="latency", - salsa_number_of_core=8, -) - -# Launch the MainStage -mainstage.run() diff --git a/zigzag/api.py b/zigzag/api.py index 11569b238..8810f0020 100644 --- a/zigzag/api.py +++ b/zigzag/api.py @@ -1,6 +1,6 @@ import logging from datetime import datetime -from typing import Any +from typing import Any, Literal from onnx import ModelProto @@ -11,6 +11,7 @@ SearchInterLayerDataLocalityStage, ) from zigzag.stages.main import MainStage +from zigzag.stages.mapping.salsa import SalsaStage from zigzag.stages.mapping.spatial_mapping_generation import SpatialMappingGeneratorStage from zigzag.stages.mapping.temporal_mapping_generator_stage import TemporalMappingGeneratorStage from zigzag.stages.parser.accelerator_parser import AcceleratorParserStage @@ -28,6 +29,7 @@ def get_hardware_performance_zigzag( accelerator: str, mapping: str, *, + temporal_mapping_search_engine: Literal["loma"] | Literal["salsa"] = "loma", opt: str = "latency", dump_folder: str = f"outputs/{datetime.now()}", pickle_filename: str | None = None, @@ -83,6 +85,8 @@ def get_hardware_performance_zigzag( do_exploint_inter_layer_locality = in_memory_compute or exploit_data_locality or enable_mix_spatial_mapping # Whether `mixed` mappings (e.g. `D1: {K:8, C:4}`) can be generated do_mix_spatial_mapping_generation = in_memory_compute or enable_mix_spatial_mapping + # Select temporal mapping engine based on the function input + temporal_mapping_engine = SalsaStage if temporal_mapping_search_engine == "salsa" else TemporalMappingGeneratorStage stages = [ # Parse the ONNX Model into the workload @@ -112,7 +116,7 @@ def get_hardware_performance_zigzag( # Reduce all CMEs, returning minimal energy/latency one opt_stage, # Generate multiple temporal mappings (TM) - TemporalMappingGeneratorStage, + temporal_mapping_engine, # Evaluate generated SM and TM through cost model CostModelStage, ]