From 18ec1719bb2b8aceb8fe142c63e2422da38ed937 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sergey=20Vostokov/AI=20Tools=20Lab=20/SRR/Staff=20Engineer/?= =?utf8?q?=EC=82=BC=EC=84=B1=EC=A0=84=EC=9E=90?= Date: Wed, 4 Jul 2018 16:34:22 +0900 Subject: [PATCH] Update SW HLD content (#322) Add HLD content This commit adds the content of High-Level Design Document Signed-off-by: Sergey Vostokov --- doc/images/nncc_components.png | Bin 0 -> 45359 bytes doc/project/high_level_design.md | 399 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 387 insertions(+), 12 deletions(-) create mode 100644 doc/images/nncc_components.png diff --git a/doc/images/nncc_components.png b/doc/images/nncc_components.png new file mode 100644 index 0000000000000000000000000000000000000000..becd63d147c8667585edcb2c506ff6a5d81777e4 GIT binary patch literal 45359 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

Omw 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 z + + + + + + + +Item +Assumptions, Dependencies and the Constraints +Reference + + + + +Tizen SW Platform +

+
The following items should be provided:
+
    +
  • Tizen API
  • +
  • Tizen kernel
  • +
  • Tizen FW
  • +
  • Tizen SDK
  • +
  • Tizen naming convention
  • +
+
+
+- www.tizen.org
- wiki.tizen.org
- developer.tizen.org + + +SmartMachine OS Platform +
+
The following items should be provided:
+
    +
  • SmartMachine API
  • +
  • SmartMachine kernel
  • +
  • SmartMachine FW
  • +
  • SmartMachine SDK
  • +
  • SmartMachine naming convention
  • +
+
+
+- Platform confluence
- Github
- Functional Safety confluence + + +Host OS +Linux-based OS (Ubuntu, Archlinux, etc) +- Ubuntu site
- Archlinux site + + +Tizen target HW +The reference device should be provided: Tizen TM2 + + + +SmartMachine target HW +The reference device should be provided + + + + +Table 1-2. Assumptions, Dependecies and the Constraints + ## SW System Architecture Design ### Overall Architecture +The picture below presents the result of high-level analysis of the +requirements which **nncc** should satisfy. It describes the main +function **Compilation** of the compiler collection using IDEF0 +(functional modeling) notation. The full information on IDEF family of +modeling languages is available at this link on [Wikipedia: +IDEF](https://en.wikipedia.org/wiki/IDEF). + +![image](../images/nncc_idef0_a0.png) + +Figure 1. Top-Level Context Diagram of compilation function. + + +The short explanation of the **Figure 1**: + +**1. Input entities:** + + - *NN Model instance:* It is the main input of *nncc*. The compiler + takes from a user information describing a neural network which + should be compiled. In most cases, this NN is produced by a + machine learning framework and stored in one or many files. The + contents of these files constitute the essence of the neural + network. Here it is denoted as an instance of NN model. + - *Command line options:* In order to provide the most convenient + way to use the compiler, it should be configurable. Current design + presents a tool which has a Command Line Interface (CLI). Command + line options are a symbolic representation of directions + instructing the compiler how to set up a working session to get + the desired result. + +**2. Output:** + + - *Target binaries:* Everything that is produced by the compilation + operation. In general case the result may consist of one or more + files. Each of them may be one of the following: an executable, a + source code file, a log/verification/error report. For example, + when we require the compiler to compile a neural network for + execution on GPU, the output artefact may be OpenCL/C/C++ source + code, or a binary containing invocation of the procedures + delegating the calculations to GPU. + +**3. Rules and notations:** + + - *NN Model specification:* Each machine learning framework has its + own architecture design and uses its own format to + serialize/deserialize computation graphs which represent neural + networks. On a storage device, it may be saved as a file or many + files using a unique markup of binary data. To enable *nncc* to + read such data and process it, in the future it should recognize + the format of the container. Importer/parser subsystem of *nncc* + stores the full knowledge of the NN specifications and is + responsible for reading and parsing NN models (see [Import NN + model](#import-nn-model)). + - *High-Level and Low-Level Optimization techniques:* Before + deployment, a neural network developer might want to verify their + product and optimize it by size and performance. There are many + techniques for reducing the common size of neural network weights + and improving performance of the inference. NN optimization + activity can be automated by implementing each technique in the + middleend according to its specifications (see [Apply + Optimizations](#apply-optimizations)). + - *Target Runtime Environment (TRE):* In the case when the compiler + produces the binary for execution on a specific SW platform, it + should take into account the common API of this SW Platform. It + includes the full public API of a chosen OS available to the 3rd + party developers. + - *Target Instruction Set Architecture (Target ISA):* Resulting + artefact is always executed on a SW Platform using some specified + API. The user may want to generate the artefact that would use + OpenBlas or Arm Compute Library or something else (if supported by + the compiler), to perform calculations. In order to provide such + possibility, *nncc* should be aware of the API to the specified + 3rd party libraries. + - *Device specifications:* Some of the optimization techniques may + take into account the technological features of the computing + device, like the time to perform some specific calculations. Such + information is very helpful during optimization of the final code + of the compiled artefact because it may be used to select an + optimal sequence of command invocations in order to achieve the + best performance. + +**4. Mechanism:** + + - *Optimizing NN Compiler:* The implemented compiler itself. Since + *nncc* is dedicated to producing the code for the most efficient + execution, we may regard the tool as optimizing. + - *Host OS:* Since the compiler is a tool that works in some SW + Environment, the main Top-Level SW system is an Operating System. + In the SW Requirements specification it may be defined as a + Linux-like OS, for example Ubuntu, Archlinux, etc. + ### Composition of Architecture -| Layer or Subsystem Name | Description | -| ----------------------- | ----------- | -| | -| | -| | +The compiler consists of three main parts: frontend, middleend, backend. +Together they form a Neural Network instance processing pipeline. +Moreover, there is one additional part that is in charge of the compiler +configuration. + +![image](../images/nncc_components.png) + +Figure 2. Top-Level Components of the +*nncc*. + +| Layer or Subsystem Name | Description | +| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | +| Frontend | Imports a specified Neural Network, presents it as a computation graph | +| Middleend | Provides various optimizations over the computation graph; at the end transforms it to internal IR | +| Backend | Produces the specified artefact as a result of compilation procedure using specified parameters describing the target OS, target HW, etc | +| Configuration system | Accepts command line options and configures *nncc* according to their contents | + + +The detailed decomposition of the main function **Compilation** is +presented on the diagram A1 below. ### Interface +Similar to any console application the *nncc* CLI accepts two types of +options: + + - Options that have values, for example, a name of the output executable + - Options that don't have values (switches) that turn various features on and off + +Additionally, options can be general and subsystem-specific. + +General options direct the process of the neural network compilation as +a whole, and also control the utility functions like the verbosity of +the messages that *nncc* outputs during the compilation process. + +Subsystem-specific options control each respective subsystem: + + - Frontend subsystem takes options that point to the NN model to + compile, which format it has, which version of the format and so + on. + - Middleend subsystem takes options that either turn on specific + optimizations for the NN model, or just point at the more desired + outcome, for example "target performance efficiency" or "target + memory efficiency". + - Backend subsystem takes options that describe the desired target + device or architecture and so on. + +For better usability, high-level options are also supported. A single +high-level option is mapped to a group of lower level options, similarly +to how it is done with conventional compiler drivers, like gcc. This way +by choosing a single Middleend option "target performance", nncc will +automatically choose a number of performance optimizations by itself. + ## SW System Operation Design -## Appendix 1. Tracebility Matrix +The Figure 3 presents a more detailed composition of the main function +**Compilation**. As it was shown in previous section [Composition of +Architecture](#composition-of-architecture) it is composed of 5 +subfunctions: + + - Setup and configure each module - *Block 1* (See + [Initialization](#initialization) section) + - Import the specified neural network - *Block 2* (See [Import NN + model](#import-nn-model) section) + - Apply High-Level optimizations - *Block 3* (See [Apply + Optimizations](#apply-optimizations) section) + - Apply Low-Level optimizations - *Block 4* (See [Apply + Optimizations](#apply-optimizations) section) + - Generate the output code for specified target - *Block 5* (See + [Generate the code](#generate-the-code) section) + +![image](../images/nncc_idef0_a1.png) + +Figure 3. Decomposition of top-Level function **Compilation**. + +### Initialization + +At this stage the initialization of all submodules of the *nncc* +happens. This procedure starts from command line option processing till +selection of all required and correctly configured modules. At the +parsing stage the configuration system checks its own consistency. If +command line option set is not enought to establish a valid +configuration the environment variables will be used. Also, almost all +configuration options can be read from config file if it is specified in +command line. + +### Import NN model + +The major function of the *nncc* frontend is to import specified NN +model. It means that frontend should recognize the format of given NN +model, parse all internal structures (load computation graph using +framework specific IR: NN topology, NN ops, weights), verify their +correctness and convert to Model IR. + +### Apply Optimizations + +There are two levels of neural network optimizations in *nncc*. + +First one is High-Level Optimizations, they are applied to the Model IR, +which is output by the NN Import subsystem. + +#### High-Level Optimizations + +High-Level optimizations can be divided into two groups: + + - optimizations aimed at reducing the size of the resulting model - + *size optimizations* + - optimizations aimed at reducing the inference time of the model - + *performance optimizations* + +These two groups are not mutually exclusive. Some optimization +techniques positively affect both size and performance, while some of +them might reduce the size of the model at some performance cost. + +High-Level Optimizations in this sense are purely +neural-network-specific, as they attempt to improve the model by +manipulating the computation graph and the weights. For example, some +techniques search for unused parts of the computation graph and remove +them, or they search for the parts of the graph that can be merged +together and thus gain some performance. Other techniques manipulate the +neural network weights - either reduce their amount or modify their +values in a way that allows for the reduced storage consumption. + +Currently, High-Level Optimizations are out of scope of the project. + +#### Low-Level Optimization + +The Low-Level Optimizations are applied by the compiler closer to the +end of the whole compilation process, before the executable generation. +The input for this stage of *nncc* is the Coarse-Grained IR, which is +output but High-Level Optimization subsystem. + +### Generate the code + +Present architecture allows for several backend solutions, depending on +target specified. Those solutions can be divided into 3 types: + + - *Interpretation.* At every step inference can be carried out by + interpreting IR produced after that step. + - *Soft backend.* Resulting program can be generated as source code + in high-level programming language (e.g., C/C++) that does not + depend on libraries outside of itself, with the exception of + system libraries. + - *Hardware (Binary) backend.* This type refers to generating binary + code that can be executed on target device. NN compiler can + generate code that is either executed solely on CPU, or takes + advantage of the GPU when possible if corresponding target was + specified. + +Third-party libraries incorporation can be done either in form of source +code or by compiling a binary artefact. + +## Appendix 1. Traceability Matrix + +The following table shows mapping between SW Requirements Specification +and SW High-Level Design +Document. + +| Requirement | Description | Section | +| ----------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- | +| RF-1 (Frontend: Tensorflow Lite) | The compiler should support import of NN model in Tensorflow Lite format (parsing & verification of data scheme v0-v3, 50 NN ops) | [Import NN model](#import-nn-model) | +| RF-2 (Frontend: Caffe) | The compiler should support import of NN model in Caffe format (parsing & verification) | [Import NN model](#import-nn-model) | +| RF-3 (Frontend: Caffe2 (Optional)) | The compiler should support import of NN model in Caffe2 format (parsing & verification) | [Import NN model](#import-nn-model) | +| RF-4 (Frontend: lossless import) | The frontend should use the lossless approach while it is converting any NN model to IR | [Import NN model](#import-nn-model) | +| RF-5 (Frontend: Inception\_v3) | The frontend should successful import the Inception V3 NN model | [Import NN model](#import-nn-model) | +| RF-6 (Frontend: MobileNet) | The frontend should successful import the MobileNet NN model | [Import NN model](#import-nn-model) | +| RF-7 (Backend: ARM CPU) | The compiler should produce executable for ARM CPU | [Generate the code](#generate-the-code) | +| RF-8 (Backend: ARM GPU) | The compiler should produce the binary that takes advantages of GPU when it was specified before compilation | [Generate the code](#generate-the-code) | +| RF-9 (Backend: Artefact type) | The compiler should produce executable as a shared library or as a static library | [Generate the code](#generate-the-code) | +| RF-10 (Backend: Inception\_v3) | The compiler should produce the valid compiled artefact for Inception v3 NN model | [Generate the code](#generate-the-code) | +| RF-11 (Backend: MobileNet) | The compiler should produce the valid compiled artefact for MobileNet NN model | [Generate the code](#generate-the-code) | +| RF-12 (Config: command line) | The compiler should get configuration parameters from command line | [Initialization](#initialization) | +| RF-13 (Config: config file (Optional)) | The compiler should get configuration parameters from config file | [Initialization](#initialization) | +| RF-14 (Config: environment variable (Optional)) | The compiler should get configuration parameters from environment variables | [Initialization](#initialization) | +| RF-15 (Artefact: result) | The artefact should provide comparable result to the original NN model for the same input data | [Generate the code](#generate-the-code) | +| RF-16 (Artefact: input verifications) | The artefact should verify any input data and check consistency | [Generate the code](#generate-the-code) | +| RF-17 (Artefact: GPU) | The artefact should take advantage of the GPU for GPU-enabled operations | [Generate the code](#generate-the-code) | +| RF-18 (Artefact: CPU) | The artefact should take advantage of CPU if it was specified | [Generate the code](#generate-the-code) | + +**Design Module of S/W Architecture** + +| Requirement | Import NN model | Generate the code | Initialization | +| ----------------------------------------------- | --------------- | ----------------- | -------------- | +| RF-1 (Frontend: Tensorflow Lite) | O | | | +| RF-2 (Frontend: Caffe) | O | | | +| RF-3 (Frontend: Caffe2 (Optional)) | O | | | +| RF-4 (Frontend: lossless import) | O | | | +| RF-5 (Frontend: Inception\_v3) | O | | | +| RF-6 (Frontend: MobileNet) | O | | | +| RF-7 (Backend: ARM CPU) | | O | | +| RF-8 (Backend: ARM GPU) | | O | | +| RF-9 (Backend: Artefact type) | | O | | +| RF-10 (Backend: Inception\_v3) | | O | | +| RF-11 (Backend: MobileNet) | | O | | +| RF-12 (Config: command line) | | | O | +| RF-13 (Config: config file (Optional)) | | | O | +| RF-14 (Config: environment variable (Optional)) | | | O | +| RF-15 (Artefact: result) | | O | | +| RF-16 (Artefact: input verifications) | | O | | +| RF-17 (Artefact: GPU) | | O | | +| RF-18 (Artefact: CPU) | | O | | -- 2.7.4