/******************************************************************************* * Copyright 2018 Intel Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *******************************************************************************/ #ifndef VERBOSE_HPP #define VERBOSE_HPP #include "mkldnn_debug.h" #include "c_types_map.hpp" #include "utils.hpp" #include "z_magic.hpp" namespace mkldnn { namespace impl { struct verbose_t { int level; }; const verbose_t *mkldnn_verbose(); double get_msec(); const char *get_isa_info(); #if !defined(DISABLE_VERBOSE) #include #define MKLDNN_VERBOSE_BUF_LEN 1024 #define MKLDNN_VERBOSE_DAT_LEN 128 #define MKLDNN_VERBOSE_AUX_LEN 384 #define MKLDNN_VERBOSE_PRB_LEN 384 #define DECL_DAT_AUX_PRB_STRS() \ char dat_str[MKLDNN_VERBOSE_DAT_LEN] = {'\0'}; MAYBE_UNUSED(dat_str); \ char aux_str[MKLDNN_VERBOSE_AUX_LEN] = {'\0'}; MAYBE_UNUSED(aux_str); \ char prb_str[MKLDNN_VERBOSE_PRB_LEN] = {'\0'}; MAYBE_UNUSED(prb_str) inline void verbose_templ(char *buffer, mkldnn_primitive_kind_t prim_kind, const char *impl_str, mkldnn_prop_kind_t prop_kind, const char *data_str, const char *aux_str, const char *prb_str) { MAYBE_UNUSED(verbose_templ); snprintf(buffer, MKLDNN_VERBOSE_BUF_LEN, "%s,%s,%s,%s,%s,%s", mkldnn_prim_kind2str(prim_kind), impl_str, mkldnn_prop_kind2str(prop_kind), data_str, aux_str, prb_str); } inline void format_mem_desc_str_generic(char *str, int len, const memory_desc_t *md) { auto ndims = md->ndims; auto dims = md->dims; int l = 0; for (int d = 0; d < ndims - 1; ++d) l += snprintf(str + l, len - l, "%dx", dims[d]); snprintf(str + l, len - l, "%d", dims[ndims - 1]); } // XXX: Outputs strings corresponding to memory formats used for data tensors. inline void format_mem_desc_str(char *str, int len, const memory_desc_t *md) { auto ndims = md->ndims; auto dims = md->dims; if (ndims == 1) snprintf(str, len, "x%d", dims[0]); else if (ndims == 2) snprintf(str, len, "mb%dic%d", dims[0], dims[1]); else if (ndims == 3) snprintf(str, len, "mb%dic%diw%d", dims[0], dims[1], dims[2]); else if (ndims == 4) snprintf(str, len, "mb%dic%dih%diw%d", dims[0], dims[1], dims[2], dims[3]); else if (ndims == 5) snprintf(str, len, "mb%dic%did%dih%diw%d", dims[0], dims[1], dims[2], dims[3], dims[4]); else format_mem_desc_str_generic(str, len, md); } template static void init_info_bnorm(pd_t *s, char *buffer) { DECL_DAT_AUX_PRB_STRS(); auto fmt_data = s->src_pd()->desc()->format; auto fmt_diff = s->is_bwd() ? s->diff_src_pd()->desc()->format : memory_format::undef; snprintf(dat_str, MKLDNN_VERBOSE_DAT_LEN, "fdata:%s fdiff:%s", mkldnn_fmt2str(fmt_data), mkldnn_fmt2str(fmt_diff)); snprintf(aux_str, MKLDNN_VERBOSE_AUX_LEN, "flags:%u", s->desc()->flags); format_mem_desc_str(prb_str, MKLDNN_VERBOSE_PRB_LEN, s->src_pd()->desc()); verbose_templ(buffer, s->kind(), s->name(), s->desc()->prop_kind, dat_str, aux_str, prb_str); } template static void init_info_conv(pd_t *s, char *buffer) { DECL_DAT_AUX_PRB_STRS(); auto fmt_src = (s->desc()->prop_kind == prop_kind::backward_data ? s->diff_src_pd() : s->src_pd())->desc()->format; auto fmt_wei = (s->desc()->prop_kind == prop_kind::backward_weights ? s->diff_weights_pd(0) : s->weights_pd(0))->desc()->format; auto fmt_bia = s->with_bias() ? (s->desc()->prop_kind == prop_kind::backward_weights ? s->diff_weights_pd(1) : s->weights_pd(1))->desc()->format : memory_format::undef; auto fmt_dst = (s->desc()->prop_kind == prop_kind::backward_data || s->desc()->prop_kind == prop_kind::backward_weights ? s->diff_dst_pd() : s->dst_pd())->desc()->format; snprintf(dat_str, MKLDNN_VERBOSE_DAT_LEN, "fsrc:%s fwei:%s fbia:%s fdst:%s", mkldnn_fmt2str(fmt_src), mkldnn_fmt2str(fmt_wei), mkldnn_fmt2str(fmt_bia), mkldnn_fmt2str(fmt_dst)); snprintf(aux_str, MKLDNN_VERBOSE_AUX_LEN, "alg:%s", mkldnn_alg_kind2str(s->desc()->alg_kind)); if (s->ndims() == 5) { if (s->with_groups()) snprintf(prb_str, MKLDNN_VERBOSE_PRB_LEN, "mb%d_g%dic%doc%d" "_id%dod%dkd%dsd%ddd%dpd%d" "_ih%doh%dkh%dsh%ddh%dph%d" "_iw%dow%dkw%dsw%ddw%dpw%d", s->MB(), s->G(), s->IC(), s->OC(), s->ID(), s->OD(), s->KD(), s->KSD(), s->KDD(), s->padFront(), s->IH(), s->OH(), s->KH(), s->KSH(), s->KDH(), s->padT(), s->IW(), s->OW(), s->KW(), s->KSW(), s->KDW(), s->padL()); else snprintf(prb_str, MKLDNN_VERBOSE_PRB_LEN, "mb%d_ic%doc%d" "_id%dod%dkd%dsd%ddd%dpd%d" "_ih%doh%dkh%dsh%ddh%dph%d" "_iw%dow%dkw%dsw%ddw%dpw%d", s->MB(), s->IC(), s->OC(), s->ID(), s->OD(), s->KD(), s->KSD(), s->KDD(), s->padFront(), s->IH(), s->OH(), s->KH(), s->KSH(), s->KDH(), s->padT(), s->IW(), s->OW(), s->KW(), s->KSW(), s->KDW(), s->padL()); } else { if (s->with_groups()) snprintf(prb_str, MKLDNN_VERBOSE_PRB_LEN, "mb%d_g%dic%doc%d" "_ih%doh%dkh%dsh%ddh%dph%d" "_iw%dow%dkw%dsw%ddw%dpw%d", s->MB(), s->G(), s->IC(), s->OC(), s->IH(), s->OH(), s->KH(), s->KSH(), s->KDH(), s->padT(), s->IW(), s->OW(), s->KW(), s->KSW(), s->KDW(), s->padL()); else snprintf(prb_str, MKLDNN_VERBOSE_PRB_LEN, "mb%d_ic%doc%d" "_ih%doh%dkh%dsh%ddh%dph%d" "_iw%dow%dkw%dsw%ddw%dpw%d", s->MB(), s->IC(), s->OC(), s->IH(), s->OH(), s->KH(), s->KSH(), s->KDH(), s->padT(), s->IW(), s->OW(), s->KW(), s->KSW(), s->KDW(), s->padL()); } verbose_templ(buffer, s->kind(), s->name(), s->desc()->prop_kind, dat_str, aux_str, prb_str); } template static void init_info_shuffle(pd_t *s, char *buffer) { DECL_DAT_AUX_PRB_STRS(); const auto md = (s->desc()->prop_kind == prop_kind::backward_data ? s->diff_dst_pd() : s->src_pd())->desc(); snprintf(dat_str, MKLDNN_VERBOSE_DAT_LEN, "dt:%s fmt:%s", mkldnn_dt2str(md->data_type), mkldnn_fmt2str(md->format)); snprintf(aux_str, MKLDNN_VERBOSE_AUX_LEN, "axis:%d group_size:%d", s->axis(), s->group_size()); format_mem_desc_str_generic(prb_str, MKLDNN_VERBOSE_PRB_LEN, md); verbose_templ(buffer, s->kind(), s->name(), s->desc()->prop_kind, dat_str, aux_str, prb_str); } template static void init_info_eltwise(pd_t *s, char *buffer) { DECL_DAT_AUX_PRB_STRS(); auto fmt_data = s->src_pd()->desc()->format; auto fmt_diff = s->desc()->prop_kind == prop_kind::backward_data ? s->diff_src_pd()->desc()->format : memory_format::undef; snprintf(dat_str, MKLDNN_VERBOSE_DAT_LEN, "fdata:%s fdiff:%s", mkldnn_fmt2str(fmt_data), mkldnn_fmt2str(fmt_diff)); snprintf(aux_str, MKLDNN_VERBOSE_AUX_LEN, "alg:%s", mkldnn_alg_kind2str(s->desc()->alg_kind)); format_mem_desc_str(prb_str, MKLDNN_VERBOSE_PRB_LEN, s->src_pd()->desc()); verbose_templ(buffer, s->kind(), s->name(), s->desc()->prop_kind, dat_str, aux_str, prb_str); } template static void init_info_iprod(pd_t *s, char *buffer) { DECL_DAT_AUX_PRB_STRS(); auto fmt_src = (s->desc()->prop_kind == prop_kind::backward_data ? s->diff_src_pd() : s->src_pd())->desc()->format; auto fmt_wei = (s->desc()->prop_kind == prop_kind::backward_weights ? s->diff_weights_pd(0) : s->weights_pd(0))->desc()->format; auto fmt_bia = s->with_bias() ? (s->desc()->prop_kind == prop_kind::backward_weights ? s->diff_weights_pd(1) : s->weights_pd(1))->desc()->format : memory_format::undef; auto fmt_dst = (s->desc()->prop_kind == prop_kind::backward_data || s->desc()->prop_kind == prop_kind::backward_weights ? s->diff_dst_pd() : s->dst_pd())->desc()->format; snprintf(dat_str, MKLDNN_VERBOSE_DAT_LEN, "fsrc:%s fwei:%s fbia:%s fdst:%s", mkldnn_fmt2str(fmt_src), mkldnn_fmt2str(fmt_wei), mkldnn_fmt2str(fmt_bia), mkldnn_fmt2str(fmt_dst)); snprintf(prb_str, MKLDNN_VERBOSE_PRB_LEN, "mb%dic%doc%d", s->MB(), s->IC_total(), s->OC()); verbose_templ(buffer, s->kind(), s->name(), s->desc()->prop_kind, dat_str, aux_str, prb_str); } template static void init_info_lrn(pd_t *s, char *buffer) { DECL_DAT_AUX_PRB_STRS(); auto fmt_data = s->src_pd()->desc()->format; auto fmt_diff = s->desc()->prop_kind == prop_kind::backward_data ? s->diff_src_pd()->desc()->format : memory_format::undef; snprintf(dat_str, MKLDNN_VERBOSE_DAT_LEN, "fdata:%s fdiff:%s", mkldnn_fmt2str(fmt_data), mkldnn_fmt2str(fmt_diff)); snprintf(aux_str, MKLDNN_VERBOSE_AUX_LEN, "alg:%s", mkldnn_alg_kind2str(s->desc()->alg_kind)); format_mem_desc_str(prb_str, MKLDNN_VERBOSE_PRB_LEN, s->src_pd()->desc()); verbose_templ(buffer, s->kind(), s->name(), s->desc()->prop_kind, dat_str, aux_str, prb_str); } template static void init_info_mem(pd_t *s, char *buffer) { DECL_DAT_AUX_PRB_STRS(); const auto i_md = s->input_pd(0)->desc(); const auto o_md = s->output_pd(0)->desc(); snprintf(dat_str, MKLDNN_VERBOSE_DAT_LEN, "in:%s_%s out:%s_%s", mkldnn_dt2str(i_md->data_type), mkldnn_fmt2str(i_md->format), mkldnn_dt2str(o_md->data_type), mkldnn_fmt2str(o_md->format)); snprintf(aux_str, MKLDNN_VERBOSE_AUX_LEN, "num:%d", s->n_inputs()); format_mem_desc_str_generic(prb_str, MKLDNN_VERBOSE_PRB_LEN, o_md); verbose_templ(buffer, s->kind(), s->name(), prop_kind::undef, dat_str, aux_str, prb_str); } template static void init_info_pool(pd_t *s, char *buffer) { DECL_DAT_AUX_PRB_STRS(); auto fmt_data = (s->desc()->prop_kind == prop_kind::backward_data ? s->diff_src_pd() : s->src_pd())->desc()->format; auto fmt_ws = s->workspace_pd() ? s->workspace_pd()->desc()->format : memory_format::undef; snprintf(dat_str, MKLDNN_VERBOSE_DAT_LEN, "fdata:%s fws:%s", mkldnn_fmt2str(fmt_data), mkldnn_fmt2str(fmt_ws)); snprintf(aux_str, MKLDNN_VERBOSE_AUX_LEN, "alg:%s", mkldnn_alg_kind2str(s->desc()->alg_kind)); if (s->is_3d()) { snprintf(prb_str, MKLDNN_VERBOSE_PRB_LEN, "mb%dic%d_id%dod%dkd%dsd%dpd%d_ih%doh%dkh%dsh%dph%d_iw%dow%dkw%dsw%dpw%d", s->MB(), s->C(), s->ID(), s->OD(), s->KD(), s->KSD(), s->padFront(), s->IH(), s->OH(), s->KH(), s->KSH(), s->padT(), s->IW(), s->OW(), s->KW(), s->KSW(), s->padL()); } else { snprintf(prb_str, MKLDNN_VERBOSE_PRB_LEN, "mb%dic%d_ih%doh%dkh%dsh%dph%d_iw%dow%dkw%dsw%dpw%d", s->MB(), s->C(), s->IH(), s->OH(), s->KH(), s->KSH(), s->padT(), s->IW(), s->OW(), s->KW(), s->KSW(), s->padL()); } verbose_templ(buffer, s->kind(), s->name(), s->desc()->prop_kind, dat_str, aux_str, prb_str); } template static void init_info_softmax(pd_t *s, char *buffer) { DECL_DAT_AUX_PRB_STRS(); auto md = (s->desc()->prop_kind == prop_kind::backward_data ? s->diff_src_pd() : s->src_pd())->desc(); auto fmt_data = md->format; auto fmt_diff = s->desc()->prop_kind == prop_kind::backward_data ? s->diff_src_pd()->desc()->format : memory_format::undef; snprintf(dat_str, MKLDNN_VERBOSE_DAT_LEN, "fdata:%s fdiff:%s", mkldnn_fmt2str(fmt_data), mkldnn_fmt2str(fmt_diff)); format_mem_desc_str(prb_str, MKLDNN_VERBOSE_PRB_LEN, md); verbose_templ(buffer, s->kind(), s->name(), s->desc()->prop_kind, dat_str, aux_str, prb_str); } /// @todo print meaningful data template static void init_info_rnn(pd_t *s, char *buffer) { DECL_DAT_AUX_PRB_STRS(); const mkldnn::impl::memory_desc_t *src_lay_md, *src_iter_md, *wei_lay_md, *wei_iter_md, *bias_md, *dst_lay_md, *dst_iter_md; if (s->desc()->prop_kind != prop_kind::backward_data) { src_lay_md = s->src_pd(0)->desc(); src_iter_md = s->src_pd(1) ? s->src_pd(1)->desc() : nullptr; wei_lay_md = s->weights_pd(0)->desc(); wei_iter_md = s->weights_pd(1)->desc(); bias_md = s->weights_pd(2)->desc(); dst_lay_md = s->dst_pd(0)->desc(); dst_iter_md = s->dst_pd(1) ? s->dst_pd(1)->desc() : nullptr; } else { src_lay_md = s->diff_src_pd(0)->desc(); src_iter_md = s->diff_src_pd(1) ? s->diff_src_pd(1)->desc() : nullptr; wei_lay_md = s->diff_weights_pd(0)->desc(); wei_iter_md = s->diff_weights_pd(1)->desc(); bias_md = s->diff_weights_pd(2)->desc(); dst_lay_md = s->diff_dst_pd(0)->desc(); dst_iter_md = s->diff_dst_pd(1) ? s->diff_dst_pd(1)->desc() : nullptr; } alg_kind_t alg_kind = s->cell_kind(); rnn_direction_t rnn_dir = s->direction(); snprintf(aux_str, MKLDNN_VERBOSE_AUX_LEN, "alg:%s_%s", mkldnn_alg_kind2str(alg_kind), mkldnn_rnn_direction2str(rnn_dir)); snprintf(dat_str, MKLDNN_VERBOSE_DAT_LEN, "fdata:%s-%s-%s-%s fwei:%s-%s-%s ddata:%s%s-%s%s dwei:%s%s%s", mkldnn_fmt2str(src_lay_md->format), mkldnn_fmt2str(src_iter_md ? src_iter_md->format : memory_format::undef), mkldnn_fmt2str(dst_lay_md->format), mkldnn_fmt2str(dst_iter_md ? dst_iter_md->format : memory_format::undef), mkldnn_fmt2str(wei_lay_md->format), mkldnn_fmt2str(wei_iter_md->format), mkldnn_fmt2str(bias_md->format), mkldnn_dt2str(src_lay_md->data_type), mkldnn_dt2str(src_iter_md ? src_iter_md->data_type : data_type::undef), mkldnn_dt2str(dst_lay_md->data_type), mkldnn_dt2str(dst_iter_md ? dst_iter_md->data_type : data_type::undef), mkldnn_dt2str(wei_lay_md->data_type), mkldnn_dt2str(wei_iter_md->data_type), mkldnn_dt2str(bias_md->data_type)); snprintf(prb_str, MKLDNN_VERBOSE_PRB_LEN, "l%dt%dmb%dsic%dslc%ddic%ddlc%d", s->L(), s->T(), s->MB(), s->SIC(), s->SLC(), s->DIC(), s->DLC()); verbose_templ(buffer, s->kind(), s->name(), s->desc()->prop_kind, dat_str, aux_str, prb_str); } #else /* !defined(DISABLE_VERBOSE) */ #define MKLDNN_VERBOSE_BUF_LEN 1 #define DEFINE_STUB(name) \ template \ static void CONCAT2(init_info_, name)(pd_t *s, char *buffer) \ { UNUSED(s); UNUSED(buffer); } DEFINE_STUB(bnorm); DEFINE_STUB(conv); DEFINE_STUB(eltwise); DEFINE_STUB(iprod); DEFINE_STUB(lrn); DEFINE_STUB(mem); DEFINE_STUB(pool); DEFINE_STUB(softmax); DEFINE_STUB(rnn); DEFINE_STUB(shuffle); #undef DEFINE_STUB #endif /* !defined(DISABLE_VERBOSE) */ } } #endif