1 // Copyright (C) 2018-2019 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
12 #include "debug_options.h"
14 namespace CLDNNPlugin {
16 DebugOptions::DebugOptions() {
17 m_bDebugLayerContent =
18 #ifdef _DEBUG_LAYER_CONTENT
24 m_bDebugLayerContentIndexed =
25 #ifdef _DEBUG_LAYER_CONTENT_INDEXED
32 #ifdef _DEBUG_LAYER_FORMAT
39 #ifdef _PLUGIN_PERF_PRINTS
46 #ifdef _DEBUG_LAYER_CONTENT_FULL
53 void DebugOptions::PrintOptions() const {
55 std::cout << "Debug Options:" << std::endl;
56 std::cout << "\tDebug Layer Content: " << m_bDebugLayerContent << std::endl;
57 std::cout << "\tDebug Layer Content Indexed: " << m_bDebugLayerContentIndexed << std::endl;
58 std::cout << "\tDebug Layers Format: " << m_bDebugLayerFormat << std::endl;
59 std::cout << "\tPlugin Performance Prints: " << m_bPluginPerfPrints << std::endl;
60 std::cout << "\tPrint Size: " << m_maxPrintSize << std::endl;
64 std::string DebugOptions::GetFormatName(cldnn::format::type format) {
66 case cldnn::format::yxfb:
68 case cldnn::format::byxf:
70 case cldnn::format::bfyx:
72 case cldnn::format::fyxb:
75 return "Unknown Format";
79 std::string DebugOptions::GetDataTypeName(cldnn::data_types dataType) {
81 case cldnn::data_types::f16:
83 case cldnn::data_types::f32:
86 return "Unknown Data Type";
90 void DebugOptions::PrintInput(const InferenceEngine::TBlob<float>& input) const {
92 const float* inputBlobPtr = input.readOnly();
94 if (m_bDebugLayerContent) {
95 std::cout << "Input (" << input.size() << ") = ";
96 for (size_t i = 0; i < std::min<size_t>(m_maxPrintSize, input.size()); i++) {
97 std::cout << inputBlobPtr[i] << ", ";
99 std::cout << std::endl;
104 float DebugOptions::SimpleConvertFP16toFP32(uint16_t u16val) {
106 // convert to fp32 (1,5,10)->(1,8,23)
107 // trivial conversion not handling inf/denorm
108 uint32_t sign = (u16val & 0x8000U) << 16;
109 uint32_t mantissa = (u16val & 0x3FFU) << 13;
110 uint32_t exp_val_f16 = (u16val & 0x7C00U) >> 10;
111 uint32_t exp = (exp_val_f16 == 0x1FU ? 0xFFU : exp_val_f16 + 127 - 15) << 23;;
112 uint32_t val = sign | exp | mantissa;
113 float fval = *(reinterpret_cast<float*>(&val));
114 return (fabs(fval) < 1e-4f) ? 0.0f : fval; // clamp epsilon fp16 to 0
118 void DebugOptions::PrintIndexedValue(const cldnn::memory& mem, const cldnn::tensor index) const {
120 auto layout = mem.get_layout();
122 switch (layout.data_type) {
123 case cldnn::data_types::f32: {
124 auto p32 = mem.pointer<float>();
125 auto resPtrF32 = p32.data();
126 fval = resPtrF32[CalcLinearIndex(layout, index)];
129 case cldnn::data_types::f16:
131 auto p16 = mem.pointer<uint16_t>();
132 auto resPtrU16 = p16.data();
133 fval = SimpleConvertFP16toFP32(resPtrU16[CalcLinearIndex(layout, index)]);
137 assert(0); // unhandled data type
141 if (m_bDebugLayerContentIndexed) {
143 for (size_t i = 0; i < index.raw.size(); i++) {
144 std::cout << index.raw[i] << ",";
146 std::cout << "] = " << fval << "\n";
148 std::cout << fval << ", ";
153 uint32_t DebugOptions::CalcLinearIndex(const cldnn::layout& memLayout, const cldnn::tensor index) {
155 uint32_t bPitch, fPitch, xPitch, yPitch;
156 switch (memLayout.format) {
157 case cldnn::format::yxfb:
159 fPitch = memLayout.size.batch[0] * bPitch;
160 xPitch = memLayout.size.feature[0] * fPitch;
161 yPitch = memLayout.size.spatial[1] * xPitch;
162 return (index.batch[0] * bPitch)
163 + (index.feature[0] * fPitch)
164 + (index.spatial[1] * xPitch)
165 + (index.spatial[0] * yPitch);
167 case cldnn::format::bfyx:
169 yPitch = memLayout.size.spatial[1] * xPitch;
170 fPitch = memLayout.size.spatial[0] * yPitch;
171 bPitch = memLayout.size.feature[0] * fPitch;
172 return (index.batch[0] * bPitch)
173 + (index.feature[0] * fPitch)
174 + (index.spatial[1] * xPitch)
175 + (index.spatial[0] * yPitch);
185 void DebugOptions::PrintNetworkOutputs(std::map<cldnn::primitive_id, cldnn::network_output>& outputsMap) const {
187 if (!m_bDebugLayerContent && !m_bDebugLayerFormat) {
191 for (auto& layer : outputsMap) {
192 std::cout << layer.first << ":\n";
193 auto mem = layer.second.get_memory();
194 auto layout = mem.get_layout();
195 if (m_bDebugLayerFormat) {
196 std::string formatName = GetFormatName(layout.format);
197 std::string datatypeName = GetDataTypeName(layout.data_type);
198 std::cout << " Layout: ( " <<
199 GetDataTypeName(layout.data_type) << ", " <<
200 GetFormatName(layout.format) << ", [";
201 for (auto s : layout.size.sizes()) {
202 std::cout << s << ",";
204 std::cout << "] )\n";
206 if (m_bDebugLayerContent) {
207 DumpSingleOutput(layer.first, outputsMap);
214 void DebugOptions::DumpSingleOutput(cldnn::primitive_id name, std::map<cldnn::primitive_id, cldnn::network_output>& outputs, bool bSingleFeatureMap) const {
216 if (outputs.find(name) == outputs.end()) {
217 std::cout << "Couldn't find output: " << name << std::endl;
221 auto output = outputs.at(name);
222 std::cout << name << ":\n";
223 auto mem = output.get_memory();
224 auto layout = mem.get_layout();
225 cldnn::tensor lowerPad = layout.data_padding.lower_size();
226 cldnn::tensor upperPad = layout.data_padding.upper_size();
228 std::string formatName = GetFormatName(layout.format);
229 std::string datatypeName = GetDataTypeName(layout.data_type);
230 std::cout << " Layout: ( " <<
231 GetDataTypeName(layout.data_type) << ", " <<
232 GetFormatName(layout.format) << ", [";
233 for (auto s : layout.size.sizes()) {
234 std::cout << s << ",";
237 for (auto p : layout.data_padding.lower_size().sizes()) {
238 std::cout << p << ",";
241 for (auto p : layout.data_padding.upper_size().sizes()) {
242 std::cout << p << ",";
244 std::cout << "] )\n";
247 switch (layout.format) {
248 case cldnn::format::bfyx:
250 std::vector<size_t> pitches;
252 if (bSingleFeatureMap) {
253 elements = layout.size.spatial[1] * layout.size.spatial[0];
255 for (int i = 0; i < 4; i++) {
256 elements *= layout.size.sizes()[i] + lowerPad.sizes()[i] + upperPad.sizes()[i];
259 pitches.push_back(layout.size.spatial[0] + lowerPad.spatial[0] + upperPad.spatial[0]); // x or width - rowpitch
260 pitches.push_back(pitches[0] * (layout.size.spatial[1] + lowerPad.spatial[1] + upperPad.spatial[1])); // slice pitch
261 pitches.push_back(pitches[0] * pitches[1] * layout.size.feature[0]); // depth/feature pitch
262 if (layout.data_type == cldnn::data_types::f32)
263 DumpElementsRaw<float>(mem, pitches, elements);
265 DumpElementsRaw<uint16_t>(mem, pitches, elements);
269 assert(0); // unhandled format
277 void DebugOptions::AddTimedEvent(std::string eventName, std::string startingAt) {
278 #ifdef _PLUGIN_PERF_PRINTS
279 m_TimedEventTimestamp[eventName] = std::chrono::steady_clock::now();
280 if (startingAt.compare(std::string()) == 0) {
281 startingAt = eventName;
283 m_TimedEventStart[eventName] = startingAt;
284 #endif // _PLUGIN_PERF_PRINTS
287 void DebugOptions::PrintTimedEvents() {
288 #ifdef _PLUGIN_PERF_PRINTS
289 for (auto& e : m_TimedEventStart) {
290 if (e.first.compare(e.second)) {
291 std::cout << "[Plugin Internal Metric]: \t" << e.first << " took: " <<
292 std::chrono::duration_cast<std::chrono::duration<double, std::chrono::milliseconds::period>>
293 (m_TimedEventTimestamp[e.first] - m_TimedEventTimestamp[e.second]).count() << " ms\n";
296 #endif // _PLUGIN_PERF_PRINTS
299 void DebugOptions::ClearTimedEvents() {
300 #ifdef _PLUGIN_PERF_PRINTS
301 m_TimedEventStart.clear();
302 m_TimedEventTimestamp.clear();
303 #endif // _PLUGIN_PERF_PRINTS
306 void DebugOptions::EnableWA(std::string name) {
308 m_workaroundNames.insert(name);
312 void DebugOptions::DisableWA(std::string name) {
314 m_workaroundNames.erase(name);
318 bool DebugOptions::IsWAActive(std::string name) {
320 return (m_workaroundNames.find(name) != m_workaroundNames.end());
326 std::string DebugOptions::IELayoutToString(InferenceEngine::Layout layout) {
328 case InferenceEngine::ANY: return "ANY";
329 case InferenceEngine::NCHW: return "NCHW";
330 case InferenceEngine::NHWC: return "NHWC";
331 case InferenceEngine::NCDHW: return "NCDHW";
332 case InferenceEngine::OIHW: return "OIHW";
333 case InferenceEngine::C: return "C";
334 case InferenceEngine::CHW: return "CHW";
335 case InferenceEngine::HW: return "HW";
336 case InferenceEngine::NC: return "NC";
337 default: return "Unknown";
341 }; // namespace CLDNNPlugin