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 139637de38SSrikanth Yalavarthi rte_ml_io_float32_to_int8(float scale, uint64_t nb_elements, void *input, void *output) 149637de38SSrikanth Yalavarthi { 159637de38SSrikanth Yalavarthi float *input_buffer; 169637de38SSrikanth Yalavarthi int8_t *output_buffer; 179637de38SSrikanth Yalavarthi uint64_t i; 189637de38SSrikanth Yalavarthi int i32; 199637de38SSrikanth Yalavarthi 209637de38SSrikanth Yalavarthi if ((scale == 0) || (nb_elements == 0) || (input == NULL) || (output == NULL)) 219637de38SSrikanth Yalavarthi return -EINVAL; 229637de38SSrikanth Yalavarthi 239637de38SSrikanth Yalavarthi input_buffer = (float *)input; 249637de38SSrikanth Yalavarthi output_buffer = (int8_t *)output; 259637de38SSrikanth Yalavarthi 269637de38SSrikanth Yalavarthi for (i = 0; i < nb_elements; i++) { 279637de38SSrikanth Yalavarthi i32 = (int32_t)round((*input_buffer) * scale); 289637de38SSrikanth Yalavarthi 299637de38SSrikanth Yalavarthi if (i32 < INT8_MIN) 309637de38SSrikanth Yalavarthi i32 = INT8_MIN; 319637de38SSrikanth Yalavarthi 329637de38SSrikanth Yalavarthi if (i32 > INT8_MAX) 339637de38SSrikanth Yalavarthi i32 = INT8_MAX; 349637de38SSrikanth Yalavarthi 359637de38SSrikanth Yalavarthi *output_buffer = (int8_t)i32; 369637de38SSrikanth Yalavarthi 379637de38SSrikanth Yalavarthi input_buffer++; 389637de38SSrikanth Yalavarthi output_buffer++; 399637de38SSrikanth Yalavarthi } 409637de38SSrikanth Yalavarthi 419637de38SSrikanth Yalavarthi return 0; 429637de38SSrikanth Yalavarthi } 439637de38SSrikanth Yalavarthi 448c9bfcb1SSrikanth Yalavarthi int 459637de38SSrikanth Yalavarthi rte_ml_io_int8_to_float32(float scale, uint64_t nb_elements, void *input, void *output) 469637de38SSrikanth Yalavarthi { 479637de38SSrikanth Yalavarthi int8_t *input_buffer; 489637de38SSrikanth Yalavarthi float *output_buffer; 499637de38SSrikanth Yalavarthi uint64_t i; 509637de38SSrikanth Yalavarthi 519637de38SSrikanth Yalavarthi if ((scale == 0) || (nb_elements == 0) || (input == NULL) || (output == NULL)) 529637de38SSrikanth Yalavarthi return -EINVAL; 539637de38SSrikanth Yalavarthi 549637de38SSrikanth Yalavarthi input_buffer = (int8_t *)input; 559637de38SSrikanth Yalavarthi output_buffer = (float *)output; 569637de38SSrikanth Yalavarthi 579637de38SSrikanth Yalavarthi for (i = 0; i < nb_elements; i++) { 589637de38SSrikanth Yalavarthi *output_buffer = scale * (float)(*input_buffer); 599637de38SSrikanth Yalavarthi 609637de38SSrikanth Yalavarthi input_buffer++; 619637de38SSrikanth Yalavarthi output_buffer++; 629637de38SSrikanth Yalavarthi } 639637de38SSrikanth Yalavarthi 649637de38SSrikanth Yalavarthi return 0; 659637de38SSrikanth Yalavarthi } 669637de38SSrikanth Yalavarthi 678c9bfcb1SSrikanth Yalavarthi int 689637de38SSrikanth Yalavarthi rte_ml_io_float32_to_uint8(float scale, uint64_t nb_elements, void *input, void *output) 699637de38SSrikanth Yalavarthi { 709637de38SSrikanth Yalavarthi float *input_buffer; 719637de38SSrikanth Yalavarthi uint8_t *output_buffer; 729637de38SSrikanth Yalavarthi int32_t i32; 739637de38SSrikanth Yalavarthi uint64_t i; 749637de38SSrikanth Yalavarthi 759637de38SSrikanth Yalavarthi if ((scale == 0) || (nb_elements == 0) || (input == NULL) || (output == NULL)) 769637de38SSrikanth Yalavarthi return -EINVAL; 779637de38SSrikanth Yalavarthi 789637de38SSrikanth Yalavarthi input_buffer = (float *)input; 799637de38SSrikanth Yalavarthi output_buffer = (uint8_t *)output; 809637de38SSrikanth Yalavarthi 819637de38SSrikanth Yalavarthi for (i = 0; i < nb_elements; i++) { 829637de38SSrikanth Yalavarthi i32 = (int32_t)round((*input_buffer) * scale); 839637de38SSrikanth Yalavarthi 849637de38SSrikanth Yalavarthi if (i32 < 0) 859637de38SSrikanth Yalavarthi i32 = 0; 869637de38SSrikanth Yalavarthi 879637de38SSrikanth Yalavarthi if (i32 > UINT8_MAX) 889637de38SSrikanth Yalavarthi i32 = UINT8_MAX; 899637de38SSrikanth Yalavarthi 909637de38SSrikanth Yalavarthi *output_buffer = (uint8_t)i32; 919637de38SSrikanth Yalavarthi 929637de38SSrikanth Yalavarthi input_buffer++; 939637de38SSrikanth Yalavarthi output_buffer++; 949637de38SSrikanth Yalavarthi } 959637de38SSrikanth Yalavarthi 969637de38SSrikanth Yalavarthi return 0; 979637de38SSrikanth Yalavarthi } 989637de38SSrikanth Yalavarthi 998c9bfcb1SSrikanth Yalavarthi int 1009637de38SSrikanth Yalavarthi rte_ml_io_uint8_to_float32(float scale, uint64_t nb_elements, void *input, void *output) 1019637de38SSrikanth Yalavarthi { 1029637de38SSrikanth Yalavarthi uint8_t *input_buffer; 1039637de38SSrikanth Yalavarthi float *output_buffer; 1049637de38SSrikanth Yalavarthi uint64_t i; 1059637de38SSrikanth Yalavarthi 1069637de38SSrikanth Yalavarthi if ((scale == 0) || (nb_elements == 0) || (input == NULL) || (output == NULL)) 1079637de38SSrikanth Yalavarthi return -EINVAL; 1089637de38SSrikanth Yalavarthi 1099637de38SSrikanth Yalavarthi input_buffer = (uint8_t *)input; 1109637de38SSrikanth Yalavarthi output_buffer = (float *)output; 1119637de38SSrikanth Yalavarthi 1129637de38SSrikanth Yalavarthi for (i = 0; i < nb_elements; i++) { 1139637de38SSrikanth Yalavarthi *output_buffer = scale * (float)(*input_buffer); 1149637de38SSrikanth Yalavarthi 1159637de38SSrikanth Yalavarthi input_buffer++; 1169637de38SSrikanth Yalavarthi output_buffer++; 1179637de38SSrikanth Yalavarthi } 1189637de38SSrikanth Yalavarthi 1199637de38SSrikanth Yalavarthi return 0; 1209637de38SSrikanth Yalavarthi } 1219637de38SSrikanth Yalavarthi 1228c9bfcb1SSrikanth Yalavarthi int 1239637de38SSrikanth Yalavarthi rte_ml_io_float32_to_int16(float scale, uint64_t nb_elements, void *input, void *output) 1249637de38SSrikanth Yalavarthi { 1259637de38SSrikanth Yalavarthi float *input_buffer; 1269637de38SSrikanth Yalavarthi int16_t *output_buffer; 1279637de38SSrikanth Yalavarthi int32_t i32; 1289637de38SSrikanth Yalavarthi uint64_t i; 1299637de38SSrikanth Yalavarthi 1309637de38SSrikanth Yalavarthi if ((scale == 0) || (nb_elements == 0) || (input == NULL) || (output == NULL)) 1319637de38SSrikanth Yalavarthi return -EINVAL; 1329637de38SSrikanth Yalavarthi 1339637de38SSrikanth Yalavarthi input_buffer = (float *)input; 1349637de38SSrikanth Yalavarthi output_buffer = (int16_t *)output; 1359637de38SSrikanth Yalavarthi 1369637de38SSrikanth Yalavarthi for (i = 0; i < nb_elements; i++) { 1379637de38SSrikanth Yalavarthi i32 = (int32_t)round((*input_buffer) * scale); 1389637de38SSrikanth Yalavarthi 1399637de38SSrikanth Yalavarthi if (i32 < INT16_MIN) 1409637de38SSrikanth Yalavarthi i32 = INT16_MIN; 1419637de38SSrikanth Yalavarthi 1429637de38SSrikanth Yalavarthi if (i32 > INT16_MAX) 1439637de38SSrikanth Yalavarthi i32 = INT16_MAX; 1449637de38SSrikanth Yalavarthi 1459637de38SSrikanth Yalavarthi *output_buffer = (int16_t)i32; 1469637de38SSrikanth Yalavarthi 1479637de38SSrikanth Yalavarthi input_buffer++; 1489637de38SSrikanth Yalavarthi output_buffer++; 1499637de38SSrikanth Yalavarthi } 1509637de38SSrikanth Yalavarthi 1519637de38SSrikanth Yalavarthi return 0; 1529637de38SSrikanth Yalavarthi } 1539637de38SSrikanth Yalavarthi 1548c9bfcb1SSrikanth Yalavarthi int 1559637de38SSrikanth Yalavarthi rte_ml_io_int16_to_float32(float scale, uint64_t nb_elements, void *input, void *output) 1569637de38SSrikanth Yalavarthi { 1579637de38SSrikanth Yalavarthi int16_t *input_buffer; 1589637de38SSrikanth Yalavarthi float *output_buffer; 1599637de38SSrikanth Yalavarthi uint64_t i; 1609637de38SSrikanth Yalavarthi 1619637de38SSrikanth Yalavarthi if ((scale == 0) || (nb_elements == 0) || (input == NULL) || (output == NULL)) 1629637de38SSrikanth Yalavarthi return -EINVAL; 1639637de38SSrikanth Yalavarthi 1649637de38SSrikanth Yalavarthi input_buffer = (int16_t *)input; 1659637de38SSrikanth Yalavarthi output_buffer = (float *)output; 1669637de38SSrikanth Yalavarthi 1679637de38SSrikanth Yalavarthi for (i = 0; i < nb_elements; i++) { 1689637de38SSrikanth Yalavarthi *output_buffer = scale * (float)(*input_buffer); 1699637de38SSrikanth Yalavarthi 1709637de38SSrikanth Yalavarthi input_buffer++; 1719637de38SSrikanth Yalavarthi output_buffer++; 1729637de38SSrikanth Yalavarthi } 1739637de38SSrikanth Yalavarthi 1749637de38SSrikanth Yalavarthi return 0; 1759637de38SSrikanth Yalavarthi } 1769637de38SSrikanth Yalavarthi 1778c9bfcb1SSrikanth Yalavarthi int 1789637de38SSrikanth Yalavarthi rte_ml_io_float32_to_uint16(float scale, uint64_t nb_elements, void *input, void *output) 1799637de38SSrikanth Yalavarthi { 1809637de38SSrikanth Yalavarthi float *input_buffer; 1819637de38SSrikanth Yalavarthi uint16_t *output_buffer; 1829637de38SSrikanth Yalavarthi int32_t i32; 1839637de38SSrikanth Yalavarthi uint64_t i; 1849637de38SSrikanth Yalavarthi 1859637de38SSrikanth Yalavarthi if ((scale == 0) || (nb_elements == 0) || (input == NULL) || (output == NULL)) 1869637de38SSrikanth Yalavarthi return -EINVAL; 1879637de38SSrikanth Yalavarthi 1889637de38SSrikanth Yalavarthi input_buffer = (float *)input; 1899637de38SSrikanth Yalavarthi output_buffer = (uint16_t *)output; 1909637de38SSrikanth Yalavarthi 1919637de38SSrikanth Yalavarthi for (i = 0; i < nb_elements; i++) { 1929637de38SSrikanth Yalavarthi i32 = (int32_t)round((*input_buffer) * scale); 1939637de38SSrikanth Yalavarthi 1949637de38SSrikanth Yalavarthi if (i32 < 0) 1959637de38SSrikanth Yalavarthi i32 = 0; 1969637de38SSrikanth Yalavarthi 1979637de38SSrikanth Yalavarthi if (i32 > UINT16_MAX) 1989637de38SSrikanth Yalavarthi i32 = UINT16_MAX; 1999637de38SSrikanth Yalavarthi 2009637de38SSrikanth Yalavarthi *output_buffer = (uint16_t)i32; 2019637de38SSrikanth Yalavarthi 2029637de38SSrikanth Yalavarthi input_buffer++; 2039637de38SSrikanth Yalavarthi output_buffer++; 2049637de38SSrikanth Yalavarthi } 2059637de38SSrikanth Yalavarthi 2069637de38SSrikanth Yalavarthi return 0; 2079637de38SSrikanth Yalavarthi } 2089637de38SSrikanth Yalavarthi 2098c9bfcb1SSrikanth Yalavarthi int 2109637de38SSrikanth Yalavarthi rte_ml_io_uint16_to_float32(float scale, uint64_t nb_elements, void *input, void *output) 2119637de38SSrikanth Yalavarthi { 2129637de38SSrikanth Yalavarthi uint16_t *input_buffer; 2139637de38SSrikanth Yalavarthi float *output_buffer; 2149637de38SSrikanth Yalavarthi uint64_t i; 2159637de38SSrikanth Yalavarthi 2169637de38SSrikanth Yalavarthi if ((scale == 0) || (nb_elements == 0) || (input == NULL) || (output == NULL)) 2179637de38SSrikanth Yalavarthi return -EINVAL; 2189637de38SSrikanth Yalavarthi 2199637de38SSrikanth Yalavarthi input_buffer = (uint16_t *)input; 2209637de38SSrikanth Yalavarthi output_buffer = (float *)output; 2219637de38SSrikanth Yalavarthi 2229637de38SSrikanth Yalavarthi for (i = 0; i < nb_elements; i++) { 2239637de38SSrikanth Yalavarthi *output_buffer = scale * (float)(*input_buffer); 2249637de38SSrikanth Yalavarthi 2259637de38SSrikanth Yalavarthi input_buffer++; 2269637de38SSrikanth Yalavarthi output_buffer++; 2279637de38SSrikanth Yalavarthi } 2289637de38SSrikanth Yalavarthi 2299637de38SSrikanth Yalavarthi return 0; 2309637de38SSrikanth Yalavarthi } 2319637de38SSrikanth Yalavarthi 23250513ae5SSrikanth Yalavarthi int 23350513ae5SSrikanth Yalavarthi rte_ml_io_float32_to_int32(float scale, uint64_t nb_elements, void *input, void *output) 23450513ae5SSrikanth Yalavarthi { 23550513ae5SSrikanth Yalavarthi float *input_buffer; 23650513ae5SSrikanth Yalavarthi int32_t *output_buffer; 23750513ae5SSrikanth Yalavarthi uint64_t i; 23850513ae5SSrikanth Yalavarthi 23950513ae5SSrikanth Yalavarthi if ((scale == 0) || (nb_elements == 0) || (input == NULL) || (output == NULL)) 24050513ae5SSrikanth Yalavarthi return -EINVAL; 24150513ae5SSrikanth Yalavarthi 24250513ae5SSrikanth Yalavarthi input_buffer = (float *)input; 24350513ae5SSrikanth Yalavarthi output_buffer = (int32_t *)output; 24450513ae5SSrikanth Yalavarthi 24550513ae5SSrikanth Yalavarthi for (i = 0; i < nb_elements; i++) { 24650513ae5SSrikanth Yalavarthi *output_buffer = (int32_t)round((*input_buffer) * scale); 24750513ae5SSrikanth Yalavarthi 24850513ae5SSrikanth Yalavarthi input_buffer++; 24950513ae5SSrikanth Yalavarthi output_buffer++; 25050513ae5SSrikanth Yalavarthi } 25150513ae5SSrikanth Yalavarthi 25250513ae5SSrikanth Yalavarthi return 0; 25350513ae5SSrikanth Yalavarthi } 25450513ae5SSrikanth Yalavarthi 25550513ae5SSrikanth Yalavarthi int 25650513ae5SSrikanth Yalavarthi rte_ml_io_int32_to_float32(float scale, uint64_t nb_elements, void *input, void *output) 25750513ae5SSrikanth Yalavarthi { 25850513ae5SSrikanth Yalavarthi int32_t *input_buffer; 25950513ae5SSrikanth Yalavarthi float *output_buffer; 26050513ae5SSrikanth Yalavarthi uint64_t i; 26150513ae5SSrikanth Yalavarthi 26250513ae5SSrikanth Yalavarthi if ((scale == 0) || (nb_elements == 0) || (input == NULL) || (output == NULL)) 26350513ae5SSrikanth Yalavarthi return -EINVAL; 26450513ae5SSrikanth Yalavarthi 26550513ae5SSrikanth Yalavarthi input_buffer = (int32_t *)input; 26650513ae5SSrikanth Yalavarthi output_buffer = (float *)output; 26750513ae5SSrikanth Yalavarthi 26850513ae5SSrikanth Yalavarthi for (i = 0; i < nb_elements; i++) { 26950513ae5SSrikanth Yalavarthi *output_buffer = scale * (float)(*input_buffer); 27050513ae5SSrikanth Yalavarthi 27150513ae5SSrikanth Yalavarthi input_buffer++; 27250513ae5SSrikanth Yalavarthi output_buffer++; 27350513ae5SSrikanth Yalavarthi } 27450513ae5SSrikanth Yalavarthi 27550513ae5SSrikanth Yalavarthi return 0; 27650513ae5SSrikanth Yalavarthi } 27750513ae5SSrikanth Yalavarthi 27850513ae5SSrikanth Yalavarthi int 27950513ae5SSrikanth Yalavarthi rte_ml_io_float32_to_uint32(float scale, uint64_t nb_elements, void *input, void *output) 28050513ae5SSrikanth Yalavarthi { 28150513ae5SSrikanth Yalavarthi float *input_buffer; 28250513ae5SSrikanth Yalavarthi uint32_t *output_buffer; 28350513ae5SSrikanth Yalavarthi int32_t i32; 28450513ae5SSrikanth Yalavarthi uint64_t i; 28550513ae5SSrikanth Yalavarthi 28650513ae5SSrikanth Yalavarthi if ((scale == 0) || (nb_elements == 0) || (input == NULL) || (output == NULL)) 28750513ae5SSrikanth Yalavarthi return -EINVAL; 28850513ae5SSrikanth Yalavarthi 28950513ae5SSrikanth Yalavarthi input_buffer = (float *)input; 29050513ae5SSrikanth Yalavarthi output_buffer = (uint32_t *)output; 29150513ae5SSrikanth Yalavarthi 29250513ae5SSrikanth Yalavarthi for (i = 0; i < nb_elements; i++) { 29350513ae5SSrikanth Yalavarthi i32 = (int32_t)round((*input_buffer) * scale); 29450513ae5SSrikanth Yalavarthi 29550513ae5SSrikanth Yalavarthi if (i32 < 0) 29650513ae5SSrikanth Yalavarthi i32 = 0; 29750513ae5SSrikanth Yalavarthi 29850513ae5SSrikanth Yalavarthi *output_buffer = (uint32_t)i32; 29950513ae5SSrikanth Yalavarthi 30050513ae5SSrikanth Yalavarthi input_buffer++; 30150513ae5SSrikanth Yalavarthi output_buffer++; 30250513ae5SSrikanth Yalavarthi } 30350513ae5SSrikanth Yalavarthi 30450513ae5SSrikanth Yalavarthi return 0; 30550513ae5SSrikanth Yalavarthi } 30650513ae5SSrikanth Yalavarthi 30750513ae5SSrikanth Yalavarthi int 30850513ae5SSrikanth Yalavarthi rte_ml_io_uint32_to_float32(float scale, uint64_t nb_elements, void *input, void *output) 30950513ae5SSrikanth Yalavarthi { 31050513ae5SSrikanth Yalavarthi uint32_t *input_buffer; 31150513ae5SSrikanth Yalavarthi float *output_buffer; 31250513ae5SSrikanth Yalavarthi uint64_t i; 31350513ae5SSrikanth Yalavarthi 31450513ae5SSrikanth Yalavarthi if ((scale == 0) || (nb_elements == 0) || (input == NULL) || (output == NULL)) 31550513ae5SSrikanth Yalavarthi return -EINVAL; 31650513ae5SSrikanth Yalavarthi 31750513ae5SSrikanth Yalavarthi input_buffer = (uint32_t *)input; 31850513ae5SSrikanth Yalavarthi output_buffer = (float *)output; 31950513ae5SSrikanth Yalavarthi 32050513ae5SSrikanth Yalavarthi for (i = 0; i < nb_elements; i++) { 32150513ae5SSrikanth Yalavarthi *output_buffer = scale * (float)(*input_buffer); 32250513ae5SSrikanth Yalavarthi 32350513ae5SSrikanth Yalavarthi input_buffer++; 32450513ae5SSrikanth Yalavarthi output_buffer++; 32550513ae5SSrikanth Yalavarthi } 32650513ae5SSrikanth Yalavarthi 32750513ae5SSrikanth Yalavarthi return 0; 32850513ae5SSrikanth Yalavarthi } 32950513ae5SSrikanth Yalavarthi 330*42f3dcd9SSrikanth Yalavarthi int 331*42f3dcd9SSrikanth Yalavarthi rte_ml_io_float32_to_int64(float scale, uint64_t nb_elements, void *input, void *output) 332*42f3dcd9SSrikanth Yalavarthi { 333*42f3dcd9SSrikanth Yalavarthi float *input_buffer; 334*42f3dcd9SSrikanth Yalavarthi int64_t *output_buffer; 335*42f3dcd9SSrikanth Yalavarthi uint64_t i; 336*42f3dcd9SSrikanth Yalavarthi 337*42f3dcd9SSrikanth Yalavarthi if ((scale == 0) || (nb_elements == 0) || (input == NULL) || (output == NULL)) 338*42f3dcd9SSrikanth Yalavarthi return -EINVAL; 339*42f3dcd9SSrikanth Yalavarthi 340*42f3dcd9SSrikanth Yalavarthi input_buffer = (float *)input; 341*42f3dcd9SSrikanth Yalavarthi output_buffer = (int64_t *)output; 342*42f3dcd9SSrikanth Yalavarthi 343*42f3dcd9SSrikanth Yalavarthi for (i = 0; i < nb_elements; i++) { 344*42f3dcd9SSrikanth Yalavarthi *output_buffer = (int64_t)round((*input_buffer) * scale); 345*42f3dcd9SSrikanth Yalavarthi 346*42f3dcd9SSrikanth Yalavarthi input_buffer++; 347*42f3dcd9SSrikanth Yalavarthi output_buffer++; 348*42f3dcd9SSrikanth Yalavarthi } 349*42f3dcd9SSrikanth Yalavarthi 350*42f3dcd9SSrikanth Yalavarthi return 0; 351*42f3dcd9SSrikanth Yalavarthi } 352*42f3dcd9SSrikanth Yalavarthi 353*42f3dcd9SSrikanth Yalavarthi int 354*42f3dcd9SSrikanth Yalavarthi rte_ml_io_int64_to_float32(float scale, uint64_t nb_elements, void *input, void *output) 355*42f3dcd9SSrikanth Yalavarthi { 356*42f3dcd9SSrikanth Yalavarthi int64_t *input_buffer; 357*42f3dcd9SSrikanth Yalavarthi float *output_buffer; 358*42f3dcd9SSrikanth Yalavarthi uint64_t i; 359*42f3dcd9SSrikanth Yalavarthi 360*42f3dcd9SSrikanth Yalavarthi if ((scale == 0) || (nb_elements == 0) || (input == NULL) || (output == NULL)) 361*42f3dcd9SSrikanth Yalavarthi return -EINVAL; 362*42f3dcd9SSrikanth Yalavarthi 363*42f3dcd9SSrikanth Yalavarthi input_buffer = (int64_t *)input; 364*42f3dcd9SSrikanth Yalavarthi output_buffer = (float *)output; 365*42f3dcd9SSrikanth Yalavarthi 366*42f3dcd9SSrikanth Yalavarthi for (i = 0; i < nb_elements; i++) { 367*42f3dcd9SSrikanth Yalavarthi *output_buffer = scale * (float)(*input_buffer); 368*42f3dcd9SSrikanth Yalavarthi 369*42f3dcd9SSrikanth Yalavarthi input_buffer++; 370*42f3dcd9SSrikanth Yalavarthi output_buffer++; 371*42f3dcd9SSrikanth Yalavarthi } 372*42f3dcd9SSrikanth Yalavarthi 373*42f3dcd9SSrikanth Yalavarthi return 0; 374*42f3dcd9SSrikanth Yalavarthi } 375*42f3dcd9SSrikanth Yalavarthi 376*42f3dcd9SSrikanth Yalavarthi int 377*42f3dcd9SSrikanth Yalavarthi rte_ml_io_float32_to_uint64(float scale, uint64_t nb_elements, void *input, void *output) 378*42f3dcd9SSrikanth Yalavarthi { 379*42f3dcd9SSrikanth Yalavarthi float *input_buffer; 380*42f3dcd9SSrikanth Yalavarthi uint64_t *output_buffer; 381*42f3dcd9SSrikanth Yalavarthi int64_t i64; 382*42f3dcd9SSrikanth Yalavarthi uint64_t i; 383*42f3dcd9SSrikanth Yalavarthi 384*42f3dcd9SSrikanth Yalavarthi if ((scale == 0) || (nb_elements == 0) || (input == NULL) || (output == NULL)) 385*42f3dcd9SSrikanth Yalavarthi return -EINVAL; 386*42f3dcd9SSrikanth Yalavarthi 387*42f3dcd9SSrikanth Yalavarthi input_buffer = (float *)input; 388*42f3dcd9SSrikanth Yalavarthi output_buffer = (uint64_t *)output; 389*42f3dcd9SSrikanth Yalavarthi 390*42f3dcd9SSrikanth Yalavarthi for (i = 0; i < nb_elements; i++) { 391*42f3dcd9SSrikanth Yalavarthi i64 = (int64_t)round((*input_buffer) * scale); 392*42f3dcd9SSrikanth Yalavarthi 393*42f3dcd9SSrikanth Yalavarthi if (i64 < 0) 394*42f3dcd9SSrikanth Yalavarthi i64 = 0; 395*42f3dcd9SSrikanth Yalavarthi 396*42f3dcd9SSrikanth Yalavarthi *output_buffer = (uint64_t)i64; 397*42f3dcd9SSrikanth Yalavarthi 398*42f3dcd9SSrikanth Yalavarthi input_buffer++; 399*42f3dcd9SSrikanth Yalavarthi output_buffer++; 400*42f3dcd9SSrikanth Yalavarthi } 401*42f3dcd9SSrikanth Yalavarthi 402*42f3dcd9SSrikanth Yalavarthi return 0; 403*42f3dcd9SSrikanth Yalavarthi } 404*42f3dcd9SSrikanth Yalavarthi 405*42f3dcd9SSrikanth Yalavarthi int 406*42f3dcd9SSrikanth Yalavarthi rte_ml_io_uint64_to_float32(float scale, uint64_t nb_elements, void *input, void *output) 407*42f3dcd9SSrikanth Yalavarthi { 408*42f3dcd9SSrikanth Yalavarthi uint64_t *input_buffer; 409*42f3dcd9SSrikanth Yalavarthi float *output_buffer; 410*42f3dcd9SSrikanth Yalavarthi uint64_t i; 411*42f3dcd9SSrikanth Yalavarthi 412*42f3dcd9SSrikanth Yalavarthi if ((scale == 0) || (nb_elements == 0) || (input == NULL) || (output == NULL)) 413*42f3dcd9SSrikanth Yalavarthi return -EINVAL; 414*42f3dcd9SSrikanth Yalavarthi 415*42f3dcd9SSrikanth Yalavarthi input_buffer = (uint64_t *)input; 416*42f3dcd9SSrikanth Yalavarthi output_buffer = (float *)output; 417*42f3dcd9SSrikanth Yalavarthi 418*42f3dcd9SSrikanth Yalavarthi for (i = 0; i < nb_elements; i++) { 419*42f3dcd9SSrikanth Yalavarthi *output_buffer = scale * (float)(*input_buffer); 420*42f3dcd9SSrikanth Yalavarthi 421*42f3dcd9SSrikanth Yalavarthi input_buffer++; 422*42f3dcd9SSrikanth Yalavarthi output_buffer++; 423*42f3dcd9SSrikanth Yalavarthi } 424*42f3dcd9SSrikanth Yalavarthi 425*42f3dcd9SSrikanth Yalavarthi return 0; 426*42f3dcd9SSrikanth Yalavarthi } 427*42f3dcd9SSrikanth Yalavarthi 4289637de38SSrikanth Yalavarthi /* Convert a single precision floating point number (float32) into a half precision 4299637de38SSrikanth Yalavarthi * floating point number (float16) using round to nearest rounding mode. 4309637de38SSrikanth Yalavarthi */ 4319637de38SSrikanth Yalavarthi static uint16_t 4329637de38SSrikanth Yalavarthi __float32_to_float16_scalar_rtn(float x) 4339637de38SSrikanth Yalavarthi { 4349637de38SSrikanth Yalavarthi union float32 f32; /* float32 input */ 4359637de38SSrikanth Yalavarthi uint32_t f32_s; /* float32 sign */ 4369637de38SSrikanth Yalavarthi uint32_t f32_e; /* float32 exponent */ 4379637de38SSrikanth Yalavarthi uint32_t f32_m; /* float32 mantissa */ 4389637de38SSrikanth Yalavarthi uint16_t f16_s; /* float16 sign */ 4399637de38SSrikanth Yalavarthi uint16_t f16_e; /* float16 exponent */ 4409637de38SSrikanth Yalavarthi uint16_t f16_m; /* float16 mantissa */ 4419637de38SSrikanth Yalavarthi uint32_t tbits; /* number of truncated bits */ 4429637de38SSrikanth Yalavarthi uint32_t tmsb; /* MSB position of truncated bits */ 4439637de38SSrikanth Yalavarthi uint32_t m_32; /* temporary float32 mantissa */ 4449637de38SSrikanth Yalavarthi uint16_t m_16; /* temporary float16 mantissa */ 4459637de38SSrikanth Yalavarthi uint16_t u16; /* float16 output */ 4469637de38SSrikanth Yalavarthi int be_16; /* float16 biased exponent, signed */ 4479637de38SSrikanth Yalavarthi 4489637de38SSrikanth Yalavarthi f32.f = x; 4499637de38SSrikanth Yalavarthi f32_s = (f32.u & FP32_MASK_S) >> FP32_LSB_S; 4509637de38SSrikanth Yalavarthi f32_e = (f32.u & FP32_MASK_E) >> FP32_LSB_E; 4519637de38SSrikanth Yalavarthi f32_m = (f32.u & FP32_MASK_M) >> FP32_LSB_M; 4529637de38SSrikanth Yalavarthi 4539637de38SSrikanth Yalavarthi f16_s = f32_s; 4549637de38SSrikanth Yalavarthi f16_e = 0; 4559637de38SSrikanth Yalavarthi f16_m = 0; 4569637de38SSrikanth Yalavarthi 4579637de38SSrikanth Yalavarthi switch (f32_e) { 4589637de38SSrikanth Yalavarthi case (0): /* float32: zero or subnormal number */ 4599637de38SSrikanth Yalavarthi f16_e = 0; 460f71c5365SSrikanth Yalavarthi f16_m = 0; /* convert to zero */ 4619637de38SSrikanth Yalavarthi break; 4629637de38SSrikanth Yalavarthi case (FP32_MASK_E >> FP32_LSB_E): /* float32: infinity or nan */ 4639637de38SSrikanth Yalavarthi f16_e = FP16_MASK_E >> FP16_LSB_E; 4649637de38SSrikanth Yalavarthi if (f32_m == 0) { /* infinity */ 4659637de38SSrikanth Yalavarthi f16_m = 0; 4669637de38SSrikanth Yalavarthi } else { /* nan, propagate mantissa and set MSB of mantissa to 1 */ 4679637de38SSrikanth Yalavarthi f16_m = f32_m >> (FP32_MSB_M - FP16_MSB_M); 4689637de38SSrikanth Yalavarthi f16_m |= BIT(FP16_MSB_M); 4699637de38SSrikanth Yalavarthi } 4709637de38SSrikanth Yalavarthi break; 4719637de38SSrikanth Yalavarthi default: /* float32: normal number */ 4729637de38SSrikanth Yalavarthi /* compute biased exponent for float16 */ 4739637de38SSrikanth Yalavarthi be_16 = (int)f32_e - FP32_BIAS_E + FP16_BIAS_E; 4749637de38SSrikanth Yalavarthi 4759637de38SSrikanth Yalavarthi /* overflow, be_16 = [31-INF], set to infinity */ 4769637de38SSrikanth Yalavarthi if (be_16 >= (int)(FP16_MASK_E >> FP16_LSB_E)) { 4779637de38SSrikanth Yalavarthi f16_e = FP16_MASK_E >> FP16_LSB_E; 4789637de38SSrikanth Yalavarthi f16_m = 0; 4799637de38SSrikanth Yalavarthi } else if ((be_16 >= 1) && (be_16 < (int)(FP16_MASK_E >> FP16_LSB_E))) { 4809637de38SSrikanth Yalavarthi /* normal float16, be_16 = [1:30]*/ 4819637de38SSrikanth Yalavarthi f16_e = be_16; 4829637de38SSrikanth Yalavarthi m_16 = f32_m >> (FP32_LSB_E - FP16_LSB_E); 4839637de38SSrikanth Yalavarthi tmsb = FP32_MSB_M - FP16_MSB_M - 1; 4849637de38SSrikanth Yalavarthi if ((f32_m & GENMASK_U32(tmsb, 0)) > BIT(tmsb)) { 4859637de38SSrikanth Yalavarthi /* round: non-zero truncated bits except MSB */ 4869637de38SSrikanth Yalavarthi m_16++; 4879637de38SSrikanth Yalavarthi 4889637de38SSrikanth Yalavarthi /* overflow into exponent */ 4899637de38SSrikanth Yalavarthi if (((m_16 & FP16_MASK_E) >> FP16_LSB_E) == 0x1) 4909637de38SSrikanth Yalavarthi f16_e++; 4919637de38SSrikanth Yalavarthi } else if ((f32_m & GENMASK_U32(tmsb, 0)) == BIT(tmsb)) { 4929637de38SSrikanth Yalavarthi /* round: MSB of truncated bits and LSB of m_16 is set */ 4939637de38SSrikanth Yalavarthi if ((m_16 & 0x1) == 0x1) { 4949637de38SSrikanth Yalavarthi m_16++; 4959637de38SSrikanth Yalavarthi 4969637de38SSrikanth Yalavarthi /* overflow into exponent */ 4979637de38SSrikanth Yalavarthi if (((m_16 & FP16_MASK_E) >> FP16_LSB_E) == 0x1) 4989637de38SSrikanth Yalavarthi f16_e++; 4999637de38SSrikanth Yalavarthi } 5009637de38SSrikanth Yalavarthi } 5019637de38SSrikanth Yalavarthi f16_m = m_16 & FP16_MASK_M; 5029637de38SSrikanth Yalavarthi } else if ((be_16 >= -(int)(FP16_MSB_M)) && (be_16 < 1)) { 5039637de38SSrikanth Yalavarthi /* underflow: zero / subnormal, be_16 = [-9:0] */ 5049637de38SSrikanth Yalavarthi f16_e = 0; 5059637de38SSrikanth Yalavarthi 5069637de38SSrikanth Yalavarthi /* add implicit leading zero */ 5079637de38SSrikanth Yalavarthi m_32 = f32_m | BIT(FP32_LSB_E); 5089637de38SSrikanth Yalavarthi tbits = FP32_LSB_E - FP16_LSB_E - be_16 + 1; 5099637de38SSrikanth Yalavarthi m_16 = m_32 >> tbits; 5109637de38SSrikanth Yalavarthi 5119637de38SSrikanth Yalavarthi /* if non-leading truncated bits are set */ 5129637de38SSrikanth Yalavarthi if ((f32_m & GENMASK_U32(tbits - 1, 0)) > BIT(tbits - 1)) { 5139637de38SSrikanth Yalavarthi m_16++; 5149637de38SSrikanth Yalavarthi 5159637de38SSrikanth Yalavarthi /* overflow into exponent */ 5169637de38SSrikanth Yalavarthi if (((m_16 & FP16_MASK_E) >> FP16_LSB_E) == 0x1) 5179637de38SSrikanth Yalavarthi f16_e++; 5189637de38SSrikanth Yalavarthi } else if ((f32_m & GENMASK_U32(tbits - 1, 0)) == BIT(tbits - 1)) { 5199637de38SSrikanth Yalavarthi /* if leading truncated bit is set */ 5209637de38SSrikanth Yalavarthi if ((m_16 & 0x1) == 0x1) { 5219637de38SSrikanth Yalavarthi m_16++; 5229637de38SSrikanth Yalavarthi 5239637de38SSrikanth Yalavarthi /* overflow into exponent */ 5249637de38SSrikanth Yalavarthi if (((m_16 & FP16_MASK_E) >> FP16_LSB_E) == 0x1) 5259637de38SSrikanth Yalavarthi f16_e++; 5269637de38SSrikanth Yalavarthi } 5279637de38SSrikanth Yalavarthi } 5289637de38SSrikanth Yalavarthi f16_m = m_16 & FP16_MASK_M; 5299637de38SSrikanth Yalavarthi } else if (be_16 == -(int)(FP16_MSB_M + 1)) { 5309637de38SSrikanth Yalavarthi /* underflow: zero, be_16 = [-10] */ 5319637de38SSrikanth Yalavarthi f16_e = 0; 5329637de38SSrikanth Yalavarthi if (f32_m != 0) 5339637de38SSrikanth Yalavarthi f16_m = 1; 5349637de38SSrikanth Yalavarthi else 5359637de38SSrikanth Yalavarthi f16_m = 0; 5369637de38SSrikanth Yalavarthi } else { 5379637de38SSrikanth Yalavarthi /* underflow: zero, be_16 = [-INF:-11] */ 5389637de38SSrikanth Yalavarthi f16_e = 0; 5399637de38SSrikanth Yalavarthi f16_m = 0; 5409637de38SSrikanth Yalavarthi } 5419637de38SSrikanth Yalavarthi 5429637de38SSrikanth Yalavarthi break; 5439637de38SSrikanth Yalavarthi } 5449637de38SSrikanth Yalavarthi 5459637de38SSrikanth Yalavarthi u16 = FP16_PACK(f16_s, f16_e, f16_m); 5469637de38SSrikanth Yalavarthi 5479637de38SSrikanth Yalavarthi return u16; 5489637de38SSrikanth Yalavarthi } 5499637de38SSrikanth Yalavarthi 5508c9bfcb1SSrikanth Yalavarthi int 5519637de38SSrikanth Yalavarthi rte_ml_io_float32_to_float16(uint64_t nb_elements, void *input, void *output) 5529637de38SSrikanth Yalavarthi { 5539637de38SSrikanth Yalavarthi float *input_buffer; 5549637de38SSrikanth Yalavarthi uint16_t *output_buffer; 5559637de38SSrikanth Yalavarthi uint64_t i; 5569637de38SSrikanth Yalavarthi 5579637de38SSrikanth Yalavarthi if ((nb_elements == 0) || (input == NULL) || (output == NULL)) 5589637de38SSrikanth Yalavarthi return -EINVAL; 5599637de38SSrikanth Yalavarthi 5609637de38SSrikanth Yalavarthi input_buffer = (float *)input; 5619637de38SSrikanth Yalavarthi output_buffer = (uint16_t *)output; 5629637de38SSrikanth Yalavarthi 5639637de38SSrikanth Yalavarthi for (i = 0; i < nb_elements; i++) { 5649637de38SSrikanth Yalavarthi *output_buffer = __float32_to_float16_scalar_rtn(*input_buffer); 5659637de38SSrikanth Yalavarthi 5669637de38SSrikanth Yalavarthi input_buffer = input_buffer + 1; 5679637de38SSrikanth Yalavarthi output_buffer = output_buffer + 1; 5689637de38SSrikanth Yalavarthi } 5699637de38SSrikanth Yalavarthi 5709637de38SSrikanth Yalavarthi return 0; 5719637de38SSrikanth Yalavarthi } 5729637de38SSrikanth Yalavarthi 5739637de38SSrikanth Yalavarthi /* Convert a half precision floating point number (float16) into a single precision 5749637de38SSrikanth Yalavarthi * floating point number (float32). 5759637de38SSrikanth Yalavarthi */ 5769637de38SSrikanth Yalavarthi static float 5779637de38SSrikanth Yalavarthi __float16_to_float32_scalar_rtx(uint16_t f16) 5789637de38SSrikanth Yalavarthi { 5799637de38SSrikanth Yalavarthi union float32 f32; /* float32 output */ 5809637de38SSrikanth Yalavarthi uint16_t f16_s; /* float16 sign */ 5819637de38SSrikanth Yalavarthi uint16_t f16_e; /* float16 exponent */ 5829637de38SSrikanth Yalavarthi uint16_t f16_m; /* float16 mantissa */ 5839637de38SSrikanth Yalavarthi uint32_t f32_s; /* float32 sign */ 5849637de38SSrikanth Yalavarthi uint32_t f32_e; /* float32 exponent */ 5859637de38SSrikanth Yalavarthi uint32_t f32_m; /* float32 mantissa*/ 5869637de38SSrikanth Yalavarthi uint8_t shift; /* number of bits to be shifted */ 5879637de38SSrikanth Yalavarthi uint32_t clz; /* count of leading zeroes */ 5889637de38SSrikanth Yalavarthi int e_16; /* float16 exponent unbiased */ 5899637de38SSrikanth Yalavarthi 5909637de38SSrikanth Yalavarthi f16_s = (f16 & FP16_MASK_S) >> FP16_LSB_S; 5919637de38SSrikanth Yalavarthi f16_e = (f16 & FP16_MASK_E) >> FP16_LSB_E; 5929637de38SSrikanth Yalavarthi f16_m = (f16 & FP16_MASK_M) >> FP16_LSB_M; 5939637de38SSrikanth Yalavarthi 5949637de38SSrikanth Yalavarthi f32_s = f16_s; 5959637de38SSrikanth Yalavarthi switch (f16_e) { 5969637de38SSrikanth Yalavarthi case (FP16_MASK_E >> FP16_LSB_E): /* float16: infinity or nan */ 5979637de38SSrikanth Yalavarthi f32_e = FP32_MASK_E >> FP32_LSB_E; 5989637de38SSrikanth Yalavarthi if (f16_m == 0x0) { /* infinity */ 5999637de38SSrikanth Yalavarthi f32_m = f16_m; 6009637de38SSrikanth Yalavarthi } else { /* nan, propagate mantissa, set MSB of mantissa to 1 */ 6019637de38SSrikanth Yalavarthi f32_m = f16_m; 6029637de38SSrikanth Yalavarthi shift = FP32_MSB_M - FP16_MSB_M; 6039637de38SSrikanth Yalavarthi f32_m = (f32_m << shift) & FP32_MASK_M; 6049637de38SSrikanth Yalavarthi f32_m |= BIT(FP32_MSB_M); 6059637de38SSrikanth Yalavarthi } 6069637de38SSrikanth Yalavarthi break; 6079637de38SSrikanth Yalavarthi case 0: /* float16: zero or sub-normal */ 6089637de38SSrikanth Yalavarthi f32_m = f16_m; 6099637de38SSrikanth Yalavarthi if (f16_m == 0) { /* zero signed */ 6109637de38SSrikanth Yalavarthi f32_e = 0; 6119637de38SSrikanth Yalavarthi } else { /* subnormal numbers */ 6123d4e27fdSDavid Marchand clz = rte_clz32((uint32_t)f16_m) - sizeof(uint32_t) * 8 + FP16_LSB_E; 6139637de38SSrikanth Yalavarthi e_16 = (int)f16_e - clz; 6149637de38SSrikanth Yalavarthi f32_e = FP32_BIAS_E + e_16 - FP16_BIAS_E; 6159637de38SSrikanth Yalavarthi 6169637de38SSrikanth Yalavarthi shift = clz + (FP32_MSB_M - FP16_MSB_M) + 1; 6179637de38SSrikanth Yalavarthi f32_m = (f32_m << shift) & FP32_MASK_M; 6189637de38SSrikanth Yalavarthi } 6199637de38SSrikanth Yalavarthi break; 6209637de38SSrikanth Yalavarthi default: /* normal numbers */ 6219637de38SSrikanth Yalavarthi f32_m = f16_m; 6229637de38SSrikanth Yalavarthi e_16 = (int)f16_e; 6239637de38SSrikanth Yalavarthi f32_e = FP32_BIAS_E + e_16 - FP16_BIAS_E; 6249637de38SSrikanth Yalavarthi 6259637de38SSrikanth Yalavarthi shift = (FP32_MSB_M - FP16_MSB_M); 6269637de38SSrikanth Yalavarthi f32_m = (f32_m << shift) & FP32_MASK_M; 6279637de38SSrikanth Yalavarthi } 6289637de38SSrikanth Yalavarthi 6299637de38SSrikanth Yalavarthi f32.u = FP32_PACK(f32_s, f32_e, f32_m); 6309637de38SSrikanth Yalavarthi 6319637de38SSrikanth Yalavarthi return f32.f; 6329637de38SSrikanth Yalavarthi } 6339637de38SSrikanth Yalavarthi 6348c9bfcb1SSrikanth Yalavarthi int 6359637de38SSrikanth Yalavarthi rte_ml_io_float16_to_float32(uint64_t nb_elements, void *input, void *output) 6369637de38SSrikanth Yalavarthi { 6379637de38SSrikanth Yalavarthi uint16_t *input_buffer; 6389637de38SSrikanth Yalavarthi float *output_buffer; 6399637de38SSrikanth Yalavarthi uint64_t i; 6409637de38SSrikanth Yalavarthi 6419637de38SSrikanth Yalavarthi if ((nb_elements == 0) || (input == NULL) || (output == NULL)) 6429637de38SSrikanth Yalavarthi return -EINVAL; 6439637de38SSrikanth Yalavarthi 6449637de38SSrikanth Yalavarthi input_buffer = (uint16_t *)input; 6459637de38SSrikanth Yalavarthi output_buffer = (float *)output; 6469637de38SSrikanth Yalavarthi 6479637de38SSrikanth Yalavarthi for (i = 0; i < nb_elements; i++) { 6489637de38SSrikanth Yalavarthi *output_buffer = __float16_to_float32_scalar_rtx(*input_buffer); 6499637de38SSrikanth Yalavarthi 6509637de38SSrikanth Yalavarthi input_buffer = input_buffer + 1; 6519637de38SSrikanth Yalavarthi output_buffer = output_buffer + 1; 6529637de38SSrikanth Yalavarthi } 6539637de38SSrikanth Yalavarthi 6549637de38SSrikanth Yalavarthi return 0; 6559637de38SSrikanth Yalavarthi } 656