def _run_variadic_bitwise(
        op: str, model: delay_model_pb2.DelayModel,
        stub: synthesis_service_pb2_grpc.SynthesisServiceStub) -> None:
    """Characterize variadic bitwise ops."""
    # Add op_model to protobuf message
    add_op_model = model.op_models.add(op=op)
    expr = add_op_model.estimator.regression.expressions.add()
    expr.factor.source = delay_model_pb2.DelayFactor.OPERAND_BIT_COUNT
    expr.factor.operand_number = 0

    op = ENUM2NAME_MAP[op]

    # Compute samples
    widths = get_bit_widths()
    arity = list(range(2, 8))
    combs = itertools.product(widths, arity)
    results = []
    for bit_count, arity in combs:
        op_type = f'bits[{bit_count}]'
        ir_text = op_module_generator.generate_ir_package(
            op, op_type, (op_type, ) * arity)
        result = _synthesize_ir(stub, ir_text, op, bit_count,
                                (bit_count, ) * arity)
        results.append(result)
    model.data_points.extend(results)
def _run_extension(
        op: str, model: delay_model_pb2.DelayModel,
        stub: synthesis_service_pb2_grpc.SynthesisServiceStub) -> None:
    """Characterize extension ops (sign- and zero-)."""
    # Add op_model to protobuf message
    add_op_model = model.op_models.add(op=op)
    expression = add_op_model.estimator.regression.expressions.add()
    expression.factor.source = delay_model_pb2.DelayFactor.OPERAND_BIT_COUNT
    expression.factor.operand_number = 0

    op = ENUM2NAME_MAP[op]

    # Compute samples
    widths = get_bit_widths()
    combs = filter(lambda b: b[1] > b[0], itertools.product(widths, widths))
    results = []
    for bit_count, new_bit_count in combs:
        op_type = f'bits[{bit_count}]'
        ret_type = f'bits[{new_bit_count}]'
        ir_text = op_module_generator.generate_ir_package(op,
                                                          ret_type,
                                                          (op_type, ),
                                                          attributes=[
                                                              ('new_bit_count',
                                                               new_bit_count)
                                                          ])
        result = _synthesize_ir(stub, ir_text, op, new_bit_count,
                                (bit_count, 64))
        results.append(result)
    model.data_points.extend(results)
 def test_8_bit_add_verilog(self):
     ir_text = opgen.generate_ir_package('add',
                                         output_type='bits[8]',
                                         operand_types=('bits[8]',
                                                        'bits[8]'))
     verilog_text = opgen.generate_verilog_module('add_module',
                                                  ir_text).verilog_text
     self.assertIn('module add_module', verilog_text)
     self.assertIn('p0_op0 + p0_op1', verilog_text)
    def test_mixed_width_mul(self):
        self.assertEqual(
            """package umul_characterization

fn main(op0: bits[27], op1: bits[5]) -> bits[42] {
  ret umul.1: bits[42] = umul(op0, op1)
}""",
            opgen.generate_ir_package('umul',
                                      output_type='bits[42]',
                                      operand_types=('bits[27]', 'bits[5]')))
    def test_8_bit_add(self):
        self.assertEqual(
            """package add_characterization

fn main(op0: bits[8], op1: bits[8]) -> bits[8] {
  ret add.1: bits[8] = add(op0, op1)
}""",
            opgen.generate_ir_package('add',
                                      output_type='bits[8]',
                                      operand_types=('bits[8]', 'bits[8]')))
    def test_sign_extend(self):
        self.assertEqual(
            """package sign_ext_characterization

fn main(op0: bits[16]) -> bits[32] {
  ret sign_ext.1: bits[32] = sign_ext(op0, new_bit_count=32)
}""",
            opgen.generate_ir_package('sign_ext',
                                      output_type='bits[32]',
                                      operand_types=('bits[16]', ),
                                      attributes=(('new_bit_count', '32'), )))
    def test_array_update(self):
        self.assertEqual(
            """package array_update_characterization

fn main(op0: bits[17][42], op1: bits[3], op2: bits[17]) -> bits[17][42] {
  ret array_update.1: bits[17][42] = array_update(op0, op1, op2)
}""",
            opgen.generate_ir_package('array_update',
                                      output_type='bits[17][42]',
                                      operand_types=('bits[17][42]', 'bits[3]',
                                                     'bits[17]')))
Exemple #8
0
    def test_array_index(self):
        self.assertEqual(
            """package array_index_characterization

fn main(op0: bits[17][42][10], op1: bits[32], op2: bits[3]) -> bits[17] {
  ret result: bits[17] = array_index(op0, indices=[op1, op2])
}""",
            opgen.generate_ir_package('array_index',
                                      output_type='bits[17]',
                                      operand_types=('bits[17][42][10]',
                                                     'bits[32]', 'bits[3]')))
Exemple #9
0
    def test_select_with_default(self):
        self.assertEqual(
            """package sel_characterization

fn main(op0: bits[2], op1: bits[32], op2: bits[32], op3: bits[32]) -> bits[32] {
  ret result: bits[32] = sel(op0, cases=[op1, op2], default=op3)
}""",
            opgen.generate_ir_package('sel',
                                      output_type='bits[32]',
                                      operand_types=('bits[2]', 'bits[32]',
                                                     'bits[32]', 'bits[32]')))
    def test_add_with_literal_operand(self):
        self.assertEqual(
            """package add_characterization

fn main(op0: bits[32]) -> bits[32] {
  literal.1: bits[32] = literal(value=0xd82c07cd)
  ret add.2: bits[32] = add(op0, literal.1)
}""",
            opgen.generate_ir_package('add',
                                      output_type='bits[32]',
                                      operand_types=('bits[32]', 'bits[32]'),
                                      literal_operand=1))
    def test_parallel_add_verilog(self):
        add8_ir = opgen.generate_ir_package('add',
                                            output_type='bits[8]',
                                            operand_types=('bits[8]',
                                                           'bits[8]'))
        add16_ir = opgen.generate_ir_package('add',
                                             output_type='bits[16]',
                                             operand_types=('bits[16]',
                                                            'bits[16]'))
        add24_ir = opgen.generate_ir_package('add',
                                             output_type='bits[24]',
                                             operand_types=('bits[24]',
                                                            'bits[24]'))

        modules = (opgen.generate_verilog_module('add8_module', add8_ir),
                   opgen.generate_verilog_module('add16_module', add16_ir),
                   opgen.generate_verilog_module('add24_module', add24_ir))
        parallel_module = opgen.generate_parallel_module(modules, 'foo')
        self.assertEqual(
            parallel_module,
            runfiles.get_contents_as_text(
                'xls/delay_model/testdata/parallel_op_module.vtxt'))
    def test_array_update_with_literal_operand(self):
        self.assertEqual(
            """package array_update_characterization

fn main(op1: bits[3], op2: bits[17]) -> bits[17][4] {
  literal.1: bits[17][4] = literal(value=[0x1b058, 0xc53e, 0x18412, 0x1c7ce])
  ret array_update.2: bits[17][4] = array_update(literal.1, op1, op2)
}""",
            opgen.generate_ir_package('array_update',
                                      output_type='bits[17][4]',
                                      operand_types=('bits[17][4]', 'bits[3]',
                                                     'bits[17]'),
                                      literal_operand=0))
Exemple #13
0
    def _generate_sources(
            self, op: op_pb2.OpProto,
            operand_types: Iterable[xls_type_pb2.TypeProto],
            output_type: xls_type_pb2.TypeProto) -> Tuple[str, str]:
        """Generates XLS IR and netlist sources for a single LEC execution.

    This function creates IR and a netlist for the given op and argument/output
    types, suitable as inputs to a LEC operation.

    Currently, this only supports a single op (per the internal operation of
    op_module_generator). In the future, it will likely be useful to see how
    execution time scales with operation composition.

    Args:
      op: The XLS IR opcode for which to generate sources.
      operand_types: The types of the arguments to use for this op execution.
      output_type: The type of the operation output.

    Returns:
      A tuple of IR and netlist sources for executing the given operation as
      text.
    """
        op_name = op_pb2.OpProto.Name(op)[3:].lower()
        operand_type_strs = [
            self._proto_to_ir_type(ot) for ot in operand_types
        ]
        ir_text = op_module_generator.generate_ir_package(
            op_name, self._proto_to_ir_type(output_type), operand_type_strs,
            [], None)
        verilog_text = op_module_generator.generate_verilog_module(
            self._MODULE_NAME, ir_text).verilog_text

        creds = client_credentials.get_credentials()
        netlist_text = None
        with grpc.secure_channel(self._synthesis_server_address,
                                 creds) as channel:
            grpc.channel_ready_future(channel).result()
            stub = synthesis_service_pb2_grpc.SynthesisServiceStub(channel)

            request = synthesis_pb2.CompileRequest()
            logging.vlog(logging.INFO, 'Module text:\n %s', verilog_text)
            request.module_text = verilog_text
            request.top_module_name = self._MODULE_NAME
            # We're always going to be in a single cycle.
            request.target_frequency_hz = 1

            response = stub.Compile(request)
            netlist_text = response.netlist

        return (ir_text, netlist_text)
def _synthesize_op_and_make_bare_data_point(
        op: str,
        kop: str,
        op_type: str,
        operand_types: List[str],
        stub: synthesis_service_pb2_grpc.SynthesisServiceStub,
        attributes: Sequence[Tuple[str, str]] = (),
        literal_operand: Optional[int] = None) -> delay_model_pb2.DataPoint:
    """Characterize an operation via synthesis server.

  Sets the area and op of the data point but not any other information about the
  node / operands.

  Args:
    op: Operation name to use for generating an IR package; e.g. 'add'.
    kop: Operation name to emit into datapoints, generally in kConstant form for
      use in the delay model; e.g. 'kAdd'.
    op_type: The type of the operation result.
    operand_types: The type of each operation.
    stub: Handle to the synthesis server.
    attributes: Attributes to include in the operation mnemonic. For example,
      "new_bit_count" in extend operations. Forwarded to generate_ir_package.
    literal_operand: Optionally specifies that the given operand number should
      be substituted with a randomly generated literal instead of a function
      parameter. Forwarded to generate_ir_package.

  Returns:
    datapoint produced via the synthesis server with the area and op (but no
    other fields)
    set.

  """
    ir_text = op_module_generator.generate_ir_package(op, op_type,
                                                      operand_types,
                                                      attributes,
                                                      literal_operand)
    module_name_safe_op_type = op_type.replace('[', '_').replace(']', '')
    module_name = f'{op}_{module_name_safe_op_type}'
    mod_generator_result = op_module_generator.generate_verilog_module(
        module_name, ir_text)
    top_name = module_name + '_wrapper'
    verilog_text = op_module_generator.generate_parallel_module(
        [mod_generator_result], top_name)

    response = _synth(stub, verilog_text, top_name)
    result = delay_model_pb2.DataPoint()
    _record_area(response, result)
    result.operation.op = kop

    return result
def _run_shift(op: str, model: delay_model_pb2.DelayModel,
               data_points: Dict[str, Set[str]],
               stub: synthesis_service_pb2_grpc.SynthesisServiceStub) -> None:
    """Characterize shift ops."""
    # Add op_model to protobuf message
    add_op_model = model.op_models.add(op=op)
    expr = add_op_model.estimator.regression.expressions.add()
    expr.factor.source = delay_model_pb2.DelayFactor.OPERAND_BIT_COUNT
    expr.factor.operand_number = 0

    op = ENUM2NAME_MAP[op]

    # Compute samples
    for bit_count in get_bit_widths():
        op_type = f'bits[{bit_count}]'
        ir_text = op_module_generator.generate_ir_package(
            op, op_type, (op_type, op_type))
        _synthesize_ir(stub, model, data_points, ir_text, op, bit_count,
                       (bit_count, ))
def _run_arithmetic_unary(
        op: str, model: delay_model_pb2.DelayModel,
        stub: synthesis_service_pb2_grpc.SynthesisServiceStub) -> None:
    """Characterize unary ops."""
    # Add op_model to protobuf message
    add_op_model = model.op_models.add(op=op)
    expr = add_op_model.estimator.regression.expressions.add()
    expr.factor.source = delay_model_pb2.DelayFactor.OPERAND_BIT_COUNT
    expr.factor.operand_number = 0

    op = ENUM2NAME_MAP[op]

    results = []
    for bit_count in get_bit_widths():
        op_type = f'bits[{bit_count}]'
        ir_text = op_module_generator.generate_ir_package(
            op, op_type, (op_type, ))
        result = _synthesize_ir(stub, ir_text, op, bit_count, (bit_count, ))
        results.append(result)
    model.data_points.extend(results)
 def test_invalid_ir(self):
     with self.assertRaisesRegex(Exception, 'does not match expected type'):
         opgen.generate_ir_package('and',
                                   output_type='bits[17]',
                                   operand_types=('bits[123]', 'bits[17]'))
Exemple #18
0
 def test_select_invalid_selector_type(self):
     with self.assertRaises(ValueError):
         opgen.generate_ir_package('sel',
                                   output_type='bits[32]',
                                   operand_types=('bits[1][2]', 'bits[32]',
                                                  'bits[32]'))