1/*******************************************************************************
2* Copyright 2019 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 <assert.h>
18#include <stdio.h>
19#include <cinttypes>
20
21#include "mkldnn_debug.h"
22#include "mkldnn_types.h"
23
24#include "c_types_map.hpp"
25#include "type_helpers.hpp"
26#include "utils.hpp"
27
28#define DPRINT(...) do { \
29 int l = snprintf(str + written_len, str_len, __VA_ARGS__); \
30 if (l < 0) return l; \
31 if ((size_t)l >= str_len) return -1; \
32 written_len += l; str_len -= l; \
33} while(0)
34
35int mkldnn_md2fmt_str(char *str, size_t str_len,
36 const mkldnn_memory_desc_t *mdesc) {
37 using namespace mkldnn::impl;
38
39 if (str == nullptr || str_len <= 1u)
40 return -1;
41
42 int written_len = 0;
43
44 if (mdesc == nullptr) {
45 DPRINT("%s::%s::",
46 mkldnn_dt2str(data_type::undef),
47 mkldnn_fmt_kind2str(format_kind::undef));
48 return written_len;
49 }
50
51 memory_desc_wrapper md(mdesc);
52
53 DPRINT("%s:", mkldnn_dt2str(md.data_type()));
54
55 bool padded_dims = false, padded_offsets = false;
56 for (int d = 0; d < md.ndims(); ++d) {
57 if (md.dims()[d] != md.padded_dims()[d]) padded_dims = true;
58 if (md.padded_offsets()[d] != 0) padded_offsets = true;
59 }
60 bool offset0 = md.offset0();
61 DPRINT("%s%s%s:",
62 padded_dims ? "p" : "",
63 padded_offsets ? "o" : "",
64 offset0 ? "0" : "");
65
66 DPRINT("%s:", mkldnn_fmt_kind2str(md.format_kind()));
67
68 if (!md.is_blocking_desc()) {
69 /* TODO: extend */
70 DPRINT("%s:", "");
71 } else {
72 const auto &blk = md.blocking_desc();
73
74 dims_t blocks;
75 md.compute_blocks(blocks);
76
77 char dim_chars[MKLDNN_MAX_NDIMS + 1];
78
79 bool plain = true;
80 for (int d = 0; d < md.ndims(); ++d) {
81 dim_chars[d] = (blocks[d] == 1 ? 'a' : 'A') + (char)d;
82 if (blocks[d] != 1) plain = false;
83 }
84
85 dims_t strides;
86 utils::array_copy(strides, blk.strides, md.ndims());
87 utils::simultaneous_sort(strides, dim_chars, md.ndims(),
88 [](dim_t a, dim_t b) { return b - a; });
89
90 dim_chars[md.ndims()] = '\0';
91 DPRINT("%s", dim_chars);
92
93 if (!plain) {
94 for (int iblk = 0; iblk < blk.inner_nblks; ++iblk) {
95 DPRINT("%d%c", (int)blk.inner_blks[iblk],
96 'a' + (char)blk.inner_idxs[iblk]);
97 }
98 }
99
100 DPRINT("%s", ":");
101 }
102
103 DPRINT("f%lx", (long)md.extra().flags);
104
105 return written_len;
106}
107
108int mkldnn_md2dim_str(char *str, size_t str_len,
109 const mkldnn_memory_desc_t *mdesc) {
110 using namespace mkldnn::impl;
111
112 if (str == nullptr || str_len <= 1)
113 return -1;
114
115 int written_len = 0;
116
117 if (mdesc == nullptr || mdesc->ndims == 0) {
118 DPRINT("%s", "");
119 return written_len;
120 }
121
122 memory_desc_wrapper md(mdesc);
123
124 for (int d = 0; d < md.ndims() - 1; ++d)
125 DPRINT("%" PRId64 "x", md.dims()[d]);
126 DPRINT("%" PRId64, md.dims()[md.ndims() - 1]);
127
128 return written_len;
129}
130
131#undef DPRINT
132