3ad0d2ccaf84672261aab81acd14de6cde1628b0
1 /******************************************************************************
2 * Copyright (c) 2017-2018 Texas Instruments Incorporated - http://www.ti.com/
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of Texas Instruments Incorporated nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26 * THE POSSIBILITY OF SUCH DAMAGE.
27 *****************************************************************************/
29 #include <boost/spirit/include/qi.hpp>
30 #include <boost/spirit/include/phoenix_operator.hpp>
31 #include <boost/fusion/include/std_pair.hpp>
33 #include <string>
34 #include <fstream>
35 #include <iostream>
36 #include <algorithm>
37 #include <cctype>
38 #include <utility>
39 #include <map>
41 #include "configuration.h"
43 namespace qi = boost::spirit::qi;
44 namespace ascii = boost::spirit::ascii;
45 namespace ph = boost::phoenix;
47 using namespace tidl;
49 template <typename Iterator>
50 struct ConfigParser : qi::grammar<Iterator, ascii::space_type>
51 {
52 ConfigParser(Configuration &x) : ConfigParser::base_type(entry)
53 {
54 using qi::int_;
55 using qi::float_;
56 using qi::bool_;
57 using qi::lit;
58 using qi::lexeme;
59 using ascii::char_;
60 using qi::_1;
62 // Rules for parsing layer id assignments: { {int, int}, ... }
63 id2group = '{' >> int_ >> ',' >> int_ >> '}';
64 id2groups = '{' >> id2group >> *(qi::lit(',') >> id2group) >> '}';
66 // Rules for parsing paths. Discard '"'
67 path %= lexeme[+(char_ - '"')];
68 q_path = qi::omit[*char_('"')] >> path >> qi::omit[*char_('"')];
70 // Rules for parsing subgraph data conversion information
71 intvec = int_ >> *int_;
72 floatvec = float_ >> *float_;
74 // Grammar for parsing configuration file
75 entry %=
76 lit("layerIndex2LayerGroupId") >> '=' >>
77 id2groups[ph::ref(x.layerIndex2LayerGroupId) = _1] |
78 lit("#") >> *(char_) /* discard comments */ |
79 lit("numFrames") >> '=' >> int_[ph::ref(x.numFrames) = _1] |
80 lit("preProcType") >> '=' >> int_[ph::ref(x.preProcType) = _1] |
81 lit("inWidth") >> '=' >> int_[ph::ref(x.inWidth) = _1] |
82 lit("inHeight") >> '=' >> int_[ph::ref(x.inHeight) = _1] |
83 lit("inNumChannels") >> '=' >> int_[ph::ref(x.inNumChannels) = _1] |
84 lit("inData") >> '=' >> q_path[ph::ref(x.inData) = _1] |
85 lit("outData") >> '=' >> q_path[ph::ref(x.outData) = _1] |
86 lit("netBinFile") >> '=' >> q_path[ph::ref(x.netBinFile) = _1] |
87 lit("paramsBinFile") >> '=' >> q_path[ph::ref(x.paramsBinFile) = _1] |
88 lit("enableTrace") >> '=' >> bool_[ph::ref(x.enableOutputTrace)= _1] |
89 lit("quantHistoryParam1") >> '=' >>
90 int_[ph::ref(x.quantHistoryParam1)= _1] |
91 lit("quantHistoryParam2") >> '=' >>
92 int_[ph::ref(x.quantHistoryParam2)= _1] |
93 lit("quantMargin") >> '=' >> int_[ph::ref(x.quantMargin)= _1] |
94 lit("inConvType") >> '=' >> intvec[ph::ref(x.inConvType) = _1] |
95 lit("inIsSigned") >> '=' >> intvec[ph::ref(x.inIsSigned) = _1] |
96 lit("inScaleF2Q") >> '=' >> floatvec[ph::ref(x.inScaleF2Q) = _1] |
97 lit("inIsNCHW") >> '=' >> intvec[ph::ref(x.inIsNCHW) = _1] |
98 lit("outConvType") >> '=' >> intvec[ph::ref(x.outConvType) = _1] |
99 lit("outIsSigned") >> '=' >> intvec[ph::ref(x.outIsSigned) = _1] |
100 lit("outScaleF2Q") >> '=' >> floatvec[ph::ref(x.outScaleF2Q) = _1] |
101 lit("outIsNCHW") >> '=' >> intvec[ph::ref(x.outIsNCHW) = _1]
102 ;
103 }
105 qi::rule<Iterator, std::string(), ascii::space_type> path;
106 qi::rule<Iterator, std::string(), ascii::space_type> q_path;
107 qi::rule<Iterator, ascii::space_type> entry;
109 qi::rule<Iterator, std::pair<int, int>(), ascii::space_type> id2group;
110 qi::rule<Iterator, std::map<int, int>(), ascii::space_type> id2groups;
112 qi::rule<Iterator, std::vector<int>(), ascii::space_type> intvec;
113 qi::rule<Iterator, std::vector<float>(), ascii::space_type> floatvec;
114 };
116 bool Configuration::ReadFromFile(const std::string &file_name)
117 {
118 std::ifstream IFS(file_name);
120 if (!IFS.good())
121 return false;
123 typedef ConfigParser<std::string::const_iterator> ConfigParser;
125 ConfigParser G(*this);
126 std::string str;
128 bool result = true;
130 int line_num = 0;
131 while (getline(IFS, str))
132 {
133 line_num++;
135 // Skip lines with whitespace
136 auto f = [](unsigned char const c) { return std::isspace(c); };
137 if (std::all_of(str.begin(),str.end(), f))
138 continue;
140 result = phrase_parse(str.cbegin(), str.cend(), G, ascii::space);
142 if (!result)
143 {
144 std::cout << "Parsing failed on line " << line_num
145 << ": " << str << std::endl;
146 break;
147 }
148 }
150 IFS.close();
152 // If read failed, return false
153 if (!result)
154 return false;
156 // If validate fails, return false
157 if (!Validate())
158 return false;
160 return true;
161 }
163 #if 0
164 --- test.cfg ---
165 numFrames = 1
166 preProcType = 0
167 inData = ../test/testvecs/input/preproc_0_224x224.y
168 outData = stats_tool_out.bin
169 netBinFile = ../test/testvecs/config/tidl_models/tidl_net_imagenet_jacintonet11v2.bin
170 paramsBinFile = ../test/testvecs/config/tidl_models/tidl_param_imagenet_jacintonet11v2.bin
171 inWidth = 224
172 inHeight = 224
173 inNumChannels = 3
175 # Enable tracing of output buffers
176 enableTrace = true
178 # Override layer group id assignments in the network
179 layerIndex2LayerGroupId = { {12, 2}, {13, 2}, {14, 2} }
180 ----------------
181 #endif
183 #if TEST_PARSING
184 int main()
185 {
186 Configuration c;
187 c.ReadFromFile("test.cfg");
189 return 0;
190 }
191 #endif