xref: /dpdk/lib/mldev/mldev_utils_scalar.c (revision 50513ae53ea9c4cc35b4d7d5df6361da77f77cbb)
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 
232*50513ae5SSrikanth Yalavarthi int
233*50513ae5SSrikanth Yalavarthi rte_ml_io_float32_to_int32(float scale, uint64_t nb_elements, void *input, void *output)
234*50513ae5SSrikanth Yalavarthi {
235*50513ae5SSrikanth Yalavarthi 	float *input_buffer;
236*50513ae5SSrikanth Yalavarthi 	int32_t *output_buffer;
237*50513ae5SSrikanth Yalavarthi 	uint64_t i;
238*50513ae5SSrikanth Yalavarthi 
239*50513ae5SSrikanth Yalavarthi 	if ((scale == 0) || (nb_elements == 0) || (input == NULL) || (output == NULL))
240*50513ae5SSrikanth Yalavarthi 		return -EINVAL;
241*50513ae5SSrikanth Yalavarthi 
242*50513ae5SSrikanth Yalavarthi 	input_buffer = (float *)input;
243*50513ae5SSrikanth Yalavarthi 	output_buffer = (int32_t *)output;
244*50513ae5SSrikanth Yalavarthi 
245*50513ae5SSrikanth Yalavarthi 	for (i = 0; i < nb_elements; i++) {
246*50513ae5SSrikanth Yalavarthi 		*output_buffer = (int32_t)round((*input_buffer) * scale);
247*50513ae5SSrikanth Yalavarthi 
248*50513ae5SSrikanth Yalavarthi 		input_buffer++;
249*50513ae5SSrikanth Yalavarthi 		output_buffer++;
250*50513ae5SSrikanth Yalavarthi 	}
251*50513ae5SSrikanth Yalavarthi 
252*50513ae5SSrikanth Yalavarthi 	return 0;
253*50513ae5SSrikanth Yalavarthi }
254*50513ae5SSrikanth Yalavarthi 
255*50513ae5SSrikanth Yalavarthi int
256*50513ae5SSrikanth Yalavarthi rte_ml_io_int32_to_float32(float scale, uint64_t nb_elements, void *input, void *output)
257*50513ae5SSrikanth Yalavarthi {
258*50513ae5SSrikanth Yalavarthi 	int32_t *input_buffer;
259*50513ae5SSrikanth Yalavarthi 	float *output_buffer;
260*50513ae5SSrikanth Yalavarthi 	uint64_t i;
261*50513ae5SSrikanth Yalavarthi 
262*50513ae5SSrikanth Yalavarthi 	if ((scale == 0) || (nb_elements == 0) || (input == NULL) || (output == NULL))
263*50513ae5SSrikanth Yalavarthi 		return -EINVAL;
264*50513ae5SSrikanth Yalavarthi 
265*50513ae5SSrikanth Yalavarthi 	input_buffer = (int32_t *)input;
266*50513ae5SSrikanth Yalavarthi 	output_buffer = (float *)output;
267*50513ae5SSrikanth Yalavarthi 
268*50513ae5SSrikanth Yalavarthi 	for (i = 0; i < nb_elements; i++) {
269*50513ae5SSrikanth Yalavarthi 		*output_buffer = scale * (float)(*input_buffer);
270*50513ae5SSrikanth Yalavarthi 
271*50513ae5SSrikanth Yalavarthi 		input_buffer++;
272*50513ae5SSrikanth Yalavarthi 		output_buffer++;
273*50513ae5SSrikanth Yalavarthi 	}
274*50513ae5SSrikanth Yalavarthi 
275*50513ae5SSrikanth Yalavarthi 	return 0;
276*50513ae5SSrikanth Yalavarthi }
277*50513ae5SSrikanth Yalavarthi 
278*50513ae5SSrikanth Yalavarthi int
279*50513ae5SSrikanth Yalavarthi rte_ml_io_float32_to_uint32(float scale, uint64_t nb_elements, void *input, void *output)
280*50513ae5SSrikanth Yalavarthi {
281*50513ae5SSrikanth Yalavarthi 	float *input_buffer;
282*50513ae5SSrikanth Yalavarthi 	uint32_t *output_buffer;
283*50513ae5SSrikanth Yalavarthi 	int32_t i32;
284*50513ae5SSrikanth Yalavarthi 	uint64_t i;
285*50513ae5SSrikanth Yalavarthi 
286*50513ae5SSrikanth Yalavarthi 	if ((scale == 0) || (nb_elements == 0) || (input == NULL) || (output == NULL))
287*50513ae5SSrikanth Yalavarthi 		return -EINVAL;
288*50513ae5SSrikanth Yalavarthi 
289*50513ae5SSrikanth Yalavarthi 	input_buffer = (float *)input;
290*50513ae5SSrikanth Yalavarthi 	output_buffer = (uint32_t *)output;
291*50513ae5SSrikanth Yalavarthi 
292*50513ae5SSrikanth Yalavarthi 	for (i = 0; i < nb_elements; i++) {
293*50513ae5SSrikanth Yalavarthi 		i32 = (int32_t)round((*input_buffer) * scale);
294*50513ae5SSrikanth Yalavarthi 
295*50513ae5SSrikanth Yalavarthi 		if (i32 < 0)
296*50513ae5SSrikanth Yalavarthi 			i32 = 0;
297*50513ae5SSrikanth Yalavarthi 
298*50513ae5SSrikanth Yalavarthi 		*output_buffer = (uint32_t)i32;
299*50513ae5SSrikanth Yalavarthi 
300*50513ae5SSrikanth Yalavarthi 		input_buffer++;
301*50513ae5SSrikanth Yalavarthi 		output_buffer++;
302*50513ae5SSrikanth Yalavarthi 	}
303*50513ae5SSrikanth Yalavarthi 
304*50513ae5SSrikanth Yalavarthi 	return 0;
305*50513ae5SSrikanth Yalavarthi }
306*50513ae5SSrikanth Yalavarthi 
307*50513ae5SSrikanth Yalavarthi int
308*50513ae5SSrikanth Yalavarthi rte_ml_io_uint32_to_float32(float scale, uint64_t nb_elements, void *input, void *output)
309*50513ae5SSrikanth Yalavarthi {
310*50513ae5SSrikanth Yalavarthi 	uint32_t *input_buffer;
311*50513ae5SSrikanth Yalavarthi 	float *output_buffer;
312*50513ae5SSrikanth Yalavarthi 	uint64_t i;
313*50513ae5SSrikanth Yalavarthi 
314*50513ae5SSrikanth Yalavarthi 	if ((scale == 0) || (nb_elements == 0) || (input == NULL) || (output == NULL))
315*50513ae5SSrikanth Yalavarthi 		return -EINVAL;
316*50513ae5SSrikanth Yalavarthi 
317*50513ae5SSrikanth Yalavarthi 	input_buffer = (uint32_t *)input;
318*50513ae5SSrikanth Yalavarthi 	output_buffer = (float *)output;
319*50513ae5SSrikanth Yalavarthi 
320*50513ae5SSrikanth Yalavarthi 	for (i = 0; i < nb_elements; i++) {
321*50513ae5SSrikanth Yalavarthi 		*output_buffer = scale * (float)(*input_buffer);
322*50513ae5SSrikanth Yalavarthi 
323*50513ae5SSrikanth Yalavarthi 		input_buffer++;
324*50513ae5SSrikanth Yalavarthi 		output_buffer++;
325*50513ae5SSrikanth Yalavarthi 	}
326*50513ae5SSrikanth Yalavarthi 
327*50513ae5SSrikanth Yalavarthi 	return 0;
328*50513ae5SSrikanth Yalavarthi }
329*50513ae5SSrikanth Yalavarthi 
3309637de38SSrikanth Yalavarthi /* Convert a single precision floating point number (float32) into a half precision
3319637de38SSrikanth Yalavarthi  * floating point number (float16) using round to nearest rounding mode.
3329637de38SSrikanth Yalavarthi  */
3339637de38SSrikanth Yalavarthi static uint16_t
3349637de38SSrikanth Yalavarthi __float32_to_float16_scalar_rtn(float x)
3359637de38SSrikanth Yalavarthi {
3369637de38SSrikanth Yalavarthi 	union float32 f32; /* float32 input */
3379637de38SSrikanth Yalavarthi 	uint32_t f32_s;	   /* float32 sign */
3389637de38SSrikanth Yalavarthi 	uint32_t f32_e;	   /* float32 exponent */
3399637de38SSrikanth Yalavarthi 	uint32_t f32_m;	   /* float32 mantissa */
3409637de38SSrikanth Yalavarthi 	uint16_t f16_s;	   /* float16 sign */
3419637de38SSrikanth Yalavarthi 	uint16_t f16_e;	   /* float16 exponent */
3429637de38SSrikanth Yalavarthi 	uint16_t f16_m;	   /* float16 mantissa */
3439637de38SSrikanth Yalavarthi 	uint32_t tbits;	   /* number of truncated bits */
3449637de38SSrikanth Yalavarthi 	uint32_t tmsb;	   /* MSB position of truncated bits */
3459637de38SSrikanth Yalavarthi 	uint32_t m_32;	   /* temporary float32 mantissa */
3469637de38SSrikanth Yalavarthi 	uint16_t m_16;	   /* temporary float16 mantissa */
3479637de38SSrikanth Yalavarthi 	uint16_t u16;	   /* float16 output */
3489637de38SSrikanth Yalavarthi 	int be_16;	   /* float16 biased exponent, signed */
3499637de38SSrikanth Yalavarthi 
3509637de38SSrikanth Yalavarthi 	f32.f = x;
3519637de38SSrikanth Yalavarthi 	f32_s = (f32.u & FP32_MASK_S) >> FP32_LSB_S;
3529637de38SSrikanth Yalavarthi 	f32_e = (f32.u & FP32_MASK_E) >> FP32_LSB_E;
3539637de38SSrikanth Yalavarthi 	f32_m = (f32.u & FP32_MASK_M) >> FP32_LSB_M;
3549637de38SSrikanth Yalavarthi 
3559637de38SSrikanth Yalavarthi 	f16_s = f32_s;
3569637de38SSrikanth Yalavarthi 	f16_e = 0;
3579637de38SSrikanth Yalavarthi 	f16_m = 0;
3589637de38SSrikanth Yalavarthi 
3599637de38SSrikanth Yalavarthi 	switch (f32_e) {
3609637de38SSrikanth Yalavarthi 	case (0): /* float32: zero or subnormal number */
3619637de38SSrikanth Yalavarthi 		f16_e = 0;
362f71c5365SSrikanth Yalavarthi 		f16_m = 0; /* convert to zero */
3639637de38SSrikanth Yalavarthi 		break;
3649637de38SSrikanth Yalavarthi 	case (FP32_MASK_E >> FP32_LSB_E): /* float32: infinity or nan */
3659637de38SSrikanth Yalavarthi 		f16_e = FP16_MASK_E >> FP16_LSB_E;
3669637de38SSrikanth Yalavarthi 		if (f32_m == 0) { /* infinity */
3679637de38SSrikanth Yalavarthi 			f16_m = 0;
3689637de38SSrikanth Yalavarthi 		} else { /* nan, propagate mantissa and set MSB of mantissa to 1 */
3699637de38SSrikanth Yalavarthi 			f16_m = f32_m >> (FP32_MSB_M - FP16_MSB_M);
3709637de38SSrikanth Yalavarthi 			f16_m |= BIT(FP16_MSB_M);
3719637de38SSrikanth Yalavarthi 		}
3729637de38SSrikanth Yalavarthi 		break;
3739637de38SSrikanth Yalavarthi 	default: /* float32: normal number */
3749637de38SSrikanth Yalavarthi 		/* compute biased exponent for float16 */
3759637de38SSrikanth Yalavarthi 		be_16 = (int)f32_e - FP32_BIAS_E + FP16_BIAS_E;
3769637de38SSrikanth Yalavarthi 
3779637de38SSrikanth Yalavarthi 		/* overflow, be_16 = [31-INF], set to infinity */
3789637de38SSrikanth Yalavarthi 		if (be_16 >= (int)(FP16_MASK_E >> FP16_LSB_E)) {
3799637de38SSrikanth Yalavarthi 			f16_e = FP16_MASK_E >> FP16_LSB_E;
3809637de38SSrikanth Yalavarthi 			f16_m = 0;
3819637de38SSrikanth Yalavarthi 		} else if ((be_16 >= 1) && (be_16 < (int)(FP16_MASK_E >> FP16_LSB_E))) {
3829637de38SSrikanth Yalavarthi 			/* normal float16, be_16 = [1:30]*/
3839637de38SSrikanth Yalavarthi 			f16_e = be_16;
3849637de38SSrikanth Yalavarthi 			m_16 = f32_m >> (FP32_LSB_E - FP16_LSB_E);
3859637de38SSrikanth Yalavarthi 			tmsb = FP32_MSB_M - FP16_MSB_M - 1;
3869637de38SSrikanth Yalavarthi 			if ((f32_m & GENMASK_U32(tmsb, 0)) > BIT(tmsb)) {
3879637de38SSrikanth Yalavarthi 				/* round: non-zero truncated bits except MSB */
3889637de38SSrikanth Yalavarthi 				m_16++;
3899637de38SSrikanth Yalavarthi 
3909637de38SSrikanth Yalavarthi 				/* overflow into exponent */
3919637de38SSrikanth Yalavarthi 				if (((m_16 & FP16_MASK_E) >> FP16_LSB_E) == 0x1)
3929637de38SSrikanth Yalavarthi 					f16_e++;
3939637de38SSrikanth Yalavarthi 			} else if ((f32_m & GENMASK_U32(tmsb, 0)) == BIT(tmsb)) {
3949637de38SSrikanth Yalavarthi 				/* round: MSB of truncated bits and LSB of m_16 is set */
3959637de38SSrikanth Yalavarthi 				if ((m_16 & 0x1) == 0x1) {
3969637de38SSrikanth Yalavarthi 					m_16++;
3979637de38SSrikanth Yalavarthi 
3989637de38SSrikanth Yalavarthi 					/* overflow into exponent */
3999637de38SSrikanth Yalavarthi 					if (((m_16 & FP16_MASK_E) >> FP16_LSB_E) == 0x1)
4009637de38SSrikanth Yalavarthi 						f16_e++;
4019637de38SSrikanth Yalavarthi 				}
4029637de38SSrikanth Yalavarthi 			}
4039637de38SSrikanth Yalavarthi 			f16_m = m_16 & FP16_MASK_M;
4049637de38SSrikanth Yalavarthi 		} else if ((be_16 >= -(int)(FP16_MSB_M)) && (be_16 < 1)) {
4059637de38SSrikanth Yalavarthi 			/* underflow: zero / subnormal, be_16 = [-9:0] */
4069637de38SSrikanth Yalavarthi 			f16_e = 0;
4079637de38SSrikanth Yalavarthi 
4089637de38SSrikanth Yalavarthi 			/* add implicit leading zero */
4099637de38SSrikanth Yalavarthi 			m_32 = f32_m | BIT(FP32_LSB_E);
4109637de38SSrikanth Yalavarthi 			tbits = FP32_LSB_E - FP16_LSB_E - be_16 + 1;
4119637de38SSrikanth Yalavarthi 			m_16 = m_32 >> tbits;
4129637de38SSrikanth Yalavarthi 
4139637de38SSrikanth Yalavarthi 			/* if non-leading truncated bits are set */
4149637de38SSrikanth Yalavarthi 			if ((f32_m & GENMASK_U32(tbits - 1, 0)) > BIT(tbits - 1)) {
4159637de38SSrikanth Yalavarthi 				m_16++;
4169637de38SSrikanth Yalavarthi 
4179637de38SSrikanth Yalavarthi 				/* overflow into exponent */
4189637de38SSrikanth Yalavarthi 				if (((m_16 & FP16_MASK_E) >> FP16_LSB_E) == 0x1)
4199637de38SSrikanth Yalavarthi 					f16_e++;
4209637de38SSrikanth Yalavarthi 			} else if ((f32_m & GENMASK_U32(tbits - 1, 0)) == BIT(tbits - 1)) {
4219637de38SSrikanth Yalavarthi 				/* if leading truncated bit is set */
4229637de38SSrikanth Yalavarthi 				if ((m_16 & 0x1) == 0x1) {
4239637de38SSrikanth Yalavarthi 					m_16++;
4249637de38SSrikanth Yalavarthi 
4259637de38SSrikanth Yalavarthi 					/* overflow into exponent */
4269637de38SSrikanth Yalavarthi 					if (((m_16 & FP16_MASK_E) >> FP16_LSB_E) == 0x1)
4279637de38SSrikanth Yalavarthi 						f16_e++;
4289637de38SSrikanth Yalavarthi 				}
4299637de38SSrikanth Yalavarthi 			}
4309637de38SSrikanth Yalavarthi 			f16_m = m_16 & FP16_MASK_M;
4319637de38SSrikanth Yalavarthi 		} else if (be_16 == -(int)(FP16_MSB_M + 1)) {
4329637de38SSrikanth Yalavarthi 			/* underflow: zero, be_16 = [-10] */
4339637de38SSrikanth Yalavarthi 			f16_e = 0;
4349637de38SSrikanth Yalavarthi 			if (f32_m != 0)
4359637de38SSrikanth Yalavarthi 				f16_m = 1;
4369637de38SSrikanth Yalavarthi 			else
4379637de38SSrikanth Yalavarthi 				f16_m = 0;
4389637de38SSrikanth Yalavarthi 		} else {
4399637de38SSrikanth Yalavarthi 			/* underflow: zero, be_16 = [-INF:-11] */
4409637de38SSrikanth Yalavarthi 			f16_e = 0;
4419637de38SSrikanth Yalavarthi 			f16_m = 0;
4429637de38SSrikanth Yalavarthi 		}
4439637de38SSrikanth Yalavarthi 
4449637de38SSrikanth Yalavarthi 		break;
4459637de38SSrikanth Yalavarthi 	}
4469637de38SSrikanth Yalavarthi 
4479637de38SSrikanth Yalavarthi 	u16 = FP16_PACK(f16_s, f16_e, f16_m);
4489637de38SSrikanth Yalavarthi 
4499637de38SSrikanth Yalavarthi 	return u16;
4509637de38SSrikanth Yalavarthi }
4519637de38SSrikanth Yalavarthi 
4528c9bfcb1SSrikanth Yalavarthi int
4539637de38SSrikanth Yalavarthi rte_ml_io_float32_to_float16(uint64_t nb_elements, void *input, void *output)
4549637de38SSrikanth Yalavarthi {
4559637de38SSrikanth Yalavarthi 	float *input_buffer;
4569637de38SSrikanth Yalavarthi 	uint16_t *output_buffer;
4579637de38SSrikanth Yalavarthi 	uint64_t i;
4589637de38SSrikanth Yalavarthi 
4599637de38SSrikanth Yalavarthi 	if ((nb_elements == 0) || (input == NULL) || (output == NULL))
4609637de38SSrikanth Yalavarthi 		return -EINVAL;
4619637de38SSrikanth Yalavarthi 
4629637de38SSrikanth Yalavarthi 	input_buffer = (float *)input;
4639637de38SSrikanth Yalavarthi 	output_buffer = (uint16_t *)output;
4649637de38SSrikanth Yalavarthi 
4659637de38SSrikanth Yalavarthi 	for (i = 0; i < nb_elements; i++) {
4669637de38SSrikanth Yalavarthi 		*output_buffer = __float32_to_float16_scalar_rtn(*input_buffer);
4679637de38SSrikanth Yalavarthi 
4689637de38SSrikanth Yalavarthi 		input_buffer = input_buffer + 1;
4699637de38SSrikanth Yalavarthi 		output_buffer = output_buffer + 1;
4709637de38SSrikanth Yalavarthi 	}
4719637de38SSrikanth Yalavarthi 
4729637de38SSrikanth Yalavarthi 	return 0;
4739637de38SSrikanth Yalavarthi }
4749637de38SSrikanth Yalavarthi 
4759637de38SSrikanth Yalavarthi /* Convert a half precision floating point number (float16) into a single precision
4769637de38SSrikanth Yalavarthi  * floating point number (float32).
4779637de38SSrikanth Yalavarthi  */
4789637de38SSrikanth Yalavarthi static float
4799637de38SSrikanth Yalavarthi __float16_to_float32_scalar_rtx(uint16_t f16)
4809637de38SSrikanth Yalavarthi {
4819637de38SSrikanth Yalavarthi 	union float32 f32; /* float32 output */
4829637de38SSrikanth Yalavarthi 	uint16_t f16_s;	   /* float16 sign */
4839637de38SSrikanth Yalavarthi 	uint16_t f16_e;	   /* float16 exponent */
4849637de38SSrikanth Yalavarthi 	uint16_t f16_m;	   /* float16 mantissa */
4859637de38SSrikanth Yalavarthi 	uint32_t f32_s;	   /* float32 sign */
4869637de38SSrikanth Yalavarthi 	uint32_t f32_e;	   /* float32 exponent */
4879637de38SSrikanth Yalavarthi 	uint32_t f32_m;	   /* float32 mantissa*/
4889637de38SSrikanth Yalavarthi 	uint8_t shift;	   /* number of bits to be shifted */
4899637de38SSrikanth Yalavarthi 	uint32_t clz;	   /* count of leading zeroes */
4909637de38SSrikanth Yalavarthi 	int e_16;	   /* float16 exponent unbiased */
4919637de38SSrikanth Yalavarthi 
4929637de38SSrikanth Yalavarthi 	f16_s = (f16 & FP16_MASK_S) >> FP16_LSB_S;
4939637de38SSrikanth Yalavarthi 	f16_e = (f16 & FP16_MASK_E) >> FP16_LSB_E;
4949637de38SSrikanth Yalavarthi 	f16_m = (f16 & FP16_MASK_M) >> FP16_LSB_M;
4959637de38SSrikanth Yalavarthi 
4969637de38SSrikanth Yalavarthi 	f32_s = f16_s;
4979637de38SSrikanth Yalavarthi 	switch (f16_e) {
4989637de38SSrikanth Yalavarthi 	case (FP16_MASK_E >> FP16_LSB_E): /* float16: infinity or nan */
4999637de38SSrikanth Yalavarthi 		f32_e = FP32_MASK_E >> FP32_LSB_E;
5009637de38SSrikanth Yalavarthi 		if (f16_m == 0x0) { /* infinity */
5019637de38SSrikanth Yalavarthi 			f32_m = f16_m;
5029637de38SSrikanth Yalavarthi 		} else { /* nan, propagate mantissa, set MSB of mantissa to 1 */
5039637de38SSrikanth Yalavarthi 			f32_m = f16_m;
5049637de38SSrikanth Yalavarthi 			shift = FP32_MSB_M - FP16_MSB_M;
5059637de38SSrikanth Yalavarthi 			f32_m = (f32_m << shift) & FP32_MASK_M;
5069637de38SSrikanth Yalavarthi 			f32_m |= BIT(FP32_MSB_M);
5079637de38SSrikanth Yalavarthi 		}
5089637de38SSrikanth Yalavarthi 		break;
5099637de38SSrikanth Yalavarthi 	case 0: /* float16: zero or sub-normal */
5109637de38SSrikanth Yalavarthi 		f32_m = f16_m;
5119637de38SSrikanth Yalavarthi 		if (f16_m == 0) { /* zero signed */
5129637de38SSrikanth Yalavarthi 			f32_e = 0;
5139637de38SSrikanth Yalavarthi 		} else { /* subnormal numbers */
5143d4e27fdSDavid Marchand 			clz = rte_clz32((uint32_t)f16_m) - sizeof(uint32_t) * 8 + FP16_LSB_E;
5159637de38SSrikanth Yalavarthi 			e_16 = (int)f16_e - clz;
5169637de38SSrikanth Yalavarthi 			f32_e = FP32_BIAS_E + e_16 - FP16_BIAS_E;
5179637de38SSrikanth Yalavarthi 
5189637de38SSrikanth Yalavarthi 			shift = clz + (FP32_MSB_M - FP16_MSB_M) + 1;
5199637de38SSrikanth Yalavarthi 			f32_m = (f32_m << shift) & FP32_MASK_M;
5209637de38SSrikanth Yalavarthi 		}
5219637de38SSrikanth Yalavarthi 		break;
5229637de38SSrikanth Yalavarthi 	default: /* normal numbers */
5239637de38SSrikanth Yalavarthi 		f32_m = f16_m;
5249637de38SSrikanth Yalavarthi 		e_16 = (int)f16_e;
5259637de38SSrikanth Yalavarthi 		f32_e = FP32_BIAS_E + e_16 - FP16_BIAS_E;
5269637de38SSrikanth Yalavarthi 
5279637de38SSrikanth Yalavarthi 		shift = (FP32_MSB_M - FP16_MSB_M);
5289637de38SSrikanth Yalavarthi 		f32_m = (f32_m << shift) & FP32_MASK_M;
5299637de38SSrikanth Yalavarthi 	}
5309637de38SSrikanth Yalavarthi 
5319637de38SSrikanth Yalavarthi 	f32.u = FP32_PACK(f32_s, f32_e, f32_m);
5329637de38SSrikanth Yalavarthi 
5339637de38SSrikanth Yalavarthi 	return f32.f;
5349637de38SSrikanth Yalavarthi }
5359637de38SSrikanth Yalavarthi 
5368c9bfcb1SSrikanth Yalavarthi int
5379637de38SSrikanth Yalavarthi rte_ml_io_float16_to_float32(uint64_t nb_elements, void *input, void *output)
5389637de38SSrikanth Yalavarthi {
5399637de38SSrikanth Yalavarthi 	uint16_t *input_buffer;
5409637de38SSrikanth Yalavarthi 	float *output_buffer;
5419637de38SSrikanth Yalavarthi 	uint64_t i;
5429637de38SSrikanth Yalavarthi 
5439637de38SSrikanth Yalavarthi 	if ((nb_elements == 0) || (input == NULL) || (output == NULL))
5449637de38SSrikanth Yalavarthi 		return -EINVAL;
5459637de38SSrikanth Yalavarthi 
5469637de38SSrikanth Yalavarthi 	input_buffer = (uint16_t *)input;
5479637de38SSrikanth Yalavarthi 	output_buffer = (float *)output;
5489637de38SSrikanth Yalavarthi 
5499637de38SSrikanth Yalavarthi 	for (i = 0; i < nb_elements; i++) {
5509637de38SSrikanth Yalavarthi 		*output_buffer = __float16_to_float32_scalar_rtx(*input_buffer);
5519637de38SSrikanth Yalavarthi 
5529637de38SSrikanth Yalavarthi 		input_buffer = input_buffer + 1;
5539637de38SSrikanth Yalavarthi 		output_buffer = output_buffer + 1;
5549637de38SSrikanth Yalavarthi 	}
5559637de38SSrikanth Yalavarthi 
5569637de38SSrikanth Yalavarthi 	return 0;
5579637de38SSrikanth Yalavarthi }
558