NVIDIA NvNeural SDK  2021.1
GPU inference framework for NVIDIA Nsight Deep Learning Designer
ModelPreprocessor.h
Go to the documentation of this file.
1 /*
2 * SPDX-FileCopyrightText: Copyright (c) 2020-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3 * SPDX-License-Identifier: MIT
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23 
25 
26 #ifndef NVNEURAL_MODELPREPROCESSOR_H
27 #define NVNEURAL_MODELPREPROCESSOR_H
28 
29 #include <nvneural/CoreTypes.h>
30 #include <Pugixml/pugixml.hpp>
31 #include <memory>
32 #include <unordered_map>
33 #include <unordered_set>
34 #include <vector>
35 
36 namespace nvneural { namespace detail {
37 
44 class XmlModelPreprocessor
45 {
46 public:
47  explicit XmlModelPreprocessor(XmlModelPreprocessor* pParent = nullptr, bool inlineModels = false);
48  ~XmlModelPreprocessor();
49  void clear();
50 
51  void addCustomLayer(const std::string& layer);
52 
53  enum class FusingRuleResult : std::uint16_t
54  {
55  Success = 0,
56  OutOfScope = 1,
57  Failure = 2
58  };
59  FusingRuleResult addFusingScript(const std::string& script);
60 
62  FusingRuleResult addScopedFusingScript(const TensorFormat& currentScope, const std::string& script);
63  void setScriptDebug(bool enable);
64 
65  void addCutLayer(const std::string name);
66 
67  bool loadModelText(const std::string& text, bool autoUpdateModelVersion = true);
68  bool loadModelFile(const std::string& fileName, bool autoUpdateModelVersion = true);
69  bool generateLinked(pugi::xml_document& doc);
70  std::string serializeCurrent() const;
71 
72  bool supportedByEditor() const;
73 
74  static void pushIncludeDirectory(const std::string& path);
75 
76  // "for inference"
77  struct ioDesc
78  {
79  std::string name;
80  std::string source;
81  };
82  const std::vector<ioDesc>& getOutputs() const;
83  const std::vector<ioDesc>& getInputs() const;
84 
85  int searchOutputDescIndex(const std::string& layerName) const;
86 
87  // static helpers for working with the XML model
88  static void cloneXmlNode(pugi::xml_node& dest, const pugi::xml_node& src);
89  static bool isCustomScripted(const pugi::xml_node& layer);
90  static bool isInputTypeLayer(const std::string& type);
91 
92  const static std::vector<std::string> m_prototypeCode;
93 
94  int currentModelVersion() const; // see header
95  static int actualModelVersion(); // see header
96  void updateModelVersion();
97 
98  std::string getLastError() const; // see header
99 
100 private:
101  int m_modelVersion;
102 
103  struct rulex // rule lexeme
104  {
105  enum TypeCode : uint8_t
106  {
107  ID,
108  INTEGER,
109  FLOAT,
110  DIMENSION,
111  STRING,
112  OPERATOR,
113  COMMENT,
114  FATAL_ERROR,
115  };
116  TypeCode type = FATAL_ERROR;
117  std::string value;
118  };
119  std::vector<rulex> lexParser(const std::string& text);
120 
121  struct ruleSyntaxTreeNode
122  {
123  enum class TypeCode
124  {
125  RULE,
126  LAYER,
127  INPUTS,
128  SELECTION,
129  RANGE,
130  ANY,
131  CONSTANT,
132  PARAMETER,
133  OR,
134  AND,
135  COMP,
136  FATAL_ERROR,
137  };
138  TypeCode type = TypeCode::FATAL_ERROR;
139  rulex literal;
140  rulex flag;
141  std::vector<ruleSyntaxTreeNode> params;
142  };
143  ruleSyntaxTreeNode syntaxParser(std::vector<rulex>& lexemes);
144  ruleSyntaxTreeNode syntaxParseLayer(std::vector<rulex>& lexemes, size_t& offset);
145  ruleSyntaxTreeNode syntaxParseConditionOr(std::vector<rulex>& lexemes, size_t& offset);
146  ruleSyntaxTreeNode syntaxParseInputs(std::vector<rulex>& lexemes, size_t& offset);
147  ruleSyntaxTreeNode syntaxParseSelection(std::vector<rulex>& lexemes, size_t& offset);
148  ruleSyntaxTreeNode syntaxParseConditionAnd(std::vector<rulex>& lexemes, size_t& offset);
149  ruleSyntaxTreeNode syntaxParseComparison(std::vector<rulex>& lexemes, size_t& offset);
150  ruleSyntaxTreeNode syntaxParseOperand(std::vector<rulex>& lexemes, size_t& offset);
151  ruleSyntaxTreeNode syntaxParseRange(std::vector<rulex>& lexemes, size_t& offset);
152  void syntaxError(const ruleSyntaxTreeNode& errorResult, size_t offset) const;
153 
154  bool m_debugFusingScript = false;
155  void printSyntaxTree(const ruleSyntaxTreeNode& node, int indent) const;
156 
157  std::vector<ruleSyntaxTreeNode> m_fusingScripts;
158 
159  static std::vector<std::string> s_includeDirs;
160  static std::string findFile(const std::string& fileName);
161 
162  XmlModelPreprocessor* m_pParent;
163  bool m_inlineModels;
164  std::string m_fileName;
165  bool checkExternalCollision(const std::string& fileName) const;
166 
167  std::string m_lastError;
168  void setError(const std::string& text); // differs from original
169  void setError(const std::string& text, const pugi::xml_node& node);
170  void addError(const std::string& text);
171 
172  struct modelLayerNode
173  {
174  std::string finalName;
175  std::vector<std::string> inputList;
176  pugi::xml_node xmlNode; // "layer node (can't be from template, only final nodes of model)"
177  pugi::xml_node templateNode; // "template node (for overwrites)"
178  };
179 
180  std::string inputLayerName(std::string input);
181  std::string inputLayerName(modelLayerNode &node, size_t index);
182 
183  std::vector<std::string> m_inputs;
184  std::vector<ioDesc> m_inputDescriptors;
185  std::unordered_map<std::string, modelLayerNode> m_table;
186  std::vector<std::string> m_outputs;
187  std::unordered_map<std::string, std::string> m_outputLink;
188  std::vector<ioDesc> m_outputDescriptors;
189  std::unordered_map<std::string, std::string> m_customLayers;
190  std::unordered_set<std::string> m_cutLayers;
191 
192  std::vector<pugi::xml_node> m_extraNodes;
193 
194  bool tryFusingLayer(modelLayerNode& layer, ruleSyntaxTreeNode& rule);
195  std::string collectFusingInputs(modelLayerNode& layer, std::vector<std::string>& fusingInputs);
196  bool interpretLayer(modelLayerNode& layer, ruleSyntaxTreeNode& rule, std::vector<std::string>& fused);
197  bool interpretCondition(modelLayerNode& layer, ruleSyntaxTreeNode& rule);
198  bool interpretInputs(modelLayerNode& layer, ruleSyntaxTreeNode& rule, std::vector<std::string>& fused, size_t& in_index);
199  bool interpretSelection(modelLayerNode& layer, ruleSyntaxTreeNode& rule, std::vector<std::string>& fused, size_t& in_index);
200  bool interpretParameter(modelLayerNode& layer, ruleSyntaxTreeNode& rule, rulex& op);
201  bool interpretCheckBreak(ruleSyntaxTreeNode& rule, int count);
202 
203  XmlModelPreprocessor* getSubgraphAsModel(
204  const std::vector<std::string>& inputs,
205  const std::vector<std::string>& outputs);
206 
207  bool inlineTemplate(
208  const XmlModelPreprocessor* pTempModel,
209  std::unordered_map<std::string, std::string> &synonym,
210  const std::string& name,
211  pugi::xml_node& layer,
212  const std::string& input);
213 
214  pugi::xml_document m_model;
215 
216  bool parseModel(pugi::xml_node networkModel, int version);
217  bool backWayCollector(
218  const std::string& node,
219  std::unordered_set<std::string>& collection,
220  std::vector<std::string>& controlStack,
221  const std::vector<std::string>* pStopList);
222 
223  std::unordered_map<std::string, std::unique_ptr<XmlModelPreprocessor>> m_innerTemplates;
224  std::unordered_map<std::string, std::unique_ptr<XmlModelPreprocessor>> m_externTemplates;
225  std::unordered_map<std::string, std::unique_ptr<XmlModelPreprocessor>> m_patternTemplates;
226 
227  enum class FusingRuleLayoutScope
228  {
229  Nchw = 0,
230  Nhwc = 1,
231  Any = 2,
232  };
233 
234  enum class FusingRuleDataTypeScope
235  {
236  Float = 0,
237  Half = 1,
238  Any = 2,
239  };
240 
241  bool preprocessFusingScriptScope(std::vector<rulex>& lexemes, FusingRuleLayoutScope& layoutScope, FusingRuleDataTypeScope& dataTypeScope) const;
242  bool checkAndAddFusingScript(const std::vector<rulex> lexemes);
243  bool checkFusingScript(const std::vector<rulex>& lexemes); // equivalent to checkAndAdd without the add
244 };
245 
246 } } // namespace nvneural::detail
247 #endif // NVNEURAL_MODELPREPROCESSOR_H
Fundamental NvNeural data types are declared here.
@ Float
32-bit floating point elements (float)
@ Half
16-bit floating point elements (__half)
@ Success
Operation succeeded. Generic result.
@ Failure
Operation failed. Generic result.