1 /* Copyright 2015 The TensorFlow Authors. All Rights Reserved.
2
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6
7 http://www.apache.org/licenses/LICENSE-2.0
8
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15
16 #ifndef TENSORFLOW_CORE_KERNELS_MKL_MKL_QUANTIZED_CONV_OPS_H_
17 #define TENSORFLOW_CORE_KERNELS_MKL_MKL_QUANTIZED_CONV_OPS_H_
18
19 #include "third_party/eigen3/unsupported/Eigen/CXX11/Tensor"
20 #include "tensorflow/core/framework/tensor.h"
21
22 #ifdef INTEL_MKL
23
24 namespace tensorflow {
25 template <class T>
MklFloatForOneQuantizedLevel(float range_min,float range_max)26 float MklFloatForOneQuantizedLevel(float range_min, float range_max) {
27 int64 highest = static_cast<int64>(Eigen::NumTraits<T>::highest());
28 int64 lowest = static_cast<int64>(Eigen::NumTraits<T>::lowest());
29
30 // Adjusting for having a symmetric range.
31 // for example: for 8-bit [-127, 127] as opposed to [-128, 127].
32 if (lowest < -highest) ++lowest;
33
34 const float float_for_one_quantized_level =
35 (range_max - range_min) / (highest - lowest);
36 return float_for_one_quantized_level;
37 }
38
39 template <class T1, class T2, class T3>
MklQuantizationRangeForMultiplication(float min_a,float max_a,float min_b,float max_b,float * min_c,float * max_c)40 void MklQuantizationRangeForMultiplication(float min_a, float max_a,
41 float min_b, float max_b,
42 float* min_c, float* max_c) {
43 const float a_float_for_one_quant_level =
44 MklFloatForOneQuantizedLevel<T1>(min_a, max_a);
45 const float b_float_for_one_quant_level =
46 MklFloatForOneQuantizedLevel<T2>(min_b, max_b);
47
48 const int64 c_highest = static_cast<int64>(Eigen::NumTraits<T3>::highest());
49 const int64 c_lowest = static_cast<int64>(Eigen::NumTraits<T3>::lowest());
50 const float c_float_for_one_quant_level =
51 a_float_for_one_quant_level * b_float_for_one_quant_level;
52
53 *min_c = c_float_for_one_quant_level * c_lowest;
54 *max_c = c_float_for_one_quant_level * c_highest;
55 }
56
57 template <class T1, class T2, class T3>
MklQuantizationRangeForMultiplication(float min_a,float max_a,const Tensor & min_b_vector,const Tensor & max_b_vector,Tensor ** min_c_vector,Tensor ** max_c_vector)58 void MklQuantizationRangeForMultiplication(float min_a, float max_a,
59 const Tensor& min_b_vector,
60 const Tensor& max_b_vector,
61 Tensor** min_c_vector,
62 Tensor** max_c_vector) {
63 DCHECK(min_b_vector.NumElements() == (*min_c_vector)->NumElements());
64 DCHECK(max_b_vector.NumElements() == (*max_c_vector)->NumElements());
65 size_t n_channel = min_b_vector.NumElements();
66 const int64 c_highest = static_cast<int64>(Eigen::NumTraits<T3>::highest());
67 const int64 c_lowest = static_cast<int64>(Eigen::NumTraits<T3>::lowest());
68 const float* min_b = min_b_vector.flat<float>().data();
69 const float* max_b = max_b_vector.flat<float>().data();
70 float* min_c = (*min_c_vector)->flat<float>().data();
71 float* max_c = (*max_c_vector)->flat<float>().data();
72
73 #ifndef ENABLE_MKLDNN_THREADPOOL
74 #pragma omp parallel for
75 #endif // !ENABLE_MKLDNN_THREADPOOL
76 // TODO: Add eigen parallel_for
77 for (int64_t n = 0; n < n_channel; ++n) {
78 float a_float_for_one_quant_level =
79 MklFloatForOneQuantizedLevel<T1>(min_a, max_a);
80 float b_float_for_one_quant_level =
81 MklFloatForOneQuantizedLevel<T2>(min_b[n], max_b[n]);
82 float c_float_for_one_quant_level =
83 a_float_for_one_quant_level * b_float_for_one_quant_level;
84 min_c[n] = c_float_for_one_quant_level * c_lowest;
85 max_c[n] = c_float_for_one_quant_level * c_highest;
86 }
87 }
88
89 } // namespace tensorflow
90
91 #endif // INTEL_MKL
92
93 #endif // TENSORFLOW_CORE_KERNELS_MKL_MKL_QUANTIZED_CONV_OPS_H_
94