You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

utils.cc 7.6 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /**
  2. * Copyright 2019 Huawei Technologies Co., Ltd
  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. #include "common/utils.h"
  17. namespace mindspore {
  18. namespace predict {
  19. uint64_t GetTimeUs() {
  20. struct timespec ts = {0, 0};
  21. if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
  22. return 0;
  23. }
  24. // USECS_IN_SEC *NSECS_IN_USEC;
  25. auto retval = static_cast<uint64_t>((ts.tv_sec * USEC) + (ts.tv_nsec / MSEC));
  26. return retval;
  27. }
  28. static const unsigned int FP32_BIT_SIZE = 32;
  29. static const unsigned int FP32_EXPONENT_BIAS = 127;
  30. static const unsigned int FP32_SIGNIFICAND = 23;
  31. static const unsigned int FP32_EXPONENT_MAX = 255;
  32. static const unsigned int FP16_BIT_SIZE = 16;
  33. static const unsigned int FP16_EXPONENT_BIAS = 15;
  34. static const unsigned int FP16_SIGNIFICAND = 10;
  35. static const int FP16_EXPONENT_MAX = 30;
  36. static const int FP16_EXPONENT_MIN = -10;
  37. float ShortToFloat32(int16_t srcValue) {
  38. uint16_t expHalf16 = srcValue & 0x7C00;
  39. int exp1 = static_cast<int>(expHalf16);
  40. uint16_t mantissa16 = srcValue & 0x03FF;
  41. int mantissa1 = static_cast<int>(mantissa16);
  42. int sign = static_cast<int>(srcValue & 0x8000);
  43. sign = sign << FP16_BIT_SIZE;
  44. // nan or inf
  45. if (expHalf16 == 0x7C00) {
  46. // nan
  47. if (mantissa16 > 0) {
  48. int res = (0x7FC00000 | sign);
  49. int *iRes = &res;
  50. MS_ASSERT(iRes != nullptr);
  51. auto fres = static_cast<float>(*iRes);
  52. return fres;
  53. }
  54. // inf
  55. int res = (0x7F800000 | sign);
  56. int *iRes = &res;
  57. MS_ASSERT(iRes != nullptr);
  58. auto fres = static_cast<float>(*iRes);
  59. return fres;
  60. }
  61. if (expHalf16 != 0) {
  62. exp1 += ((FP32_EXPONENT_BIAS - FP16_EXPONENT_BIAS) << FP16_SIGNIFICAND); // exponents converted to float32 bias
  63. int res = (exp1 | mantissa1);
  64. res = res << (FP32_SIGNIFICAND - FP16_SIGNIFICAND);
  65. res = (res | sign);
  66. int *iRes = &res;
  67. auto fres = static_cast<float>(*iRes);
  68. return fres;
  69. }
  70. int xmm1 = exp1 > (1 << FP16_SIGNIFICAND) ? exp1 : (1 << FP16_SIGNIFICAND);
  71. xmm1 = (xmm1 << (FP32_SIGNIFICAND - FP16_SIGNIFICAND));
  72. xmm1 += ((FP32_EXPONENT_BIAS - FP16_EXPONENT_BIAS - FP16_SIGNIFICAND)
  73. << FP32_SIGNIFICAND); // add the bias difference to xmm1
  74. xmm1 = xmm1 | sign; // Combine with the sign mask
  75. auto res = static_cast<float>(mantissa1); // Convert mantissa to float
  76. res *= static_cast<float>(xmm1);
  77. return res;
  78. }
  79. int16_t Float32ToShort(float srcValue) {
  80. auto srcValueBit = static_cast<unsigned int>(srcValue);
  81. int sign = srcValueBit >> (FP32_BIT_SIZE - 1);
  82. int mantissa = srcValueBit & 0x007FFFFF;
  83. // exponent
  84. int exp = ((srcValueBit & 0x7F800000) >> FP32_SIGNIFICAND) + FP16_EXPONENT_BIAS - FP32_EXPONENT_BIAS;
  85. int16_t res;
  86. if (exp > 0 && exp < FP16_EXPONENT_MAX) {
  87. // use rte rounding mode, round the significand, combine sign, exponent and significand into a short.
  88. res = (sign << (FP16_BIT_SIZE - 1)) | (exp << FP16_SIGNIFICAND) |
  89. ((mantissa + 0x00001000) >> (FP32_SIGNIFICAND - FP16_SIGNIFICAND));
  90. } else if (srcValueBit == 0) {
  91. res = 0;
  92. } else {
  93. if (exp <= 0) {
  94. if (exp < FP16_EXPONENT_MIN) {
  95. // value is less than min half float point
  96. res = 0;
  97. } else {
  98. // normalized single, magnitude is less than min normal half float point.
  99. mantissa = (mantissa | 0x00800000) >> (1 - exp);
  100. // round to nearest
  101. if ((mantissa & 0x00001000) > 0) {
  102. mantissa = mantissa + 0x00002000;
  103. }
  104. // combine sign & mantissa (exp is zero to get denormalized number)
  105. res = (sign << FP16_EXPONENT_BIAS) | (mantissa >> (FP32_SIGNIFICAND - FP16_SIGNIFICAND));
  106. }
  107. } else if (exp == (FP32_EXPONENT_MAX - FP32_EXPONENT_BIAS + FP16_EXPONENT_BIAS)) {
  108. if (mantissa == 0) {
  109. // input float is infinity, return infinity half
  110. res = (sign << FP16_EXPONENT_BIAS) | 0x7C00;
  111. } else {
  112. // input float is NaN, return half NaN
  113. res = (sign << FP16_EXPONENT_BIAS) | 0x7C00 | (mantissa >> (FP32_SIGNIFICAND - FP16_SIGNIFICAND));
  114. }
  115. } else {
  116. // exp > 0, normalized single, round to nearest
  117. if ((mantissa & 0x00001000) > 0) {
  118. mantissa = mantissa + 0x00002000;
  119. if ((mantissa & 0x00800000) > 0) {
  120. mantissa = 0;
  121. exp = exp + 1;
  122. }
  123. }
  124. if (exp > FP16_EXPONENT_MAX) {
  125. // exponent overflow - return infinity half
  126. res = (sign << FP16_EXPONENT_BIAS) | 0x7C00;
  127. } else {
  128. // combine sign, exp and mantissa into normalized half
  129. res = (sign << FP16_EXPONENT_BIAS) | (exp << FP16_SIGNIFICAND) |
  130. (mantissa >> (FP32_SIGNIFICAND - FP16_SIGNIFICAND));
  131. }
  132. }
  133. }
  134. return res;
  135. }
  136. std::string Remove(const std::string &from, const std::string &subStr, Mode mode) {
  137. std::string result = from;
  138. if (mode == PREFIX) {
  139. if (from.substr(0, subStr.length()) == subStr) {
  140. result = from.substr(subStr.size());
  141. }
  142. } else if (mode == SUFFIX) {
  143. if (from.rfind(subStr) == from.size() - subStr.size()) {
  144. result = from.substr(0, from.size() - subStr.size());
  145. }
  146. } else {
  147. size_t index;
  148. while ((index = result.find(subStr)) != std::string::npos) {
  149. result = result.erase(index, subStr.size());
  150. }
  151. }
  152. return result;
  153. }
  154. std::vector<std::string> StrSplit(const std::string &str, const std::string &pattern) {
  155. std::string::size_type pos;
  156. std::vector<std::string> result;
  157. std::string tmpStr(str + pattern);
  158. std::string::size_type size = tmpStr.size();
  159. for (std::string::size_type i = 0; i < size; i++) {
  160. pos = tmpStr.find(pattern, i);
  161. if (pos < size) {
  162. std::string s = tmpStr.substr(i, pos - i);
  163. result.push_back(s);
  164. i = pos + pattern.size() - 1;
  165. }
  166. }
  167. return result;
  168. }
  169. std::vector<std::string> Tokenize(const std::string &src, const std::string &delimiters,
  170. const Option<size_t> &maxTokenNum) {
  171. if (maxTokenNum.IsSome() && maxTokenNum.Get() == 0) {
  172. return {};
  173. }
  174. std::vector<std::string> tokens;
  175. size_t offset = 0;
  176. while (true) {
  177. size_t nonDelimiter = src.find_first_not_of(delimiters, offset);
  178. if (nonDelimiter == std::string::npos) {
  179. break;
  180. }
  181. size_t delimiter = src.find_first_of(delimiters, nonDelimiter);
  182. if (delimiter == std::string::npos || (maxTokenNum.IsSome() && tokens.size() == maxTokenNum.Get() - 1)) {
  183. tokens.push_back(src.substr(nonDelimiter));
  184. break;
  185. }
  186. tokens.push_back(src.substr(nonDelimiter, delimiter - nonDelimiter));
  187. offset = delimiter;
  188. }
  189. return tokens;
  190. }
  191. void ShortToFloat32(const int16_t *srcdata, float *dstdata, size_t elementSize) {
  192. MS_ASSERT(srcdata != nullptr);
  193. MS_ASSERT(dstdata != nullptr);
  194. for (size_t i = 0; i < elementSize; i++) {
  195. dstdata[i] = ShortToFloat32(srcdata[i]);
  196. }
  197. }
  198. void Float32ToShort(const float *srcdata, int16_t *dstdata, size_t elementSize) {
  199. MS_ASSERT(srcdata != nullptr);
  200. MS_ASSERT(dstdata != nullptr);
  201. for (size_t i = 0; i < elementSize; i++) {
  202. dstdata[i] = Float32ToShort(srcdata[i]);
  203. }
  204. }
  205. } // namespace predict
  206. } // namespace mindspore