Updates to User's Guide and related examples
[tidl/tidl-api.git] / examples / common / utils.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 <boost/format.hpp>
30 #include <cstring>
32 #include "utils.h"
34 using namespace tidl;
36 using boost::format;
37 using std::string;
38 using std::istream;
39 using std::ostream;
40 using std::vector;
43 // Create an Executor with the specified type and number of EOs
44 Executor* CreateExecutor(DeviceType dt, int num, const Configuration& c,
45                          int layer_group_id)
46 {
47     if (num == 0) return nullptr;
49     DeviceIds ids;
50     for (int i = 0; i < num; i++)
51         ids.insert(static_cast<DeviceId>(i));
53     return new Executor(dt, ids, c, layer_group_id);
54 }
55 static bool read_frame_helper(char* ptr, size_t size, istream& input_file);
57 bool ReadFrame(ExecutionObject*     eo,
58                int                  frame_idx,
59                const Configuration& configuration,
60                std::istream&        input_file)
61 {
62     if (frame_idx >= configuration.numFrames)
63         return false;
65     // Note: Frame index is used by the EO for debug messages only
66     eo->SetFrameIndex(frame_idx);
68     return read_frame_helper(eo->GetInputBufferPtr(),
69                              eo->GetInputBufferSizeInBytes(),
70                              input_file);
71 }
73 bool ReadFrame(ExecutionObjectPipeline* eop,
74                int                      frame_idx,
75                const Configuration&     configuration,
76                std::istream&            input_file)
77 {
78     if (frame_idx >= configuration.numFrames)
79         return false;
81     // Note: Frame index is used by the EOP for debug messages only
82     eop->SetFrameIndex(frame_idx);
84     return read_frame_helper(eop->GetInputBufferPtr(),
85                              eop->GetInputBufferSizeInBytes(),
86                              input_file);
87 }
89 bool read_frame_helper(char* ptr, size_t size, istream& input_file)
90 {
91     assert (ptr != nullptr);
92     assert (input_file.good());
94     input_file.read(ptr, size);
95     assert (input_file.good());
97     if (input_file.eof())
98         return false;
100     // Wrap-around : if EOF is reached, start reading from the beginning.
101     if (input_file.peek() == EOF)
102         input_file.seekg(0, input_file.beg);
104     if (input_file.good())
105         return true;
107     return false;
111 bool WriteFrame(const ExecutionObject* eo, ostream& output_file)
113     output_file.write(eo->GetOutputBufferPtr(),
114                       eo->GetOutputBufferSizeInBytes());
115     assert(output_file.good() == true);
117     if (output_file.good())
118         return true;
120     return false;
123 void ReportTime(const ExecutionObject* eo)
125     double elapsed_host   = eo->GetHostProcessTimeInMilliSeconds();
126     double elapsed_device = eo->GetProcessTimeInMilliSeconds();
127     double overhead = 100 - (elapsed_device/elapsed_host*100);
129     std::cout << format("frame[%3d]: Time on %s: %4.2f ms, host: %4.2f ms"
130                         " API overhead: %2.2f %%\n")
131                         % eo->GetFrameIndex() % eo->GetDeviceName()
132                         % elapsed_device % elapsed_host % overhead;
135 void ReportTime(const ExecutionObjectPipeline* eop)
137     double elapsed_host   = eop->GetHostProcessTimeInMilliSeconds();
138     double elapsed_device = eop->GetProcessTimeInMilliSeconds();
139     double overhead = 100 - (elapsed_device/elapsed_host*100);
141     std::cout << format("frame[%3d]: Time on %s: %4.2f ms, host: %4.2f ms"
142                         " API overhead: %2.2f %%\n")
143                         % eop->GetFrameIndex() % eop->GetDeviceName()
144                         % elapsed_device % elapsed_host % overhead;
147 // Compare output against reference output
148 bool CheckFrame(const ExecutionObject *eo, const char *ref_output)
150     if (std::memcmp(static_cast<const void*>(ref_output),
151                static_cast<const void*>(eo->GetOutputBufferPtr()),
152                eo->GetOutputBufferSizeInBytes()) == 0)
153         return true;
155     return false;
158 bool CheckFrame(const ExecutionObjectPipeline *eop, const char *ref_output)
160     if (std::memcmp(static_cast<const void*>(ref_output),
161                static_cast<const void*>(eop->GetOutputBufferPtr()),
162                eop->GetOutputBufferSizeInBytes()) == 0)
163         return true;
165     return false;
169 namespace tidl {
170 std::size_t GetBinaryFileSize (const std::string &F);
171 bool        ReadBinary        (const std::string &F, char* buffer, int size);
174 // Read file into a buffer.
175 const char* ReadReferenceOutput(const string& name)
177     size_t size = GetBinaryFileSize(name);
179     if (size == 0)
180         return nullptr;
182     char* buffer = new char[size];
184     if (!buffer)
185         return nullptr;
187     if (!ReadBinary(name, buffer, size))
188     {
189         delete [] buffer;
190         return nullptr;
191     }
193     return buffer;
196 // Allocate input and output memory for each EO
197 void AllocateMemory(const vector<ExecutionObject *>& eos)
199     // Allocate input and output buffers for each execution object
200     for (auto eo : eos)
201     {
202         size_t in_size  = eo->GetInputBufferSizeInBytes();
203         size_t out_size = eo->GetOutputBufferSizeInBytes();
204         void*  in_ptr   = malloc(in_size);
205         void*  out_ptr  = malloc(out_size);
206         assert(in_ptr != nullptr && out_ptr != nullptr);
208         ArgInfo in  = { ArgInfo(in_ptr,  in_size)};
209         ArgInfo out = { ArgInfo(out_ptr, out_size)};
210         eo->SetInputOutputBuffer(in, out);
211     }
214 // Free the input and output memory associated with each EO
215 void FreeMemory(const vector<ExecutionObject *>& eos)
217     for (auto eo : eos)
218     {
219         free(eo->GetInputBufferPtr());
220         free(eo->GetOutputBufferPtr());
221     }
224 // Allocate input and output memory for each EOP
225 void AllocateMemory(const vector<ExecutionObjectPipeline *>& eops)
227     // Allocate input and output buffers for each execution object
228     for (auto eop : eops)
229     {
230         size_t in_size  = eop->GetInputBufferSizeInBytes();
231         size_t out_size = eop->GetOutputBufferSizeInBytes();
232         void*  in_ptr   = malloc(in_size);
233         void*  out_ptr  = malloc(out_size);
234         assert(in_ptr != nullptr && out_ptr != nullptr);
236         ArgInfo in  = { ArgInfo(in_ptr,  in_size)};
237         ArgInfo out = { ArgInfo(out_ptr, out_size)};
238         eop->SetInputOutputBuffer(in, out);
239     }
242 // Free the input and output memory associated with each EOP
243 void FreeMemory(const vector<ExecutionObjectPipeline *>& eops)
245     for (auto eop : eops)
246     {
247         free(eop->GetInputBufferPtr());
248         free(eop->GetOutputBufferPtr());
249     }