72a18def122f7d0ef34a13bd693b23cb9582410a
[platform/core/ml/nnfw.git] / runtime / onert / core / src / exec / JSONExecTime.cc
1 /*
2  * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *    http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "exec/JSONExecTime.h"
18 #include "backend/IConfig.h"
19 #include <fstream>
20
21 namespace onert
22 {
23 namespace exec
24 {
25 /**
26  * @brief Helper function for reading string from stream
27  *
28  * @param str Output string
29  * @param stream File stream
30  */
31 void readString(std::string &str, std::ifstream &stream)
32 {
33   str.clear();
34   char buf;
35   while (stream.good())
36   {
37     stream.get(buf);
38     if (buf == '"')
39       break;
40     str.push_back(buf);
41   }
42 }
43
44 /**
45  * @brief Helper function for reading bool from stream
46  *
47  * @param quant Output bool
48  * @param stream File stream
49  */
50 void readBool(bool &quant, std::ifstream &stream)
51 {
52   char buf;
53   stream.get(buf);
54   quant = (buf == '1');
55   stream.get(buf);
56 }
57
58 void printString(const std::string &str, std::ofstream &stream) { stream << "\"" << str << "\""; }
59
60 void printBool(bool quant, std::ofstream &stream) { stream << "\"" << quant << "\""; }
61
62 void JSON::readOperation(const std::string &backend, const std::string &operation, bool quant,
63                          std::ifstream &stream)
64 {
65   uint32_t size = 0;
66   int64_t time = 0;
67
68   std::string int_buf;
69   char buf;
70   int number_of_closed_braces = 0;
71   int number_of_commas = 0;
72
73   while (stream.good())
74   {
75     stream.get(buf);
76
77     switch (buf)
78     {
79       case ']':
80       {
81         number_of_closed_braces++;
82         break;
83       }
84       case '[':
85       {
86         number_of_closed_braces--;
87         break;
88       }
89       default:
90       {
91         if (std::isdigit(buf))
92         {
93           int_buf.push_back(buf);
94         }
95         break;
96       }
97     }
98
99     if (number_of_closed_braces == 1)
100       break;
101
102     if ((buf == ']' && number_of_closed_braces == 0) ||
103         (buf == ',' && number_of_closed_braces == -1))
104     {
105       switch (number_of_commas % 2)
106       {
107         case 0:
108         {
109           size = static_cast<uint32_t>(std::atoi(int_buf.c_str()));
110           break;
111         }
112         case 1:
113         {
114           time = static_cast<int64_t>(std::atol(int_buf.c_str()));
115           auto bf = _backends.find(backend);
116           if (bf != _backends.end())
117           {
118             _measurements[bf->second][operation][quant][size] = time;
119           } // we ignore the records for unsupported backends
120           break;
121         }
122       }
123       number_of_commas++;
124       int_buf.clear();
125     }
126   }
127 }
128 void JSON::printOperation(const std::map<uint32_t, int64_t> &operation_info,
129                           std::ofstream &stream) const
130 {
131   for (const auto &items : operation_info)
132   {
133     stream << "[" << items.first << ", " << items.second << "], ";
134   }
135   stream.seekp(-2, std::ofstream::end);
136 }
137
138 void JSON::uploadOperationsExecTime() const
139 {
140   std::ofstream stream(_measurement_file);
141   if (!stream.is_open())
142   {
143     throw std::runtime_error("Failed to save backend config file");
144   }
145   else
146   {
147     stream << "{";
148     for (const auto &backend : _measurements)
149     {
150       printString(backend.first->config()->id(), stream);
151       stream << ": {";
152       for (const auto &operation : backend.second)
153       {
154         printString(operation.first, stream);
155         stream << ": {";
156         for (const auto &type : operation.second)
157         {
158           printBool(type.first, stream);
159           stream << ": [";
160           printOperation(type.second, stream);
161           stream << "], ";
162         }
163         stream.seekp(-2, std::ofstream::end);
164         stream << "}, ";
165       }
166       stream.seekp(-2, std::ofstream::end);
167       stream << "}, ";
168     }
169     stream.seekp(-2, std::ofstream::end);
170     stream << "}";
171     stream.close();
172   }
173 }
174
175 void JSON::loadOperationsExecTime()
176 {
177   std::ifstream stream(_measurement_file);
178   if (stream.is_open())
179   {
180     std::string backend;
181     std::string operation;
182     bool quant = false;
183     char buf;
184     int number_of_open_braces = 0;
185
186     while (stream.good())
187     {
188       stream.get(buf);
189       switch (buf)
190       {
191         case '{':
192           number_of_open_braces++;
193           break;
194         case '}':
195           number_of_open_braces--;
196           break;
197         case '"':
198         {
199           if (number_of_open_braces == 1)
200           {
201             // read backend string
202             readString(backend, stream);
203           }
204           if (number_of_open_braces == 2)
205           {
206             // read operation string
207             readString(operation, stream);
208           }
209           if (number_of_open_braces == 3)
210           {
211             // read operation string
212             readBool(quant, stream);
213           }
214           break;
215         }
216         case '[':
217         {
218           // reading and creating all info for operation
219           readOperation(backend, operation, quant, stream);
220           break;
221         }
222         default:
223           break;
224       }
225     }
226     stream.close();
227   }
228 }
229
230 } // namespace exec
231 } // namespace onert