def testMixedTypeMathDoubleMode(self): switchable = FpBinarySwitchable(fp_mode=False, float_value=15.25) fp_bin = FpBinary(10, 8, signed=True, value=-0.25) self.assertEqual(switchable + fp_bin, 15.0) self.assertTrue(isinstance(switchable + fp_bin, FpBinarySwitchable)) self.assertEqual(fp_bin + switchable, 15.0) self.assertFalse((fp_bin + switchable).fp_mode) self.assertTrue(isinstance((fp_bin + switchable).value, float)) self.assertTrue(isinstance(fp_bin + switchable, FpBinarySwitchable)) self.assertEqual(switchable + -0.25, 15.0) self.assertTrue(isinstance(switchable + -0.25, FpBinarySwitchable)) self.assertEqual(-0.25 + switchable, 15.0) self.assertFalse((-0.25 + switchable).fp_mode) self.assertTrue(isinstance((-0.25 + switchable).value, float)) self.assertTrue(isinstance(-0.25 + switchable, FpBinarySwitchable)) switchable = FpBinarySwitchable(fp_mode=False, float_value=15.25) fp_bin = FpBinary(10, 8, signed=True, value=20.5) self.assertEqual(switchable - fp_bin, -5.25) self.assertTrue(isinstance(switchable - fp_bin, FpBinarySwitchable)) self.assertEqual(fp_bin - switchable, 5.25) self.assertFalse((fp_bin - switchable).fp_mode) self.assertTrue(isinstance((fp_bin - switchable).value, float)) self.assertTrue(isinstance(fp_bin - switchable, FpBinarySwitchable)) self.assertEqual(switchable - 20.5, -5.25) self.assertTrue(isinstance(switchable - 20.5, FpBinarySwitchable)) self.assertEqual(20.5 - switchable, 5.25) self.assertFalse((20.5 - switchable).fp_mode) self.assertTrue(isinstance((20.5 - switchable).value, float)) self.assertTrue(isinstance(20.5 - switchable, FpBinarySwitchable)) switchable = FpBinarySwitchable(fp_mode=False, float_value=-3.125) fp_bin = FpBinary(10, 8, signed=True, value=-2.0) self.assertEqual(switchable * fp_bin, 6.25) self.assertTrue(isinstance(switchable * fp_bin, FpBinarySwitchable)) self.assertEqual(fp_bin * switchable, 6.25) self.assertFalse((fp_bin * switchable).fp_mode) self.assertTrue(isinstance((fp_bin * switchable).value, float)) self.assertTrue(isinstance(fp_bin * switchable, FpBinarySwitchable)) self.assertEqual(switchable * -2.0, 6.25) self.assertTrue(isinstance(switchable * -2.0, FpBinarySwitchable)) self.assertEqual(-2.0 * switchable, 6.25) self.assertFalse((-2.0 * switchable).fp_mode) self.assertTrue(isinstance((-2.0 * switchable).value, float)) self.assertTrue(isinstance(-2.0 * switchable, FpBinarySwitchable)) switchable = FpBinarySwitchable(fp_mode=False, float_value=3.0) fp_bin = FpBinary(10, 8, signed=True, value=1.5) self.assertEqual(switchable / fp_bin, 2.0) self.assertTrue(isinstance(switchable / fp_bin, FpBinarySwitchable)) self.assertEqual(fp_bin / switchable, 0.5) self.assertFalse((fp_bin / switchable).fp_mode) self.assertTrue(isinstance((fp_bin / switchable).value, float)) self.assertTrue(isinstance(fp_bin / switchable, FpBinarySwitchable)) self.assertEqual(switchable / 1.5, 2.0) self.assertTrue(isinstance(switchable / 1.5, FpBinarySwitchable)) self.assertEqual(1.5 / switchable, 0.5) self.assertFalse((1.5 / switchable).fp_mode) self.assertTrue(isinstance((1.5 / switchable).value, float)) self.assertTrue(isinstance(1.5 / switchable, FpBinarySwitchable))
def testFormatProperty(self): fp_num = FpBinarySwitchable(True, fp_value=FpBinary(8, 8, signed=True, value=-56.89)) self.assertEqual(fp_num.format, (8, 8)) fp_num = FpBinarySwitchable(True, fp_value=FpBinary(-2, 8, signed=True, value=-0.0625)) self.assertEqual(fp_num.format, (-2, 8)) fp_num = FpBinarySwitchable(True, fp_value=FpBinary(10, -4, signed=True, value=32.0)) self.assertEqual(fp_num.format, (10, -4)) # Check floating point mode doesn't raise an exception fp_num = FpBinarySwitchable(False, float_value=1.3125) the_format = fp_num.format
def img_to_bin(source, dest, val_line=1): """Write image to binary file.""" os.makedirs(dest, exist_ok=True) img_fixed, img_float, img_bin = [], [], [] tmp_fixed, tmp_float = [], [] for index, item in enumerate(np.nditer(source)): # write to first position of line (order needed at BRAM) item_fixed = to_binary_string(FpBinary(8, 0, signed=False, value=item)) tmp_fixed.insert(0, item_fixed) tmp_float.insert(0, "%s %d " % (item_fixed, item)) img_bin.append(int(item_fixed, 2).to_bytes(1, byteorder="big")) if (index + 1) % val_line == 0: img_fixed.extend(tmp_fixed + ["\n"]) tmp_fixed = [] img_float.extend(tmp_float + ["\n"]) tmp_float = [] with open(dest + "/IMAGE.txt", "w") as outfile: outfile.write("".join(img_fixed)) with open(dest + "/IMAGE_DEBUG.txt", "w") as outfile: outfile.write("".join(img_float)) with open(dest + "/IMAGE.bin", "wb") as outfile: outfile.write(b"".join(img_bin))
def testCopy(self): fp_num = FpBinarySwitchable(True, fp_value=FpBinary(10, 10, signed=True, value=1.3125)) fp_num.value = fp_num - 1.0 fp_num.value = fp_num + 10.0 fp_num.value = FpBinarySwitchable(True, fp_value=FpBinary(10, 10, signed=True, value=1.3125)) fp_copy = copy.copy(fp_num) self.assertTrue(test_utils.fp_binary_instances_are_totally_equal(fp_num, fp_copy)) self.assertFalse(fp_num is fp_copy) fp_num = FpBinarySwitchable(False, float_value=1.3125) # Provide some min and max values fp_num.value = fp_num - 1.0 fp_num.value = fp_num + 10.0 fp_num.value = 1.3125 fp_copy = copy.copy(fp_num) self.assertTrue(test_utils.fp_binary_instances_are_totally_equal(fp_num, fp_copy)) self.assertFalse(fp_num is fp_copy)
def testBitShifts(self): # fp mode switchable = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(16, 16, signed=True, value=5.875)) self.assertEqual(switchable << long(2), 23.5) self.assertEqual(switchable >> long(3), 0.734375) # double mode (shifts are mult/div by 2 switchable = FpBinarySwitchable(fp_mode=False, float_value=5.875) self.assertEqual(switchable << long(2), 23.5) self.assertEqual(switchable >> long(3), 0.734375)
def testCopy(self): fp_num = FpBinarySwitchable(True, fp_value=FpBinary(10, 10, signed=True, value=1.3125)) fp_copy = copy.copy(fp_num) self.assertEqual(fp_num, fp_copy) self.assertFalse(fp_num is fp_copy) fp_num = FpBinarySwitchable(False, float_value=1.3125) fp_copy = copy.copy(fp_num) self.assertEqual(fp_num, fp_copy) self.assertFalse(fp_num is fp_copy)
def testResizeFpMode(self): # Wrap b01.0101 -> b01.01 fp_num = FpBinarySwitchable(True, fp_value=FpBinary(10, 10, signed=True, value=1.3125), float_value=4.5) self.assertEqual(fp_num.resize((2, 2), overflow_mode=OverflowEnum.wrap, round_mode=RoundingEnum.direct_neg_inf), 1.25) self.assertEqual(fp_num.format, (2, 2)) # Round Up b01.0101 -> b01.011 fp_num = FpBinarySwitchable(True, fp_value=FpBinary(10, 10, signed=True, value=1.3125), float_value=4.5) self.assertEqual(fp_num.resize((2, 3), overflow_mode=OverflowEnum.wrap, round_mode=RoundingEnum.near_pos_inf), 1.375) self.assertEqual(fp_num.format, (2, 3)) # Check no exception with floating point mode fp_num = FpBinarySwitchable(False, float_value=54.000987) fp_num.resize((2, 2), overflow_mode=OverflowEnum.wrap, round_mode=RoundingEnum.direct_neg_inf)
def create_stimuli(root, bitwidth, leaky, sample_cnt: int = 1): a_rand = random_fixed_array((sample_cnt), bitwidth) a_in = v_to_fixedint(a_rand) np.savetxt(join(root, "src", "input_" + "leaky" * leaky + ".csv"), a_in, delimiter=", ", fmt="%3d") a_out = (relu(a_rand) if not leaky else leaky_relu( a_rand, FpBinary(int_bits=0, frac_bits=3, value=0.125))) np.savetxt(join(root, "src", "output_" + "leaky" * leaky + ".csv"), v_to_fixedint(a_out), delimiter=", ", fmt="%3d")
def testValueSet(self): # Exception when in fp mode and set to object that isn't instance of # FpBinary or FpBinarySwitchable switchable = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(16, 16, signed=True, value=67.3453)) with self.assertRaises(TypeError): switchable.value = object() with self.assertRaises(TypeError): switchable.value = 1.0 with self.assertRaises(TypeError): switchable.value = 56 # Exception when not in fp mode and set to object that can't be cast # to a float switchable = FpBinarySwitchable(fp_mode=False, float_value=-45367.12345) with self.assertRaises(TypeError): switchable.value = object() with self.assertRaises(TypeError): switchable.value = 'test' # Valid types when in fp mode: FpBinary and FpBinarySwitchable switchable = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(16, 16, signed=True, value=-0.00123)) switchable.value = FpBinary(16, 16, signed=False, value=0.125) self.assertEqual(switchable, 0.125) self.assertEqual(switchable.value, 0.125) switchable.value = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(16, 16, signed=True, value=-0.0625)) self.assertEqual(switchable, -0.0625) self.assertEqual(switchable.value, -0.0625) # Valid types when not in fp mode: float castable switchable = FpBinarySwitchable(fp_mode=False, float_value=0.0001234) switchable.value = -678.987 self.assertEqual(switchable, -678.987) self.assertEqual(switchable.value, -678.987) switchable.value = 45 self.assertEqual(switchable, 45) self.assertEqual(switchable.value, 45)
def numpy_inference(onnx_model, input_): """Calculate the inference of a given input with a given model.""" weights_dict = {} for init in onnx_model.graph.initializer: weights_dict[init.name] = numpy_helper.to_array(init) next_input = input_ for node in onnx_model.graph.node: params = parse_param.parse_node_attributes(node) if node.op_type == "Conv": raise NotSupportedError(f"Layer {node.op_type} not supported.") if node.op_type == "QLinearConv": pad = parse_param.get_pad(params) if pad: next_input = cnn_reference.zero_pad(next_input, pad) ksize, stride = parse_param.get_kernel_params(params) int_bits_weights = 8 - int(math.log2(weights_dict[node.input[4]])) frac_bits_weights = int(math.log2(weights_dict[node.input[4]])) weights = to_fixed_point_array(weights_dict[node.input[3]], int_bits=int_bits_weights, frac_bits=frac_bits_weights) bias = to_fixed_point_array(weights_dict[node.input[8]], int_bits=int_bits_weights, frac_bits=frac_bits_weights) bitwidth_out = ( 8 - int(math.log2(weights_dict[node.input[6]])), int(math.log2(weights_dict[node.input[6]])), ) next_input = cnn_reference.conv(next_input, weights, bias, (ksize, stride), bitwidth_out) elif node.op_type == "MaxPool": ksize, stride = parse_param.get_kernel_params(params) next_input = cnn_reference.max_pool(next_input, ksize, stride) elif node.op_type == "GlobalAveragePool": next_input = cnn_reference.avg_pool(next_input) elif node.op_type == "Relu": next_input = cnn_reference.relu(next_input) elif node.op_type == "LeakyRelu": next_input = cnn_reference.leaky_relu( next_input, FpBinary(int_bits=0, frac_bits=3, value=0.125)) return next_input
def testDoubleVsFpModeMath(self): # fixed point mode takes precedence double_num = FpBinarySwitchable(fp_mode=False, float_value=1.5) fp_num = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(10, 3, signed=True, value=3.0)) self.assertEqual(double_num + fp_num, 4.5) self.assertTrue((double_num + fp_num).fp_mode) self.assertTrue(isinstance((double_num + fp_num).value, FpBinary)) self.assertEqual(fp_num + double_num, 4.5) self.assertTrue((fp_num + double_num).fp_mode) self.assertTrue(isinstance((fp_num + double_num).value, FpBinary)) self.assertEqual(double_num - fp_num, -1.5) self.assertTrue((double_num - fp_num).fp_mode) self.assertTrue(isinstance((double_num - fp_num).value, FpBinary)) self.assertEqual(fp_num - double_num, 1.5) self.assertTrue((fp_num - double_num).fp_mode) self.assertTrue(isinstance((fp_num - double_num).value, FpBinary)) self.assertEqual(double_num * fp_num, 4.5) self.assertTrue((double_num * fp_num).fp_mode) self.assertTrue(isinstance((double_num * fp_num).value, FpBinary)) self.assertEqual(fp_num * double_num, 4.5) self.assertTrue((fp_num * double_num).fp_mode) self.assertTrue(isinstance((fp_num * double_num).value, FpBinary)) self.assertEqual(double_num / fp_num, 0.5) self.assertTrue((double_num / fp_num).fp_mode) self.assertTrue(isinstance((double_num / fp_num).value, FpBinary)) self.assertEqual(fp_num / double_num, 2.0) self.assertTrue((fp_num / double_num).fp_mode) self.assertTrue(isinstance((fp_num * double_num).value, FpBinary))
def build_create_params_fpswitchable_non_fpmode(int_bits, frac_bits, val): return (False, FpBinary(int_bits=int_bits, frac_bits=frac_bits, signed=True, value=val), val)
def testBasicMathFpMode(self): # Negate fpNum = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(10, 16, signed=True, value=12.125)) self.assertEqual(-fpNum, -12.125) self.assertTrue((-fpNum).fp_mode) self.assertTrue(isinstance((-fpNum).value, FpBinary)) fpNum = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(-7, 20, signed=True, value=0.0001220703125)) self.assertEqual(-fpNum, -0.0001220703125) self.assertTrue((-fpNum).fp_mode) self.assertTrue(isinstance((-fpNum).value, FpBinary)) fpNum = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(16, -8, signed=True, value=1024.0)) self.assertEqual(-fpNum, -1024.0) self.assertTrue((-fpNum).fp_mode) self.assertTrue(isinstance((-fpNum).value, FpBinary)) # Add fpNum1 = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(10, 16, signed=True, value=15.25)) fpNum2 = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(10, 16, signed=True, value=-0.25)) self.assertEqual(fpNum1 + fpNum2, 15.0) self.assertTrue((fpNum1 + fpNum2).fp_mode) self.assertTrue(isinstance((fpNum1 + fpNum2).value, FpBinary)) self.assertTrue(isinstance(fpNum1 + fpNum2, FpBinarySwitchable)) fpNum1 = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(10, 16, signed=True, value=15.03125)) fpNum2 = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(-3, 19, signed=True, value=-0.03125)) self.assertEqual(fpNum1 + fpNum2, 15.0) self.assertTrue((fpNum1 + fpNum2).fp_mode) self.assertTrue(isinstance((fpNum1 + fpNum2).value, FpBinary)) self.assertTrue(isinstance(fpNum1 + fpNum2, FpBinarySwitchable)) fpNum1 = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(10, 16, signed=True, value=15.0)) fpNum2 = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(10, -3, signed=True, value=8.0)) self.assertEqual(fpNum1 + fpNum2, 23.0) self.assertTrue((fpNum1 + fpNum2).fp_mode) self.assertTrue(isinstance((fpNum1 + fpNum2).value, FpBinary)) self.assertTrue(isinstance(fpNum1 + fpNum2, FpBinarySwitchable)) # Subtract fpNum1 = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(10, 16, signed=True, value=15.25)) fpNum2 = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(10, 16, signed=True, value=-0.25)) self.assertEqual(fpNum1 - fpNum2, 15.5) self.assertTrue((fpNum1 - fpNum2).fp_mode) self.assertTrue(isinstance((fpNum1 - fpNum2).value, FpBinary)) self.assertTrue(isinstance(fpNum1 - fpNum2, FpBinarySwitchable)) fpNum1 = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(10, 16, signed=True, value=15.03125)) fpNum2 = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(-3, 19, signed=True, value=-0.03125)) self.assertEqual(fpNum1 - fpNum2, 15.0625) self.assertTrue((fpNum1 - fpNum2).fp_mode) self.assertTrue(isinstance((fpNum1 - fpNum2).value, FpBinary)) self.assertTrue(isinstance(fpNum1 - fpNum2, FpBinarySwitchable)) fpNum1 = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(10, 16, signed=True, value=15.0)) fpNum2 = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(10, -3, signed=True, value=8.0)) self.assertEqual(fpNum1 - fpNum2, 7.0) self.assertTrue((fpNum1 - fpNum2).fp_mode) self.assertTrue(isinstance((fpNum1 + fpNum2).value, FpBinary)) self.assertTrue(isinstance(fpNum1 + fpNum2, FpBinarySwitchable)) # Multiply fpNum1 = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(100, 16, signed=True, value=0.0625)) fpNum2 = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(10, 16, signed=True, value=2.0)) self.assertEqual(fpNum1 * fpNum2, 0.125) self.assertTrue((fpNum1 * fpNum2).fp_mode) self.assertTrue(isinstance((fpNum1 * fpNum2).value, FpBinary)) self.assertTrue(isinstance(fpNum1 * fpNum2, FpBinarySwitchable)) fpNum1 = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(-3, 19, signed=True, value=-0.03125)) fpNum2 = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(10, 16, signed=True, value=6.25)) self.assertEqual(fpNum1 * fpNum2, -0.1953125) self.assertTrue((fpNum1 * fpNum2).fp_mode) self.assertTrue(isinstance((fpNum1 * fpNum2).value, FpBinary)) self.assertTrue(isinstance(fpNum1 * fpNum2, FpBinarySwitchable)) fpNum1 = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(10, 16, signed=True, value=2.5)) fpNum2 = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(12, -3, signed=True, value=-72.0)) self.assertEqual(fpNum1 * fpNum2, -180.0) self.assertTrue((fpNum1 * fpNum2).fp_mode) self.assertTrue(isinstance((fpNum1 + fpNum2).value, FpBinary)) self.assertTrue(isinstance(fpNum1 + fpNum2, FpBinarySwitchable)) # Divide fpNum1 = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(5, 5, signed=True, value=-3.0)) fpNum2 = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(5, 5, signed=True, value=2.0)) self.assertEqual(fpNum1 / fpNum2, -1.5) self.assertTrue((fpNum1 / fpNum2).fp_mode) self.assertTrue(isinstance((fpNum1 / fpNum2).value, FpBinary)) self.assertTrue(isinstance(fpNum1 / fpNum2, FpBinarySwitchable)) fpNum1 = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(-3, 19, signed=True, value=0.03125)) fpNum2 = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(10, 16, signed=True, value=-0.03125)) self.assertEqual(fpNum1 / fpNum2, -1.0) self.assertTrue((fpNum1 / fpNum2).fp_mode) self.assertTrue(isinstance((fpNum1 / fpNum2).value, FpBinary)) self.assertTrue(isinstance(fpNum1 / fpNum2, FpBinarySwitchable)) fpNum1 = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(10, 16, signed=True, value=80.0)) fpNum2 = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(8, -3, signed=True, value=-40.0)) self.assertEqual(fpNum1 / fpNum2, -2.0) self.assertTrue((fpNum1 / fpNum2).fp_mode) self.assertTrue(isinstance((fpNum1 + fpNum2).value, FpBinary)) self.assertTrue(isinstance(fpNum1 + fpNum2, FpBinarySwitchable)) # ABS fpNum = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(10, 16, signed=True, value=-12.125)) self.assertEqual(abs(fpNum), 12.125) self.assertTrue(abs(fpNum).fp_mode) self.assertTrue(isinstance(abs(fpNum).value, FpBinary)) self.assertTrue(isinstance(abs(fpNum1), FpBinarySwitchable)) fpNum = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(10, 16, signed=True, value=12.125)) self.assertEqual(abs(fpNum), 12.125) fpNum = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(-3, 19, signed=True, value=-0.0234375)) self.assertEqual(abs(fpNum), 0.0234375) self.assertTrue(abs(fpNum).fp_mode) self.assertTrue(isinstance(abs(fpNum).value, FpBinary)) self.assertTrue(isinstance(abs(fpNum1), FpBinarySwitchable)) fpNum = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(-3, 19, signed=True, value=0.0234375)) self.assertEqual(abs(fpNum), 0.0234375) fpNum = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(16, -8, signed=True, value=-256.0)) self.assertEqual(abs(fpNum), 256.0) self.assertTrue(abs(fpNum).fp_mode) self.assertTrue(isinstance(abs(fpNum).value, FpBinary)) self.assertTrue(isinstance(abs(fpNum1), FpBinarySwitchable)) fpNum = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(16, -8, signed=True, value=256.0)) self.assertEqual(abs(fpNum), 256.0)
and op1.max_value == op2.max_value and fp_binary_instances_are_totally_equal( op1.value, op2.value)) return (op1 == op2) # ================================================================================ # Generating and getting back pickled data from multiple versions. # This includes FpBinary and FpBinarySwitchable instances # ================================================================================ pickle_static_file_prefix = 'pickletest' pickle_static_file_dir = 'data' pickle_static_data = [ FpBinary(8, 8, signed=True, value=0.01234), FpBinary(8, 8, signed=True, value=-3.01234), FpBinary(8, 8, signed=False, value=0.01234), FpBinary(64 - 2, 2, signed=True, value=56.789), FpBinary(64 - 2, 2, signed=False, value=56.789), FpBinarySwitchable(fp_mode=False, fp_value=FpBinary(16, 16, signed=True, value=5.875)), FpBinarySwitchable(fp_mode=False, float_value=-45.6), # All ones, small size FpBinary(64 - 2, 2, signed=True, bit_field=(1 << 64) - 1), FpBinary(64 - 2, 2, signed=False, bit_field=(1 << 64) - 1), FpBinary(64 - 2, 3, signed=True, value=56436.25), FpBinary(64 - 2, 3, signed=False, value=56436.25), FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(64 - 2, 2, signed=True)),
import math from collections import deque from fpbinary import FpBinary, OverflowEnum, RoundingEnum # ====================================== # Basic FIR Demo data_path_len = 32 # Just a delay filter filter_len = 11 filter_coeffs = int(filter_len / 2) * [FpBinary(2, 30, value=0.0)] + \ [FpBinary(2, 30, value=1.0)] + \ int(filter_len / 2) * [FpBinary(2, 30, value=0.0)] # 32 bit data delay_line = deque(filter_len * [FpBinary(2, 30, value=0.0)], filter_len) def fir_next_sample(sample): # Allow for hardware specs guard_bits = int(math.log(filter_len, 2)) + 1 adder_bits = 48 adder_in_format = (2 + guard_bits, adder_bits - 2 - guard_bits) output_format = (2 + guard_bits, 32 - 2 - guard_bits) # Ensure data is correct format delay_line.appendleft( sample.resize(format=delay_line[0], overflow_mode=OverflowEnum.wrap)) accum = 0.0 for tap, coeff in zip(delay_line, filter_coeffs):
def testPickle(self): # Instances with min and max values set fp1 = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(16, 16, signed=True, value=5.875), float_value=5.875) fp1.value = FpBinary(16, 16, signed=True, value=-34.5) fp1.value = FpBinary(16, 16, signed=True, value=34.5) fp2 = FpBinarySwitchable(fp_mode=False, fp_value=FpBinary(16, 16, signed=True, value=5.875), float_value=5.875) fp2.value = FpBinary(16, 16, signed=True, value=-34.5) fp2.value = FpBinary(16, 16, signed=True, value=34.5) fp3 = FpBinarySwitchable(fp_mode=False, fp_value=FpBinary(16, 16, signed=True, value=5.875), float_value=5.875) fp3.value = -56.98 fp3.value = 26 fp_list = [ FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(16, 16, signed=True, value=5.875)), FpBinarySwitchable(fp_mode=False, fp_value=FpBinary(16, 16, signed=True, value=5.875)), FpBinarySwitchable(fp_mode=False, float_value=-45.6), # Extreme sized FpBinary instances FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(test_utils.get_small_type_size() - 2, 2, signed=True)), FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(test_utils.get_small_type_size() - 2, 3, signed=True)), FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(test_utils.get_small_type_size(), test_utils.get_small_type_size(), signed=True, bit_field=(1 << (test_utils.get_small_type_size() + 5)) + 23)), FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(test_utils.get_small_type_size(), test_utils.get_small_type_size(), signed=False, bit_field=(1 << (test_utils.get_small_type_size() * 2)) - 1)), fp1, fp2, fp3, ] for pickle_lib in pickle_libs: unpickled = None # Test saving of individual objects for test_case in fp_list: with open(pickle_test_file_name, 'wb') as f: pickle_lib.dump(test_case, f, pickle_lib.HIGHEST_PROTOCOL) with open(pickle_test_file_name, 'rb') as f: unpickled = pickle_lib.load(f) self.assertTrue( test_utils.fp_binary_instances_are_totally_equal(test_case, unpickled)) # Test that the unpickled object is usable self.assertEqual(test_case + 1.0, unpickled + 1.0) self.assertEqual(test_case * 2.0, unpickled * 2.0) # With append remove_pickle_file() for test_case in fp_list: with open(pickle_test_file_name, 'ab') as f: pickle_lib.dump(test_case, f, pickle_lib.HIGHEST_PROTOCOL) unpickled = [] with open(pickle_test_file_name, 'rb') as f: while True: try: unpickled.append(pickle_lib.load(f)) except: break for expected, loaded in zip(fp_list, unpickled): self.assertTrue( test_utils.fp_binary_instances_are_totally_equal(expected, loaded)) # Test saving of list of objects with open(pickle_test_file_name, 'wb') as f: pickle_lib.dump(fp_list, f, pickle_lib.HIGHEST_PROTOCOL) with open(pickle_test_file_name, 'rb') as f: unpickled = pickle_lib.load(f) for expected, loaded in zip(fp_list, unpickled): self.assertTrue( test_utils.fp_binary_instances_are_totally_equal(expected, loaded)) # Test that the unpickled object is usable self.assertEqual(expected - 2, loaded - 2) self.assertEqual(expected * 3, loaded * 3)
def testBasicMathFpMode(self): fpNum = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(10, 16, signed=True, value=12.125)) self.assertEqual(-fpNum, -12.125) self.assertTrue((-fpNum).fp_mode) self.assertTrue(isinstance((-fpNum).value, FpBinary)) fpNum1 = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(10, 16, signed=True, value=15.25)) fpNum2 = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(10, 16, signed=True, value=-0.25)) self.assertEqual(fpNum1 + fpNum2, 15.0) self.assertTrue((fpNum1 + fpNum2).fp_mode) self.assertTrue(isinstance((fpNum1 + fpNum2).value, FpBinary)) self.assertTrue(isinstance(fpNum1 + fpNum2, FpBinarySwitchable)) fpNum1 = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(10, 16, signed=True, value=15.25)) fpNum2 = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(10, 16, signed=True, value=-0.25)) self.assertEqual(fpNum1 - fpNum2, 15.5) self.assertTrue((fpNum1 - fpNum2).fp_mode) self.assertTrue(isinstance((fpNum1 - fpNum2).value, FpBinary)) self.assertTrue(isinstance(fpNum1 - fpNum2, FpBinarySwitchable)) fpNum1 = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(100, 16, signed=True, value=0.0625)) fpNum2 = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(10, 16, signed=True, value=2.0)) self.assertEqual(fpNum1 * fpNum2, 0.125) self.assertTrue((fpNum1 * fpNum2).fp_mode) self.assertTrue(isinstance((fpNum1 * fpNum2).value, FpBinary)) self.assertTrue(isinstance(fpNum1 * fpNum2, FpBinarySwitchable)) fpNum1 = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(5, 5, signed=True, value=-3.0)) fpNum2 = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(5, 5, signed=True, value=2.0)) self.assertEqual(fpNum1 / fpNum2, -1.5) self.assertTrue((fpNum1 / fpNum2).fp_mode) self.assertTrue(isinstance((fpNum1 / fpNum2).value, FpBinary)) self.assertTrue(isinstance(fpNum1 / fpNum2, FpBinarySwitchable)) fpNum = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(10, 16, signed=True, value=-12.125)) self.assertEqual(abs(fpNum), 12.125) self.assertTrue(abs(fpNum).fp_mode) self.assertTrue(isinstance(abs(fpNum).value, FpBinary)) self.assertTrue(isinstance(abs(fpNum1), FpBinarySwitchable)) fpNum = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(10, 16, signed=True, value=12.125)) self.assertEqual(abs(fpNum), 12.125)
from fpbinary import FpBinary, OverflowEnum, RoundingEnum # New fixed point number from float value FpBinary(int_bits=4, frac_bits=4, signed=True, value=2.5) # New fixed point number from float value, format set by another instance FpBinary(format_inst=FpBinary(int_bits=4, frac_bits=4, signed=True, value=2.5), signed=True, value=2.5) # The (int_bits, frac_bits) tuple can be accessed via the format property FpBinary(4, 6).format # If you are dealing with massive numbers such that the float value doesn't have # enough precision, you can define your value as a bit field (type int) fp_massive = FpBinary(int_bits=128, frac_bits=128, signed=True, bit_field=(1 << 255) + 1) # The default string rep uses floats, but the str_ex() method outputs a string that # preserves precision fp_massive fp_massive.str_ex() # The format can have negative int_bits or negative frac_bits so long as the total # bits is greater than 0. The meaning of a negative format value is that number of # bits is removed from the other format part, but the extreme bit position remains # the same. E.g.: # # a format of (-2, 10) gives 8 fractional bits, 0 integer bits and the fractional
def testDoubleVsFpModeBasic(self): switchable_double = FpBinarySwitchable(fp_mode=False, float_value=1.0 / 3.0) switchable_fp = FpBinarySwitchable(fp_mode=True, fp_value=FpBinary(10, 3, signed=True, value=(1.0 / 3.0))) self.assertNotEqual(switchable_double, switchable_fp) self.assertEqual(switchable_double, 1.0 / 3.0) self.assertEqual(switchable_fp, 0.375)
def gamma_fp(gamma): gamma_fp_value = FpBinary(int_bits=8, frac_bits=0, signed=False, value=gamma) return gamma_fp_value
return (op1.fp_mode == op2.fp_mode and op1.min_value == op2.min_value and op1.max_value == op2.max_value and fp_binary_instances_are_totally_equal(op1.value, op2.value)) return (op1 == op2) # ================================================================================ # Generating and getting back pickled data from multiple versions. # This includes FpBinary and FpBinarySwitchable instances # ================================================================================ pickle_static_file_prefix = 'pickletest' pickle_static_file_dir = 'data' pickle_static_data = [ FpBinary(8, 8, signed=True, value=0.01234), FpBinary(8, 8, signed=True, value=-3.01234), FpBinary(8, 8, signed=False, value=0.01234), FpBinary(get_small_type_size() - 2, 2, signed=True, value=56.789), FpBinary(get_small_type_size() - 2, 2, signed=False, value=56.789), FpBinarySwitchable(fp_mode=False, fp_value=FpBinary(16, 16, signed=True, value=5.875)), FpBinarySwitchable(fp_mode=False, float_value=-45.6), # All ones, small size FpBinary(get_small_type_size() - 2, 2, signed=True, bit_field=(1 << get_small_type_size()) - 1), FpBinary(get_small_type_size() - 2, 2, signed=False, bit_field=(1 << get_small_type_size()) - 1),