2 // Copyright (c) 2016 Intel Corporation
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
8 // http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include "instrumentation.h"
26 namespace instrumentation {
27 // initalize dumping directory for whole run
28 const std::string logger::dump_dir = DUMP_DIRECTORY;
30 static float convert_half_to_float(half_t val, bool flush_denorm_to_zero = false)
32 #if defined HALF_HALF_HPP
35 // FP32 parts extracted from FP16.
36 uint32_t sign = (static_cast<uint16_t>(val) & 0x8000U) << 16;
37 uint32_t mantissa = (static_cast<uint16_t>(val) & 0x3FFU) << 13;
39 uint32_t exp_val_f16 = (static_cast<uint16_t>(val) & 0x7C00U) >> 10;
43 // Handling +/-0 and denormals.
48 else if (flush_denorm_to_zero)
56 // Denorms conversion to normal numbers.
58 while (!(mantissa & 0x400000U))
63 mantissa = (mantissa << 1) & 0x7FFFFFU;
69 // Handling +/-infinity, NaN and normal numbers.
70 exp = (exp_val_f16 == 0x1FU ? 0xFFU : exp_val_f16 + 127 - 15) << 23;
74 reinterpret_cast<uint32_t&>(ret) = sign | exp | mantissa;
80 float convert_element(float f)
85 float convert_element(half_t h)
87 return convert_half_to_float(h);
90 template<typename elemType>
91 void dump_byxf(const cldnn::memory& mem, bool single_batch, cldnn::tensor::value_type batch_id, bool single_feature, cldnn::tensor::value_type feature_id, std::vector<std::vector<std::stringstream>> & streams)
93 auto mem_arg = mem.get_layout();
94 auto mem_ptr = mem.pointer<elemType>();
96 unsigned int input_it = 0;
97 for (cldnn::tensor::value_type b = 0; b < mem_arg.size.batch[0]; b++)
99 for (cldnn::tensor::value_type y = 0; y < mem_arg.size.spatial[1]; y++)
101 for (cldnn::tensor::value_type x = 0; x < mem_arg.size.spatial[0]; x++)
103 for (cldnn::tensor::value_type f = 0; f < mem_arg.size.feature[0]; f++)
105 if ((!single_batch || b == batch_id) && (!single_feature || f == feature_id))
107 streams[b][f] << convert_element(mem_ptr[input_it]) << " ";
108 if (x == mem_arg.size.spatial[0] - 1)
110 streams[b][f] << std::endl;
120 template<typename elemType>
121 void dump_bfyx(const cldnn::memory& mem, bool single_batch, cldnn::tensor::value_type batch_id, bool single_feature, cldnn::tensor::value_type feature_id, std::vector<std::vector<std::stringstream>> & streams)
123 auto mem_arg = mem.get_layout();
124 auto mem_ptr = mem.pointer<elemType>();
126 unsigned int input_it = 0;
127 for (cldnn::tensor::value_type b = 0; b < mem_arg.size.batch[0]; b++)
129 for (cldnn::tensor::value_type f = 0; f < mem_arg.size.feature[0]; f++)
131 for (cldnn::tensor::value_type y = 0; y < mem_arg.size.spatial[1]; y++)
133 for (cldnn::tensor::value_type x = 0; x < mem_arg.size.spatial[0]; x++)
135 if ((!single_batch || b == batch_id) && (!single_feature || f == feature_id))
137 streams[b][f] << convert_element(mem_ptr[input_it]) << " ";
138 if (x == mem_arg.size.spatial[0] - 1)
140 streams[b][f] << std::endl;
150 template<typename elemType>
151 void dump_yxfb(const cldnn::memory& mem, bool single_batch, cldnn::tensor::value_type batch_id, bool single_feature, cldnn::tensor::value_type feature_id, std::vector<std::vector<std::stringstream>> & streams)
153 auto mem_arg = mem.get_layout();
154 auto mem_ptr = mem.pointer<elemType>();
156 unsigned int input_it = 0;
157 for (cldnn::tensor::value_type y = 0; y < mem_arg.size.spatial[1]; y++)
159 for (cldnn::tensor::value_type x = 0; x < mem_arg.size.spatial[0]; x++)
161 for (cldnn::tensor::value_type f = 0; f < mem_arg.size.feature[0]; f++)
163 for (cldnn::tensor::value_type b = 0; b < mem_arg.size.batch[0]; b++)
165 if ((!single_batch || b == batch_id) && (!single_feature || f == feature_id))
167 streams[b][f] << convert_element(mem_ptr[input_it]) << " ";
168 if (x == mem_arg.size.spatial[0] - 1)
170 streams[b][f] << std::endl;
180 template<typename elemType>
181 void dump_xb(const cldnn::memory& mem, bool single_batch, cldnn::tensor::value_type batch_id, std::vector<std::vector<std::stringstream>> & streams)
183 auto mem_arg = mem.get_layout();
184 auto mem_ptr = mem.pointer<elemType>();
186 unsigned int input_it = 0;
187 for (cldnn::tensor::value_type x = 0; x < mem_arg.size.spatial[0]; x++)
189 for (cldnn::tensor::value_type b = 0; b < mem_arg.size.batch[0]; b++)
191 if (!single_batch || b == batch_id)
193 streams[b][0] << convert_element(mem_ptr[input_it]) << std::endl;
200 template<typename elemType>
201 void dump_bx(const cldnn::memory& mem, bool single_batch, cldnn::tensor::value_type batch_id, std::vector<std::vector<std::stringstream>> & streams)
203 auto mem_arg = mem.get_layout();
204 auto mem_ptr = mem.pointer<elemType>();
206 unsigned int input_it = 0;
207 for (cldnn::tensor::value_type b = 0; b < mem_arg.size.batch[0]; b++)
209 for (cldnn::tensor::value_type x = 0; x < mem_arg.size.spatial[0]; x++)
211 if (!single_batch || b == batch_id)
213 streams[b][0] << convert_element(mem_ptr[input_it]) << std::endl;
220 template<typename elemType>
221 void dump_yxio(const cldnn::memory& mem, std::stringstream & stream)
223 auto mem_arg = mem.get_layout();
224 auto mem_ptr = mem.pointer<elemType>();
226 auto i_size = mem_arg.size.batch[0];
227 auto o_size = mem_arg.size.feature[0];
228 auto x_size = mem_arg.size.spatial[0];
229 auto y_size = mem_arg.size.spatial[1];
230 unsigned int input_it = 0;
231 for (cldnn::tensor::value_type o = 0; o < o_size; o++)
233 for (cldnn::tensor::value_type i = 0; i < i_size; i++)
235 for (cldnn::tensor::value_type x = 0; x < x_size; x++)
237 for (cldnn::tensor::value_type y = 0; y < y_size; y++)
239 stream<< convert_element(mem_ptr[input_it]) << " ";
248 template<typename elemType>
249 void dump_oiyx(const cldnn::memory& mem, std::stringstream & stream)
251 auto mem_arg = mem.get_layout();
252 auto mem_ptr = mem.pointer<elemType>();
254 auto i_size = mem_arg.size.batch[0];
255 auto o_size = mem_arg.size.feature[0];
256 auto x_size = mem_arg.size.spatial[0];
257 auto y_size = mem_arg.size.spatial[1];
258 unsigned int input_it = 0;
259 for (cldnn::tensor::value_type x = 0; x < x_size; x++)
261 for (cldnn::tensor::value_type y = 0; y < y_size; y++)
263 for (cldnn::tensor::value_type i = 0; i < i_size; i++)
265 for (cldnn::tensor::value_type o = 0; o < o_size; o++)
267 stream << convert_element(mem_ptr[input_it]) << " ";
276 template<typename elemType>
277 void dump_os_iyx_osv16(const cldnn::memory& mem, std::stringstream & stream)
279 auto mem_arg = mem.get_layout();
280 auto mem_ptr = mem.pointer<elemType>();
282 auto i_size = mem_arg.size.batch[0];
283 auto o_size = mem_arg.size.feature[0];
284 auto x_size = mem_arg.size.spatial[0];
285 auto y_size = mem_arg.size.spatial[1];
286 auto weights_size = i_size * o_size * x_size * y_size; //count() also counts feature[1]
287 int slice_value = 16;
288 cldnn::tensor::value_type it = 0;
289 while (it < weights_size)
291 stream << convert_element(mem_ptr[it]) << " ";
293 if (it % slice_value == 0) //separate every bsv with a new line
298 template<typename elemType>
299 void dump_bs_xs_xsv8_bsv8(const cldnn::memory& mem, std::stringstream & stream)
301 auto mem_arg = mem.get_layout();
302 auto mem_ptr = mem.pointer<elemType>();
304 auto i_size = mem_arg.size.batch[0]; //batch = input feature map
305 auto x_size = mem_arg.size.spatial[0]; // spatial_x = output feature map
306 auto weights_size = mem_arg.size.count();
307 int xsv = 8, bsv = 8;
308 unsigned int input_it = 0, input_i_it= 0 , input_o_it = 0;
309 for (cldnn::tensor::value_type it = 0; it < weights_size; it++)
311 stream << convert_element(mem_ptr[input_it]) << " ";
313 if (input_i_it % bsv == 0) //separete every input slice with a new line
319 input_it = input_o_it*bsv + input_i_it;
321 if (input_it % (xsv*bsv) == 0) // seperate every block (8x8) with a new line
326 template<typename elemType>
327 void dump_bs_x_bsv16(const cldnn::memory& mem, std::stringstream & stream)
329 auto mem_arg = mem.get_layout();
330 auto mem_ptr = mem.pointer<elemType>();
332 auto i_size = mem_arg.size.batch[0]; //batch = input feature map
333 auto x_size = mem_arg.size.spatial[0]; // spatial_x = output feature map
334 auto weights_size = mem_arg.size.count();
336 cldnn::tensor::value_type it = 0;
337 while (it < weights_size)
339 stream << convert_element(mem_ptr[it]) << " ";
341 if (it % bsv == 0) //separate every bsv with a new line
347 void dump(const cldnn::memory& mem, std::stringstream& stream)
349 auto mem_ptr = mem.pointer<T>();
351 auto&& pitches = mem.get_layout().get_pitches();
352 auto&& size = mem.get_layout().size;
353 for (cldnn::tensor::value_type b = 0; b < size.batch[0]; ++b)
355 stream << "============= BATCH " << b << " ============\n\n";
356 for (cldnn::tensor::value_type f = 0; f < size.feature[0]; ++f)
358 stream << "feature " << f << ":\n";
359 for (cldnn::tensor::value_type y = 0; y < size.spatial[1]; ++y)
361 for (cldnn::tensor::value_type x = 0; x < size.spatial[0]; ++x)
363 unsigned int input_it = b*pitches.batch[0] + f*pitches.feature[0] + y*pitches.spatial[1] + x*pitches.spatial[0];
364 stream << convert_element(mem_ptr[input_it]) << " ";
375 void dump(const cldnn::memory& mem, std::vector<std::vector<std::string>>& dump_strings)
377 auto mem_ptr = mem.pointer<T>();
378 std::stringstream stream;
380 auto&& pitches = mem.get_layout().get_pitches();
381 auto&& size = mem.get_layout().size;
382 for (cldnn::tensor::value_type b = 0; b < size.batch[0]; ++b)
384 for (cldnn::tensor::value_type f = 0; f < size.feature[0]; ++f)
386 for (cldnn::tensor::value_type y = 0; y < size.spatial[1]; ++y)
388 for (cldnn::tensor::value_type x = 0; x < size.spatial[0]; ++x)
390 unsigned int input_it = b*pitches.batch[0] + f*pitches.feature[0] + y*pitches.spatial[1] + x*pitches.spatial[0];
391 stream << convert_element(mem_ptr[input_it]) << " ";
395 dump_strings[b][f] = stream.str();
401 void logger::log_memory_to_file(const cldnn::memory& mem, std::string prefix, bool single_batch, cldnn::tensor::value_type batch_id, bool single_feature, cldnn::tensor::value_type feature_id)
403 auto batch = mem.get_layout().size.batch[0];
404 auto feature = mem.get_layout().size.feature[0];
405 auto eng_type = "gpu" ;
406 std::vector<std::vector<std::string>> dump_strings(batch);
407 for(cldnn::tensor::value_type b = 0; b < batch; b++)
409 dump_strings[b].resize(feature);
412 if (mem.get_layout().data_type == cldnn::data_types::f32)
413 dump<float>(mem, dump_strings);
415 dump<half_t>(mem, dump_strings);
417 for (cldnn::tensor::value_type b = 0; b < batch; b++)
418 for (cldnn::tensor::value_type f = 0; f < feature; f++)
420 if (!single_batch || (b == batch_id && f == feature_id))
422 std::string filename((dump_dir + "/" + prefix + "_" + eng_type + "_b" + std::to_string(b) + "_f" + std::to_string(f) + ".txt"));
423 std::ofstream file_stream(filename);
424 file_stream << dump_strings[b][f];
430 void logger::log_weights_to_file(const cldnn::memory& mem, std::string prefix)
432 std::stringstream stream;
434 if (mem.get_layout().data_type == cldnn::data_types::f32)
435 dump<float>(mem, stream);
437 dump<half_t>(mem, stream);
439 std::string filename((dump_dir + "/" + prefix + ".txt"));
440 std::ofstream file_stream(filename);
441 file_stream << stream.str();