1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5
6 #include "Debug.hpp"
7 #include <common/include/ProfilingGuid.hpp>
8 #include <armnnUtils/Filesystem.hpp>
9
10 #include <BFloat16.hpp>
11 #include <Half.hpp>
12
13 #include <algorithm>
14 #include <iostream>
15 #include <iosfwd>
16 #include <fstream>
17 #include <sys/stat.h>
18
19 namespace armnn
20 {
21
22 template<typename T>
PrintOutput(const TensorInfo & inputInfo,const T * inputData,LayerGuid guid,const std::string & layerName,unsigned int slotIndex,std::ostream & os)23 void PrintOutput(const TensorInfo& inputInfo,
24 const T* inputData,
25 LayerGuid guid,
26 const std::string& layerName,
27 unsigned int slotIndex,
28 std::ostream& os)
29 {
30 const unsigned int numDims = inputInfo.GetNumDimensions();
31 const unsigned int numElements = inputInfo.GetNumElements();
32 const TensorShape& inputShape = inputInfo.GetShape();
33
34 std::vector<unsigned int> strides(numDims, 0);
35 strides[numDims - 1] = inputShape[numDims - 1];
36
37 for (unsigned int i = 2; i <= numDims; i++)
38 {
39 strides[numDims - i] = strides[numDims - i + 1] * inputShape[numDims - i];
40 }
41
42 os << "{ ";
43 os << "\"layerGuid\": " << guid << ", ";
44 os << "\"layerName\": \"" << layerName << "\", ";
45 os << "\"outputSlot\": " << slotIndex << ", ";
46 os << "\"shape\": ";
47
48 os << "[";
49 for (unsigned int i = 0; i < numDims; i++)
50 {
51 os << inputShape[i];
52 if (i != numDims - 1)
53 {
54 os << ", ";
55 }
56 }
57 os << "], ";
58
59 os << "\"min\": "
60 << static_cast<float>(*std::min_element(inputData, inputData + numElements)) << ", ";
61
62 os << "\"max\": "
63 << static_cast<float>(*std::max_element(inputData, inputData + numElements)) << ", ";
64
65 os << "\"data\": ";
66
67 for (unsigned int i = 0; i < numElements; i++)
68 {
69 for (unsigned int j = 0; j < numDims; j++)
70 {
71 if (i % strides[j] == 0)
72 {
73 os << "[";
74 }
75 }
76
77 os << static_cast<float>(inputData[i]);
78
79 for (unsigned int j = 0; j < numDims; j++)
80 {
81 if ((i + 1) % strides[j] == 0)
82 {
83 os << "]";
84 }
85 }
86
87 if (i != numElements - 1)
88 {
89 os << ", ";
90 }
91 }
92
93 os << " }" << std::endl;
94 }
95
96 template<typename T>
Debug(const TensorInfo & inputInfo,const T * inputData,LayerGuid guid,const std::string & layerName,unsigned int slotIndex,bool outputsToFile)97 void Debug(const TensorInfo& inputInfo,
98 const T* inputData,
99 LayerGuid guid,
100 const std::string& layerName,
101 unsigned int slotIndex,
102 bool outputsToFile)
103 {
104 if (outputsToFile)
105 {
106 fs::path tmpDir = fs::temp_directory_path();
107 std::ofstream out(tmpDir.generic_string() + "/ArmNNIntermediateLayerOutputs/" + layerName + ".numpy");
108 PrintOutput<T>(inputInfo, inputData, guid, layerName, slotIndex, out);
109 out.close();
110 }
111 else
112 {
113 PrintOutput<T>(inputInfo, inputData, guid, layerName, slotIndex, std::cout);
114 }
115 }
116
117 template void Debug<BFloat16>(const TensorInfo& inputInfo,
118 const BFloat16* inputData,
119 LayerGuid guid,
120 const std::string& layerName,
121 unsigned int slotIndex,
122 bool outputsToFile);
123
124 template void Debug<Half>(const TensorInfo& inputInfo,
125 const Half* inputData,
126 LayerGuid guid,
127 const std::string& layerName,
128 unsigned int slotIndex,
129 bool outputsToFile);
130
131 template void Debug<float>(const TensorInfo& inputInfo,
132 const float* inputData,
133 LayerGuid guid,
134 const std::string& layerName,
135 unsigned int slotIndex,
136 bool outputsToFile);
137
138 template void Debug<uint8_t>(const TensorInfo& inputInfo,
139 const uint8_t* inputData,
140 LayerGuid guid,
141 const std::string& layerName,
142 unsigned int slotIndex,
143 bool outputsToFile);
144
145 template void Debug<int8_t>(const TensorInfo& inputInfo,
146 const int8_t* inputData,
147 LayerGuid guid,
148 const std::string& layerName,
149 unsigned int slotIndex,
150 bool outputsToFile);
151
152 template void Debug<int16_t>(const TensorInfo& inputInfo,
153 const int16_t* inputData,
154 LayerGuid guid,
155 const std::string& layerName,
156 unsigned int slotIndex,
157 bool outputsToFile);
158
159 template void Debug<int32_t>(const TensorInfo& inputInfo,
160 const int32_t* inputData,
161 LayerGuid guid,
162 const std::string& layerName,
163 unsigned int slotIndex,
164 bool outputsToFile);
165
166 } // namespace armnn
167