Browse Source

!14537 [MS][LITE]rewrite fp32 to fp16

From: @cjh9368
Reviewed-by: @zhang_xue_tong,@zhanghaibo5
Signed-off-by: @zhang_xue_tong
tags/v1.2.0
mindspore-ci-bot Gitee 5 years ago
parent
commit
110996a423
3 changed files with 14 additions and 52 deletions
  1. +11
    -51
      mindspore/lite/nnacl/nnacl_common.c
  2. +1
    -1
      mindspore/lite/tools/converter/converter_flags.cc
  3. +2
    -0
      mindspore/lite/tools/optimizer/fusion/conv_transform_fusion.cc

+ 11
- 51
mindspore/lite/nnacl/nnacl_common.c View File

@@ -42,56 +42,16 @@ float ShortToFloat32(uint16_t src_value) {
}

uint16_t Float32ToShort(float src_value) {
float *psrcValue = NULL;
psrcValue = &src_value;
unsigned int srcValueBit = (unsigned int)(*psrcValue);
unsigned int sign = srcValueBit >> (FP32_BIT_SIZE - 1);
unsigned int mantissa = srcValueBit & 0x007FFFFF;
float32_bits src_value_bits;
src_value_bits.f = src_value;
uint16_t res = 0;
// mantissa
res += (src_value_bits.u >> 13);
// exponent
int exp = ((srcValueBit & 0x7F800000) >> FP32_SIGNIFICAND) + FP16_EXPONENT_BIAS - FP32_EXPONENT_BIAS;
uint16_t short_res;
if (exp > 0 && exp < FP16_EXPONENT_MAX) {
// use rte rounding mode, round the significand, combine sign, exponent and significand into a short.
short_res = (sign << (FP16_BIT_SIZE - 1)) | (exp << FP16_SIGNIFICAND) |
((mantissa + 0x00001000) >> (FP32_SIGNIFICAND - FP16_SIGNIFICAND));
} else if (srcValueBit == 0) {
short_res = 0;
} else {
if (exp <= 0) {
short_res = 0;
if (exp >= FP16_EXPONENT_MIN) {
mantissa = (mantissa | 0x00800000) >> (1 - exp);
if ((mantissa & 0x00001000) > 0) {
mantissa = mantissa + 0x00002000;
}
short_res = (sign << FP16_EXPONENT_BIAS) | (mantissa >> (FP32_SIGNIFICAND - FP16_SIGNIFICAND));
}
} else if (exp == (FP32_EXPONENT_MAX - FP32_EXPONENT_BIAS + FP16_EXPONENT_BIAS)) {
if (mantissa == 0) {
// input float is infinity, return infinity half
short_res = (sign << FP16_EXPONENT_BIAS) | 0x7C00;
} else {
// input float is NaN, return half NaN
short_res = (sign << FP16_EXPONENT_BIAS) | 0x7C00 | (mantissa >> (FP32_SIGNIFICAND - FP16_SIGNIFICAND));
}
} else {
// exp > 0, normalized single, round to nearest
if ((mantissa & 0x00001000) > 0) {
mantissa = mantissa + 0x00002000;
if ((mantissa & 0x00800000) > 0) {
mantissa = 0;
exp = exp + 1;
}
}
if (exp > FP16_EXPONENT_MAX) {
// exponent overflow - return infinity half
short_res = (sign << FP16_EXPONENT_BIAS) | 0x7C00;
} else {
// combine sign, exp and mantissa into normalized half
short_res = (sign << FP16_EXPONENT_BIAS) | (exp << FP16_SIGNIFICAND) |
(mantissa >> (FP32_SIGNIFICAND - FP16_SIGNIFICAND));
}
}
}
return short_res;
res += (src_value_bits.u >> 13) & 0x3fc00;
res -= (127 - 15) << 13;

// sign
res |= (src_value_bits.u & 0x400000000) >> 16;
return res;
}

+ 1
- 1
mindspore/lite/tools/converter/converter_flags.cc View File

@@ -104,7 +104,7 @@ int Flags::InitFmk() {
}

bool Flags::IsValidNum(const std::string &str, int *num) {
char *ptr;
char *ptr = nullptr;
*num = strtol(str.c_str(), &ptr, 10);
return ptr == (str.c_str() + str.size());
}


+ 2
- 0
mindspore/lite/tools/optimizer/fusion/conv_transform_fusion.cc View File

@@ -60,6 +60,7 @@ void GenerateNewWeightConv2D(float *dst_weight, const float *conv_weight, const
dst_weight[i] = conv_weight[i] * scale_weight[i % kernel_num];
}
} else {
MS_ASSERT(kernel_num > 0);
auto kernel_size = weight_shape_size / kernel_num;
for (int i = 0; i < kernel_num; i++) {
for (int j = 0; j < kernel_size; j++) {
@@ -87,6 +88,7 @@ void GenerateNewWeightConv2DTranspose(float *dst_weight, const float *scale_weig
}
}
} else {
MS_ASSERT(group > 0);
auto cin_group = weight_tensor->tensor_shape()[0] / group;
int area_size = weight_tensor->tensor_shape()[2] * weight_tensor->tensor_shape()[3];
int cout_size = kernel_num * area_size;


Loading…
Cancel
Save