• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Arm Limited.
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 #ifndef SRC_RUNTIME_CL_MLGO_MLGO_PARSER_H
25 #define SRC_RUNTIME_CL_MLGO_MLGO_PARSER_H
26 
27 #include "src/runtime/CL/mlgo/MLGOHeuristics.h"
28 
29 #include <deque>
30 #include <istream>
31 #include <string>
32 #include <utility>
33 
34 /** A DotMLGO file parser (LL(k) parser)
35  *
36  * The grammar of DotMLGO is defined as the following ENBF:
37  *
38  * delim = "," | "\n"; // Note that delimiters are omitted from the definition below
39  *
40  * mlgo = header, heuristics-table, {heuristic-tree};
41  *
42  * header = "<header>", gemm-version, ip-type, "</header>";
43  * gemm-version = "gemm-version",  "[", int,  int,  int, "]";
44  * ip-type = "ip-type",  ("gpu" | "cpu");
45  *
46  * heiristics-table = "<heuristics-table>", {heuristics-table-entry}, "</heuristics-table>";
47  * heuristics-table-entry = entry-id,  ip-name,  num-cores, data-type,  gpu-priority,  gpu-behavior,  heuristic-type,  free-vars;
48  * entry-id = int;
49  * ip-name = char-sequence;
50  * num-cores = int;
51  * data-type = "f32" | "f16" | "qasymm8";
52  * gpu-priority = "best-performance" | "best-memory-usage";
53  * gpu-behavior = "static" | "dynamic";
54  * heuristic-type = "gemm-type" | "gemm-config-native" | "gemm-config-reshaped-only-rhs" | "gemm-config-reshaped";
55  * free-vars = "[", {char-sequence}, "]";
56  *
57  * heuristic-tree = "<heuristic",  entry-id, ">", {tree-node}, "</heuristic>";
58  * tree-node = branch-node | leaf-node;
59  * branch-node = "b",  entry-id,  lhs-type,  lhs-value,  conditional-op,  rhs-type,  rhs-value,  true-node,  false-node;
60  * lhs-type = comparator-type;
61  * lhs-value = comparator-value;
62  * rhs-type = comparator-type;
63  * rhs-value = comparator-value;
64  * comparator-type = "var" | "num" | "enum";
65  * comparator-value = char-sequence | float;
66  * conditional-op = "<" | "<=" | "==" | ">=" | ">";
67  * true-node = entry-id;
68  * false-node = entry-id;
69  * leaf-node = "l",  entry-id,  heuristic-type,  leaf-value;
70  * leaf-value = gemm-type | gemm-config-native | gemm-config-reshaped-only-rhs | gemm-config-reshaped
71  * gemm-type = "native" | "reshaped-only-rhs" | "reshaped";
72  * gemm-config-native = "[", int, int, int, "]";
73  * gemm-config-reshaped-only-rhs = "[", int, int, int, int, bool, bool, bool, "]";
74  * gemm-config-reshaped = "[", int, int, int, int, int, bool, bool, bool, bool, "]";
75  */
76 
77 namespace arm_compute
78 {
79 namespace mlgo
80 {
81 namespace parser
82 {
83 /** Type of Token */
84 enum class TokenType
85 {
86     L_List = '[', /**< List open */
87     R_List = ']', /**< List close */
88     Int,          /**< Integral */
89     Float,        /**< Floating */
90     Text,         /**< Text/String */
91     End,          /**< End of stream */
92 };
93 
94 struct CharPosition
95 {
96     bool operator==(const CharPosition &other) const
97     {
98         return ln == other.ln && col == other.col;
99     }
100 
101     size_t ln{ 0 };
102     size_t col{ 0 };
103 };
104 
105 /** Token */
106 struct Token
107 {
TokenToken108     Token(TokenType t, std::string v, CharPosition pos)
109         : type{ t }, value{ v }, pos{ pos }
110     {
111     }
112 
113     bool operator==(const Token &other) const
114     {
115         return type == other.type && value == other.value && pos == other.pos;
116     }
117 
118     TokenType    type;  /**< Token type */
119     std::string  value; /**< Token value */
120     CharPosition pos;
121 };
122 
123 /** A stream of token */
124 class TokenStream
125 {
126     // NOTE: _tokens is never empty. The end of token stream is signalled by the End Token
127 public:
128     static constexpr size_t max_look_ahead = 10;
129 
130 public:
131     /** Constructor
132      *
133      * @param[in] s      Input stream
134      * @param[in] delims Delimiter characters packed in a string. Each char from the string can be used as a delim on its own
135      */
136     TokenStream(std::istream &s, const std::string &delims = ",\n");
137 
138     /** Check if there're more (non-End) Tokens
139      * @return true  If there are more tokens
140      * @return false If reached end of stream (only End token)
141      */
142     explicit operator bool() const;
143 
144     /** Get and pop off the current token
145      *
146      * @return Token
147      */
148     Token take();
149 
150     /** Peek the next ith token
151      *
152      * @param[in] i The next ith token. i < @ref max_look_ahead.
153      *
154      * @return Token
155      */
156     Token peek(size_t i = 0);
157 
158     /** Get the position of the current token
159      *
160      * @return CharPosition
161      */
current_pos()162     CharPosition current_pos() const
163     {
164         return _tokens.front().pos;
165     }
166 
167 private:
168     void read();
169 
170     Token recognize_tok(char ch);
171 
172     Token num_st(std::string value = "");
173 
174     Token float_after_dp_st(std::string value = "");
175 
176     Token text_st(std::string value = "");
177 
178     bool reached_end() const;
179 
180     bool is_delim(char ch) const;
181 
182     std::string       _delims;
183     std::istream     &_istream;
184     std::deque<Token> _tokens;
185     CharPosition      _lookahead_pos;
186 };
187 
188 /** Parse and construct a @ref MLGOHeuristics from input stream
189  *
190  * @param[in] in Input stream
191  *
192  * @return MLGOHeuristics
193  */
194 std::pair<bool, MLGOHeuristics> parse_mlgo(std::istream &in);
195 
196 } // namespace parser
197 } // namespace mlgo
198 } // namespace arm_compute
199 #endif //SRC_RUNTIME_CL_MLGO_MLGO_PARSER_H