1 /*******************************************************************************
2 * Copyright 2019 Intel Corporation
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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 *******************************************************************************/
17 #ifndef BFLOAT16_UTILS_HPP
18 #define BFLOAT16_UTILS_HPP
21 #include "jit_avx512_core_bf16cvt.hpp"
26 namespace bf16_cvt_utils {
30 mkldnn_bfloat16_t vbfloat[2];
33 extern jit_avx512_core_cvt_ps_to_bf16_t cvt_one_ps_to_bf16;
34 extern jit_avx512_core_cvt_ps_to_bf16_t cvt_ps_to_bf16_;
35 extern jit_avx512_core_cvt_bf16_to_ps_t cvt_bf16_to_ps_;
36 extern jit_avx512_core_add_cvt_ps_to_bf16_t add_cvt_ps_to_bf16_;
38 inline mkldnn_bfloat16_t cvt_float_to_bfloat16(float inp) {
39 assert(mayiuse(avx512_core));
40 mkldnn_bfloat16_t out;
44 cvt_one_ps_to_bf16.jit_ker(&p);
48 inline void cvt_float_to_bfloat16(mkldnn_bfloat16_t *out, const float *inp) {
49 assert(mayiuse(avx512_core));
53 cvt_one_ps_to_bf16.jit_ker(&p);
56 inline void cvt_float_to_bfloat16(mkldnn_bfloat16_t *out, const float *inp,
58 assert(mayiuse(avx512_core));
63 cvt_ps_to_bf16_.jit_ker(&p_);
66 inline float cvt_bfloat16_to_float(mkldnn_bfloat16_t inp) {
67 assert(mayiuse(avx512_core));
73 inline void cvt_bfloat16_to_float(float *out, const mkldnn_bfloat16_t *inp) {
74 assert(mayiuse(avx512_core));
76 cvt.vbfloat[1] = *inp;
80 inline void cvt_bfloat16_to_float(float *out, const mkldnn_bfloat16_t *inp,
82 assert(mayiuse(avx512_core));
87 cvt_bf16_to_ps_.jit_ker(&p_);
90 // performs element-by-element sum of inp and add float arrays and stores
91 // result to bfloat16 out array with downconversion
92 inline void add_floats_and_cvt_to_bfloat16(mkldnn_bfloat16_t *out,
96 assert(mayiuse(avx512_core));
98 p_.inp = (void *)inp0;
99 p_.add = (void *)inp1;
100 p_.out = (void *)out;
102 add_cvt_ps_to_bf16_.jit_ker(&p_);
105 inline mkldnn_bfloat16_t approx_bfloat16_lowest() {
106 /* jit fails to convert FLT_MIN to bfloat16.
107 * It converst FLT_MIN to -INF. Truncate FLT_MIN
108 * to bfloat16 to get a value close to minimum bfloat16*/
109 f32_bf16_t f_raw = {0};
110 f_raw.vfloat = nstl::numeric_limits<float>::lowest();
111 f_raw.vbfloat[0] = 0;
112 return f_raw.vbfloat[1];
115 inline bool is_float_representable_in_bfloat16(float x) {
116 f32_bf16_t cvt = {0};
118 return cvt.vbfloat[0] == 0;