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