19637de38SSrikanth Yalavarthi /* SPDX-License-Identifier: BSD-3-Clause 29637de38SSrikanth Yalavarthi * Copyright (c) 2022 Marvell. 39637de38SSrikanth Yalavarthi */ 49637de38SSrikanth Yalavarthi 5538f6997SSrikanth Yalavarthi #include "mldev_utils_scalar.h" 69637de38SSrikanth Yalavarthi 79637de38SSrikanth Yalavarthi /* Description: 89637de38SSrikanth Yalavarthi * This file implements scalar versions of Machine Learning utility functions used to convert data 9538f6997SSrikanth Yalavarthi * types from higher precision to lower precision and vice-versa, except bfloat16. 109637de38SSrikanth Yalavarthi */ 119637de38SSrikanth Yalavarthi 128c9bfcb1SSrikanth Yalavarthi int 13*65282e9fSSrikanth Yalavarthi rte_ml_io_float32_to_int8(const void *input, void *output, uint64_t nb_elements, float scale, 14*65282e9fSSrikanth Yalavarthi int8_t zero_point) 159637de38SSrikanth Yalavarthi { 16*65282e9fSSrikanth Yalavarthi const float *input_buffer; 179637de38SSrikanth Yalavarthi int8_t *output_buffer; 189637de38SSrikanth Yalavarthi uint64_t i; 199637de38SSrikanth Yalavarthi int i32; 209637de38SSrikanth Yalavarthi 219637de38SSrikanth Yalavarthi if ((scale == 0) || (nb_elements == 0) || (input == NULL) || (output == NULL)) 229637de38SSrikanth Yalavarthi return -EINVAL; 239637de38SSrikanth Yalavarthi 24*65282e9fSSrikanth Yalavarthi input_buffer = (const float *)input; 259637de38SSrikanth Yalavarthi output_buffer = (int8_t *)output; 269637de38SSrikanth Yalavarthi 279637de38SSrikanth Yalavarthi for (i = 0; i < nb_elements; i++) { 28*65282e9fSSrikanth Yalavarthi i32 = (int32_t)(round(*input_buffer / scale) + zero_point); 299637de38SSrikanth Yalavarthi 309637de38SSrikanth Yalavarthi if (i32 < INT8_MIN) 319637de38SSrikanth Yalavarthi i32 = INT8_MIN; 329637de38SSrikanth Yalavarthi 339637de38SSrikanth Yalavarthi if (i32 > INT8_MAX) 349637de38SSrikanth Yalavarthi i32 = INT8_MAX; 359637de38SSrikanth Yalavarthi 369637de38SSrikanth Yalavarthi *output_buffer = (int8_t)i32; 379637de38SSrikanth Yalavarthi 389637de38SSrikanth Yalavarthi input_buffer++; 399637de38SSrikanth Yalavarthi output_buffer++; 409637de38SSrikanth Yalavarthi } 419637de38SSrikanth Yalavarthi 429637de38SSrikanth Yalavarthi return 0; 439637de38SSrikanth Yalavarthi } 449637de38SSrikanth Yalavarthi 458c9bfcb1SSrikanth Yalavarthi int 46*65282e9fSSrikanth Yalavarthi rte_ml_io_int8_to_float32(const void *input, void *output, uint64_t nb_elements, float scale, 47*65282e9fSSrikanth Yalavarthi int8_t zero_point) 489637de38SSrikanth Yalavarthi { 49*65282e9fSSrikanth Yalavarthi const int8_t *input_buffer; 509637de38SSrikanth Yalavarthi float *output_buffer; 519637de38SSrikanth Yalavarthi uint64_t i; 529637de38SSrikanth Yalavarthi 539637de38SSrikanth Yalavarthi if ((scale == 0) || (nb_elements == 0) || (input == NULL) || (output == NULL)) 549637de38SSrikanth Yalavarthi return -EINVAL; 559637de38SSrikanth Yalavarthi 56*65282e9fSSrikanth Yalavarthi input_buffer = (const int8_t *)input; 579637de38SSrikanth Yalavarthi output_buffer = (float *)output; 589637de38SSrikanth Yalavarthi 599637de38SSrikanth Yalavarthi for (i = 0; i < nb_elements; i++) { 60*65282e9fSSrikanth Yalavarthi *output_buffer = scale * (float)(*input_buffer - zero_point); 619637de38SSrikanth Yalavarthi 629637de38SSrikanth Yalavarthi input_buffer++; 639637de38SSrikanth Yalavarthi output_buffer++; 649637de38SSrikanth Yalavarthi } 659637de38SSrikanth Yalavarthi 669637de38SSrikanth Yalavarthi return 0; 679637de38SSrikanth Yalavarthi } 689637de38SSrikanth Yalavarthi 698c9bfcb1SSrikanth Yalavarthi int 70*65282e9fSSrikanth Yalavarthi rte_ml_io_float32_to_uint8(const void *input, void *output, uint64_t nb_elements, float scale, 71*65282e9fSSrikanth Yalavarthi uint8_t zero_point) 729637de38SSrikanth Yalavarthi { 73*65282e9fSSrikanth Yalavarthi const float *input_buffer; 749637de38SSrikanth Yalavarthi uint8_t *output_buffer; 759637de38SSrikanth Yalavarthi int32_t i32; 769637de38SSrikanth Yalavarthi uint64_t i; 779637de38SSrikanth Yalavarthi 789637de38SSrikanth Yalavarthi if ((scale == 0) || (nb_elements == 0) || (input == NULL) || (output == NULL)) 799637de38SSrikanth Yalavarthi return -EINVAL; 809637de38SSrikanth Yalavarthi 81*65282e9fSSrikanth Yalavarthi input_buffer = (const float *)input; 829637de38SSrikanth Yalavarthi output_buffer = (uint8_t *)output; 839637de38SSrikanth Yalavarthi 849637de38SSrikanth Yalavarthi for (i = 0; i < nb_elements; i++) { 85*65282e9fSSrikanth Yalavarthi i32 = (int32_t)(round(*input_buffer / scale) + zero_point); 869637de38SSrikanth Yalavarthi 879637de38SSrikanth Yalavarthi if (i32 < 0) 889637de38SSrikanth Yalavarthi i32 = 0; 899637de38SSrikanth Yalavarthi 909637de38SSrikanth Yalavarthi if (i32 > UINT8_MAX) 919637de38SSrikanth Yalavarthi i32 = UINT8_MAX; 929637de38SSrikanth Yalavarthi 939637de38SSrikanth Yalavarthi *output_buffer = (uint8_t)i32; 949637de38SSrikanth Yalavarthi 959637de38SSrikanth Yalavarthi input_buffer++; 969637de38SSrikanth Yalavarthi output_buffer++; 979637de38SSrikanth Yalavarthi } 989637de38SSrikanth Yalavarthi 999637de38SSrikanth Yalavarthi return 0; 1009637de38SSrikanth Yalavarthi } 1019637de38SSrikanth Yalavarthi 1028c9bfcb1SSrikanth Yalavarthi int 103*65282e9fSSrikanth Yalavarthi rte_ml_io_uint8_to_float32(const void *input, void *output, uint64_t nb_elements, float scale, 104*65282e9fSSrikanth Yalavarthi uint8_t zero_point) 1059637de38SSrikanth Yalavarthi { 106*65282e9fSSrikanth Yalavarthi const uint8_t *input_buffer; 1079637de38SSrikanth Yalavarthi float *output_buffer; 1089637de38SSrikanth Yalavarthi uint64_t i; 1099637de38SSrikanth Yalavarthi 1109637de38SSrikanth Yalavarthi if ((scale == 0) || (nb_elements == 0) || (input == NULL) || (output == NULL)) 1119637de38SSrikanth Yalavarthi return -EINVAL; 1129637de38SSrikanth Yalavarthi 113*65282e9fSSrikanth Yalavarthi input_buffer = (const uint8_t *)input; 1149637de38SSrikanth Yalavarthi output_buffer = (float *)output; 1159637de38SSrikanth Yalavarthi 1169637de38SSrikanth Yalavarthi for (i = 0; i < nb_elements; i++) { 117*65282e9fSSrikanth Yalavarthi *output_buffer = scale * (float)(*input_buffer - zero_point); 1189637de38SSrikanth Yalavarthi 1199637de38SSrikanth Yalavarthi input_buffer++; 1209637de38SSrikanth Yalavarthi output_buffer++; 1219637de38SSrikanth Yalavarthi } 1229637de38SSrikanth Yalavarthi 1239637de38SSrikanth Yalavarthi return 0; 1249637de38SSrikanth Yalavarthi } 1259637de38SSrikanth Yalavarthi 1268c9bfcb1SSrikanth Yalavarthi int 127*65282e9fSSrikanth Yalavarthi rte_ml_io_float32_to_int16(const void *input, void *output, uint64_t nb_elements, float scale, 128*65282e9fSSrikanth Yalavarthi int16_t zero_point) 1299637de38SSrikanth Yalavarthi { 130*65282e9fSSrikanth Yalavarthi const float *input_buffer; 1319637de38SSrikanth Yalavarthi int16_t *output_buffer; 1329637de38SSrikanth Yalavarthi int32_t i32; 1339637de38SSrikanth Yalavarthi uint64_t i; 1349637de38SSrikanth Yalavarthi 1359637de38SSrikanth Yalavarthi if ((scale == 0) || (nb_elements == 0) || (input == NULL) || (output == NULL)) 1369637de38SSrikanth Yalavarthi return -EINVAL; 1379637de38SSrikanth Yalavarthi 138*65282e9fSSrikanth Yalavarthi input_buffer = (const float *)input; 1399637de38SSrikanth Yalavarthi output_buffer = (int16_t *)output; 1409637de38SSrikanth Yalavarthi 1419637de38SSrikanth Yalavarthi for (i = 0; i < nb_elements; i++) { 142*65282e9fSSrikanth Yalavarthi i32 = (int32_t)(round(*input_buffer / scale) + zero_point); 1439637de38SSrikanth Yalavarthi 1449637de38SSrikanth Yalavarthi if (i32 < INT16_MIN) 1459637de38SSrikanth Yalavarthi i32 = INT16_MIN; 1469637de38SSrikanth Yalavarthi 1479637de38SSrikanth Yalavarthi if (i32 > INT16_MAX) 1489637de38SSrikanth Yalavarthi i32 = INT16_MAX; 1499637de38SSrikanth Yalavarthi 1509637de38SSrikanth Yalavarthi *output_buffer = (int16_t)i32; 1519637de38SSrikanth Yalavarthi 1529637de38SSrikanth Yalavarthi input_buffer++; 1539637de38SSrikanth Yalavarthi output_buffer++; 1549637de38SSrikanth Yalavarthi } 1559637de38SSrikanth Yalavarthi 1569637de38SSrikanth Yalavarthi return 0; 1579637de38SSrikanth Yalavarthi } 1589637de38SSrikanth Yalavarthi 1598c9bfcb1SSrikanth Yalavarthi int 160*65282e9fSSrikanth Yalavarthi rte_ml_io_int16_to_float32(const void *input, void *output, uint64_t nb_elements, float scale, 161*65282e9fSSrikanth Yalavarthi int16_t zero_point) 1629637de38SSrikanth Yalavarthi { 163*65282e9fSSrikanth Yalavarthi const int16_t *input_buffer; 1649637de38SSrikanth Yalavarthi float *output_buffer; 1659637de38SSrikanth Yalavarthi uint64_t i; 1669637de38SSrikanth Yalavarthi 1679637de38SSrikanth Yalavarthi if ((scale == 0) || (nb_elements == 0) || (input == NULL) || (output == NULL)) 1689637de38SSrikanth Yalavarthi return -EINVAL; 1699637de38SSrikanth Yalavarthi 170*65282e9fSSrikanth Yalavarthi input_buffer = (const int16_t *)input; 1719637de38SSrikanth Yalavarthi output_buffer = (float *)output; 1729637de38SSrikanth Yalavarthi 1739637de38SSrikanth Yalavarthi for (i = 0; i < nb_elements; i++) { 174*65282e9fSSrikanth Yalavarthi *output_buffer = scale * (float)(*input_buffer - zero_point); 1759637de38SSrikanth Yalavarthi 1769637de38SSrikanth Yalavarthi input_buffer++; 1779637de38SSrikanth Yalavarthi output_buffer++; 1789637de38SSrikanth Yalavarthi } 1799637de38SSrikanth Yalavarthi 1809637de38SSrikanth Yalavarthi return 0; 1819637de38SSrikanth Yalavarthi } 1829637de38SSrikanth Yalavarthi 1838c9bfcb1SSrikanth Yalavarthi int 184*65282e9fSSrikanth Yalavarthi rte_ml_io_float32_to_uint16(const void *input, void *output, uint64_t nb_elements, float scale, 185*65282e9fSSrikanth Yalavarthi uint16_t zero_point) 1869637de38SSrikanth Yalavarthi { 187*65282e9fSSrikanth Yalavarthi const float *input_buffer; 1889637de38SSrikanth Yalavarthi uint16_t *output_buffer; 1899637de38SSrikanth Yalavarthi int32_t i32; 1909637de38SSrikanth Yalavarthi uint64_t i; 1919637de38SSrikanth Yalavarthi 1929637de38SSrikanth Yalavarthi if ((scale == 0) || (nb_elements == 0) || (input == NULL) || (output == NULL)) 1939637de38SSrikanth Yalavarthi return -EINVAL; 1949637de38SSrikanth Yalavarthi 195*65282e9fSSrikanth Yalavarthi input_buffer = (const float *)input; 1969637de38SSrikanth Yalavarthi output_buffer = (uint16_t *)output; 1979637de38SSrikanth Yalavarthi 1989637de38SSrikanth Yalavarthi for (i = 0; i < nb_elements; i++) { 199*65282e9fSSrikanth Yalavarthi i32 = (int32_t)(round(*input_buffer / scale) + zero_point); 2009637de38SSrikanth Yalavarthi 2019637de38SSrikanth Yalavarthi if (i32 < 0) 2029637de38SSrikanth Yalavarthi i32 = 0; 2039637de38SSrikanth Yalavarthi 2049637de38SSrikanth Yalavarthi if (i32 > UINT16_MAX) 2059637de38SSrikanth Yalavarthi i32 = UINT16_MAX; 2069637de38SSrikanth Yalavarthi 2079637de38SSrikanth Yalavarthi *output_buffer = (uint16_t)i32; 2089637de38SSrikanth Yalavarthi 2099637de38SSrikanth Yalavarthi input_buffer++; 2109637de38SSrikanth Yalavarthi output_buffer++; 2119637de38SSrikanth Yalavarthi } 2129637de38SSrikanth Yalavarthi 2139637de38SSrikanth Yalavarthi return 0; 2149637de38SSrikanth Yalavarthi } 2159637de38SSrikanth Yalavarthi 2168c9bfcb1SSrikanth Yalavarthi int 217*65282e9fSSrikanth Yalavarthi rte_ml_io_uint16_to_float32(const void *input, void *output, uint64_t nb_elements, float scale, 218*65282e9fSSrikanth Yalavarthi uint16_t zero_point) 2199637de38SSrikanth Yalavarthi { 220*65282e9fSSrikanth Yalavarthi const uint16_t *input_buffer; 2219637de38SSrikanth Yalavarthi float *output_buffer; 2229637de38SSrikanth Yalavarthi uint64_t i; 2239637de38SSrikanth Yalavarthi 2249637de38SSrikanth Yalavarthi if ((scale == 0) || (nb_elements == 0) || (input == NULL) || (output == NULL)) 2259637de38SSrikanth Yalavarthi return -EINVAL; 2269637de38SSrikanth Yalavarthi 227*65282e9fSSrikanth Yalavarthi input_buffer = (const uint16_t *)input; 2289637de38SSrikanth Yalavarthi output_buffer = (float *)output; 2299637de38SSrikanth Yalavarthi 2309637de38SSrikanth Yalavarthi for (i = 0; i < nb_elements; i++) { 231*65282e9fSSrikanth Yalavarthi *output_buffer = scale * (float)(*input_buffer - zero_point); 2329637de38SSrikanth Yalavarthi 2339637de38SSrikanth Yalavarthi input_buffer++; 2349637de38SSrikanth Yalavarthi output_buffer++; 2359637de38SSrikanth Yalavarthi } 2369637de38SSrikanth Yalavarthi 2379637de38SSrikanth Yalavarthi return 0; 2389637de38SSrikanth Yalavarthi } 2399637de38SSrikanth Yalavarthi 24050513ae5SSrikanth Yalavarthi int 241*65282e9fSSrikanth Yalavarthi rte_ml_io_float32_to_int32(const void *input, void *output, uint64_t nb_elements, float scale, 242*65282e9fSSrikanth Yalavarthi int32_t zero_point) 24350513ae5SSrikanth Yalavarthi { 244*65282e9fSSrikanth Yalavarthi const float *input_buffer; 24550513ae5SSrikanth Yalavarthi int32_t *output_buffer; 24650513ae5SSrikanth Yalavarthi uint64_t i; 24750513ae5SSrikanth Yalavarthi 24850513ae5SSrikanth Yalavarthi if ((scale == 0) || (nb_elements == 0) || (input == NULL) || (output == NULL)) 24950513ae5SSrikanth Yalavarthi return -EINVAL; 25050513ae5SSrikanth Yalavarthi 251*65282e9fSSrikanth Yalavarthi input_buffer = (const float *)input; 25250513ae5SSrikanth Yalavarthi output_buffer = (int32_t *)output; 25350513ae5SSrikanth Yalavarthi 25450513ae5SSrikanth Yalavarthi for (i = 0; i < nb_elements; i++) { 255*65282e9fSSrikanth Yalavarthi *output_buffer = (int32_t)(round(*input_buffer / scale) + zero_point); 25650513ae5SSrikanth Yalavarthi 25750513ae5SSrikanth Yalavarthi input_buffer++; 25850513ae5SSrikanth Yalavarthi output_buffer++; 25950513ae5SSrikanth Yalavarthi } 26050513ae5SSrikanth Yalavarthi 26150513ae5SSrikanth Yalavarthi return 0; 26250513ae5SSrikanth Yalavarthi } 26350513ae5SSrikanth Yalavarthi 26450513ae5SSrikanth Yalavarthi int 265*65282e9fSSrikanth Yalavarthi rte_ml_io_int32_to_float32(const void *input, void *output, uint64_t nb_elements, float scale, 266*65282e9fSSrikanth Yalavarthi int32_t zero_point) 26750513ae5SSrikanth Yalavarthi { 268*65282e9fSSrikanth Yalavarthi const int32_t *input_buffer; 26950513ae5SSrikanth Yalavarthi float *output_buffer; 27050513ae5SSrikanth Yalavarthi uint64_t i; 27150513ae5SSrikanth Yalavarthi 27250513ae5SSrikanth Yalavarthi if ((scale == 0) || (nb_elements == 0) || (input == NULL) || (output == NULL)) 27350513ae5SSrikanth Yalavarthi return -EINVAL; 27450513ae5SSrikanth Yalavarthi 275*65282e9fSSrikanth Yalavarthi input_buffer = (const int32_t *)input; 27650513ae5SSrikanth Yalavarthi output_buffer = (float *)output; 27750513ae5SSrikanth Yalavarthi 27850513ae5SSrikanth Yalavarthi for (i = 0; i < nb_elements; i++) { 279*65282e9fSSrikanth Yalavarthi *output_buffer = scale * (float)(*input_buffer - zero_point); 28050513ae5SSrikanth Yalavarthi 28150513ae5SSrikanth Yalavarthi input_buffer++; 28250513ae5SSrikanth Yalavarthi output_buffer++; 28350513ae5SSrikanth Yalavarthi } 28450513ae5SSrikanth Yalavarthi 28550513ae5SSrikanth Yalavarthi return 0; 28650513ae5SSrikanth Yalavarthi } 28750513ae5SSrikanth Yalavarthi 28850513ae5SSrikanth Yalavarthi int 289*65282e9fSSrikanth Yalavarthi rte_ml_io_float32_to_uint32(const void *input, void *output, uint64_t nb_elements, float scale, 290*65282e9fSSrikanth Yalavarthi uint32_t zero_point) 29150513ae5SSrikanth Yalavarthi { 292*65282e9fSSrikanth Yalavarthi const float *input_buffer; 29350513ae5SSrikanth Yalavarthi uint32_t *output_buffer; 29450513ae5SSrikanth Yalavarthi int32_t i32; 29550513ae5SSrikanth Yalavarthi uint64_t i; 29650513ae5SSrikanth Yalavarthi 29750513ae5SSrikanth Yalavarthi if ((scale == 0) || (nb_elements == 0) || (input == NULL) || (output == NULL)) 29850513ae5SSrikanth Yalavarthi return -EINVAL; 29950513ae5SSrikanth Yalavarthi 300*65282e9fSSrikanth Yalavarthi input_buffer = (const float *)input; 30150513ae5SSrikanth Yalavarthi output_buffer = (uint32_t *)output; 30250513ae5SSrikanth Yalavarthi 30350513ae5SSrikanth Yalavarthi for (i = 0; i < nb_elements; i++) { 304*65282e9fSSrikanth Yalavarthi i32 = (int32_t)(round(*input_buffer / scale) + zero_point); 30550513ae5SSrikanth Yalavarthi 30650513ae5SSrikanth Yalavarthi if (i32 < 0) 30750513ae5SSrikanth Yalavarthi i32 = 0; 30850513ae5SSrikanth Yalavarthi 30950513ae5SSrikanth Yalavarthi *output_buffer = (uint32_t)i32; 31050513ae5SSrikanth Yalavarthi 31150513ae5SSrikanth Yalavarthi input_buffer++; 31250513ae5SSrikanth Yalavarthi output_buffer++; 31350513ae5SSrikanth Yalavarthi } 31450513ae5SSrikanth Yalavarthi 31550513ae5SSrikanth Yalavarthi return 0; 31650513ae5SSrikanth Yalavarthi } 31750513ae5SSrikanth Yalavarthi 31850513ae5SSrikanth Yalavarthi int 319*65282e9fSSrikanth Yalavarthi rte_ml_io_uint32_to_float32(const void *input, void *output, uint64_t nb_elements, float scale, 320*65282e9fSSrikanth Yalavarthi uint32_t zero_point) 32150513ae5SSrikanth Yalavarthi { 322*65282e9fSSrikanth Yalavarthi const uint32_t *input_buffer; 32350513ae5SSrikanth Yalavarthi float *output_buffer; 32450513ae5SSrikanth Yalavarthi uint64_t i; 32550513ae5SSrikanth Yalavarthi 32650513ae5SSrikanth Yalavarthi if ((scale == 0) || (nb_elements == 0) || (input == NULL) || (output == NULL)) 32750513ae5SSrikanth Yalavarthi return -EINVAL; 32850513ae5SSrikanth Yalavarthi 329*65282e9fSSrikanth Yalavarthi input_buffer = (const uint32_t *)input; 33050513ae5SSrikanth Yalavarthi output_buffer = (float *)output; 33150513ae5SSrikanth Yalavarthi 33250513ae5SSrikanth Yalavarthi for (i = 0; i < nb_elements; i++) { 333*65282e9fSSrikanth Yalavarthi *output_buffer = scale * (float)(*input_buffer - zero_point); 33450513ae5SSrikanth Yalavarthi 33550513ae5SSrikanth Yalavarthi input_buffer++; 33650513ae5SSrikanth Yalavarthi output_buffer++; 33750513ae5SSrikanth Yalavarthi } 33850513ae5SSrikanth Yalavarthi 33950513ae5SSrikanth Yalavarthi return 0; 34050513ae5SSrikanth Yalavarthi } 34150513ae5SSrikanth Yalavarthi 34242f3dcd9SSrikanth Yalavarthi int 343*65282e9fSSrikanth Yalavarthi rte_ml_io_float32_to_int64(const void *input, void *output, uint64_t nb_elements, float scale, 344*65282e9fSSrikanth Yalavarthi int64_t zero_point) 34542f3dcd9SSrikanth Yalavarthi { 346*65282e9fSSrikanth Yalavarthi const float *input_buffer; 34742f3dcd9SSrikanth Yalavarthi int64_t *output_buffer; 34842f3dcd9SSrikanth Yalavarthi uint64_t i; 34942f3dcd9SSrikanth Yalavarthi 35042f3dcd9SSrikanth Yalavarthi if ((scale == 0) || (nb_elements == 0) || (input == NULL) || (output == NULL)) 35142f3dcd9SSrikanth Yalavarthi return -EINVAL; 35242f3dcd9SSrikanth Yalavarthi 353*65282e9fSSrikanth Yalavarthi input_buffer = (const float *)input; 35442f3dcd9SSrikanth Yalavarthi output_buffer = (int64_t *)output; 35542f3dcd9SSrikanth Yalavarthi 35642f3dcd9SSrikanth Yalavarthi for (i = 0; i < nb_elements; i++) { 357*65282e9fSSrikanth Yalavarthi *output_buffer = (int64_t)(round(*input_buffer / scale) + zero_point); 35842f3dcd9SSrikanth Yalavarthi 35942f3dcd9SSrikanth Yalavarthi input_buffer++; 36042f3dcd9SSrikanth Yalavarthi output_buffer++; 36142f3dcd9SSrikanth Yalavarthi } 36242f3dcd9SSrikanth Yalavarthi 36342f3dcd9SSrikanth Yalavarthi return 0; 36442f3dcd9SSrikanth Yalavarthi } 36542f3dcd9SSrikanth Yalavarthi 36642f3dcd9SSrikanth Yalavarthi int 367*65282e9fSSrikanth Yalavarthi rte_ml_io_int64_to_float32(const void *input, void *output, uint64_t nb_elements, float scale, 368*65282e9fSSrikanth Yalavarthi int64_t zero_point) 36942f3dcd9SSrikanth Yalavarthi { 370*65282e9fSSrikanth Yalavarthi const int64_t *input_buffer; 37142f3dcd9SSrikanth Yalavarthi float *output_buffer; 37242f3dcd9SSrikanth Yalavarthi uint64_t i; 37342f3dcd9SSrikanth Yalavarthi 37442f3dcd9SSrikanth Yalavarthi if ((scale == 0) || (nb_elements == 0) || (input == NULL) || (output == NULL)) 37542f3dcd9SSrikanth Yalavarthi return -EINVAL; 37642f3dcd9SSrikanth Yalavarthi 377*65282e9fSSrikanth Yalavarthi input_buffer = (const int64_t *)input; 37842f3dcd9SSrikanth Yalavarthi output_buffer = (float *)output; 37942f3dcd9SSrikanth Yalavarthi 38042f3dcd9SSrikanth Yalavarthi for (i = 0; i < nb_elements; i++) { 381*65282e9fSSrikanth Yalavarthi *output_buffer = scale * (float)(*input_buffer - zero_point); 38242f3dcd9SSrikanth Yalavarthi 38342f3dcd9SSrikanth Yalavarthi input_buffer++; 38442f3dcd9SSrikanth Yalavarthi output_buffer++; 38542f3dcd9SSrikanth Yalavarthi } 38642f3dcd9SSrikanth Yalavarthi 38742f3dcd9SSrikanth Yalavarthi return 0; 38842f3dcd9SSrikanth Yalavarthi } 38942f3dcd9SSrikanth Yalavarthi 39042f3dcd9SSrikanth Yalavarthi int 391*65282e9fSSrikanth Yalavarthi rte_ml_io_float32_to_uint64(const void *input, void *output, uint64_t nb_elements, float scale, 392*65282e9fSSrikanth Yalavarthi uint64_t zero_point) 39342f3dcd9SSrikanth Yalavarthi { 394*65282e9fSSrikanth Yalavarthi const float *input_buffer; 39542f3dcd9SSrikanth Yalavarthi uint64_t *output_buffer; 39642f3dcd9SSrikanth Yalavarthi int64_t i64; 39742f3dcd9SSrikanth Yalavarthi uint64_t i; 39842f3dcd9SSrikanth Yalavarthi 39942f3dcd9SSrikanth Yalavarthi if ((scale == 0) || (nb_elements == 0) || (input == NULL) || (output == NULL)) 40042f3dcd9SSrikanth Yalavarthi return -EINVAL; 40142f3dcd9SSrikanth Yalavarthi 402*65282e9fSSrikanth Yalavarthi input_buffer = (const float *)input; 40342f3dcd9SSrikanth Yalavarthi output_buffer = (uint64_t *)output; 40442f3dcd9SSrikanth Yalavarthi 40542f3dcd9SSrikanth Yalavarthi for (i = 0; i < nb_elements; i++) { 406*65282e9fSSrikanth Yalavarthi i64 = (int64_t)(round(*input_buffer / scale) + zero_point); 40742f3dcd9SSrikanth Yalavarthi 40842f3dcd9SSrikanth Yalavarthi if (i64 < 0) 40942f3dcd9SSrikanth Yalavarthi i64 = 0; 41042f3dcd9SSrikanth Yalavarthi 41142f3dcd9SSrikanth Yalavarthi *output_buffer = (uint64_t)i64; 41242f3dcd9SSrikanth Yalavarthi 41342f3dcd9SSrikanth Yalavarthi input_buffer++; 41442f3dcd9SSrikanth Yalavarthi output_buffer++; 41542f3dcd9SSrikanth Yalavarthi } 41642f3dcd9SSrikanth Yalavarthi 41742f3dcd9SSrikanth Yalavarthi return 0; 41842f3dcd9SSrikanth Yalavarthi } 41942f3dcd9SSrikanth Yalavarthi 42042f3dcd9SSrikanth Yalavarthi int 421*65282e9fSSrikanth Yalavarthi rte_ml_io_uint64_to_float32(const void *input, void *output, uint64_t nb_elements, float scale, 422*65282e9fSSrikanth Yalavarthi uint64_t zero_point) 42342f3dcd9SSrikanth Yalavarthi { 424*65282e9fSSrikanth Yalavarthi const uint64_t *input_buffer; 42542f3dcd9SSrikanth Yalavarthi float *output_buffer; 42642f3dcd9SSrikanth Yalavarthi uint64_t i; 42742f3dcd9SSrikanth Yalavarthi 42842f3dcd9SSrikanth Yalavarthi if ((scale == 0) || (nb_elements == 0) || (input == NULL) || (output == NULL)) 42942f3dcd9SSrikanth Yalavarthi return -EINVAL; 43042f3dcd9SSrikanth Yalavarthi 431*65282e9fSSrikanth Yalavarthi input_buffer = (const uint64_t *)input; 43242f3dcd9SSrikanth Yalavarthi output_buffer = (float *)output; 43342f3dcd9SSrikanth Yalavarthi 43442f3dcd9SSrikanth Yalavarthi for (i = 0; i < nb_elements; i++) { 435*65282e9fSSrikanth Yalavarthi *output_buffer = scale * (float)(*input_buffer - zero_point); 43642f3dcd9SSrikanth Yalavarthi 43742f3dcd9SSrikanth Yalavarthi input_buffer++; 43842f3dcd9SSrikanth Yalavarthi output_buffer++; 43942f3dcd9SSrikanth Yalavarthi } 44042f3dcd9SSrikanth Yalavarthi 44142f3dcd9SSrikanth Yalavarthi return 0; 44242f3dcd9SSrikanth Yalavarthi } 44342f3dcd9SSrikanth Yalavarthi 4449637de38SSrikanth Yalavarthi /* Convert a single precision floating point number (float32) into a half precision 4459637de38SSrikanth Yalavarthi * floating point number (float16) using round to nearest rounding mode. 4469637de38SSrikanth Yalavarthi */ 4479637de38SSrikanth Yalavarthi static uint16_t 4489637de38SSrikanth Yalavarthi __float32_to_float16_scalar_rtn(float x) 4499637de38SSrikanth Yalavarthi { 4509637de38SSrikanth Yalavarthi union float32 f32; /* float32 input */ 4519637de38SSrikanth Yalavarthi uint32_t f32_s; /* float32 sign */ 4529637de38SSrikanth Yalavarthi uint32_t f32_e; /* float32 exponent */ 4539637de38SSrikanth Yalavarthi uint32_t f32_m; /* float32 mantissa */ 4549637de38SSrikanth Yalavarthi uint16_t f16_s; /* float16 sign */ 4559637de38SSrikanth Yalavarthi uint16_t f16_e; /* float16 exponent */ 4569637de38SSrikanth Yalavarthi uint16_t f16_m; /* float16 mantissa */ 4579637de38SSrikanth Yalavarthi uint32_t tbits; /* number of truncated bits */ 4589637de38SSrikanth Yalavarthi uint32_t tmsb; /* MSB position of truncated bits */ 4599637de38SSrikanth Yalavarthi uint32_t m_32; /* temporary float32 mantissa */ 4609637de38SSrikanth Yalavarthi uint16_t m_16; /* temporary float16 mantissa */ 4619637de38SSrikanth Yalavarthi uint16_t u16; /* float16 output */ 4629637de38SSrikanth Yalavarthi int be_16; /* float16 biased exponent, signed */ 4639637de38SSrikanth Yalavarthi 4649637de38SSrikanth Yalavarthi f32.f = x; 4659637de38SSrikanth Yalavarthi f32_s = (f32.u & FP32_MASK_S) >> FP32_LSB_S; 4669637de38SSrikanth Yalavarthi f32_e = (f32.u & FP32_MASK_E) >> FP32_LSB_E; 4679637de38SSrikanth Yalavarthi f32_m = (f32.u & FP32_MASK_M) >> FP32_LSB_M; 4689637de38SSrikanth Yalavarthi 4699637de38SSrikanth Yalavarthi f16_s = f32_s; 4709637de38SSrikanth Yalavarthi f16_e = 0; 4719637de38SSrikanth Yalavarthi f16_m = 0; 4729637de38SSrikanth Yalavarthi 4739637de38SSrikanth Yalavarthi switch (f32_e) { 4749637de38SSrikanth Yalavarthi case (0): /* float32: zero or subnormal number */ 4759637de38SSrikanth Yalavarthi f16_e = 0; 476f71c5365SSrikanth Yalavarthi f16_m = 0; /* convert to zero */ 4779637de38SSrikanth Yalavarthi break; 4789637de38SSrikanth Yalavarthi case (FP32_MASK_E >> FP32_LSB_E): /* float32: infinity or nan */ 4799637de38SSrikanth Yalavarthi f16_e = FP16_MASK_E >> FP16_LSB_E; 4809637de38SSrikanth Yalavarthi if (f32_m == 0) { /* infinity */ 4819637de38SSrikanth Yalavarthi f16_m = 0; 4829637de38SSrikanth Yalavarthi } else { /* nan, propagate mantissa and set MSB of mantissa to 1 */ 4839637de38SSrikanth Yalavarthi f16_m = f32_m >> (FP32_MSB_M - FP16_MSB_M); 4849637de38SSrikanth Yalavarthi f16_m |= BIT(FP16_MSB_M); 4859637de38SSrikanth Yalavarthi } 4869637de38SSrikanth Yalavarthi break; 4879637de38SSrikanth Yalavarthi default: /* float32: normal number */ 4889637de38SSrikanth Yalavarthi /* compute biased exponent for float16 */ 4899637de38SSrikanth Yalavarthi be_16 = (int)f32_e - FP32_BIAS_E + FP16_BIAS_E; 4909637de38SSrikanth Yalavarthi 4919637de38SSrikanth Yalavarthi /* overflow, be_16 = [31-INF], set to infinity */ 4929637de38SSrikanth Yalavarthi if (be_16 >= (int)(FP16_MASK_E >> FP16_LSB_E)) { 4939637de38SSrikanth Yalavarthi f16_e = FP16_MASK_E >> FP16_LSB_E; 4949637de38SSrikanth Yalavarthi f16_m = 0; 4959637de38SSrikanth Yalavarthi } else if ((be_16 >= 1) && (be_16 < (int)(FP16_MASK_E >> FP16_LSB_E))) { 4969637de38SSrikanth Yalavarthi /* normal float16, be_16 = [1:30]*/ 4979637de38SSrikanth Yalavarthi f16_e = be_16; 4989637de38SSrikanth Yalavarthi m_16 = f32_m >> (FP32_LSB_E - FP16_LSB_E); 4999637de38SSrikanth Yalavarthi tmsb = FP32_MSB_M - FP16_MSB_M - 1; 5009637de38SSrikanth Yalavarthi if ((f32_m & GENMASK_U32(tmsb, 0)) > BIT(tmsb)) { 5019637de38SSrikanth Yalavarthi /* round: non-zero truncated bits except MSB */ 5029637de38SSrikanth Yalavarthi m_16++; 5039637de38SSrikanth Yalavarthi 5049637de38SSrikanth Yalavarthi /* overflow into exponent */ 5059637de38SSrikanth Yalavarthi if (((m_16 & FP16_MASK_E) >> FP16_LSB_E) == 0x1) 5069637de38SSrikanth Yalavarthi f16_e++; 5079637de38SSrikanth Yalavarthi } else if ((f32_m & GENMASK_U32(tmsb, 0)) == BIT(tmsb)) { 5089637de38SSrikanth Yalavarthi /* round: MSB of truncated bits and LSB of m_16 is set */ 5099637de38SSrikanth Yalavarthi if ((m_16 & 0x1) == 0x1) { 5109637de38SSrikanth Yalavarthi m_16++; 5119637de38SSrikanth Yalavarthi 5129637de38SSrikanth Yalavarthi /* overflow into exponent */ 5139637de38SSrikanth Yalavarthi if (((m_16 & FP16_MASK_E) >> FP16_LSB_E) == 0x1) 5149637de38SSrikanth Yalavarthi f16_e++; 5159637de38SSrikanth Yalavarthi } 5169637de38SSrikanth Yalavarthi } 5179637de38SSrikanth Yalavarthi f16_m = m_16 & FP16_MASK_M; 5189637de38SSrikanth Yalavarthi } else if ((be_16 >= -(int)(FP16_MSB_M)) && (be_16 < 1)) { 5199637de38SSrikanth Yalavarthi /* underflow: zero / subnormal, be_16 = [-9:0] */ 5209637de38SSrikanth Yalavarthi f16_e = 0; 5219637de38SSrikanth Yalavarthi 5229637de38SSrikanth Yalavarthi /* add implicit leading zero */ 5239637de38SSrikanth Yalavarthi m_32 = f32_m | BIT(FP32_LSB_E); 5249637de38SSrikanth Yalavarthi tbits = FP32_LSB_E - FP16_LSB_E - be_16 + 1; 5259637de38SSrikanth Yalavarthi m_16 = m_32 >> tbits; 5269637de38SSrikanth Yalavarthi 5279637de38SSrikanth Yalavarthi /* if non-leading truncated bits are set */ 5289637de38SSrikanth Yalavarthi if ((f32_m & GENMASK_U32(tbits - 1, 0)) > BIT(tbits - 1)) { 5299637de38SSrikanth Yalavarthi m_16++; 5309637de38SSrikanth Yalavarthi 5319637de38SSrikanth Yalavarthi /* overflow into exponent */ 5329637de38SSrikanth Yalavarthi if (((m_16 & FP16_MASK_E) >> FP16_LSB_E) == 0x1) 5339637de38SSrikanth Yalavarthi f16_e++; 5349637de38SSrikanth Yalavarthi } else if ((f32_m & GENMASK_U32(tbits - 1, 0)) == BIT(tbits - 1)) { 5359637de38SSrikanth Yalavarthi /* if leading truncated bit is set */ 5369637de38SSrikanth Yalavarthi if ((m_16 & 0x1) == 0x1) { 5379637de38SSrikanth Yalavarthi m_16++; 5389637de38SSrikanth Yalavarthi 5399637de38SSrikanth Yalavarthi /* overflow into exponent */ 5409637de38SSrikanth Yalavarthi if (((m_16 & FP16_MASK_E) >> FP16_LSB_E) == 0x1) 5419637de38SSrikanth Yalavarthi f16_e++; 5429637de38SSrikanth Yalavarthi } 5439637de38SSrikanth Yalavarthi } 5449637de38SSrikanth Yalavarthi f16_m = m_16 & FP16_MASK_M; 5459637de38SSrikanth Yalavarthi } else if (be_16 == -(int)(FP16_MSB_M + 1)) { 5469637de38SSrikanth Yalavarthi /* underflow: zero, be_16 = [-10] */ 5479637de38SSrikanth Yalavarthi f16_e = 0; 5489637de38SSrikanth Yalavarthi if (f32_m != 0) 5499637de38SSrikanth Yalavarthi f16_m = 1; 5509637de38SSrikanth Yalavarthi else 5519637de38SSrikanth Yalavarthi f16_m = 0; 5529637de38SSrikanth Yalavarthi } else { 5539637de38SSrikanth Yalavarthi /* underflow: zero, be_16 = [-INF:-11] */ 5549637de38SSrikanth Yalavarthi f16_e = 0; 5559637de38SSrikanth Yalavarthi f16_m = 0; 5569637de38SSrikanth Yalavarthi } 5579637de38SSrikanth Yalavarthi 5589637de38SSrikanth Yalavarthi break; 5599637de38SSrikanth Yalavarthi } 5609637de38SSrikanth Yalavarthi 5619637de38SSrikanth Yalavarthi u16 = FP16_PACK(f16_s, f16_e, f16_m); 5629637de38SSrikanth Yalavarthi 5639637de38SSrikanth Yalavarthi return u16; 5649637de38SSrikanth Yalavarthi } 5659637de38SSrikanth Yalavarthi 5668c9bfcb1SSrikanth Yalavarthi int 567*65282e9fSSrikanth Yalavarthi rte_ml_io_float32_to_float16(const void *input, void *output, uint64_t nb_elements) 5689637de38SSrikanth Yalavarthi { 569*65282e9fSSrikanth Yalavarthi const float *input_buffer; 5709637de38SSrikanth Yalavarthi uint16_t *output_buffer; 5719637de38SSrikanth Yalavarthi uint64_t i; 5729637de38SSrikanth Yalavarthi 5739637de38SSrikanth Yalavarthi if ((nb_elements == 0) || (input == NULL) || (output == NULL)) 5749637de38SSrikanth Yalavarthi return -EINVAL; 5759637de38SSrikanth Yalavarthi 576*65282e9fSSrikanth Yalavarthi input_buffer = (const float *)input; 5779637de38SSrikanth Yalavarthi output_buffer = (uint16_t *)output; 5789637de38SSrikanth Yalavarthi 5799637de38SSrikanth Yalavarthi for (i = 0; i < nb_elements; i++) { 5809637de38SSrikanth Yalavarthi *output_buffer = __float32_to_float16_scalar_rtn(*input_buffer); 5819637de38SSrikanth Yalavarthi 5829637de38SSrikanth Yalavarthi input_buffer = input_buffer + 1; 5839637de38SSrikanth Yalavarthi output_buffer = output_buffer + 1; 5849637de38SSrikanth Yalavarthi } 5859637de38SSrikanth Yalavarthi 5869637de38SSrikanth Yalavarthi return 0; 5879637de38SSrikanth Yalavarthi } 5889637de38SSrikanth Yalavarthi 5899637de38SSrikanth Yalavarthi /* Convert a half precision floating point number (float16) into a single precision 5909637de38SSrikanth Yalavarthi * floating point number (float32). 5919637de38SSrikanth Yalavarthi */ 5929637de38SSrikanth Yalavarthi static float 5939637de38SSrikanth Yalavarthi __float16_to_float32_scalar_rtx(uint16_t f16) 5949637de38SSrikanth Yalavarthi { 5959637de38SSrikanth Yalavarthi union float32 f32; /* float32 output */ 5969637de38SSrikanth Yalavarthi uint16_t f16_s; /* float16 sign */ 5979637de38SSrikanth Yalavarthi uint16_t f16_e; /* float16 exponent */ 5989637de38SSrikanth Yalavarthi uint16_t f16_m; /* float16 mantissa */ 5999637de38SSrikanth Yalavarthi uint32_t f32_s; /* float32 sign */ 6009637de38SSrikanth Yalavarthi uint32_t f32_e; /* float32 exponent */ 6019637de38SSrikanth Yalavarthi uint32_t f32_m; /* float32 mantissa*/ 6029637de38SSrikanth Yalavarthi uint8_t shift; /* number of bits to be shifted */ 6039637de38SSrikanth Yalavarthi uint32_t clz; /* count of leading zeroes */ 6049637de38SSrikanth Yalavarthi int e_16; /* float16 exponent unbiased */ 6059637de38SSrikanth Yalavarthi 6069637de38SSrikanth Yalavarthi f16_s = (f16 & FP16_MASK_S) >> FP16_LSB_S; 6079637de38SSrikanth Yalavarthi f16_e = (f16 & FP16_MASK_E) >> FP16_LSB_E; 6089637de38SSrikanth Yalavarthi f16_m = (f16 & FP16_MASK_M) >> FP16_LSB_M; 6099637de38SSrikanth Yalavarthi 6109637de38SSrikanth Yalavarthi f32_s = f16_s; 6119637de38SSrikanth Yalavarthi switch (f16_e) { 6129637de38SSrikanth Yalavarthi case (FP16_MASK_E >> FP16_LSB_E): /* float16: infinity or nan */ 6139637de38SSrikanth Yalavarthi f32_e = FP32_MASK_E >> FP32_LSB_E; 6149637de38SSrikanth Yalavarthi if (f16_m == 0x0) { /* infinity */ 6159637de38SSrikanth Yalavarthi f32_m = f16_m; 6169637de38SSrikanth Yalavarthi } else { /* nan, propagate mantissa, set MSB of mantissa to 1 */ 6179637de38SSrikanth Yalavarthi f32_m = f16_m; 6189637de38SSrikanth Yalavarthi shift = FP32_MSB_M - FP16_MSB_M; 6199637de38SSrikanth Yalavarthi f32_m = (f32_m << shift) & FP32_MASK_M; 6209637de38SSrikanth Yalavarthi f32_m |= BIT(FP32_MSB_M); 6219637de38SSrikanth Yalavarthi } 6229637de38SSrikanth Yalavarthi break; 6239637de38SSrikanth Yalavarthi case 0: /* float16: zero or sub-normal */ 6249637de38SSrikanth Yalavarthi f32_m = f16_m; 6259637de38SSrikanth Yalavarthi if (f16_m == 0) { /* zero signed */ 6269637de38SSrikanth Yalavarthi f32_e = 0; 6279637de38SSrikanth Yalavarthi } else { /* subnormal numbers */ 6283d4e27fdSDavid Marchand clz = rte_clz32((uint32_t)f16_m) - sizeof(uint32_t) * 8 + FP16_LSB_E; 6299637de38SSrikanth Yalavarthi e_16 = (int)f16_e - clz; 6309637de38SSrikanth Yalavarthi f32_e = FP32_BIAS_E + e_16 - FP16_BIAS_E; 6319637de38SSrikanth Yalavarthi 6329637de38SSrikanth Yalavarthi shift = clz + (FP32_MSB_M - FP16_MSB_M) + 1; 6339637de38SSrikanth Yalavarthi f32_m = (f32_m << shift) & FP32_MASK_M; 6349637de38SSrikanth Yalavarthi } 6359637de38SSrikanth Yalavarthi break; 6369637de38SSrikanth Yalavarthi default: /* normal numbers */ 6379637de38SSrikanth Yalavarthi f32_m = f16_m; 6389637de38SSrikanth Yalavarthi e_16 = (int)f16_e; 6399637de38SSrikanth Yalavarthi f32_e = FP32_BIAS_E + e_16 - FP16_BIAS_E; 6409637de38SSrikanth Yalavarthi 6419637de38SSrikanth Yalavarthi shift = (FP32_MSB_M - FP16_MSB_M); 6429637de38SSrikanth Yalavarthi f32_m = (f32_m << shift) & FP32_MASK_M; 6439637de38SSrikanth Yalavarthi } 6449637de38SSrikanth Yalavarthi 6459637de38SSrikanth Yalavarthi f32.u = FP32_PACK(f32_s, f32_e, f32_m); 6469637de38SSrikanth Yalavarthi 6479637de38SSrikanth Yalavarthi return f32.f; 6489637de38SSrikanth Yalavarthi } 6499637de38SSrikanth Yalavarthi 6508c9bfcb1SSrikanth Yalavarthi int 651*65282e9fSSrikanth Yalavarthi rte_ml_io_float16_to_float32(const void *input, void *output, uint64_t nb_elements) 6529637de38SSrikanth Yalavarthi { 653*65282e9fSSrikanth Yalavarthi const uint16_t *input_buffer; 6549637de38SSrikanth Yalavarthi float *output_buffer; 6559637de38SSrikanth Yalavarthi uint64_t i; 6569637de38SSrikanth Yalavarthi 6579637de38SSrikanth Yalavarthi if ((nb_elements == 0) || (input == NULL) || (output == NULL)) 6589637de38SSrikanth Yalavarthi return -EINVAL; 6599637de38SSrikanth Yalavarthi 660*65282e9fSSrikanth Yalavarthi input_buffer = (const uint16_t *)input; 6619637de38SSrikanth Yalavarthi output_buffer = (float *)output; 6629637de38SSrikanth Yalavarthi 6639637de38SSrikanth Yalavarthi for (i = 0; i < nb_elements; i++) { 6649637de38SSrikanth Yalavarthi *output_buffer = __float16_to_float32_scalar_rtx(*input_buffer); 6659637de38SSrikanth Yalavarthi 6669637de38SSrikanth Yalavarthi input_buffer = input_buffer + 1; 6679637de38SSrikanth Yalavarthi output_buffer = output_buffer + 1; 6689637de38SSrikanth Yalavarthi } 6699637de38SSrikanth Yalavarthi 6709637de38SSrikanth Yalavarthi return 0; 6719637de38SSrikanth Yalavarthi } 672