1/*******************************************************************************
2* Copyright 2019-2022 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 <stdio.h>
18#include <stdlib.h>
19
20#include <sstream>
21
22#include "dnnl_common.hpp"
23#include "utils/parser.hpp"
24
25#include "eltwise/eltwise.hpp"
26
27namespace eltwise {
28
29void check_correctness(const settings_t &s) {
30 for_(const auto &i_dir : s.dir)
31 for_(const auto &i_dt : s.dt)
32 for_(const auto &i_tag : s.tag)
33 for_(const auto &i_alg : s.alg)
34 for_(const auto &i_alpha : s.alpha)
35 for_(const auto &i_beta : s.beta)
36 for_(const auto &i_mb : s.mb)
37 for_(const auto &i_post_ops : s.post_ops)
38 for_(const auto &i_scratchpad_mode : s.scratchpad_mode)
39 for_(const auto &i_ctx_init : s.ctx_init)
40 for_(const auto &i_ctx_exe : s.ctx_exe)
41 for (auto i_inplace : s.inplace) {
42 bool ok = i_alg > alg_t::ELTWISE_START && i_alg < alg_t::ELTWISE_END;
43 if (!ok) {
44 std::stringstream ss;
45 ss << i_alg;
46 BENCHDNN_PRINT(0, "%s%s%s\n", "ERROR: unknown algorithm `",
47 ss.str().c_str(), "`.");
48 SAFE_V(FAIL);
49 }
50
51 // iterator over alpha and beta (alphabetic order!)
52 switch (i_alg) {
53 case alg_t::ABS:
54 case alg_t::EXP:
55 case alg_t::EXP_DST:
56 case alg_t::GELU_ERF:
57 case alg_t::GELU_TANH:
58 case alg_t::HARDSWISH:
59 case alg_t::LOG:
60 case alg_t::LOGISTIC:
61 case alg_t::LOGISTIC_DST:
62 case alg_t::MISH:
63 case alg_t::ROUND:
64 case alg_t::SQRT:
65 case alg_t::SQRT_DST:
66 case alg_t::SQUARE:
67 case alg_t::TANH:
68 case alg_t::TANH_DST:
69 if (i_alpha != 0)
70 BENCHDNN_PRINT(2, "%s\n",
71 "WARNING: non-zero alpha is ignored. "
72 "Consider adding --alpha=0 to a command line.");
73 if (i_beta != 0)
74 BENCHDNN_PRINT(2, "%s\n",
75 "WARNING: non-zero beta is ignored. "
76 "Consider adding --beta=0 to a command line.");
77 break;
78 case alg_t::ELU:
79 case alg_t::ELU_DST:
80 case alg_t::RELU:
81 case alg_t::RELU_DST:
82 case alg_t::SRELU:
83 case alg_t::SWISH:
84 if (i_beta != 0)
85 BENCHDNN_PRINT(2, "%s\n",
86 "WARNING: non-zero beta is ignored. "
87 "Consider adding --beta=0 to a command line.");
88 break;
89 default:;
90 };
91
92 auto attr = settings_t::get_attr(i_post_ops, i_scratchpad_mode);
93
94 const prb_t prb(s.prb_dims, i_dir, i_dt, i_tag, i_alg, i_alpha, i_beta,
95 i_inplace, attr, i_ctx_init, i_ctx_exe, i_mb);
96 std::stringstream ss;
97 ss << prb;
98 const std::string cpp_pstr = ss.str();
99 const char *pstr = cpp_pstr.c_str();
100 BENCHDNN_PRINT(1, "run: %s\n", pstr);
101
102 res_t res {};
103 doit(&prb, &res);
104
105 parse_result(res, pstr);
106
107 if (is_bench_mode(PERF)) {
108 perf_report_t pr(&prb, s.perf_template);
109 pr.report(&res, pstr);
110 }
111 }
112}
113
114static const std::string help_alpha_beta
115 = "FLOAT (Default: 0.f)\n Specifies algorithm parameter "
116 "extension where applicable.\n";
117
118int bench(int argc, char **argv) {
119 driver_name = "eltwise";
120 using namespace parser;
121 static settings_t s;
122 static const settings_t def {};
123 for (; argc > 0; --argc, ++argv) {
124 const bool parsed_options = parse_bench_settings(argv[0])
125 || parse_batch(bench, argv[0])
126 || parse_dir(s.dir, def.dir, argv[0])
127 || parse_dt(s.dt, def.dt, argv[0])
128 || parse_tag(s.tag, def.tag, argv[0])
129 || parse_vector_option(s.alpha, def.alpha, atof, argv[0],
130 "alpha", help_alpha_beta)
131 || parse_vector_option(s.beta, def.beta, atof, argv[0], "beta",
132 help_alpha_beta)
133 || parse_alg(
134 s.alg, def.alg, attr_t::post_ops_t::str2kind, argv[0])
135 || parse_inplace(s.inplace, def.inplace, argv[0])
136 || parse_mb(s.mb, def.mb, argv[0])
137 || parse_attr_post_ops(s.post_ops, argv[0])
138 || parse_attr_scratchpad_mode(
139 s.scratchpad_mode, def.scratchpad_mode, argv[0])
140 || parse_ctx_init(s.ctx_init, def.ctx_init, argv[0])
141 || parse_ctx_exe(s.ctx_exe, def.ctx_exe, argv[0])
142 || parse_perf_template(s.perf_template, s.perf_template_def,
143 s.perf_template_csv(), argv[0])
144 || parse_reset(s, argv[0]) || parse_help(argv[0]);
145 if (!parsed_options) {
146 catch_unknown_options(argv[0]);
147
148 parse_prb_dims(s.prb_dims, argv[0]);
149 check_correctness(s);
150 }
151 }
152
153 return parse_last_argument();
154}
155} // namespace eltwise
156