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;
108 }
111 bool WriteFrame(const ExecutionObject* eo, ostream& output_file)
112 {
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;
121 }
123 void ReportTime(const ExecutionObject* eo)
124 {
125 double elapsed_device = eo->GetProcessTimeInMilliSeconds();
127 std::cout << format("frame[%3d]: Time on %s: %4.2f ms\n")
128 % eo->GetFrameIndex() % eo->GetDeviceName()
129 % elapsed_device;
130 }
132 // Compare output against reference output
133 bool CheckFrame(const ExecutionObject *eo, const char *ref_output)
134 {
135 if (std::memcmp(static_cast<const void*>(ref_output),
136 static_cast<const void*>(eo->GetOutputBufferPtr()),
137 eo->GetOutputBufferSizeInBytes()) == 0)
138 return true;
140 return false;
141 }
143 bool CheckFrame(const ExecutionObjectPipeline *eop, const char *ref_output)
144 {
145 if (std::memcmp(static_cast<const void*>(ref_output),
146 static_cast<const void*>(eop->GetOutputBufferPtr()),
147 eop->GetOutputBufferSizeInBytes()) == 0)
148 return true;
150 return false;
151 }
153 // Read file into a buffer.
154 const char* ReadReferenceOutput(const string& name)
155 {
156 size_t size = GetBinaryFileSize(name);
158 if (size == 0)
159 return nullptr;
161 char* buffer = new char[size];
163 if (!buffer)
164 return nullptr;
166 if (!ReadBinary(name, buffer, size))
167 {
168 delete [] buffer;
169 return nullptr;
170 }
172 return buffer;
173 }
175 // Allocate input and output memory for each EO
176 void AllocateMemory(const vector<ExecutionObject *>& eos)
177 {
178 // Allocate input and output buffers for each execution object
179 for (auto eo : eos)
180 {
181 size_t in_size = eo->GetInputBufferSizeInBytes();
182 size_t out_size = eo->GetOutputBufferSizeInBytes();
183 void* in_ptr = malloc(in_size);
184 void* out_ptr = malloc(out_size);
185 assert(in_ptr != nullptr && out_ptr != nullptr);
187 ArgInfo in = { ArgInfo(in_ptr, in_size)};
188 ArgInfo out = { ArgInfo(out_ptr, out_size)};
189 eo->SetInputOutputBuffer(in, out);
190 }
191 }
193 // Free the input and output memory associated with each EO
194 void FreeMemory(const vector<ExecutionObject *>& eos)
195 {
196 for (auto eo : eos)
197 {
198 free(eo->GetInputBufferPtr());
199 free(eo->GetOutputBufferPtr());
200 }
201 }
203 // Allocate input and output memory for each EOP
204 void AllocateMemory(const vector<ExecutionObjectPipeline *>& eops)
205 {
206 // Allocate input and output buffers for each execution object
207 for (auto eop : eops)
208 {
209 size_t in_size = eop->GetInputBufferSizeInBytes();
210 size_t out_size = eop->GetOutputBufferSizeInBytes();
211 void* in_ptr = malloc(in_size);
212 void* out_ptr = malloc(out_size);
213 assert(in_ptr != nullptr && out_ptr != nullptr);
215 ArgInfo in = { ArgInfo(in_ptr, in_size)};
216 ArgInfo out = { ArgInfo(out_ptr, out_size)};
217 eop->SetInputOutputBuffer(in, out);
218 }
219 }
221 // Free the input and output memory associated with each EOP
222 void FreeMemory(const vector<ExecutionObjectPipeline *>& eops)
223 {
224 for (auto eop : eops)
225 {
226 free(eop->GetInputBufferPtr());
227 free(eop->GetOutputBufferPtr());
228 }
229 }