NVIDIA NvNeural SDK  2021.2
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  std::unordered_map<std::string, std::vector<std::string>> getInnerInlinedTemplates() const;
101  std::unordered_map<std::string, std::string> getSynonyms() const { return m_synonyms; }
102 
103 private:
104  int m_modelVersion;
105 
106  struct rulex // rule lexeme
107  {
108  enum TypeCode : uint8_t
109  {
110  ID,
111  INTEGER,
112  FLOAT,
113  DIMENSION,
114  STRING,
115  OPERATOR,
116  COMMENT,
117  FATAL_ERROR,
118  };
119  TypeCode type = FATAL_ERROR;
120  std::string value;
121  };
122  std::vector<rulex> lexParser(const std::string& text);
123 
124  struct ruleSyntaxTreeNode
125  {
126  enum class TypeCode
127  {
128  RULE,
129  LAYER,
130  INPUTS,
131  SELECTION,
132  RANGE,
133  ANY,
134  CONSTANT,
135  PARAMETER,
136  OR,
137  AND,
138  COMP,
139  FATAL_ERROR,
140  };
141  TypeCode type = TypeCode::FATAL_ERROR;
142  rulex literal;
143  rulex flag;
144  std::vector<ruleSyntaxTreeNode> params;
145  };
146  ruleSyntaxTreeNode syntaxParser(std::vector<rulex>& lexemes);
147  ruleSyntaxTreeNode syntaxParseLayer(std::vector<rulex>& lexemes, size_t& offset);
148  ruleSyntaxTreeNode syntaxParseConditionOr(std::vector<rulex>& lexemes, size_t& offset);
149  ruleSyntaxTreeNode syntaxParseInputs(std::vector<rulex>& lexemes, size_t& offset);
150  ruleSyntaxTreeNode syntaxParseSelection(std::vector<rulex>& lexemes, size_t& offset);
151  ruleSyntaxTreeNode syntaxParseConditionAnd(std::vector<rulex>& lexemes, size_t& offset);
152  ruleSyntaxTreeNode syntaxParseComparison(std::vector<rulex>& lexemes, size_t& offset);
153  ruleSyntaxTreeNode syntaxParseOperand(std::vector<rulex>& lexemes, size_t& offset);
154  ruleSyntaxTreeNode syntaxParseRange(std::vector<rulex>& lexemes, size_t& offset);
155  void syntaxError(const ruleSyntaxTreeNode& errorResult, size_t offset) const;
156 
157  bool m_debugFusingScript = false;
158  void printSyntaxTree(const ruleSyntaxTreeNode& node, int indent) const;
159 
160  std::vector<ruleSyntaxTreeNode> m_fusingScripts;
161 
162  static std::vector<std::string> s_includeDirs;
163  static std::string findFile(const std::string& fileName);
164 
165  XmlModelPreprocessor* m_pParent;
166  bool m_inlineModels;
167  std::string m_fileName;
168  bool checkExternalCollision(const std::string& fileName) const;
169 
170  std::string m_lastError;
171  void setError(const std::string& text); // differs from original
172  void setError(const std::string& text, const pugi::xml_node& node);
173  void addError(const std::string& text);
174 
175  struct modelLayerNode
176  {
177  std::string finalName;
178  std::vector<std::string> inputList;
179  pugi::xml_node xmlNode; // "layer node (can't be from template, only final nodes of model)"
180  pugi::xml_node templateNode; // "template node (for overwrites)"
181  };
182 
183  std::string inputLayerName(std::string input);
184  std::string inputLayerName(modelLayerNode &node, size_t index);
185 
186  std::vector<std::string> m_inputs;
187  std::vector<ioDesc> m_inputDescriptors;
188  std::unordered_map<std::string, modelLayerNode> m_table;
189  std::vector<std::string> m_outputs;
190  std::unordered_map<std::string, std::string> m_outputLink;
191  std::vector<ioDesc> m_outputDescriptors;
192  std::unordered_map<std::string, std::string> m_customLayers;
193  std::unordered_set<std::string> m_cutLayers;
194  std::unordered_map<std::string, std::vector<std::string>> m_innerInlinedTemplateLayers;
195  std::unordered_map<std::string, std::string> m_synonyms;
196 
197  std::vector<pugi::xml_node> m_extraNodes;
198 
199  bool tryFusingLayer(modelLayerNode& layer, ruleSyntaxTreeNode& rule);
200  std::string collectFusingInputs(modelLayerNode& layer, std::vector<std::string>& fusingInputs);
201  bool interpretLayer(modelLayerNode& layer, ruleSyntaxTreeNode& rule, std::vector<std::string>& fused);
202  bool interpretCondition(modelLayerNode& layer, ruleSyntaxTreeNode& rule);
203  bool interpretInputs(modelLayerNode& layer, ruleSyntaxTreeNode& rule, std::vector<std::string>& fused, size_t& in_index);
204  bool interpretSelection(modelLayerNode& layer, ruleSyntaxTreeNode& rule, std::vector<std::string>& fused, size_t& in_index);
205  bool interpretParameter(modelLayerNode& layer, ruleSyntaxTreeNode& rule, rulex& op);
206  bool interpretCheckBreak(ruleSyntaxTreeNode& rule, int count);
207 
208  XmlModelPreprocessor* getSubgraphAsModel(
209  const std::vector<std::string>& inputs,
210  const std::vector<std::string>& outputs);
211 
212  bool inlineTemplate(
213  pugi::xml_node& network,
214  const XmlModelPreprocessor* pTempModel,
215  std::unordered_map<std::string, std::string> &synonym,
216  const std::string& name,
217  pugi::xml_node& layer,
218  const std::string& input,
219  bool isInnerTemplate);
220 
221  pugi::xml_document m_model;
222 
223  bool parseModel(pugi::xml_node networkModel, int version);
224  bool backWayCollector(
225  const std::string& node,
226  std::unordered_set<std::string>& collection,
227  std::vector<std::string>& controlStack,
228  const std::vector<std::string>* pStopList);
229 
230  std::unordered_map<std::string, std::unique_ptr<XmlModelPreprocessor>> m_innerTemplates;
231  std::unordered_map<std::string, std::unique_ptr<XmlModelPreprocessor>> m_externTemplates;
232  std::unordered_map<std::string, std::unique_ptr<XmlModelPreprocessor>> m_patternTemplates;
233 
234  enum class FusingRuleLayoutScope
235  {
236  Nchw = 0,
237  Nhwc = 1,
238  Any = 2,
239  };
240 
241  enum class FusingRuleDataTypeScope
242  {
243  Float = 0,
244  Half = 1,
245  Any = 2,
246  };
247 
248  bool preprocessFusingScriptScope(std::vector<rulex>& lexemes, FusingRuleLayoutScope& layoutScope, FusingRuleDataTypeScope& dataTypeScope) const;
249  bool checkAndAddFusingScript(const std::vector<rulex> lexemes);
250  bool checkFusingScript(const std::vector<rulex>& lexemes); // equivalent to checkAndAdd without the add
251 };
252 
253 } } // namespace nvneural::detail
254 #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.