in scripts/float16.py [0:0]
def convert_np_to_float16(np_array, min_positive_val=1e-7, max_finite_val=1e4):
"""
Convert float32 numpy array to float16 without changing sign or finiteness.
Positive values less than min_positive_val are mapped to min_positive_val.
Positive finite values greater than max_finite_val are mapped to max_finite_val.
Similar for negative values. NaN, 0, inf, and -inf are unchanged.
"""
def between(a, b, c):
return np.logical_and(a < b, b < c)
positive_values = np_array[np.where(np_array > 0)]
if positive_values.shape[0] > 0:
pos_max = positive_values.max()
pos_min = positive_values.min()
if pos_max >= max_finite_val:
warnings.warn(
"the float32 number {} will be truncated to {}".format(
pos_max, max_finite_val
)
)
if pos_min <= min_positive_val:
warnings.warn(
"the float32 number {} will be truncated to {}".format(
pos_min, min_positive_val
)
)
negative_values = np_array[np.where(np_array < 0)]
if negative_values.shape[0] > 0:
neg_max = negative_values.max()
neg_min = negative_values.min()
if neg_min <= -max_finite_val:
warnings.warn(
"the float32 number {} will be truncated to {}".format(
neg_min, -max_finite_val
)
)
if neg_max >= -min_positive_val:
warnings.warn(
"the float32 number {} will be truncated to {}".format(
neg_max, -min_positive_val
)
)
np_array = np.where(
between(0, np_array, min_positive_val), min_positive_val, np_array
)
np_array = np.where(
between(-min_positive_val, np_array, 0), -min_positive_val, np_array
)
np_array = np.where(
between(max_finite_val, np_array, float("inf")), max_finite_val, np_array
)
np_array = np.where(
between(float("-inf"), np_array, -max_finite_val), -max_finite_val, np_array
)
return np.float16(np_array)