def test_regression_estimator_binop_delay_expression_divide(self): def gen_operation(result_bit_count, operand_bit_count): return 'op: "kFoo" bit_count: %d operands { } operands { bit_count: %d }' % ( result_bit_count, operand_bit_count) data_points_str = [ 'operation { %s } delay: 5 delay_offset: 0' % gen_operation(10, 2), 'operation { %s } delay: 4 delay_offset: 0' % gen_operation(4, 1), 'operation { %s } delay: 4 delay_offset: 0' % gen_operation(20, 5), 'operation { %s } delay: 7 delay_offset: 0' % gen_operation(49, 7), 'operation { %s } delay: 5 delay_offset: 0' % gen_operation(50, 10), 'operation { %s } delay: 2 delay_offset: 0' % gen_operation(30, 15), ] expression = delay_model_pb2.DelayExpression() expression.bin_op = delay_model_pb2.DelayExpression.BinaryOperation.DIVIDE expression.lhs_expression.factor.source = \ delay_model_pb2.DelayFactor.Source.RESULT_BIT_COUNT expression.rhs_expression.factor.source = \ delay_model_pb2.DelayFactor.Source.OPERAND_BIT_COUNT expression.rhs_expression.factor.operand_number = 1 foo = delay_model.RegressionEstimator( 'kFoo', (expression, ), tuple(_parse_data_point(s) for s in data_points_str)) self.assertAlmostEqual(foo.operation_delay( _parse_operation(gen_operation(15, 15.0))), 1, delta=1) # Note: operation_delay will round to nearest int. self.assertAlmostEqual(foo.operation_delay( _parse_operation(gen_operation(45, 20))), 2.25, delta=1) self.assertAlmostEqual(foo.operation_delay( _parse_operation(gen_operation(20, 45))), 0.4444, delta=1) self.assertAlmostEqual(foo.operation_delay( _parse_operation(gen_operation(81, 9))), 9, delta=1) self.assertAlmostEqual(foo.operation_delay( _parse_operation(gen_operation(256, 2))), 128, delta=1) expression_str = r"""(static_cast<float>(node->GetType()->GetFlatBitCount()) / static_cast<float>(node->operand(1)->GetType()->GetFlatBitCount()))""" self.assertEqualIgnoringWhitespaceAndFloats( foo.cpp_delay_code('node'), r""" return std::round( 0.0 + 0.0 * {expr} + 0.0 * std::log2({expr})); """.format(expr=expression_str))
def test_one_regression_estimator_operand_count(self): def gen_operation(operand_count): operands_str = 'operands { bit_count: 42 }' return 'op: "kFoo" bit_count: 42 %s' % ' '.join( [operands_str] * operand_count) data_points_str = [ 'operation { %s } delay: 10 delay_offset: 0' % gen_operation(1), 'operation { %s } delay: 11 delay_offset: 0' % gen_operation(2), 'operation { %s } delay: 12 delay_offset: 0' % gen_operation(4), 'operation { %s } delay: 13 delay_offset: 0' % gen_operation(8), ] operand_count = delay_model_pb2.DelayExpression() operand_count.factor.source = delay_model_pb2.DelayFactor.Source.OPERAND_COUNT foo = delay_model.RegressionEstimator( 'kFoo', (operand_count, ), tuple(_parse_data_point(s) for s in data_points_str)) self.assertAlmostEqual(foo.operation_delay( _parse_operation(gen_operation(1))), 10, delta=1) self.assertAlmostEqual(foo.operation_delay( _parse_operation(gen_operation(4))), 12, delta=1) self.assertAlmostEqual(foo.operation_delay( _parse_operation(gen_operation(256))), 18, delta=1) self.assertEqualIgnoringWhitespaceAndFloats( foo.cpp_delay_code('node'), r""" return std::round( 0.0 + 0.0 * static_cast<float>(node->operand_count()) + 0.0 * std::log2(static_cast<float>(node->operand_count()))); """)
def test_one_factor_regression_estimator(self): data_points_str = [ 'operation { op: "kFoo" bit_count: 2 } delay: 210 delay_offset: 10', 'operation { op: "kFoo" bit_count: 4 } delay: 410 delay_offset: 10', 'operation { op: "kFoo" bit_count: 6 } delay: 610 delay_offset: 10', 'operation { op: "kFoo" bit_count: 8 } delay: 810 delay_offset: 10', 'operation { op: "kFoo" bit_count: 10 } delay: 1010 delay_offset: 10', ] result_bit_count = delay_model_pb2.DelayExpression() result_bit_count.factor.source = delay_model_pb2.DelayFactor.Source.RESULT_BIT_COUNT foo = delay_model.RegressionEstimator( 'kFoo', (result_bit_count, ), tuple(_parse_data_point(s) for s in data_points_str)) self.assertAlmostEqual(foo.operation_delay( _parse_operation('op: "kFoo" bit_count: 2')), 200, delta=2) self.assertAlmostEqual(foo.operation_delay( _parse_operation('op: "kFoo" bit_count: 3')), 300, delta=2) self.assertAlmostEqual(foo.operation_delay( _parse_operation('op: "kFoo" bit_count: 5')), 500, delta=2) self.assertAlmostEqual(foo.operation_delay( _parse_operation('op: "kFoo" bit_count: 42')), 4200, delta=2) self.assertEqualIgnoringWhitespaceAndFloats( foo.cpp_delay_code('node'), r""" return std::round( 0.0 + 0.0 * static_cast<float>(node->GetType()->GetFlatBitCount()) + 0.0 * std::log2(static_cast<float>(node->GetType()->GetFlatBitCount()))); """)
def test_regression_estimator_binop_delay_expression_multiply(self): def gen_operation(result_bit_count, operand_bit_count): return 'op: "kFoo" bit_count: %d operands { } operands { bit_count: %d }' % ( result_bit_count, operand_bit_count) data_points_str = [ 'operation { %s } delay: 2 delay_offset: 0' % gen_operation(1, 2), 'operation { %s } delay: 4 delay_offset: 0' % gen_operation(4, 1), 'operation { %s } delay: 24 delay_offset: 0' % gen_operation(4, 6), 'operation { %s } delay: 91 delay_offset: 0' % gen_operation(7, 13), 'operation { %s } delay: 120 delay_offset: 0' % gen_operation(10, 12), 'operation { %s } delay: 450 delay_offset: 0' % gen_operation(30, 15), ] expression = delay_model_pb2.DelayExpression() expression.bin_op = delay_model_pb2.DelayExpression.BinaryOperation.MULTIPLY expression.lhs_expression.factor.source = \ delay_model_pb2.DelayFactor.Source.RESULT_BIT_COUNT expression.rhs_expression.factor.source = \ delay_model_pb2.DelayFactor.Source.OPERAND_BIT_COUNT expression.rhs_expression.factor.operand_number = 1 foo = delay_model.RegressionEstimator( 'kFoo', (expression, ), tuple(_parse_data_point(s) for s in data_points_str)) self.assertAlmostEqual(foo.operation_delay( _parse_operation(gen_operation(15, 15))), 225, delta=1) self.assertAlmostEqual(foo.operation_delay( _parse_operation(gen_operation(45, 20))), 900, delta=1) self.assertAlmostEqual(foo.operation_delay( _parse_operation(gen_operation(20, 45))), 900, delta=1) self.assertAlmostEqual(foo.operation_delay( _parse_operation(gen_operation(10, 25))), 250, delta=1) self.assertAlmostEqual(foo.operation_delay( _parse_operation(gen_operation(2, 8))), 16, delta=1) expression_str = r"""(static_cast<float>(node->GetType()->GetFlatBitCount()) * static_cast<float>(node->operand(1)->GetType()->GetFlatBitCount()))""" self.assertEqualIgnoringWhitespaceAndFloats( foo.cpp_delay_code('node'), r""" return std::round( 0.0 + 0.0 * {expr} + 0.0 * std::log2({expr})); """.format(expr=expression_str))
def test_regression_estimator_binop_delay_expression_power(self): def gen_operation(result_bit_count, operand_bit_count): return 'op: "kFoo" bit_count: %d operands { } operands { bit_count: %d }' % ( result_bit_count, operand_bit_count) data_points_str = [ 'operation { %s } delay: 2 delay_offset: 0' % gen_operation(1, 2), 'operation { %s } delay: 4 delay_offset: 0' % gen_operation(2, 1), 'operation { %s } delay: 8 delay_offset: 0' % gen_operation(3, 6), 'operation { %s } delay: 16 delay_offset: 0' % gen_operation(4, 13), 'operation { %s } delay: 32 delay_offset: 0' % gen_operation(5, 12), 'operation { %s } delay: 64 delay_offset: 0' % gen_operation(6, 15), ] expression = delay_model_pb2.DelayExpression() expression.bin_op = delay_model_pb2.DelayExpression.BinaryOperation.POWER expression.lhs_expression.constant = 2 expression.rhs_expression.factor.source = \ delay_model_pb2.DelayFactor.Source.RESULT_BIT_COUNT foo = delay_model.RegressionEstimator( 'kFoo', (expression, ), tuple(_parse_data_point(s) for s in data_points_str)) self.assertAlmostEqual(foo.operation_delay( _parse_operation(gen_operation(7, 15))), 128, delta=1) self.assertAlmostEqual(foo.operation_delay( _parse_operation(gen_operation(8, 20))), 256, delta=1) self.assertAlmostEqual(foo.operation_delay( _parse_operation(gen_operation(9, 45))), 512, delta=1) self.assertAlmostEqual(foo.operation_delay( _parse_operation(gen_operation(10, 25))), 1024, delta=1) expression_str = r"""pow(static_cast<float>(2), static_cast<float>(node->GetType()->GetFlatBitCount()))""" self.assertEqualIgnoringWhitespaceAndFloats( foo.cpp_delay_code('node'), r""" return std::round( 0.0 + 0.0 * {expr} + 0.0 * std::log2({expr})); """.format(expr=expression_str))
def test_regression_estimator_constant_delay_expression(self): def gen_operation(result_bit_count, operand_bit_count): return 'op: "kFoo" bit_count: %d operands { } operands { bit_count: %d }' % ( result_bit_count, operand_bit_count) data_points_str = [ 'operation { %s } delay: 99 delay_offset: 0' % gen_operation(1, 2), 'operation { %s } delay: 99 delay_offset: 0' % gen_operation(4, 1), 'operation { %s } delay: 99 delay_offset: 0' % gen_operation(4, 6), 'operation { %s } delay: 99 delay_offset: 0' % gen_operation(7, 13), 'operation { %s } delay: 99 delay_offset: 0' % gen_operation(10, 12), 'operation { %s } delay: 99 delay_offset: 0' % gen_operation(30, 15), ] expression = delay_model_pb2.DelayExpression() expression.constant = 99 # Not especially usuful tests since regression includes a # constant variable that could mask issues... foo = delay_model.RegressionEstimator( 'kFoo', (expression, ), tuple(_parse_data_point(s) for s in data_points_str)) self.assertAlmostEqual(foo.operation_delay( _parse_operation(gen_operation(15, 15))), 99, delta=1) self.assertAlmostEqual(foo.operation_delay( _parse_operation(gen_operation(45, 20))), 99, delta=1) self.assertAlmostEqual(foo.operation_delay( _parse_operation(gen_operation(20, 45))), 99, delta=1) # This test is useful though! expression_str = r"""static_cast<float>(99)""" self.assertEqualIgnoringWhitespaceAndFloats( foo.cpp_delay_code('node'), r""" return std::round( 0.0 + 0.0 * {expr} + 0.0 * std::log2({expr})); """.format(expr=expression_str))
def test_two_factor_regression_estimator(self): def gen_operation(result_bit_count, operand_bit_count): return 'op: "kFoo" bit_count: %d operands { } operands { bit_count: %d }' % ( result_bit_count, operand_bit_count) data_points_str = [ 'operation { %s } delay: 100 delay_offset: 0' % gen_operation(1, 2), 'operation { %s } delay: 125 delay_offset: 0' % gen_operation(4, 1), 'operation { %s } delay: 150 delay_offset: 0' % gen_operation(4, 6), 'operation { %s } delay: 175 delay_offset: 0' % gen_operation(7, 13), 'operation { %s } delay: 200 delay_offset: 0' % gen_operation(10, 12), 'operation { %s } delay: 400 delay_offset: 0' % gen_operation(30, 15), ] result_bit_count = delay_model_pb2.DelayExpression() result_bit_count.factor.source = delay_model_pb2.DelayFactor.Source.RESULT_BIT_COUNT operand_bit_count = delay_model_pb2.DelayExpression() operand_bit_count.factor.source = delay_model_pb2.DelayFactor.Source.OPERAND_BIT_COUNT operand_bit_count.factor.operand_number = 1 foo = delay_model.RegressionEstimator( 'kFoo', (result_bit_count, operand_bit_count), tuple(_parse_data_point(s) for s in data_points_str)) self.assertAlmostEqual(foo.operation_delay( _parse_operation(gen_operation(1, 2))), 100, delta=10) self.assertAlmostEqual(foo.operation_delay( _parse_operation(gen_operation(10, 12))), 200, delta=10) self.assertAlmostEqual(foo.operation_delay( _parse_operation(gen_operation(8, 8))), 200, delta=50) self.assertEqualIgnoringWhitespaceAndFloats( foo.cpp_delay_code('node'), r""" return std::round( 0.0 + 0.0 * static_cast<float>(node->GetType()->GetFlatBitCount()) + 0.0 * std::log2(static_cast<float>(node->GetType()->GetFlatBitCount())) + 0.0 * static_cast<float>(node->operand(1)->GetType()->GetFlatBitCount()) + 0.0 * std::log2(static_cast<float>(node->operand(1)->GetType()->GetFlatBitCount()))); """)