1 /** 2 * Copyright 2021 Huawei Technologies Co., Ltd 3 * 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 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 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. 15 */ 16 17 #include "coder/generator/component/const_blocks/debug_utils.h" 18 19 namespace mindspore::lite::micro { 20 const char debug_utils_h[] = R"RAW( 21 /** 22 * Copyright 2021 Huawei Technologies Co., Ltd 23 * 24 * Licensed under the Apache License, Version 2.0 (the "License"); 25 * you may not use this file except in compliance with the License. 26 * You may obtain a copy of the License at 27 * 28 * http://www.apache.org/licenses/LICENSE-2.0 29 * 30 * Unless required by applicable law or agreed to in writing, software 31 * distributed under the License is distributed on an "AS IS" BASIS, 32 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 33 * See the License for the specific language governing permissions and 34 * limitations under the License. 35 */ 36 37 #ifndef MINDSPORE_LITE_MICRO_MICRODEBUGUTIL_H_ 38 #define MINDSPORE_LITE_MICRO_MICRODEBUGUTIL_H_ 39 40 #include <stdio.h> 41 #include <sys/time.h> 42 #include <time.h> 43 #include <stdint.h> 44 45 #define MICRO_INFO(content, args...) \ 46 { printf("[INFO] %s|%d: " #content "\r\n", __func__, __LINE__, ##args); } 47 #define MICRO_ERROR(content, args...) \ 48 { printf("[ERROR] %s|%d: " #content "\r\n", __func__, __LINE__, ##args); } 49 50 enum DataType { 51 DataType_DT_FLOAT = 0, 52 DataType_DT_FLOAT16 = 1, 53 DataType_DT_INT8 = 2, 54 DataType_DT_INT32 = 3, 55 DataType_DT_UINT8 = 4, 56 DataType_DT_INT16 = 5, 57 DataType_DT_UINT32 = 8, 58 DataType_DT_INT64 = 9, 59 DataType_DT_UINT16 = 10, 60 DataType_DT_UNDEFINED = 16, 61 DataType_MIN = DataType_DT_FLOAT, 62 DataType_MAX = DataType_DT_UNDEFINED 63 }; 64 65 enum Format { 66 Format_NCHW = 0, 67 Format_NHWC = 1, 68 Format_HWKC = 2, 69 Format_HWCK = 3, 70 Format_KCHW = 4, 71 Format_CKHW = 5, 72 Format_KHWC = 6, 73 Format_CHWK = 7, 74 Format_NC4HW4 = 100, 75 Format_NUM_OF_FORMAT = 101, 76 Format_MIN = Format_NCHW, 77 Format_MAX = Format_NUM_OF_FORMAT 78 }; 79 80 typedef struct { 81 enum DataType type; 82 enum Format format; 83 int ndim; 84 int *dim; 85 void *data; 86 } MicroTensor; 87 88 void PrintTensor(MicroTensor *tensor, FILE *output_file, const char *is_input); 89 90 void PrintTensorData(MicroTensor *tensor); 91 92 #endif // MINDSPORE_LITE_MICRO_MICRODEBUGUTIL_H_ 93 94 )RAW"; 95 96 const char debug_utils_c[] = R"RAW( 97 /** 98 * Copyright 2021 Huawei Technologies Co., Ltd 99 * 100 * Licensed under the Apache License, Version 2.0 (the "License"); 101 * you may not use this file except in compliance with the License. 102 * You may obtain a copy of the License at 103 * 104 * http://www.apache.org/licenses/LICENSE-2.0 105 * 106 * Unless required by applicable law or agreed to in writing, software 107 * distributed under the License is distributed on an "AS IS" BASIS, 108 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 109 * See the License for the specific language governing permissions and 110 * limitations under the License. 111 */ 112 113 #include <inttypes.h> 114 #include "debug_utils.h" 115 116 #define UP_DIV(x, y) (((x) + (y) - (1)) / (y)) 117 118 static const unsigned int kPrintNums = 20; 119 static const unsigned int kLineSplitNum = 44; 120 static const unsigned int kLineNum = 45; 121 unsigned int GetTensorElementSize(const MicroTensor *tensor) { 122 unsigned int ans = 1; 123 if (tensor->format == Format_NC4HW4) { 124 for (unsigned int i = 0; i < tensor->ndim; ++i) { 125 unsigned int dim = tensor->dim[i]; 126 if (i == 1) { 127 dim = UP_DIV(dim, 4) * 4; 128 } 129 ans *= dim; 130 } 131 } else { 132 for (unsigned int i = 0; i < tensor->ndim; ++i) { 133 ans *= tensor->dim[i]; 134 } 135 } 136 return ans; 137 } 138 139 static const char *const TypeNames[] = {"DT_FLOAT", "DT_FLOAT16", "DT_INT8", "DT_INT32", "DT_UINT8", "DT_INT16", 140 "", "", "DT_UINT32", "DT_INT64", "DT_UINT16", "", 141 "", "", "", "", "DT_UNDEFINED", ""}; 142 143 const char *EnumNameFormat(enum Format e) { 144 switch (e) { 145 case Format_NCHW: 146 return "NCHW"; 147 case Format_NHWC: 148 return "NHWC"; 149 case Format_HWKC: 150 return "HWKC"; 151 case Format_HWCK: 152 return "HWCK"; 153 case Format_KCHW: 154 return "KCHW"; 155 case Format_CKHW: 156 return "CKHW"; 157 case Format_KHWC: 158 return "KHWC"; 159 case Format_CHWK: 160 return "CHWK"; 161 case Format_NC4HW4: 162 return "NC4HW4"; 163 case Format_NUM_OF_FORMAT: 164 return "NUM_OF_FORMAT"; 165 default: 166 return ""; 167 } 168 } 169 170 void PrintTensorData(MicroTensor *tensor) { 171 void *data = tensor->data; 172 unsigned int elenums = GetTensorElementSize(tensor); 173 if (data == NULL || elenums == 0) { 174 MICRO_ERROR("print tensor data failed"); 175 return; 176 } 177 switch (tensor->type) { 178 case DataType_DT_FLOAT: { 179 float *addr = (float *)(data); 180 for (int i = 0; i < elenums && i < kPrintNums; ++i) { 181 printf("%f, ", addr[i]); 182 } 183 break; 184 } 185 case DataType_DT_INT32: { 186 int32_t *addr = (int32_t *)(data); 187 for (int i = 0; i < elenums && i < kPrintNums; ++i) { 188 printf("%d, ", addr[i]); 189 } 190 break; 191 } 192 case DataType_DT_INT8: { 193 int8_t *addr = (int8_t *)(data); 194 for (int i = 0; i < elenums && i < kPrintNums; ++i) { 195 printf("%d, ", addr[i]); 196 } 197 break; 198 } 199 case DataType_DT_UINT32: { 200 uint32_t *addr = (uint32_t *)(data); 201 for (int i = 0; i < elenums && i < kPrintNums; ++i) { 202 printf("%u, ", addr[i]); 203 } 204 break; 205 } 206 case DataType_DT_UINT8: { 207 uint8_t *addr = (uint8_t *)(data); 208 for (int i = 0; i < elenums && i < kPrintNums; ++i) { 209 printf("%u, ", addr[i]); 210 } 211 break; 212 } 213 default: 214 MICRO_ERROR("unsupported data type %d", tensor->type); 215 } 216 printf("\n"); 217 } 218 219 void PrintDataToFile(const void *data, const size_t elenums, const enum DataType type, FILE *file) { 220 if (data == NULL || elenums == 0) { 221 MICRO_ERROR("print tensor data to file failed"); 222 return; 223 } 224 switch (type) { 225 case DataType_DT_FLOAT: { 226 float *addr = (float *)(data); 227 for (int i = 0; i < elenums; ++i) { 228 fprintf(file, "%0.15f, ", addr[i]); 229 if (i % kLineNum == kLineSplitNum) { 230 fprintf(file, "\n"); 231 } 232 } 233 break; 234 } 235 case DataType_DT_INT32: { 236 int32_t *addr = (int32_t *)(data); 237 for (int i = 0; i < elenums; ++i) { 238 fprintf(file, "%d, ", addr[i]); 239 if (i % kLineNum == kLineSplitNum) { 240 fprintf(file, "\n"); 241 } 242 } 243 break; 244 } 245 case DataType_DT_INT8: { 246 int8_t *addr = (int8_t *)(data); 247 for (int i = 0; i < elenums; ++i) { 248 fprintf(file, "%d, ", addr[i]); 249 if (i % kLineNum == kLineSplitNum) { 250 fprintf(file, "\n"); 251 } 252 } 253 break; 254 } 255 case DataType_DT_UINT32: { 256 uint32_t *addr = (uint32_t *)(data); 257 for (int i = 0; i < elenums; ++i) { 258 fprintf(file, "%u, ", addr[i]); 259 if (i % kLineNum == kLineSplitNum) { 260 fprintf(file, "\n"); 261 } 262 } 263 break; 264 } 265 case DataType_DT_UINT8: { 266 uint8_t *addr = (uint8_t *)(data); 267 for (int i = 0; i < elenums; ++i) { 268 fprintf(file, "%u, ", addr[i]); 269 if (i % kLineNum == kLineSplitNum) { 270 fprintf(file, "\n"); 271 } 272 } 273 break; 274 } 275 default: 276 MICRO_ERROR("unsupported data type %d", type); 277 } 278 fprintf(file, "\n"); 279 } 280 281 void PrintTensor(MicroTensor *tensor, FILE *output_file, const char *is_input) { 282 if (output_file == NULL) { 283 MICRO_ERROR("output file is NULL"); 284 return; 285 } 286 fprintf(output_file, "%s ", is_input); 287 for (int i = 0; i < tensor->ndim; ++i) { 288 fprintf(output_file, "%u, ", tensor->dim[i]); 289 } 290 fprintf(output_file, "\n"); 291 292 const char *type = TypeNames[tensor->type]; 293 const char *format = EnumNameFormat(tensor->format); 294 unsigned int tensorSize = GetTensorElementSize(tensor); 295 fprintf(output_file, "%s type:%s, format:%s, elementSize: %u\n", is_input, type, format, tensorSize); 296 fprintf(output_file, "%s Data:\n", is_input); 297 PrintDataToFile(tensor->data, tensorSize, tensor->type, output_file); 298 (void)fflush(output_file); 299 } 300 301 )RAW"; 302 } // namespace mindspore::lite::micro 303