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.

math_util.h 36 kB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879
  1. /**
  2. * Copyright 2019-2020 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. #ifndef GE_COMMON_MATH_MATH_UTIL_H_
  17. #define GE_COMMON_MATH_MATH_UTIL_H_
  18. #include <climits>
  19. #include <cmath>
  20. #include <cstdint>
  21. #include <cstdlib>
  22. #include "common/fp16_t.h"
  23. #include "framework/common/debug/log.h"
  24. #include "framework/common/fmk_error_codes.h"
  25. namespace ge {
  26. /// @ingroup math_util
  27. /// @brief check whether int32 addition can result in overflow
  28. /// @param [in] a addend
  29. /// @param [in] b addend
  30. /// @return Status
  31. inline Status CheckIntAddOverflow(int a, int b) {
  32. if (((b > 0) && (a > (INT_MAX - b))) || ((b < 0) && (a < (INT_MIN - b)))) {
  33. return FAILED;
  34. }
  35. return SUCCESS;
  36. }
  37. /// @ingroup math_util
  38. /// @brief check whether int8 addition can result in overflow
  39. /// @param [in] a addend
  40. /// @param [in] b addend
  41. /// @return Status
  42. inline Status CheckInt8AddOverflow(int8_t a, int8_t b) {
  43. if (((b > 0) && (a > (INT8_MAX - b))) || ((b < 0) && (a < (INT8_MIN - b)))) {
  44. return FAILED;
  45. }
  46. return SUCCESS;
  47. }
  48. /// @ingroup math_util
  49. /// @brief check whether int16 addition can result in overflow
  50. /// @param [in] a addend
  51. /// @param [in] b addend
  52. /// @return Status
  53. inline Status CheckInt16AddOverflow(int16_t a, int16_t b) {
  54. if (((b > 0) && (a > (INT16_MAX - b))) || ((b < 0) && (a < (INT16_MIN - b)))) {
  55. return FAILED;
  56. }
  57. return SUCCESS;
  58. }
  59. /// @ingroup math_util
  60. /// @brief check whether int32 addition can result in overflow
  61. /// @param [in] a addend
  62. /// @param [in] b addend
  63. /// @return Status
  64. inline Status CheckInt32AddOverflow(int32_t a, int32_t b) {
  65. if (((b > 0) && (a > (INT32_MAX - b))) || ((b < 0) && (a < (INT32_MIN - b)))) {
  66. return FAILED;
  67. }
  68. return SUCCESS;
  69. }
  70. /// @ingroup math_util
  71. /// @brief check whether int64 addition can result in overflow
  72. /// @param [in] a addend
  73. /// @param [in] b addend
  74. /// @return Status
  75. inline Status CheckInt64AddOverflow(int64_t a, int64_t b) {
  76. if (((b > 0) && (a > (INT64_MAX - b))) || ((b < 0) && (a < (INT64_MIN - b)))) {
  77. return FAILED;
  78. }
  79. return SUCCESS;
  80. }
  81. /// @ingroup math_util
  82. /// @brief check whether uint8 addition can result in overflow
  83. /// @param [in] a addend
  84. /// @param [in] b addend
  85. /// @return Status
  86. inline Status CheckUint8AddOverflow(uint8_t a, uint8_t b) {
  87. if (a > (UINT8_MAX - b)) {
  88. return FAILED;
  89. }
  90. return SUCCESS;
  91. }
  92. /// @ingroup math_util
  93. /// @brief check whether uint16 addition can result in overflow
  94. /// @param [in] a addend
  95. /// @param [in] b addend
  96. /// @return Status
  97. inline Status CheckUint16AddOverflow(uint16_t a, uint16_t b) {
  98. if (a > (UINT16_MAX - b)) {
  99. return FAILED;
  100. }
  101. return SUCCESS;
  102. }
  103. /// @ingroup math_util
  104. /// @brief check whether uint32 addition can result in overflow
  105. /// @param [in] a addend
  106. /// @param [in] b addend
  107. /// @return Status
  108. inline Status CheckUint32AddOverflow(uint32_t a, uint32_t b) {
  109. if (a > (UINT32_MAX - b)) {
  110. return FAILED;
  111. }
  112. return SUCCESS;
  113. }
  114. /// @ingroup math_util
  115. /// @brief check whether uint64 addition can result in overflow
  116. /// @param [in] a addend
  117. /// @param [in] b addend
  118. /// @return Status
  119. inline Status CheckUint64AddOverflow(uint64_t a, uint64_t b) {
  120. if (a > (UINT64_MAX - b)) {
  121. return FAILED;
  122. }
  123. return SUCCESS;
  124. }
  125. /// @ingroup math_util
  126. /// @brief check whether fp16_t addition can result in overflow
  127. /// @param [in] a addend
  128. /// @param [in] b addend
  129. /// @return Status
  130. inline Status CheckFp16AddOverflow(fp16_t a, fp16_t b) {
  131. fp16_t result = static_cast<fp16_t>(a) + static_cast<fp16_t>(b);
  132. if (FP16_IS_INVALID(result.val)) {
  133. return FAILED;
  134. }
  135. return SUCCESS;
  136. }
  137. /// @ingroup math_util
  138. /// @brief check whether float addition can result in overflow
  139. /// @param [in] a addend
  140. /// @param [in] b addend
  141. /// @return Status
  142. inline Status CheckFloatAddOverflow(float a, float b) {
  143. if (std::isfinite(static_cast<float>(a) + static_cast<float>(b)) == false) {
  144. return FAILED;
  145. }
  146. return SUCCESS;
  147. }
  148. /// @ingroup math_util
  149. /// @brief check whether double addition can result in overflow
  150. /// @param [in] a addend
  151. /// @param [in] b addend
  152. /// @return Status
  153. inline Status CheckDoubleAddOverflow(double a, double b) {
  154. if (std::isfinite(static_cast<double>(a) + static_cast<double>(b)) == false) {
  155. return FAILED;
  156. }
  157. return SUCCESS;
  158. }
  159. /// @ingroup math_util
  160. /// @brief check whether int subtraction can result in overflow
  161. /// @param [in] a subtrahend
  162. /// @param [in] b minuend
  163. /// @return Status
  164. inline Status CheckIntSubOverflow(int a, int b) {
  165. if (((b > 0) && (a < (INT_MIN + b))) || ((b < 0) && (a > (INT_MAX + b)))) {
  166. return FAILED;
  167. }
  168. return SUCCESS;
  169. }
  170. /// @ingroup math_util
  171. /// @brief check whether int8 subtraction can result in overflow
  172. /// @param [in] a subtrahend
  173. /// @param [in] b minuend
  174. /// @return Status
  175. inline Status CheckInt8SubOverflow(int8_t a, int8_t b) {
  176. if (((b > 0) && (a < (INT8_MIN + b))) || ((b < 0) && (a > (INT8_MAX + b)))) {
  177. return FAILED;
  178. }
  179. return SUCCESS;
  180. }
  181. /// @ingroup math_util
  182. /// @brief check whether int16 subtraction can result in overflow
  183. /// @param [in] a subtrahend
  184. /// @param [in] b minuend
  185. /// @return Status
  186. inline Status CheckInt16SubOverflow(int16_t a, int16_t b) {
  187. if (((b > 0) && (a < (INT16_MIN + b))) || ((b < 0) && (a > (INT16_MAX + b)))) {
  188. return FAILED;
  189. }
  190. return SUCCESS;
  191. }
  192. /// @ingroup math_util
  193. /// @brief check whether int32 subtraction can result in overflow
  194. /// @param [in] a subtrahend
  195. /// @param [in] b minuend
  196. /// @return Status
  197. inline Status CheckInt32SubOverflow(int32_t a, int32_t b) {
  198. if (((b > 0) && (a < (INT32_MIN + b))) || ((b < 0) && (a > (INT32_MAX + b)))) {
  199. return FAILED;
  200. }
  201. return SUCCESS;
  202. }
  203. /// @ingroup math_util
  204. /// @brief check whether int64 subtraction can result in overflow
  205. /// @param [in] a subtrahend
  206. /// @param [in] b minuend
  207. /// @return Status
  208. inline Status CheckInt64SubOverflow(int64_t a, int64_t b) {
  209. if (((b > 0) && (a < (INT64_MIN + b))) || ((b < 0) && (a > (INT64_MAX + b)))) {
  210. return FAILED;
  211. }
  212. return SUCCESS;
  213. }
  214. /// @ingroup math_util
  215. /// @brief check whether uint8 subtraction can result in overflow
  216. /// @param [in] a subtrahend
  217. /// @param [in] b minuend
  218. /// @return Status
  219. inline Status CheckUint8SubOverflow(uint8_t a, uint8_t b) {
  220. if (a < b) {
  221. return FAILED;
  222. }
  223. return SUCCESS;
  224. }
  225. /// @ingroup math_util
  226. /// @brief check whether uint16 subtraction can result in overflow
  227. /// @param [in] a subtrahend
  228. /// @param [in] b minuend
  229. /// @return Status
  230. inline Status CheckUint16SubOverflow(uint16_t a, uint16_t b) {
  231. if (a < b) {
  232. return FAILED;
  233. }
  234. return SUCCESS;
  235. }
  236. /// @ingroup math_util
  237. /// @brief check whether uint32 subtraction can result in overflow
  238. /// @param [in] a subtrahend
  239. /// @param [in] b minuend
  240. /// @return Status
  241. inline Status CheckUint32SubOverflow(uint32_t a, uint32_t b) {
  242. if (a < b) {
  243. return FAILED;
  244. }
  245. return SUCCESS;
  246. }
  247. /// @ingroup math_util
  248. /// @brief check whether uint64 subtraction can result in overflow
  249. /// @param [in] a subtrahend
  250. /// @param [in] b minuend
  251. /// @return Status
  252. inline Status CheckUint64SubOverflow(uint64_t a, uint64_t b) {
  253. if (a < b) {
  254. return FAILED;
  255. }
  256. return SUCCESS;
  257. }
  258. /// @ingroup math_util
  259. /// @brief check whether fp16_t subtraction can result in overflow
  260. /// @param [in] a addend
  261. /// @param [in] b addend
  262. /// @return Status
  263. inline Status CheckFp16SubOverflow(fp16_t a, fp16_t b) {
  264. fp16_t result = static_cast<fp16_t>(a) - static_cast<fp16_t>(b);
  265. if (FP16_IS_INVALID(result.val)) {
  266. return FAILED;
  267. }
  268. return SUCCESS;
  269. }
  270. /// @ingroup math_util
  271. /// @brief check whether float subtraction can result in overflow
  272. /// @param [in] a addend
  273. /// @param [in] b addend
  274. /// @return Status
  275. inline Status CheckFloatSubOverflow(float a, float b) {
  276. if (std::isfinite(static_cast<float>(a) - static_cast<float>(b)) == false) {
  277. return FAILED;
  278. }
  279. return SUCCESS;
  280. }
  281. /// @ingroup math_util
  282. /// @brief check whether double subtraction can result in overflow
  283. /// @param [in] a addend
  284. /// @param [in] b addend
  285. /// @return Status
  286. inline Status CheckDoubleSubOverflow(double a, double b) {
  287. if (std::isfinite(static_cast<double>(a) - static_cast<double>(b)) == false) {
  288. return FAILED;
  289. }
  290. return SUCCESS;
  291. }
  292. /// @ingroup math_util
  293. /// @brief check whether int multiplication can result in overflow
  294. /// @param [in] a multiplicator
  295. /// @param [in] b multiplicator
  296. /// @return Status
  297. inline Status CheckIntMulOverflow(int a, int b) {
  298. if (a > 0) {
  299. if (b > 0) {
  300. if (a > (INT_MAX / b)) {
  301. return FAILED;
  302. }
  303. } else {
  304. if (b < (INT_MIN / a)) {
  305. return FAILED;
  306. }
  307. }
  308. } else {
  309. if (b > 0) {
  310. if (a < (INT_MIN / b)) {
  311. return FAILED;
  312. }
  313. } else {
  314. if ((a != 0) && (b < (INT_MAX / a))) {
  315. return FAILED;
  316. }
  317. }
  318. }
  319. return SUCCESS;
  320. }
  321. /// @ingroup math_util
  322. /// @brief check whether int8 multiplication can result in overflow
  323. /// @param [in] a multiplicator
  324. /// @param [in] b multiplicator
  325. /// @return Status
  326. inline Status CheckInt8MulOverflow(int8_t a, int8_t b) {
  327. if (a > 0) {
  328. if (b > 0) {
  329. if (a > (INT8_MAX / b)) {
  330. return FAILED;
  331. }
  332. } else {
  333. if (b < (INT8_MIN / a)) {
  334. return FAILED;
  335. }
  336. }
  337. } else {
  338. if (b > 0) {
  339. if (a < (INT8_MIN / b)) {
  340. return FAILED;
  341. }
  342. } else {
  343. if ((a != 0) && (b < (INT8_MAX / a))) {
  344. return FAILED;
  345. }
  346. }
  347. }
  348. return SUCCESS;
  349. }
  350. /// @ingroup math_util
  351. /// @brief check whether int16 multiplication can result in overflow
  352. /// @param [in] a multiplicator
  353. /// @param [in] b multiplicator
  354. /// @return Status
  355. inline Status CheckInt16MulOverflow(int16_t a, int16_t b) {
  356. if (a > 0) {
  357. if (b > 0) {
  358. if (a > (INT16_MAX / b)) {
  359. return FAILED;
  360. }
  361. } else {
  362. if (b < (INT16_MIN / a)) {
  363. return FAILED;
  364. }
  365. }
  366. } else {
  367. if (b > 0) {
  368. if (a < (INT16_MIN / b)) {
  369. return FAILED;
  370. }
  371. } else {
  372. if ((a != 0) && (b < (INT16_MAX / a))) {
  373. return FAILED;
  374. }
  375. }
  376. }
  377. return SUCCESS;
  378. }
  379. /// @ingroup math_util
  380. /// @brief check whether int32 multiplication can result in overflow
  381. /// @param [in] a multiplicator
  382. /// @param [in] b multiplicator
  383. /// @return Status
  384. inline Status CheckInt32MulOverflow(int32_t a, int32_t b) {
  385. if (a > 0) {
  386. if (b > 0) {
  387. if (a > (INT32_MAX / b)) {
  388. return FAILED;
  389. }
  390. } else {
  391. if (b < (INT32_MIN / a)) {
  392. return FAILED;
  393. }
  394. }
  395. } else {
  396. if (b > 0) {
  397. if (a < (INT32_MIN / b)) {
  398. return FAILED;
  399. }
  400. } else {
  401. if ((a != 0) && (b < (INT32_MAX / a))) {
  402. return FAILED;
  403. }
  404. }
  405. }
  406. return SUCCESS;
  407. }
  408. ///
  409. /// @ingroup math_util
  410. /// @brief check whether int64 int32 multiplication can result in overflow
  411. /// @param [in] a multiplicator
  412. /// @param [in] b multiplicator
  413. /// @return Status
  414. ///
  415. inline Status CheckInt64Int32MulOverflow(int64_t a, int32_t b) {
  416. if (a > 0) {
  417. if (b > 0) {
  418. if (a > (INT64_MAX / b)) {
  419. return FAILED;
  420. }
  421. } else {
  422. if (b < (INT64_MIN / a)) {
  423. return FAILED;
  424. }
  425. }
  426. } else {
  427. if (b > 0) {
  428. if (a < (INT64_MIN / b)) {
  429. return FAILED;
  430. }
  431. } else {
  432. if ((a != 0) && (b < (INT64_MAX / a))) {
  433. return FAILED;
  434. }
  435. }
  436. }
  437. return SUCCESS;
  438. }
  439. /// @ingroup math_util
  440. /// @brief check whether int64 multiplication can result in overflow
  441. /// @param [in] a multiplicator
  442. /// @param [in] b multiplicator
  443. /// @return Status
  444. inline Status Int64MulCheckOverflow(int64_t a, int64_t b) {
  445. if (a > 0) {
  446. if (b > 0) {
  447. if (a > (INT64_MAX / b)) {
  448. return FAILED;
  449. }
  450. } else {
  451. if (b < (INT64_MIN / a)) {
  452. return FAILED;
  453. }
  454. }
  455. } else {
  456. if (b > 0) {
  457. if (a < (INT64_MIN / b)) {
  458. return FAILED;
  459. }
  460. } else {
  461. if ((a != 0) && (b < (INT64_MAX / a))) {
  462. return FAILED;
  463. }
  464. }
  465. }
  466. return SUCCESS;
  467. }
  468. /// @ingroup math_util
  469. /// @brief check whether int64 multiplication can result in overflow
  470. /// @param [in] a multiplicator
  471. /// @param [in] b multiplicator
  472. /// @return Status
  473. inline Status CheckInt64Uint32MulOverflow(int64_t a, uint32_t b) {
  474. if (a == 0 || b == 0) {
  475. return SUCCESS;
  476. }
  477. if (a > 0) {
  478. if (a > (INT64_MAX / b)) {
  479. return FAILED;
  480. }
  481. } else {
  482. if (a < (INT64_MIN / b)) {
  483. return FAILED;
  484. }
  485. }
  486. return SUCCESS;
  487. }
  488. /// @ingroup math_util
  489. /// @brief check whether uint8 multiplication can result in overflow
  490. /// @param [in] a multiplicator
  491. /// @param [in] b multiplicator
  492. /// @return Status
  493. inline Status CheckUint8MulOverflow(uint8_t a, uint8_t b) {
  494. if (a == 0 || b == 0) {
  495. return SUCCESS;
  496. }
  497. if (a > (UINT8_MAX / b)) {
  498. return FAILED;
  499. }
  500. return SUCCESS;
  501. }
  502. /// @ingroup math_util
  503. /// @brief check whether uint16 multiplication can result in overflow
  504. /// @param [in] a multiplicator
  505. /// @param [in] b multiplicator
  506. /// @return Status
  507. inline Status CheckUint16MulOverflow(uint16_t a, uint16_t b) {
  508. if (a == 0 || b == 0) {
  509. return SUCCESS;
  510. }
  511. if (a > (UINT16_MAX / b)) {
  512. return FAILED;
  513. }
  514. return SUCCESS;
  515. }
  516. /// @ingroup math_util
  517. /// @brief check whether uint32 multiplication can result in overflow
  518. /// @param [in] a multiplicator
  519. /// @param [in] b multiplicator
  520. /// @return Status
  521. inline Status CheckUint32MulOverflow(uint32_t a, uint32_t b) {
  522. if (a == 0 || b == 0) {
  523. return SUCCESS;
  524. }
  525. if (a > (UINT32_MAX / b)) {
  526. return FAILED;
  527. }
  528. return SUCCESS;
  529. }
  530. /// @ingroup math_util
  531. /// @brief check whether uint64 multiplication can result in overflow
  532. /// @param [in] a multiplicator
  533. /// @param [in] b multiplicator
  534. /// @return Status
  535. inline Status CheckUint64MulOverflow(uint64_t a, uint64_t b) {
  536. if (a == 0 || b == 0) {
  537. return SUCCESS;
  538. }
  539. if (a > (UINT64_MAX / b)) {
  540. return FAILED;
  541. }
  542. return SUCCESS;
  543. }
  544. /// @ingroup math_util
  545. /// @brief check whether fp16_t multiplication can result in overflow
  546. /// @param [in] a addend
  547. /// @param [in] b addend
  548. /// @return Status
  549. inline Status CheckFp16MulOverflow(fp16_t a, fp16_t b) {
  550. fp16_t result = static_cast<fp16_t>(a) * static_cast<fp16_t>(b);
  551. if (FP16_IS_INVALID(result.val)) {
  552. return FAILED;
  553. }
  554. return SUCCESS;
  555. }
  556. /// @ingroup math_util
  557. /// @brief check whether float multiplication can result in overflow
  558. /// @param [in] a addend
  559. /// @param [in] b addend
  560. /// @return Status
  561. inline Status CheckFloatMulOverflow(float a, float b) {
  562. if (std::isfinite(static_cast<float>(a) * static_cast<float>(b)) == false) {
  563. return FAILED;
  564. }
  565. return SUCCESS;
  566. }
  567. /// @ingroup math_util
  568. /// @brief check whether double multiplication can result in overflow
  569. /// @param [in] a addend
  570. /// @param [in] b addend
  571. /// @return Status
  572. inline Status CheckDoubleMulOverflow(double a, double b) {
  573. if (std::isfinite(static_cast<double>(a) * static_cast<double>(b)) == false) {
  574. return FAILED;
  575. }
  576. return SUCCESS;
  577. }
  578. /// @ingroup math_util
  579. /// @brief check whether int division can result in overflow
  580. /// @param [in] a dividend
  581. /// @param [in] b divisor
  582. /// @return Status
  583. inline Status CheckIntDivOverflow(int a, int b) {
  584. if ((b == 0) || ((a == INT_MIN) && (b == -1))) {
  585. return FAILED;
  586. }
  587. return SUCCESS;
  588. }
  589. /// @ingroup math_util
  590. /// @brief check whether int32 division can result in overflow
  591. /// @param [in] a dividend
  592. /// @param [in] b divisor
  593. /// @return Status
  594. inline Status CheckInt32DivOverflow(int32_t a, int32_t b) {
  595. if ((b == 0) || ((a == INT32_MIN) && (b == -1))) {
  596. return FAILED;
  597. }
  598. return SUCCESS;
  599. }
  600. #define FMK_INT_ADDCHECK(a, b) \
  601. if (ge::CheckIntAddOverflow((a), (b)) != SUCCESS) { \
  602. GELOGW("Int %d and %d addition can result in overflow!", static_cast<int>(a), static_cast<int>(b)); \
  603. return INTERNAL_ERROR; \
  604. }
  605. #define FMK_INT8_ADDCHECK(a, b) \
  606. if (ge::CheckInt8AddOverflow((a), (b)) != SUCCESS) { \
  607. GELOGW("Int8 %d and %d addition can result in overflow!", static_cast<int8_t>(a), static_cast<int8_t>(b)); \
  608. return INTERNAL_ERROR; \
  609. }
  610. #define FMK_INT16_ADDCHECK(a, b) \
  611. if (ge::CheckInt16AddOverflow((a), (b)) != SUCCESS) { \
  612. GELOGW("Int16 %d and %d addition can result in overflow!", static_cast<int16_t>(a), static_cast<int16_t>(b)); \
  613. return INTERNAL_ERROR; \
  614. }
  615. #define FMK_INT32_ADDCHECK(a, b) \
  616. if (ge::CheckInt32AddOverflow((a), (b)) != SUCCESS) { \
  617. GELOGW("Int32 %d and %d addition can result in overflow!", static_cast<int32_t>(a), static_cast<int32_t>(b)); \
  618. return INTERNAL_ERROR; \
  619. }
  620. #define FMK_INT64_ADDCHECK(a, b) \
  621. if (ge::CheckInt64AddOverflow((a), (b)) != SUCCESS) { \
  622. GELOGW("Int64 %ld and %ld addition can result in overflow!", static_cast<int64_t>(a), static_cast<int64_t>(b)); \
  623. return INTERNAL_ERROR; \
  624. }
  625. #define FMK_UINT8_ADDCHECK(a, b) \
  626. if (ge::CheckUint8AddOverflow((a), (b)) != SUCCESS) { \
  627. GELOGW("Uint8 %u and %u addition can result in overflow!", static_cast<uint8_t>(a), static_cast<uint8_t>(b)); \
  628. return INTERNAL_ERROR; \
  629. }
  630. #define FMK_UINT16_ADDCHECK(a, b) \
  631. if (ge::CheckUint16AddOverflow((a), (b)) != SUCCESS) { \
  632. GELOGW("UINT16 %u and %u addition can result in overflow!", static_cast<uint16_t>(a), static_cast<uint16_t>(b)); \
  633. return INTERNAL_ERROR; \
  634. }
  635. #define FMK_UINT32_ADDCHECK(a, b) \
  636. if (ge::CheckUint32AddOverflow((a), (b)) != SUCCESS) { \
  637. GELOGW("Uint32 %u and %u addition can result in overflow!", static_cast<uint32_t>(a), static_cast<uint32_t>(b)); \
  638. return INTERNAL_ERROR; \
  639. }
  640. #define FMK_UINT64_ADDCHECK(a, b) \
  641. if (ge::CheckUint64AddOverflow((a), (b)) != SUCCESS) { \
  642. GELOGW("Uint64 %lu and %lu addition can result in overflow!", static_cast<uint64_t>(a), static_cast<uint64_t>(b)); \
  643. return INTERNAL_ERROR; \
  644. }
  645. #define FMK_FP16_ADDCHECK(a, b) \
  646. if (ge::CheckFp16AddOverflow((a), (b)) != SUCCESS) { \
  647. GELOGW("Fp16 %f and %f addition can result in overflow!", static_cast<float>(a), static_cast<float>(b)); \
  648. return INTERNAL_ERROR; \
  649. }
  650. #define FMK_FLOAT_ADDCHECK(a, b) \
  651. if (ge::CheckFloatAddOverflow((a), (b)) != SUCCESS) { \
  652. GELOGW("Float %f and %f addition can result in overflow!", static_cast<float>(a), static_cast<float>(b)); \
  653. return INTERNAL_ERROR; \
  654. }
  655. #define FMK_DOUBLE_ADDCHECK(a, b) \
  656. if (ge::CheckDoubleAddOverflow((a), (b)) != SUCCESS) { \
  657. GELOGW("Double %lf and %lf addition can result in overflow!", static_cast<double>(a), static_cast<double>(b)); \
  658. return INTERNAL_ERROR; \
  659. }
  660. #define FMK_INT_SUBCHECK(a, b) \
  661. if (ge::CheckIntSubOverflow((a), (b)) != SUCCESS) { \
  662. GELOGW("Int %d and %d subtraction can result in overflow!", static_cast<int>(a), static_cast<int>(b)); \
  663. return INTERNAL_ERROR; \
  664. }
  665. #define FMK_INT8_SUBCHECK(a, b) \
  666. if (ge::CheckInt8SubOverflow((a), (b)) != SUCCESS) { \
  667. GELOGW("Int8 %d and %d subtraction can result in overflow!", static_cast<int8_t>(a), static_cast<int8_t>(b)); \
  668. return INTERNAL_ERROR; \
  669. }
  670. #define FMK_INT16_SUBCHECK(a, b) \
  671. if (ge::CheckInt16SubOverflow((a), (b)) != SUCCESS) { \
  672. GELOGW("Int16 %d and %d subtraction can result in overflow!", static_cast<int16_t>(a), static_cast<int16_t>(b)); \
  673. return INTERNAL_ERROR; \
  674. }
  675. #define FMK_INT32_SUBCHECK(a, b) \
  676. if (ge::CheckInt32SubOverflow((a), (b)) != SUCCESS) { \
  677. GELOGW("Int32 %d and %d subtraction can result in overflow!", static_cast<int32_t>(a), static_cast<int32_t>(b)); \
  678. return INTERNAL_ERROR; \
  679. }
  680. #define FMK_INT64_SUBCHECK(a, b) \
  681. if (ge::CheckInt64SubOverflow((a), (b)) != SUCCESS) { \
  682. GELOGW("Int64 %ld and %ld subtraction can result in overflow!", static_cast<int64_t>(a), static_cast<int64_t>(b)); \
  683. return INTERNAL_ERROR; \
  684. }
  685. #define FMK_UINT8_SUBCHECK(a, b) \
  686. if (ge::CheckUint8SubOverflow((a), (b)) != SUCCESS) { \
  687. GELOGW("Uint8 %u and %u subtraction can result in overflow!", static_cast<uint8_t>(a), static_cast<uint8_t>(b)); \
  688. return INTERNAL_ERROR; \
  689. }
  690. #define FMK_UINT16_SUBCHECK(a, b) \
  691. if (ge::CheckUint16SubOverflow((a), (b)) != SUCCESS) { \
  692. GELOGW("Uint16 %u and %u subtraction can result in overflow!", static_cast<uint16_t>(a), \
  693. static_cast<uint16_t>(b)); \
  694. return INTERNAL_ERROR; \
  695. }
  696. #define FMK_UINT32_SUBCHECK(a, b) \
  697. if (ge::CheckUint32SubOverflow((a), (b)) != SUCCESS) { \
  698. GELOGW("Uint32 %u and %u subtraction can result in overflow!", static_cast<uint32_t>(a), \
  699. static_cast<uint32_t>(b)); \
  700. return INTERNAL_ERROR; \
  701. }
  702. #define FMK_UINT64_SUBCHECK(a, b) \
  703. if (ge::CheckUint64SubOverflow((a), (b)) != SUCCESS) { \
  704. GELOGW("Uint64 %lu and %lu subtraction can result in overflow!", static_cast<uint64_t>(a), \
  705. static_cast<uint64_t>(b)); \
  706. return INTERNAL_ERROR; \
  707. }
  708. #define FMK_FP16_SUBCHECK(a, b) \
  709. if (ge::CheckFp16SubOverflow((a), (b)) != SUCCESS) { \
  710. GELOGW("Fp16 %f and %f subtraction can result in overflow!", static_cast<float>(a), static_cast<float>(b)); \
  711. return INTERNAL_ERROR; \
  712. }
  713. #define FMK_FLOAT_SUBCHECK(a, b) \
  714. if (ge::CheckFloatSubOverflow((a), (b)) != SUCCESS) { \
  715. GELOGW("Float %f and %f subtraction can result in overflow!", static_cast<float>(a), static_cast<float>(b)); \
  716. return INTERNAL_ERROR; \
  717. }
  718. #define FMK_DOUBLE_SUBCHECK(a, b) \
  719. if (ge::CheckDoubleSubOverflow((a), (b)) != SUCCESS) { \
  720. GELOGW("Double %lf and %lf subtraction can result in overflow!", static_cast<double>(a), static_cast<double>(b)); \
  721. return INTERNAL_ERROR; \
  722. }
  723. #define FMK_INT_MULCHECK(a, b) \
  724. if (ge::CheckIntMulOverflow((a), (b)) != SUCCESS) { \
  725. GELOGW("Int %d and %d multiplication can result in overflow!", static_cast<int>(a), static_cast<int>(b)); \
  726. return INTERNAL_ERROR; \
  727. }
  728. #define FMK_INT8_MULCHECK(a, b) \
  729. if (ge::CheckInt8MulOverflow((a), (b)) != SUCCESS) { \
  730. GELOGW("Int8 %d and %d multiplication can result in overflow!", static_cast<int8_t>(a), static_cast<int8_t>(b)); \
  731. return INTERNAL_ERROR; \
  732. }
  733. #define FMK_INT16_MULCHECK(a, b) \
  734. if (ge::CheckInt16MulOverflow((a), (b)) != SUCCESS) { \
  735. GELOGW("Int16 %d and %d multiplication can result in overflow!", static_cast<int16_t>(a), \
  736. static_cast<int16_t>(b)); \
  737. return INTERNAL_ERROR; \
  738. }
  739. #define FMK_INT32_MULCHECK(a, b) \
  740. if (ge::CheckInt32MulOverflow((a), (b)) != SUCCESS) { \
  741. GELOGW("Int32 %d and %d multiplication can result in overflow!", static_cast<int32_t>(a), \
  742. static_cast<int32_t>(b)); \
  743. return INTERNAL_ERROR; \
  744. }
  745. #define FMK_INT64_MULCHECK(a, b) \
  746. if (ge::Int64MulCheckOverflow((a), (b)) != SUCCESS) { \
  747. GELOGW("Int64 %ld and %ld multiplication can result in overflow!", static_cast<int64_t>(a), \
  748. static_cast<int64_t>(b)); \
  749. return INTERNAL_ERROR; \
  750. }
  751. #define FMK_UINT8_MULCHECK(a, b) \
  752. if (ge::CheckUint8MulOverflow((a), (b)) != SUCCESS) { \
  753. GELOGW("Uint8 %u and %u multiplication can result in overflow!", static_cast<uint8_t>(a), \
  754. static_cast<uint8_t>(b)); \
  755. return INTERNAL_ERROR; \
  756. }
  757. #define FMK_UINT16_MULCHECK(a, b) \
  758. if (ge::CheckUint16MulOverflow((a), (b)) != SUCCESS) { \
  759. GELOGW("Uint16 %u and %u multiplication can result in overflow!", static_cast<uint16_t>(a), \
  760. static_cast<uint16_t>(b)); \
  761. return INTERNAL_ERROR; \
  762. }
  763. #define FMK_UINT32_MULCHECK(a, b) \
  764. if (ge::CheckUint32MulOverflow((a), (b)) != SUCCESS) { \
  765. GELOGW("Uint32 %u and %u multiplication can result in overflow!", static_cast<uint32_t>(a), \
  766. static_cast<uint32_t>(b)); \
  767. return INTERNAL_ERROR; \
  768. }
  769. #define FMK_UINT64_MULCHECK(a, b) \
  770. if (ge::CheckUint64MulOverflow((a), (b)) != SUCCESS) { \
  771. GELOGW("Uint64 %lu and %lu multiplication can result in overflow!", static_cast<uint64_t>(a), \
  772. static_cast<uint64_t>(b)); \
  773. return INTERNAL_ERROR; \
  774. }
  775. #define FMK_FP16_MULCHECK(a, b) \
  776. if (ge::CheckFp16MulOverflow((a), (b)) != SUCCESS) { \
  777. GELOGW("Fp16 %f and %f multiplication can result in overflow!", static_cast<float>(a), static_cast<float>(b)); \
  778. return INTERNAL_ERROR; \
  779. }
  780. #define FMK_FLOAT_MULCHECK(a, b) \
  781. if (ge::CheckFloatMulOverflow((a), (b)) != SUCCESS) { \
  782. GELOGW("Float %f and %f multiplication can result in overflow!", static_cast<float>(a), static_cast<float>(b)); \
  783. return INTERNAL_ERROR; \
  784. }
  785. #define FMK_DOUBLE_MULCHECK(a, b) \
  786. if (ge::CheckDoubleMulOverflow((a), (b)) != SUCCESS) { \
  787. GELOGW("Double %lf and %lf multiplication can result in overflow!", static_cast<double>(a), \
  788. static_cast<double>(b)); \
  789. return INTERNAL_ERROR; \
  790. }
  791. #define FMK_INT_DIVCHECK(a, b) \
  792. if (CheckIntDivOverflow((a), (b)) != SUCCESS) { \
  793. GELOGW("Int %d and %d division can result in overflow!", static_cast<int>(a), static_cast<int>(b)); \
  794. return INTERNAL_ERROR; \
  795. }
  796. #define FMK_INT32_DIVCHECK(a, b) \
  797. if (CheckInt32DivOverflow((a), (b)) != SUCCESS) { \
  798. GELOGW("Int32 %d and %d division can result in overflow!", static_cast<int32_t>(a), static_cast<int32_t>(b)); \
  799. return INTERNAL_ERROR; \
  800. }
  801. #define FMK_INT64_UINT32_MULCHECK(a, b) \
  802. if (ge::CheckInt64Uint32MulOverflow((a), (b)) != SUCCESS) { \
  803. GELOGW("Int64 %ld and UINT32 %u multiplication can result in overflow!", static_cast<uint32_t>(a), \
  804. static_cast<uint32_t>(b)); \
  805. return INTERNAL_ERROR; \
  806. }
  807. #define FMK_FP16_ZEROCHECK(a) \
  808. if (fabs(a) < DBL_EPSILON || a < 0) { \
  809. GELOGW("Fp16 %f can not less than or equal to zero! ", a); \
  810. return INTERNAL_ERROR; \
  811. }
  812. #define FMK_FLOAT_ZEROCHECK(a) \
  813. if (fabs(a) < FLT_EPSILON || a < 0) { \
  814. GELOGW("Float %f can not less than or equal to zero! ", a); \
  815. return INTERNAL_ERROR; \
  816. }
  817. #define FMK_DOUBLE_ZEROCHECK(a) \
  818. if (fabs(a) < DBL_EPSILON || a < 0) { \
  819. GELOGW("Double %lf can not less than or equal to zero! ", a); \
  820. return INTERNAL_ERROR; \
  821. }
  822. } // namespace ge
  823. #endif // GE_COMMON_MATH_MATH_UTIL_H_

图引擎模块(GE)是MindSpore的一个子模块,其代码由C++实现,位于前端模块ME和底层硬件之间,起到承接作用。图引擎模块以ME下发的图作为输入,然后进行一系列的深度图优化操作,最后输出一张可以在底层硬件上高效运行的图。GE针对昇腾AI处理器的硬件结构特点,做了特定的优化工作,以此来充分发挥出昇腾AI处理器的强大算力。在进行模型训练/推理时,GE会被自动调用而用户并不感知。GE主要由GE API和GE Core两部分组成,详细的架构图如下所示