Quantization history configuration parameters
[tidl/tidl-api.git] / tidl_api / src / configuration_parser.cpp
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::bool_;
56         using qi::lit;
57         using qi::lexeme;
58         using ascii::char_;
59         using qi::_1;
61         // Rules for parsing layer id assignments: { {int, int}, ... }
62         id2group  = '{' >> int_ >> ',' >> int_ >> '}';
63         id2groups = '{' >> id2group >> *(qi::lit(',') >> id2group) >> '}';
65         // Rules for parsing paths. Discard '"'
66         path %= lexeme[+(char_ - '"')];
67         q_path = qi::omit[*char_('"')] >> path >> qi::omit[*char_('"')];
69         // Grammar for parsing configuration file
70         entry %=
71          lit("layerIndex2LayerGroupId") >> '=' >>
72                         id2groups[ph::ref(x.layerIndex2LayerGroupId) = _1]    |
73          lit("#")             >>  *(char_) /* discard comments */             |
74          lit("numFrames")     >> '=' >> int_[ph::ref(x.numFrames) = _1]       |
75          lit("preProcType")   >> '=' >> int_[ph::ref(x.preProcType) = _1]     |
76          lit("inWidth")       >> '=' >> int_[ph::ref(x.inWidth) = _1]         |
77          lit("inHeight")      >> '=' >> int_[ph::ref(x.inHeight) = _1]        |
78          lit("inNumChannels") >> '=' >> int_[ph::ref(x.inNumChannels) = _1]   |
79          lit("inData")        >> '=' >> q_path[ph::ref(x.inData) = _1]        |
80          lit("outData")       >> '=' >> q_path[ph::ref(x.outData) = _1]       |
81          lit("netBinFile")    >> '=' >> q_path[ph::ref(x.netBinFile) = _1]    |
82          lit("paramsBinFile") >> '=' >> q_path[ph::ref(x.paramsBinFile) = _1] |
83          lit("enableTrace")   >> '=' >> bool_[ph::ref(x.enableOutputTrace)= _1] |
84          lit("quantHistoryParam1")   >> '=' >>
85                                    int_[ph::ref(x.quantHistoryParam1)= _1] |
86          lit("quantHistoryParam2")   >> '=' >>
87                                    int_[ph::ref(x.quantHistoryParam2)= _1] |
88          lit("quantMargin")   >> '=' >> int_[ph::ref(x.quantMargin)= _1]
89          ;
90     }
92     qi::rule<Iterator, std::string(), ascii::space_type> path;
93     qi::rule<Iterator, std::string(), ascii::space_type> q_path;
94     qi::rule<Iterator, ascii::space_type> entry;
96     qi::rule<Iterator, std::pair<int, int>(), ascii::space_type> id2group;
97     qi::rule<Iterator, std::map<int, int>(), ascii::space_type> id2groups;
98 };
100 bool Configuration::ReadFromFile(const std::string &file_name)
102     std::ifstream IFS(file_name);
104     if (!IFS.good())
105         return false;
107     typedef ConfigParser<std::string::const_iterator> ConfigParser;
109     ConfigParser G(*this);
110     std::string str;
112     bool result = true;
114     int line_num = 0;
115     while (getline(IFS, str))
116     {
117         line_num++;
119         // Skip lines with whitespace
120         auto f = [](unsigned char const c) { return std::isspace(c); };
121         if (std::all_of(str.begin(),str.end(), f))
122             continue;
124         result = phrase_parse(str.cbegin(), str.cend(), G, ascii::space);
126         if (!result)
127         {
128             std::cout << "Parsing failed on line " << line_num
129                       << ": " << str << std::endl;
130             break;
131         }
132     }
134     IFS.close();
136     // If read failed, return false
137     if (!result)
138         return false;
140     // If validate fails, return false
141     if (!Validate())
142         return false;
144     return true;
147 #if 0
148 --- test.cfg ---
149 numFrames     = 1
150 preProcType   = 0
151 inData        = ../test/testvecs/input/preproc_0_224x224.y
152 outData       = stats_tool_out.bin
153 netBinFile    = ../test/testvecs/config/tidl_models/tidl_net_imagenet_jacintonet11v2.bin
154 paramsBinFile = ../test/testvecs/config/tidl_models/tidl_param_imagenet_jacintonet11v2.bin
155 inWidth       = 224
156 inHeight      = 224
157 inNumChannels = 3
159 # Enable tracing of output buffers
160 enableTrace = true
162 # Override layer group id assignments in the network
163 layerIndex2LayerGroupId = { {12, 2}, {13, 2}, {14, 2} }
164 ----------------
165 #endif
167 #if TEST_PARSING
168 int main()
170     Configuration c;
171     c.ReadFromFile("test.cfg");
173     return 0;
175 #endif