1/*******************************************************************************
2* Copyright 2018 Intel Corporation
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 <stdlib.h>
18#ifndef _WIN32
19#include <sys/time.h>
20#endif
21
22#include "mkldnn.h"
23#include "mkldnn_version.h"
24#include "c_types_map.hpp"
25#include "verbose.hpp"
26#include "cpu/cpu_isa_traits.hpp"
27
28#include "batch_normalization_pd.hpp"
29#include "pooling_pd.hpp"
30#include "concat_pd.hpp"
31#include "reorder_pd.hpp"
32#include "convolution_pd.hpp"
33#include "rnn_pd.hpp"
34#include "deconvolution_pd.hpp"
35#include "shuffle_pd.hpp"
36#include "eltwise_pd.hpp"
37#include "softmax_pd.hpp"
38#include "inner_product_pd.hpp"
39#include "sum_pd.hpp"
40#include "lrn_pd.hpp"
41
42/* MKL-DNN CPU ISA info */
43#define ISA_ANY "No instruction set specific optimizations"
44#define SSE42 "Intel(R) Streaming SIMD Extensions 4.2 (Intel(R) SSE4.2)"
45#define AVX "Intel(R) Advanced Vector Extensions (Intel(R) AVX)"
46#define AVX2 "Intel(R) Advanced Vector Extensions 2 (Intel(R) AVX2)"
47#define AVX512_COMMON "Intel(R) Advanced Vector Extensions 512 (Intel(R) " \
48 "AVX-512)"
49#define AVX512_CORE "Intel(R) Advanced Vector Extensions 512 (Intel(R) " \
50 "AVX-512) with AVX512BW, AVX512VL, and AVX512DQ extensions"
51#define AVX512_CORE_VNNI "Intel(R) AVX512-Deep Learning Boost (Intel(R) " \
52 "AVX512-DL Boost)"
53#define AVX512_MIC "Intel(R) Advanced Vector Extensions 512 (Intel(R) " \
54 "AVX-512) with AVX512CD, AVX512ER, and AVX512PF extensions"
55#define AVX512_MIC_4OPS "Intel(R) Advanced Vector Extensions 512 (Intel(R) " \
56 "AVX-512) with AVX512_4FMAPS and AVX512_4VNNIW extensions"
57
58namespace mkldnn {
59namespace impl {
60
61static verbose_t verbose;
62static bool initialized;
63static bool version_printed = false;
64
65const verbose_t *mkldnn_verbose() {
66#if !defined(DISABLE_VERBOSE)
67 if (!initialized) {
68 const int len = 2;
69 char val[len] = {0};
70 if (getenv("MKLDNN_VERBOSE", val, len) == 1)
71 verbose.level = atoi(val);
72 initialized = true;
73 }
74 if (!version_printed && verbose.level > 0) {
75 printf("mkldnn_verbose,info,"
76 "Intel(R) MKL-DNN v%d.%d.%d (Git Hash %s),%s\n",
77 mkldnn_version()->major, mkldnn_version()->minor,
78 mkldnn_version()->patch, mkldnn_version()->hash,
79 get_isa_info());
80 version_printed = true;
81 }
82#else
83 verbose.level = 0;
84#endif
85 return &verbose;
86}
87
88double get_msec() {
89#ifdef _WIN32
90 static LARGE_INTEGER frequency;
91 if (frequency.QuadPart == 0)
92 QueryPerformanceFrequency(&frequency);
93 LARGE_INTEGER now;
94 QueryPerformanceCounter(&now);
95 return 1e+3 * now.QuadPart / frequency.QuadPart;
96#else
97 struct timeval time;
98 gettimeofday(&time, NULL);
99 return 1e+3 * time.tv_sec + 1e-3 * time.tv_usec;
100#endif
101}
102
103const char *get_isa_info() {
104 using namespace mkldnn::impl::cpu;
105 if (mayiuse(avx512_mic_4ops)) return AVX512_MIC_4OPS;
106 if (mayiuse(avx512_mic)) return AVX512_MIC;
107 if (mayiuse(avx512_core_vnni)) return AVX512_CORE_VNNI;
108 if (mayiuse(avx512_core)) return AVX512_CORE;
109 if (mayiuse(avx512_common)) return AVX512_COMMON;
110 if (mayiuse(avx2)) return AVX2;
111 if (mayiuse(avx)) return AVX;
112 if (mayiuse(sse42)) return SSE42;
113 return ISA_ANY;
114}
115
116/* init_info section */
117namespace {
118#if !defined(DISABLE_VERBOSE)
119#define MKLDNN_VERBOSE_DAT_LEN 256
120#define MKLDNN_VERBOSE_AUX_LEN 384
121#define MKLDNN_VERBOSE_PRB_LEN 384
122
123#define DECL_DAT_AUX_PRB_STRS() \
124 int dat_written = 0, aux_written = 0, prb_written = 0; \
125 MAYBE_UNUSED((dat_written * aux_written * prb_written)); \
126 char dat_str[MKLDNN_VERBOSE_DAT_LEN] = {'\0'}; MAYBE_UNUSED(dat_str); \
127 char aux_str[MKLDNN_VERBOSE_AUX_LEN] = {'\0'}; MAYBE_UNUSED(aux_str); \
128 char prb_str[MKLDNN_VERBOSE_PRB_LEN] = {'\0'}; MAYBE_UNUSED(prb_str)
129
130#define DFMT "%" PRId64
131
132void clear_buf(char *buf, int &written) {
133 /* TODO: do it better */
134 buf[0] = '#';
135 buf[1] = '\0';
136 written = 1;
137}
138
139#define DPRINT(buf, buf_len, written, ...) do { \
140 int l = snprintf(buf + written, buf_len - written, __VA_ARGS__); \
141 if (l < 0 || written + l > buf_len) { \
142 clear_buf(buf, written); \
143 } else { \
144 written += l; \
145 } \
146} while(0)
147
148// XXX: Outputs strings corresponding to memory formats used for data tensors.
149void format_prb_desc_str(char *str, int len, const memory_desc_t *md) {
150 const auto dims = md->dims;
151 int written = 0;
152 if (md->ndims == 1)
153 DPRINT(str, len, written,
154 "x" DFMT, dims[0]);
155 else if (md->ndims == 2)
156 DPRINT(str, len, written,
157 "mb" DFMT "ic" DFMT, dims[0], dims[1]);
158 else if (md->ndims == 3)
159 DPRINT(str, len, written,
160 "mb" DFMT "ic" DFMT "iw" DFMT,
161 dims[0], dims[1], dims[2]);
162 else if (md->ndims == 4)
163 DPRINT(str, len, written,
164 "mb" DFMT "ic" DFMT "ih" DFMT "iw" DFMT,
165 dims[0], dims[1], dims[2], dims[3]);
166 else if (md->ndims == 5)
167 DPRINT(str, len, written,
168 "mb" DFMT "ic" DFMT "id" DFMT "ih" DFMT "iw" DFMT,
169 dims[0], dims[1], dims[2], dims[3], dims[4]);
170 else
171 mkldnn_md2dim_str(str, len, md);
172}
173
174void verbose_templ(char *buffer, mkldnn_primitive_kind_t prim_kind,
175 const char *impl_str, mkldnn_prop_kind_t prop_kind,
176 const char *data_str, const char *aux_str, const char *prb_str) {
177 MAYBE_UNUSED(verbose_templ);
178 int written = 0;
179 DPRINT(buffer, MKLDNN_VERBOSE_BUF_LEN, written, "%s,%s,%s,%s,%s,%s",
180 mkldnn_prim_kind2str(prim_kind), impl_str,
181 mkldnn_prop_kind2str(prop_kind), data_str, aux_str, prb_str);
182}
183
184template <typename pd_t> static void init_info_bnorm(pd_t *s, char *buffer) {
185 DECL_DAT_AUX_PRB_STRS();
186
187 if (1) { // data
188 auto md = s->src_md();
189 DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, "data_");
190 int l = mkldnn_md2fmt_str(dat_str + dat_written,
191 MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
192 if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
193 }
194 if (1) { // diff data
195 auto md = s->diff_src_md();
196 if (md) {
197 DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, " diff_");
198 int l = mkldnn_md2fmt_str(dat_str + dat_written,
199 MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
200 if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
201 }
202 }
203
204 DPRINT(aux_str, MKLDNN_VERBOSE_AUX_LEN, aux_written,
205 "flags:%u", s->desc()->flags);
206
207 format_prb_desc_str(prb_str, MKLDNN_VERBOSE_PRB_LEN, s->src_md());
208
209 verbose_templ(buffer, s->kind(), s->name(), s->desc()->prop_kind, dat_str,
210 aux_str, prb_str);
211}
212
213template <typename pd_t> static void init_info_conv(pd_t *s, char *buffer) {
214 DECL_DAT_AUX_PRB_STRS();
215
216 if (1) { // src
217 auto md = s->desc()->prop_kind == prop_kind::backward_data
218 ? s->diff_src_md() : s->src_md();
219 DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, "src_");
220 int l = mkldnn_md2fmt_str(dat_str + dat_written,
221 MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
222 if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
223 }
224 if (1) { // wei
225 auto md = s->desc()->prop_kind == prop_kind::backward_weights
226 ? s->diff_weights_md() : s->weights_md();
227 DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, " wei_");
228 int l = mkldnn_md2fmt_str(dat_str + dat_written,
229 MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
230 if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
231 }
232 if (1) { // bia
233 auto md = s->desc()->prop_kind == prop_kind::backward_weights
234 ? s->diff_weights_md(1) : s->weights_md(1);
235 if (md) {
236 DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, " bia_");
237 int l = mkldnn_md2fmt_str(dat_str + dat_written,
238 MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
239 if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
240 }
241 }
242 if (1) { // dst
243 auto md = !s->is_fwd() ? s->diff_dst_md() : s->dst_md();
244 DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, " dst_");
245 int l = mkldnn_md2fmt_str(dat_str + dat_written,
246 MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
247 if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
248 }
249
250 DPRINT(aux_str, MKLDNN_VERBOSE_AUX_LEN, aux_written,
251 "alg:%s", mkldnn_alg_kind2str(s->desc()->alg_kind));
252
253 if (s->ndims() == 5) {
254 if (s->with_groups())
255 DPRINT(prb_str, MKLDNN_VERBOSE_PRB_LEN, prb_written,
256 "mb" DFMT "_g" DFMT "ic" DFMT "oc" DFMT
257 "_id" DFMT "od" DFMT "kd" DFMT "sd" DFMT "dd" DFMT "pd" DFMT
258 "_ih" DFMT "oh" DFMT "kh" DFMT "sh" DFMT "dh" DFMT "ph" DFMT
259 "_iw" DFMT "ow" DFMT "kw" DFMT "sw" DFMT "dw" DFMT "pw" DFMT,
260 s->MB(), s->G(), s->IC(), s->OC(),
261 s->ID(), s->OD(), s->KD(), s->KSD(), s->KDD(), s->padFront(),
262 s->IH(), s->OH(), s->KH(), s->KSH(), s->KDH(), s->padT(),
263 s->IW(), s->OW(), s->KW(), s->KSW(), s->KDW(), s->padL());
264 else
265 DPRINT(prb_str, MKLDNN_VERBOSE_PRB_LEN, prb_written,
266 "mb" DFMT "_ic" DFMT "oc" DFMT
267 "_id" DFMT "od" DFMT "kd" DFMT "sd" DFMT "dd" DFMT "pd" DFMT
268 "_ih" DFMT "oh" DFMT "kh" DFMT "sh" DFMT "dh" DFMT "ph" DFMT
269 "_iw" DFMT "ow" DFMT "kw" DFMT "sw" DFMT "dw" DFMT "pw" DFMT,
270 s->MB(), s->IC(), s->OC(),
271 s->ID(), s->OD(), s->KD(), s->KSD(), s->KDD(), s->padFront(),
272 s->IH(), s->OH(), s->KH(), s->KSH(), s->KDH(), s->padT(),
273 s->IW(), s->OW(), s->KW(), s->KSW(), s->KDW(), s->padL());
274 } else {
275 if (s->with_groups())
276 DPRINT(prb_str, MKLDNN_VERBOSE_PRB_LEN, prb_written,
277 "mb" DFMT "_g" DFMT "ic" DFMT "oc" DFMT
278 "_ih" DFMT "oh" DFMT "kh" DFMT "sh" DFMT "dh" DFMT "ph" DFMT
279 "_iw" DFMT "ow" DFMT "kw" DFMT "sw" DFMT "dw" DFMT "pw" DFMT,
280 s->MB(), s->G(), s->IC(), s->OC(),
281 s->IH(), s->OH(), s->KH(), s->KSH(), s->KDH(), s->padT(),
282 s->IW(), s->OW(), s->KW(), s->KSW(), s->KDW(), s->padL());
283 else
284 DPRINT(prb_str, MKLDNN_VERBOSE_PRB_LEN, prb_written,
285 "mb" DFMT "_ic" DFMT "oc" DFMT
286 "_ih" DFMT "oh" DFMT "kh" DFMT "sh" DFMT "dh" DFMT "ph" DFMT
287 "_iw" DFMT "ow" DFMT "kw" DFMT "sw" DFMT "dw" DFMT "pw" DFMT,
288 s->MB(), s->IC(), s->OC(),
289 s->IH(), s->OH(), s->KH(), s->KSH(), s->KDH(), s->padT(),
290 s->IW(), s->OW(), s->KW(), s->KSW(), s->KDW(), s->padL());
291 }
292
293 verbose_templ(buffer, s->kind(), s->name(), s->desc()->prop_kind, dat_str,
294 aux_str, prb_str);
295}
296
297template <typename pd_t> static void init_info_shuffle(pd_t *s, char *buffer) {
298 DECL_DAT_AUX_PRB_STRS();
299
300 auto md = s->is_fwd() ? s->src_md() : s->diff_dst_md();
301
302 if (1) { // data
303 DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, "data_");
304 int l = mkldnn_md2fmt_str(dat_str + dat_written,
305 MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
306 if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
307 }
308
309 DPRINT(aux_str, MKLDNN_VERBOSE_AUX_LEN, aux_written,
310 "axis:%d group_size:" DFMT, s->axis(), s->group_size());
311
312 mkldnn_md2dim_str(prb_str, MKLDNN_VERBOSE_PRB_LEN, md);
313
314 verbose_templ(buffer, s->kind(), s->name(), s->desc()->prop_kind, dat_str,
315 aux_str, prb_str);
316}
317
318template <typename pd_t> static void init_info_eltwise(pd_t *s, char *buffer) {
319 DECL_DAT_AUX_PRB_STRS();
320
321 if (1) { // data
322 auto md = s->src_md();
323 DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, "data_");
324 int l = mkldnn_md2fmt_str(dat_str + dat_written,
325 MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
326 if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
327 }
328 if (1) { // diff data
329 auto md = s->diff_src_md();
330 if (md) {
331 DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, " diff_");
332 int l = mkldnn_md2fmt_str(dat_str + dat_written,
333 MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
334 if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
335 }
336 }
337
338 DPRINT(aux_str, MKLDNN_VERBOSE_AUX_LEN, aux_written,
339 "alg:%s", mkldnn_alg_kind2str(s->desc()->alg_kind));
340
341 mkldnn_md2dim_str(prb_str, MKLDNN_VERBOSE_PRB_LEN, s->src_md());
342
343 verbose_templ(buffer, s->kind(), s->name(), s->desc()->prop_kind, dat_str,
344 aux_str, prb_str);
345}
346
347template <typename pd_t> static void init_info_iprod(pd_t *s, char *buffer) {
348 DECL_DAT_AUX_PRB_STRS();
349
350 if (1) { // src
351 auto md = s->desc()->prop_kind == prop_kind::backward_data
352 ? s->diff_src_md() : s->src_md();
353 DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, "src_");
354 int l = mkldnn_md2fmt_str(dat_str + dat_written,
355 MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
356 if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
357 }
358 if (1) { // wei
359 auto md = s->desc()->prop_kind == prop_kind::backward_weights
360 ? s->diff_weights_md() : s->weights_md();
361 DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, " wei_");
362 int l = mkldnn_md2fmt_str(dat_str + dat_written,
363 MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
364 if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
365 }
366 if (1) { // bia
367 auto md = s->desc()->prop_kind == prop_kind::backward_weights
368 ? s->diff_weights_md(1) : s->weights_md(1);
369 if (md) {
370 DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, " bia_");
371 int l = mkldnn_md2fmt_str(dat_str + dat_written,
372 MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
373 if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
374 }
375 }
376 if (1) { // dst
377 auto md = !s->is_fwd() ? s->diff_dst_md() : s->dst_md();
378 DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, " dst_");
379 int l = mkldnn_md2fmt_str(dat_str + dat_written,
380 MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
381 if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
382 }
383
384 DPRINT(prb_str, MKLDNN_VERBOSE_PRB_LEN, prb_written,
385 "mb" DFMT "ic" DFMT "oc" DFMT, s->MB(), s->IC_total(), s->OC());
386
387 verbose_templ(buffer, s->kind(), s->name(), s->desc()->prop_kind, dat_str,
388 aux_str, prb_str);
389}
390
391template <typename pd_t> static void init_info_lrn(pd_t *s, char *buffer) {
392 DECL_DAT_AUX_PRB_STRS();
393
394 if (1) { // data
395 auto md = s->src_md();
396 DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, "data_");
397 int l = mkldnn_md2fmt_str(dat_str + dat_written,
398 MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
399 if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
400 }
401 if (1) { // diff data
402 auto md = s->diff_src_md();
403 if (md) {
404 DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, " diff_");
405 int l = mkldnn_md2fmt_str(dat_str + dat_written,
406 MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
407 if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
408 }
409 }
410
411 DPRINT(aux_str, MKLDNN_VERBOSE_AUX_LEN, aux_written,
412 "alg:%s", mkldnn_alg_kind2str(s->desc()->alg_kind));
413
414 format_prb_desc_str(prb_str, MKLDNN_VERBOSE_PRB_LEN, s->src_md());
415
416 verbose_templ(buffer, s->kind(), s->name(), s->desc()->prop_kind, dat_str,
417 aux_str, prb_str);
418}
419
420template <typename pd_t> static void init_info_mem(pd_t *s, char *buffer) {
421 DECL_DAT_AUX_PRB_STRS();
422
423 if (1) { // src
424 auto md = s->src_md();
425 DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, "src_");
426 int l = mkldnn_md2fmt_str(dat_str + dat_written,
427 MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
428 if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
429 }
430 if (1) { // dst
431 auto md = s->dst_md();
432 DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, " dst_");
433 int l = mkldnn_md2fmt_str(dat_str + dat_written,
434 MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
435 if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
436 }
437
438 DPRINT(aux_str, MKLDNN_VERBOSE_AUX_LEN, aux_written,
439 "num:%d", s->n_inputs());
440
441 mkldnn_md2dim_str(prb_str, MKLDNN_VERBOSE_PRB_LEN, s->dst_md());
442
443 verbose_templ(buffer, s->kind(), s->name(), prop_kind::undef, dat_str,
444 aux_str, prb_str);
445}
446
447template <typename pd_t> static void init_info_pool(pd_t *s, char *buffer) {
448 DECL_DAT_AUX_PRB_STRS();
449
450 if (1) { // src
451 auto md = s->is_fwd() ? s->src_md() : s->diff_src_md();
452 DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, "src_");
453 int l = mkldnn_md2fmt_str(dat_str + dat_written,
454 MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
455 if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
456 }
457 if (1) { // dst
458 auto md = s->is_fwd() ? s->dst_md() : s->diff_dst_md();
459 DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, " dst_");
460 int l = mkldnn_md2fmt_str(dat_str + dat_written,
461 MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
462 if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
463 }
464 if (1) { // ws
465 auto md = s->workspace_md();
466 if (md) {
467 DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, " ws_");
468 int l = mkldnn_md2fmt_str(dat_str + dat_written,
469 MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
470 if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
471 }
472 }
473
474 DPRINT(aux_str, MKLDNN_VERBOSE_AUX_LEN, aux_written,
475 "alg:%s", mkldnn_alg_kind2str(s->desc()->alg_kind));
476
477 if (s->is_3d()) {
478 DPRINT(prb_str, MKLDNN_VERBOSE_PRB_LEN, prb_written,
479 "mb" DFMT "ic" DFMT "_"
480 "id" DFMT "od" DFMT "kd" DFMT "sd" DFMT "pd" DFMT "_"
481 "ih" DFMT "oh" DFMT "kh" DFMT "sh" DFMT "ph" DFMT "_"
482 "iw" DFMT "ow" DFMT "kw" DFMT "sw" DFMT "pw" DFMT "",
483 s->MB(), s->C(),
484 s->ID(), s->OD(), s->KD(), s->KSD(), s->padFront(),
485 s->IH(), s->OH(), s->KH(), s->KSH(), s->padT(),
486 s->IW(), s->OW(), s->KW(), s->KSW(), s->padL());
487 } else {
488 DPRINT(prb_str, MKLDNN_VERBOSE_PRB_LEN, prb_written,
489 "mb" DFMT "ic" DFMT "_"
490 "ih" DFMT "oh" DFMT "kh" DFMT "sh" DFMT "ph" DFMT "_"
491 "iw" DFMT "ow" DFMT "kw" DFMT "sw" DFMT "pw" DFMT,
492 s->MB(), s->C(),
493 s->IH(), s->OH(), s->KH(), s->KSH(), s->padT(),
494 s->IW(), s->OW(), s->KW(), s->KSW(), s->padL());
495 }
496
497 verbose_templ(buffer, s->kind(), s->name(), s->desc()->prop_kind, dat_str,
498 aux_str, prb_str);
499}
500
501template <typename pd_t> static void init_info_softmax(pd_t *s, char *buffer) {
502 DECL_DAT_AUX_PRB_STRS();
503
504 if (1) { // data
505 auto md = s->dst_md();
506 DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, "data_");
507 int l = mkldnn_md2fmt_str(dat_str + dat_written,
508 MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
509 if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
510 }
511 if (1) { // diff data
512 auto md = s->diff_src_md();
513 if (md) {
514 DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, " diff_");
515 int l = mkldnn_md2fmt_str(dat_str + dat_written,
516 MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
517 if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
518 }
519 }
520
521 mkldnn_md2dim_str(prb_str, MKLDNN_VERBOSE_PRB_LEN, s->dst_md());
522
523 verbose_templ(buffer, s->kind(), s->name(), s->desc()->prop_kind, dat_str,
524 aux_str, prb_str);
525}
526
527template <typename pd_t> static void init_info_rnn(pd_t *s, char *buffer) {
528 DECL_DAT_AUX_PRB_STRS();
529
530 if (1) { // src layer
531 auto md = s->is_fwd() ? s->src_md(0) : s->diff_src_md(0);
532 DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, "src_layer_");
533 int l = mkldnn_md2fmt_str(dat_str + dat_written,
534 MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
535 if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
536 }
537 if (1) { // src iter
538 auto md = s->is_fwd() ? s->src_md(1) : s->diff_src_md(1);
539 DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, "src_iter_");
540 int l = mkldnn_md2fmt_str(dat_str + dat_written,
541 MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
542 if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
543 }
544 if (1) { // wei_layer
545 auto md = s->is_fwd() ? s->weights_md(0) : s->diff_weights_md(0);
546 DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, " wei_layer_");
547 int l = mkldnn_md2fmt_str(dat_str + dat_written,
548 MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
549 if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
550 }
551 if (1) { // wei_iter
552 auto md = s->is_fwd() ? s->weights_md(1) : s->diff_weights_md(1);
553 DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, " wei_layer_");
554 int l = mkldnn_md2fmt_str(dat_str + dat_written,
555 MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
556 if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
557 }
558 if (1) { // bias
559 auto md = s->is_fwd() ? s->weights_md(2) : s->diff_weights_md(2);
560 DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, " bias_");
561 int l = mkldnn_md2fmt_str(dat_str + dat_written,
562 MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
563 if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
564 }
565 if (1) { // dst layer
566 auto md = s->is_fwd() ? s->dst_md(0) : s->diff_dst_md(0);
567 DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, "dst_layer_");
568 int l = mkldnn_md2fmt_str(dat_str + dat_written,
569 MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
570 if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
571 }
572 if (1) { // dst iter
573 auto md = s->is_fwd() ? s->dst_md(1) : s->diff_dst_md(1);
574 DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, "dst_iter_");
575 int l = mkldnn_md2fmt_str(dat_str + dat_written,
576 MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
577 if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
578 }
579
580 alg_kind_t alg_kind = s->cell_kind();
581 rnn_direction_t rnn_dir = s->direction();
582 DPRINT(aux_str, MKLDNN_VERBOSE_AUX_LEN, aux_written,
583 "alg:%s_%s", mkldnn_alg_kind2str(alg_kind),
584 mkldnn_rnn_direction2str(rnn_dir));
585
586 DPRINT(prb_str, MKLDNN_VERBOSE_PRB_LEN, prb_written,
587 "l" DFMT "t" DFMT "mb" DFMT
588 "sic" DFMT "slc" DFMT "dic" DFMT "dlc" DFMT,
589 s->L(), s->T(), s->MB(),
590 s->SIC(), s->SLC(), s->DIC(), s->DLC());
591
592 verbose_templ(buffer, s->kind(), s->name(), s->desc()->prop_kind, dat_str,
593 aux_str, prb_str);
594}
595
596#undef DPRINT
597
598#else // !defined(DISABLE_VERBOSE)
599
600#define DEFINE_STUB(name) \
601 template <typename pd_t> \
602 static void CONCAT2(init_info_, name)(pd_t *s, char *buffer) \
603 { UNUSED(s); UNUSED(buffer); }
604
605DEFINE_STUB(bnorm);
606DEFINE_STUB(conv);
607DEFINE_STUB(eltwise);
608DEFINE_STUB(iprod);
609DEFINE_STUB(lrn);
610DEFINE_STUB(mem);
611DEFINE_STUB(pool);
612DEFINE_STUB(softmax);
613DEFINE_STUB(rnn);
614DEFINE_STUB(shuffle);
615#undef DEFINE_STUB
616
617#endif // !defined(DISABLE_VERBOSE)
618}
619
620void init_info(batch_normalization_pd_t *s, char *b)
621{ init_info_bnorm(s, b); }
622void init_info(concat_pd_t *s, char *b)
623{ init_info_mem(s, b); }
624void init_info(convolution_pd_t *s, char *b)
625{ init_info_conv(s, b); }
626void init_info(deconvolution_pd_t *s, char *b)
627{ init_info_conv(s, b); }
628void init_info(eltwise_pd_t *s, char *b)
629{ init_info_eltwise(s, b); }
630void init_info(inner_product_pd_t *s, char *b)
631{ init_info_iprod(s, b); }
632void init_info(lrn_pd_t *s, char *b)
633{ init_info_lrn(s, b); }
634void init_info(pooling_pd_t *s, char *b)
635{ init_info_pool(s, b); }
636void init_info(reorder_pd_t *s, char *b)
637{ init_info_mem(s, b); }
638void init_info(rnn_pd_t *s, char *b)
639{ init_info_rnn(s, b); }
640void init_info(shuffle_pd_t *s, char *b)
641{ init_info_shuffle(s, b); }
642void init_info(softmax_pd_t *s, char *b)
643{ init_info_softmax(s, b); }
644void init_info(sum_pd_t *s, char *b)
645{ init_info_mem(s, b); }
646
647}
648}
649
650mkldnn_status_t mkldnn_set_verbose(int level) {
651 using namespace mkldnn::impl::status;
652 if (level < 0 || level > 2) return invalid_arguments;
653 mkldnn::impl::verbose.level = level;
654 mkldnn::impl::initialized = true;
655 return success;
656}
657
658const mkldnn_version_t *mkldnn_version() {
659 static mkldnn_version_t ver = {
660 MKLDNN_VERSION_MAJOR,
661 MKLDNN_VERSION_MINOR,
662 MKLDNN_VERSION_PATCH,
663 MKLDNN_VERSION_HASH};
664 return &ver;
665}
666