SiCong Li | 7061eb2 | 2021-01-08 15:16:02 +0000 | [diff] [blame] | 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 | */ |
SiCong Li | 70858d8 | 2021-02-05 09:19:51 +0000 | [diff] [blame] | 24 | #ifndef SRC_RUNTIME_CL_MLGO_MLGO_PARSER_H |
| 25 | #define SRC_RUNTIME_CL_MLGO_MLGO_PARSER_H |
SiCong Li | 7061eb2 | 2021-01-08 15:16:02 +0000 | [diff] [blame] | 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 | |
Felix Thomasmathibalan | afd38f0 | 2023-09-27 17:46:17 +0100 | [diff] [blame] | 101 | size_t ln{0}; |
| 102 | size_t col{0}; |
SiCong Li | 7061eb2 | 2021-01-08 15:16:02 +0000 | [diff] [blame] | 103 | }; |
| 104 | |
| 105 | /** Token */ |
| 106 | struct Token |
| 107 | { |
Felix Thomasmathibalan | afd38f0 | 2023-09-27 17:46:17 +0100 | [diff] [blame] | 108 | Token(TokenType t, std::string v, CharPosition pos) : type{t}, value{v}, pos{pos} |
SiCong Li | 7061eb2 | 2021-01-08 15:16:02 +0000 | [diff] [blame] | 109 | { |
| 110 | } |
| 111 | |
| 112 | bool operator==(const Token &other) const |
| 113 | { |
| 114 | return type == other.type && value == other.value && pos == other.pos; |
| 115 | } |
| 116 | |
| 117 | TokenType type; /**< Token type */ |
| 118 | std::string value; /**< Token value */ |
| 119 | CharPosition pos; |
| 120 | }; |
| 121 | |
| 122 | /** A stream of token */ |
| 123 | class TokenStream |
| 124 | { |
| 125 | // NOTE: _tokens is never empty. The end of token stream is signalled by the End Token |
| 126 | public: |
| 127 | static constexpr size_t max_look_ahead = 10; |
| 128 | |
| 129 | public: |
| 130 | /** Constructor |
| 131 | * |
| 132 | * @param[in] s Input stream |
| 133 | * @param[in] delims Delimiter characters packed in a string. Each char from the string can be used as a delim on its own |
| 134 | */ |
| 135 | TokenStream(std::istream &s, const std::string &delims = ",\n"); |
| 136 | |
| 137 | /** Check if there're more (non-End) Tokens |
| 138 | * @return true If there are more tokens |
| 139 | * @return false If reached end of stream (only End token) |
| 140 | */ |
| 141 | explicit operator bool() const; |
| 142 | |
| 143 | /** Get and pop off the current token |
| 144 | * |
| 145 | * @return Token |
| 146 | */ |
| 147 | Token take(); |
| 148 | |
| 149 | /** Peek the next ith token |
| 150 | * |
| 151 | * @param[in] i The next ith token. i < @ref max_look_ahead. |
| 152 | * |
| 153 | * @return Token |
| 154 | */ |
| 155 | Token peek(size_t i = 0); |
| 156 | |
| 157 | /** Get the position of the current token |
| 158 | * |
| 159 | * @return CharPosition |
| 160 | */ |
| 161 | CharPosition current_pos() const |
| 162 | { |
| 163 | return _tokens.front().pos; |
| 164 | } |
| 165 | |
| 166 | private: |
| 167 | void read(); |
| 168 | |
| 169 | Token recognize_tok(char ch); |
| 170 | |
| 171 | Token num_st(std::string value = ""); |
| 172 | |
| 173 | Token float_after_dp_st(std::string value = ""); |
| 174 | |
| 175 | Token text_st(std::string value = ""); |
| 176 | |
| 177 | bool reached_end() const; |
| 178 | |
| 179 | bool is_delim(char ch) const; |
| 180 | |
| 181 | std::string _delims; |
| 182 | std::istream &_istream; |
| 183 | std::deque<Token> _tokens; |
| 184 | CharPosition _lookahead_pos; |
| 185 | }; |
| 186 | |
| 187 | /** Parse and construct a @ref MLGOHeuristics from input stream |
| 188 | * |
| 189 | * @param[in] in Input stream |
| 190 | * |
| 191 | * @return MLGOHeuristics |
| 192 | */ |
| 193 | std::pair<bool, MLGOHeuristics> parse_mlgo(std::istream &in); |
| 194 | |
| 195 | } // namespace parser |
| 196 | } // namespace mlgo |
| 197 | } // namespace arm_compute |
Felix Thomasmathibalan | afd38f0 | 2023-09-27 17:46:17 +0100 | [diff] [blame] | 198 | #endif //SRC_RUNTIME_CL_MLGO_MLGO_PARSER_H |