]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - tidl/tidl-api.git/blob - tidl_api/src/util.cpp
tidl-viewer: Remove executor.h inclusion in utils.cpp
[tidl/tidl-api.git] / tidl_api / src / util.cpp
1 /******************************************************************************
2  * Copyright (c) 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 "util.h"
30 #include <iostream>
31 #include <fstream>
32 #include <assert.h>
33 #include <chrono>
34 #include <mutex>
35 #include <cstring>
36 #include <memory>
38 namespace tidl {
39 bool EnableTimeStamps(const std::string& file, size_t num_frames);
40 }
42 using namespace tidl;
44 using namespace std::chrono;
46 std::unique_ptr<TimeStamp> tidl_api_timestamps(nullptr);
48 bool tidl::EnableTimeStamps(const std::string& file, size_t num_frames)
49 {
50     std::mutex m;
51     std::lock_guard<std::mutex> guard(m);
53     if (tidl_api_timestamps.get() != nullptr)
54         return true;
56     tidl_api_timestamps.reset(new TimeStamp(file, num_frames));
57     if (tidl_api_timestamps.get() == nullptr)
58         return false;
60     return true;
61 }
63 TimeStamp::TimeStamp(const std::string& file, int num_entries):
64                         num_entries_m(num_entries), file_m(file)
65 {
66     entries_m = new Entry[num_entries_m];
67     if (entries_m)
68         std::memset(entries_m, 0, sizeof(Entry)*num_entries_m);
69 }
71 void TimeStamp::Update(int frame_idx, EventKind k, int type, int id)
72 {
73     if (!entries_m)
74         return;
76     int idx = frame_idx % num_entries_m;
78     entries_m[idx].frame_idx = frame_idx;
79     entries_m[idx].timestamp[k] = duration_cast<microseconds>
80                  (high_resolution_clock::now().time_since_epoch()).count();
82     if (k == EO1_PFSA_START)
83     {
84         entries_m[idx].eo1_id   = id;
85         entries_m[idx].eo1_type = type;
86     }
87     else if (k == EO2_PFSA_START)
88     {
89         entries_m[idx].eo2_id   = id;
90         entries_m[idx].eo2_type = type;
91     }
92 }
94 void TimeStamp::Zero(int frame_idx, EventKind k)
95 {
96     if (!entries_m)
97         return;
99     int idx = frame_idx % num_entries_m;
101     entries_m[idx].frame_idx    = frame_idx;
102     entries_m[idx].timestamp[k] = 0;
106 TimeStamp::~TimeStamp()
108     if (!entries_m)
109         return;
111     std::ofstream ofs;
112     ofs.open(file_m, std::ofstream::out);
114     for (int i=0; i < num_entries_m; i++)
115         for (int j=0; j < EventKind::NUM_EVENTS; j++)
116             if (entries_m[i].timestamp[j] != 0)
117             {
118                 ofs << entries_m[i].frame_idx << ",";
119                 switch (j)
120                 {
121                     case EOP_PFSA_START: ofs << "EOP:PFSA:Start"; break;
122                     case EOP_PFSA_END:   ofs << "EOP:PFSA:End"; break;
123                     case EOP_PFW_START:  ofs << "EOP:PFW:Start"; break;
124                     case EOP_PFW_END:    ofs << "EOP:PFW:End"; break;
125                     case EOP_RAN_START:  ofs << "EOP:RAN:Start"; break;
126                     case EOP_RAN_END:    ofs << "EOP:RAN:End"; break;
128                     case EO1_PFSA_START: ofs << "EO1:PFSA:Start"; break;
129                     case EO1_PFSA_END:   ofs << "EO1:PFSA:End"; break;
130                     case EO1_PFW_START:  ofs << "EO1:PFW:Start"; break;
131                     case EO1_PFW_END:    ofs << "EO1:PFW:End"; break;
133                     case EO2_PFSA_START: ofs << "EO2:PFSA:Start"; break;
134                     case EO2_PFSA_END:   ofs << "EO2:PFSA:End"; break;
135                     case EO2_PFW_START:  ofs << "EO2:PFW:Start"; break;
136                     case EO2_PFW_END:    ofs << "EO2:PFW:End"; break;
138                     default:             ofs << "UNKNOWN"; break;
139                 }
140                 ofs << "," << entries_m[i].timestamp[j];
142                 if (j == EO1_PFSA_START)
143                 {
144                     ofs << "," << entries_m[i].eo1_type
145                         << "," << entries_m[i].eo1_id;
146                 }
147                 else if (j == EO2_PFSA_START)
148                 {
149                     ofs << "," << entries_m[i].eo2_type
150                         << "," << entries_m[i].eo2_id;
151                 }
154                 ofs << std::endl;
155             }
157     ofs.close();
158     delete [] entries_m;
162 void tidl::RecordEvent(int frame_idx, TimeStamp::EventKind k,
163                        int eo_type, int eo_id)
165     TimeStamp* t = tidl_api_timestamps.get();
166     if (t)
167         t->Update(frame_idx, k, eo_type, eo_id);
170 void tidl::ResetEvent(int frame_idx, TimeStamp::EventKind k)
172     TimeStamp* t = tidl_api_timestamps.get();
173     if (t)
174         t->Zero(frame_idx, k);
177 std::size_t tidl::GetBinaryFileSize(const std::string &F)
179     std::ifstream is;
180     is.open (F, std::ios::binary );
182     if (!is.good())
183     {
184         std::cout << "ERROR: File read failed for " << F << std::endl;
185         return 0;
186     }
188     is.seekg (0, std::ios::end);
189     size_t length = is.tellg();
190     is.close();
192     return length;
196 bool tidl::ReadBinary(const std::string &F, char* buffer, int size)
198     std::ifstream is;
199     is.open (F, std::ios::binary );
201     if (!is.good())
202     {
203         std::cout << "ERROR: File read failed for " << F << std::endl;
204         return false;
205     }
207     is.seekg (0, std::ios::end);
208     int length = is.tellg();
210     if (length != size)
211     {
212         std::cout << length << " != " << size << std::endl;
213         is.close();
214         return false;
215     }
217     is.seekg (0, std::ios::beg);
218     is.read (buffer, length);
219     is.close();
221     return true;
224 bool tidl::CompareFiles(const std::string &F1, const std::string &F2)
226     std::size_t s1 = GetBinaryFileSize(F1);
227     std::size_t s2 = GetBinaryFileSize(F2);
229     if (s1 != s2)
230         return false;
232     char *b1 = new char[s1];
233     char *b2 = new char[s2];
235     ReadBinary(F1, b1, s1);
236     ReadBinary(F2, b2, s2);
238     int errors = 0;
239     for (size_t i=0; i < s1; i++)
240         if (b1[i] != b2[i])
241         {
242             std::cout << "Error at " << i << " " <<
243                          (int)b1[i] << " != " << (int)b2[i];
244             std::cout << std::endl;
245             errors++;
247             if (errors > 10)
248                 break;
249         }
251     delete[] b1;
252     delete[] b2;
254     if (errors == 0) return true;
256     return false;
259 bool tidl::CompareFrames(const std::string &F1, const std::string &F2,
260                          int numFrames, int width, int height)
262     bool status = true;
264     std::size_t s1 = GetBinaryFileSize(F1);
265     std::size_t s2 = GetBinaryFileSize(F2);
267     char *b1 = new char[s1];
268     char *b2 = new char[s2];
270     ReadBinary(F1, b1, s1);
271     ReadBinary(F2, b2, s2);
273     for (int f=0; f < numFrames; f++)
274     {
275         int errors = 0;
276         int frame_offset = f*width*height;
277         std::cout << "Comparing frame: " << f << std::endl;
278         for (int h=0; h < height; h++)
279         {
280             for (int w=0; w < width; w++)
281             {
282                 size_t index = frame_offset+(h*width)+w;
283                 assert (index < s1 && index < s2);
284                 if (b1[index] != b2[index])
285                 {
286                     status = false;
287                     std::cout << "Error at " << index << " " <<
288                                  (int)b1[index] << " != " << (int)b2[index];
289                     std::cout << std::endl;
290                     errors++;
292                 }
293                 if (errors > 10) break;
294             }
295             if (errors > 10) break;
296         }
297     }
299     delete[] b1;
300     delete[] b2;
302     return status;