5871e718bd74a1c2206ea0a0f292ec4d9f47bccb
[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          ;
85     }
87     qi::rule<Iterator, std::string(), ascii::space_type> path;
88     qi::rule<Iterator, std::string(), ascii::space_type> q_path;
89     qi::rule<Iterator, ascii::space_type> entry;
91     qi::rule<Iterator, std::pair<int, int>(), ascii::space_type> id2group;
92     qi::rule<Iterator, std::map<int, int>(), ascii::space_type> id2groups;
93 };
95 bool Configuration::ReadFromFile(const std::string &file_name)
96 {
97     std::ifstream IFS(file_name);
99     if (!IFS.good())
100         return false;
102     typedef ConfigParser<std::string::const_iterator> ConfigParser;
104     ConfigParser G(*this);
105     std::string str;
107     bool result = true;
109     int line_num = 0;
110     while (getline(IFS, str))
111     {
112         line_num++;
114         // Skip lines with whitespace
115         auto f = [](unsigned char const c) { return std::isspace(c); };
116         if (std::all_of(str.begin(),str.end(), f))
117             continue;
119         result = phrase_parse(str.cbegin(), str.cend(), G, ascii::space);
121         if (!result)
122         {
123             std::cout << "Parsing failed on line " << line_num
124                       << ": " << str << std::endl;
125             break;
126         }
127     }
129     IFS.close();
131     // If read failed, return false
132     if (!result)
133         return false;
135     // If validate fails, return false
136     if (!Validate())
137         return false;
139     return true;
142 #if 0
143 --- test.cfg ---
144 numFrames     = 1
145 preProcType   = 0
146 inData        = ../test/testvecs/input/preproc_0_224x224.y
147 outData       = stats_tool_out.bin
148 netBinFile    = ../test/testvecs/config/tidl_models/tidl_net_imagenet_jacintonet11v2.bin
149 paramsBinFile = ../test/testvecs/config/tidl_models/tidl_param_imagenet_jacintonet11v2.bin
150 inWidth       = 224
151 inHeight      = 224
152 inNumChannels = 3
154 # Enable tracing of output buffers
155 enableTrace = true
157 # Override layer group id assignments in the network
158 layerIndex2LayerGroupId = { {12, 2}, {13, 2}, {14, 2} }
159 ----------------
160 #endif
162 #if TEST_PARSING
163 int main()
165     Configuration c;
166     c.ReadFromFile("test.cfg");
168     return 0;
170 #endif