def test_evaluate_ir_wide(self):
     sample_dir = self._make_sample_dir()
     runner = sample_runner.SampleRunner(sample_dir)
     dslx_text = 'fn main(x: bits[100], y: bits[100]) -> bits[100] { x + y }'
     runner.run(
         sample.Sample(dslx_text, sample.SampleOptions(optimize_ir=False),
                       [[
                           interp_value_from_ir_string(
                               'bits[100]:{0:#x}'.format(10**30)),
                           interp_value_from_ir_string(
                               'bits[100]:{0:#x}'.format(10**30)),
                       ],
                        [
                            interp_value_from_ir_string(
                                'bits[100]:{0:#x}'.format(2**80)),
                            interp_value_from_ir_string(
                                'bits[100]:{0:#x}'.format(2**81)),
                        ]]))
     self.assertSequenceEqual(
         _split_nonempty_lines(sample_dir, 'sample.x.results'), [
             'bits[100]:0x9_3e59_39a0_8ce9_dbd4_8000_0000',
             'bits[100]:0x3_0000_0000_0000_0000_0000'
         ])
     self.assertSequenceEqual(
         _split_nonempty_lines(sample_dir, 'sample.ir.results'), [
             'bits[100]:0x9_3e59_39a0_8ce9_dbd4_8000_0000',
             'bits[100]:0x3_0000_0000_0000_0000_0000'
         ])
Example #2
0
 def test_dslx_to_ir(self):
     sample_dir = self._make_sample_dir()
     runner = sample_runner.SampleRunner(sample_dir)
     dslx_text = 'fn main(x: u8, y: u8) -> u8 { x + y }'
     runner.run(
         sample.Sample(dslx_text, sample.SampleOptions(optimize_ir=False)))
     self.assertIn('package sample', _read_file(sample_dir, 'sample.ir'))
Example #3
0
 def test_evaluate_ir_wide(self):
     sample_dir = self._make_sample_dir()
     runner = sample_runner.SampleRunner(sample_dir)
     dslx_text = 'fn main(x: bits[100], y: bits[100]) -> bits[100] { x + y }'
     runner.run(
         sample.Sample(
             dslx_text, sample.SampleOptions(optimize_ir=False),
             [[
                 Value.make_bits(Tag.UBITS,
                                 ir_bits.from_long(10**30, bit_count=100)),
                 Value.make_bits(Tag.UBITS,
                                 ir_bits.from_long(10**30, bit_count=100))
             ],
              [
                  Value.make_bits(Tag.UBITS,
                                  ir_bits.from_long(2**80, bit_count=100)),
                  Value.make_bits(Tag.UBITS,
                                  ir_bits.from_long(2**81, bit_count=100))
              ]]))
     self.assertSequenceEqual(
         _split_nonempty_lines(sample_dir, 'sample.x.results'), [
             'bits[100]:0x9_3e59_39a0_8ce9_dbd4_8000_0000',
             'bits[100]:0x3_0000_0000_0000_0000_0000'
         ])
     self.assertSequenceEqual(
         _split_nonempty_lines(sample_dir, 'sample.ir.results'), [
             'bits[100]:0x9_3e59_39a0_8ce9_dbd4_8000_0000',
             'bits[100]:0x3_0000_0000_0000_0000_0000'
         ])
Example #4
0
def run_sample(smp: sample.Sample,
               run_dir: Text,
               summary_file: Optional[Text] = None,
               generate_sample_ns: Optional[int] = None):
    """Runs the given sample in the given directory.

  Args:
    smp: Sample to run.
    run_dir: Directory to run the sample in. The directory should exist and be
      empty.
    summary_file: The (optional) file to append sample summary.
    generate_sample_ns: The (optional) time in nanoseconds to generate the
      sample. Recorded in the summary file, if given.

  Raises:
    sample_runner.SampleError: on any non-zero status from the sample runner.

  """
    start = time.time()

    _write_to_file(run_dir, 'sample.x', smp.input_text)
    _write_to_file(run_dir, 'options.json', smp.options.to_json())
    if smp.args_batch:
        _write_to_file(run_dir, 'args.txt',
                       sample.args_batch_to_text(smp.args_batch))

    # Create a script named 'run.sh' for rerunning the sample.
    args = [
        SAMPLE_RUNNER_MAIN_PATH, '--logtostderr', '--input_file=sample.x',
        '--options_file=options.json'
    ]
    if smp.args_batch:
        args.append('--args_file=args.txt')
    args.append(run_dir)
    _write_to_file(run_dir,
                   'run.sh',
                   f'#!/bin/sh\n\n{subprocess.list2cmdline(args)}\n',
                   executable=True)
    logging.vlog(1, 'Starting to run sample')
    logging.vlog(2, smp.input_text)
    runner = sample_runner.SampleRunner(run_dir)
    runner.run_from_files('sample.x', 'options.json', 'args.txt')
    timing = runner.timing

    timing.total_ns = int((time.time() - start) * 1e9)
    if generate_sample_ns:
        # The sample generation time, if given, is not part of the measured total
        # time, so add it in.
        timing.total_ns += generate_sample_ns
        timing.generate_sample_ns = generate_sample_ns

    logging.vlog(1, 'Completed running sample, elapsed: %0.2fs',
                 time.time() - start)

    if summary_file:
        _write_ir_summaries(run_dir, timing, summary_file)
Example #5
0
def run(run_dir: Text):
    """Runs the sample in the given run directory."""
    runner = sample_runner.SampleRunner(run_dir)
    input_filename = maybe_copy_file(FLAGS.input_file, run_dir)
    options_filename = maybe_copy_file(FLAGS.options_file, run_dir)
    if FLAGS.args_file:
        args_filename = maybe_copy_file(FLAGS.args_file, run_dir)
    else:
        args_filename = None
    runner.run_from_files(input_filename, options_filename, args_filename)
Example #6
0
 def test_interpret_mixed_signedness(self):
     sample_dir = self._make_sample_dir()
     runner = sample_runner.SampleRunner(sample_dir)
     dslx_text = 'fn main(x: u8, y: s8) -> s8 { (x as s8) + y }'
     runner.run(
         sample.Sample(dslx_text, sample.SampleOptions(optimize_ir=False),
                       [[Value.make_ubits(8, 42),
                         Value.make_sbits(8, 100)]]))
     self.assertEqual(
         _read_file(sample_dir, 'sample.x.results').strip(), 'bits[8]:0x8e')
Example #7
0
 def test_interpret_mixed_signedness_unsigned_inputs(self):
     sample_dir = self._make_sample_dir()
     runner = sample_runner.SampleRunner(sample_dir)
     dslx_text = 'fn main(x: u8, y: s8) -> s8 { (x as s8) + y }'
     runner.run(
         sample.Sample(
             dslx_text, sample.SampleOptions(optimize_ir=False),
             sample.parse_args_batch('bits[8]:0xb0; bits[8]:0x0a')))
     self.assertEqual(
         _read_file(sample_dir, 'sample.x.results').strip(), 'bits[8]:0xba')
Example #8
0
 def test_interpret_dslx_single_value(self):
     sample_dir = self._make_sample_dir()
     runner = sample_runner.SampleRunner(sample_dir)
     dslx_text = 'fn main(x: u8, y: u8) -> u8 { x + y }'
     runner.run(
         sample.Sample(dslx_text, sample.SampleOptions(convert_to_ir=False),
                       [[Value.make_ubits(8, 42),
                         Value.make_ubits(8, 100)]]))
     self.assertEqual(
         _read_file(sample_dir, 'sample.x.results').strip(), 'bits[8]:0x8e')
Example #9
0
 def test_bad_ir_input(self):
     sample_dir = self._make_sample_dir()
     runner = sample_runner.SampleRunner(sample_dir)
     ir_text = """bogus ir string"""
     with self.assertRaises(sample_runner.SampleError):
         runner.run(
             sample.Sample(ir_text,
                           sample.SampleOptions(input_is_dslx=False)))
     self.assertIn('Expected \'package\' keyword',
                   _read_file(sample_dir, 'opt_main.stderr'))
     self.assertRegex(_read_file(sample_dir, 'exception.txt'),
                      '.*opt_main.*returned non-zero exit status')
Example #10
0
 def test_interpret_mixed_signedness(self):
     sample_dir = self._make_sample_dir()
     runner = sample_runner.SampleRunner(sample_dir)
     dslx_text = 'fn main(x: u8, y: s8) -> s8 { (x as s8) + y }'
     runner.run(
         sample.Sample(
             dslx_text, sample.SampleOptions(optimize_ir=False), [[
                 interp_value_from_ir_string('bits[8]:42'),
                 interp_value_from_ir_string('bits[8]:100').to_signed()
             ]]))
     self.assertEqual(
         _read_file(sample_dir, 'sample.x.results').strip(), 'bits[8]:0x8e')
Example #11
0
 def test_interpret_opt_ir(self):
     sample_dir = self._make_sample_dir()
     runner = sample_runner.SampleRunner(sample_dir)
     dslx_text = 'fn main(x: u8, y: u8) -> u8 { x + y }'
     runner.run(
         sample.Sample(dslx_text, sample.SampleOptions(),
                       [[Value.make_ubits(8, 42),
                         Value.make_ubits(8, 100)]]))
     self.assertIn('package sample', _read_file(sample_dir,
                                                'sample.opt.ir'))
     self.assertSequenceEqual(
         _split_nonempty_lines(sample_dir, 'sample.opt.ir.results'),
         ['bits[8]:0x8e'])
Example #12
0
 def test_interpret_invalid_dslx(self):
     sample_dir = self._make_sample_dir()
     runner = sample_runner.SampleRunner(sample_dir)
     dslx_text = 'syntaxerror!!! fn main(x: u8, y: u8) -> u8 { x + y }'
     with self.assertRaises(sample_runner.SampleError):
         runner.run(
             sample.Sample(
                 dslx_text, sample.SampleOptions(convert_to_ir=False),
                 [[Value.make_ubits(8, 42),
                   Value.make_ubits(8, 100)]]))
     # Verify the exception text is written out to file.
     self.assertIn('Expected start of top-level construct',
                   _read_file(sample_dir, 'exception.txt'))
Example #13
0
 def test_interpret_dslx_multiple_values(self):
     sample_dir = self._make_sample_dir()
     runner = sample_runner.SampleRunner(sample_dir)
     dslx_text = 'fn main(x: u8, y: u8) -> u8 { x + y }'
     runner.run(
         sample.Sample(
             dslx_text, sample.SampleOptions(convert_to_ir=False),
             [[Value.make_ubits(8, 42),
               Value.make_ubits(8, 100)],
              [Value.make_ubits(8, 222),
               Value.make_ubits(8, 240)]]))
     self.assertSequenceEqual(
         _split_nonempty_lines(sample_dir, 'sample.x.results'),
         ['bits[8]:0x8e', 'bits[8]:0xce'])
Example #14
0
 def test_evaluate_ir_miscompare_single_result(self):
     sample_dir = self._make_sample_dir()
     runner = sample_runner.SampleRunner(sample_dir)
     dslx_text = 'fn main(x: u8, y: u8) -> u8 { x + y }'
     runner._evaluate_ir = lambda *args: (Value.make_ubits(8, 1), )
     with self.assertRaises(sample_runner.SampleError) as e:
         runner.run(
             sample.Sample(
                 dslx_text, sample.SampleOptions(optimize_ir=False),
                 [[Value.make_ubits(8, 42),
                   Value.make_ubits(8, 100)]]))
     self.assertIn('Result miscompare for sample 0', str(e.exception))
     self.assertIn('Result miscompare for sample 0',
                   _read_file(sample_dir, 'exception.txt'))
Example #15
0
 def test_evaluate_ir_miscompare_number_of_results(self):
     sample_dir = self._make_sample_dir()
     runner = sample_runner.SampleRunner(sample_dir)
     dslx_text = 'fn main(x: u8, y: u8) -> u8 { x + y }'
     runner._evaluate_ir = lambda *args: (Value.make_ubits(8, 100), )
     with self.assertRaises(sample_runner.SampleError) as e:
         runner.run(
             sample.Sample(dslx_text,
                           sample.SampleOptions(optimize_ir=False), []))
     self.assertIn(
         'Results for interpreted DSLX has 0 values, evaluated unopt IR (interpreter) has 1',
         str(e.exception))
     self.assertIn(
         'Results for interpreted DSLX has 0 values, evaluated unopt IR (interpreter) has 1',
         _read_file(sample_dir, 'exception.txt'))
Example #16
0
 def test_codegen_combinational_wrong_results(self):
     sample_dir = self._make_sample_dir()
     runner = sample_runner.SampleRunner(sample_dir)
     runner._simulate = lambda *args: (Value.make_ubits(8, 1), )
     dslx_text = 'fn main(x: u8, y: u8) -> u8 { x + y }'
     with self.assertRaises(sample_runner.SampleError) as e:
         runner.run(
             sample.Sample(
                 dslx_text,
                 sample.SampleOptions(
                     codegen=True,
                     codegen_args=['--generator=combinational'],
                     simulate=True,
                     simulator='iverilog'),
                 [[Value.make_ubits(8, 42),
                   Value.make_ubits(8, 100)]]))
     self.assertIn('Result miscompare for sample 0', str(e.exception))
Example #17
0
 def test_interpret_dslx_multiple_values(self):
     sample_dir = self._make_sample_dir()
     runner = sample_runner.SampleRunner(sample_dir)
     dslx_text = 'fn main(x: u8, y: u8) -> u8 { x + y }'
     runner.run(
         sample.Sample(dslx_text, sample.SampleOptions(convert_to_ir=False),
                       [[
                           interp_value_from_ir_string('bits[8]:42'),
                           interp_value_from_ir_string('bits[8]:100')
                       ],
                        [
                            interp_value_from_ir_string('bits[8]:222'),
                            interp_value_from_ir_string('bits[8]:240')
                        ]]))
     self.assertSequenceEqual(
         _split_nonempty_lines(sample_dir, 'sample.x.results'),
         ['bits[8]:0x8e', 'bits[8]:0xce'])
Example #18
0
    def test_ir_input(self):
        sample_dir = self._make_sample_dir()
        runner = sample_runner.SampleRunner(sample_dir)
        ir_text = """package foo

    fn foo(x: bits[8], y: bits[8]) -> bits[8] {
      ret add.1: bits[8] = add(x, y)
    }
    """
        runner.run(
            sample.Sample(ir_text, sample.SampleOptions(input_is_dslx=False),
                          [[Value.make_ubits(8, 42),
                            Value.make_ubits(8, 100)]]))
        self.assertIn('package foo', _read_file(sample_dir, 'sample.ir'))
        self.assertIn('package foo', _read_file(sample_dir, 'sample.opt.ir'))
        self.assertSequenceEqual(
            _split_nonempty_lines(sample_dir, 'sample.opt.ir.results'),
            ['bits[8]:0x8e'])
Example #19
0
 def test_codegen_pipeline(self):
     sample_dir = self._make_sample_dir()
     print('sample_dir = ' + sample_dir)
     runner = sample_runner.SampleRunner(sample_dir)
     dslx_text = 'fn main(x: u8, y: u8) -> u8 { x + y }'
     runner.run(
         sample.Sample(
             dslx_text,
             sample.SampleOptions(codegen=True,
                                  codegen_args=('--generator=pipeline',
                                                '--pipeline_stages=2'),
                                  simulate=True),
             [[Value.make_ubits(8, 42),
               Value.make_ubits(8, 100)]]))
     # A pipelined block should have a blocking assignment.
     self.assertIn('<=', _read_file(sample_dir, 'sample.v'))
     self.assertSequenceEqual(
         _split_nonempty_lines(sample_dir, 'sample.v.results'),
         ['bits[8]:0x8e'])
Example #20
0
def run_sample(smp: sample.Sample,
               run_dir: Text,
               summary_file: Optional[Text] = None):
    """Runs the given sample in the given directory.

  Args:
    smp: Sample to run.
    run_dir: Directory to run the sample in. The directory should exist and be
      empty.
    summary_file: The (optional) file to append sample summary.

  Raises:
    sample_runner.SampleError: on any non-zero status from the sample runner.
  """
    _write_to_file(run_dir, 'sample.x', smp.input_text)
    _write_to_file(run_dir, 'options.json', smp.options.to_json())
    if smp.args_batch:
        _write_to_file(run_dir, 'args.txt',
                       sample.args_batch_to_text(smp.args_batch))

    # Create a script named 'run.sh' for rerunning the sample.
    args = [
        SAMPLE_RUNNER_MAIN_PATH, '--logtostderr', '--input_file=sample.x',
        '--options_file=options.json'
    ]
    if smp.args_batch:
        args.append('--args_file=args.txt')
    args.append(run_dir)
    _write_to_file(run_dir,
                   'run.sh',
                   f'#!/bin/sh\n\n{subprocess.list2cmdline(args)}\n',
                   executable=True)
    start = time.time()
    logging.vlog(1, 'Starting to run sample')
    logging.vlog(2, smp.input_text)
    runner = sample_runner.SampleRunner(run_dir)
    runner.run_from_files('sample.x', 'options.json', 'args.txt')
    logging.vlog(1, 'Completed running sample, elapsed: %0.2fs',
                 time.time() - start)

    if summary_file:
        _write_ir_summaries(run_dir, summary_file)
Example #21
0
    def test_codegen_combinational(self):
        sample_dir = self._make_sample_dir()
        runner = sample_runner.SampleRunner(sample_dir)
        dslx_text = 'fn main(x: u8, y: u8) -> u8 { x + y }'
        runner.run(
            sample.Sample(
                dslx_text,
                sample.SampleOptions(
                    codegen=True,
                    codegen_args=['--generator=combinational'],
                    simulate=True),
                [[Value.make_ubits(8, 42),
                  Value.make_ubits(8, 100)]]))

        self.assertIn('endmodule', _read_file(sample_dir, 'sample.v'))
        # A combinational block should not have a blocking assignment.
        self.assertNotIn('<=', _read_file(sample_dir, 'sample.v'))
        self.assertSequenceEqual(
            _split_nonempty_lines(sample_dir, 'sample.v.results'),
            ['bits[8]:0x8e'])
Example #22
0
    def test_evaluate_ir_miscompare_number_of_results(self):
        sample_dir = self._make_sample_dir()
        runner = sample_runner.SampleRunner(sample_dir)
        dslx_text = 'fn main(x: u8, y: u8) -> u8 { x + y }'

        # Give back two results instead of one.
        def fake_evaluate_ir(*_):
            return (Value.make_ubits(8, 100), Value.make_ubits(8, 100))

        runner._evaluate_ir = fake_evaluate_ir
        args_batch = [(Value.make_ubits(8, 42), Value.make_ubits(8, 64))]
        with self.assertRaises(sample_runner.SampleError) as e:
            runner.run(
                sample.Sample(dslx_text,
                              sample.SampleOptions(optimize_ir=False),
                              args_batch))
        self.assertIn(
            'Results for evaluated unopt IR (JIT) has 2 values, interpreted DSLX has 1',
            str(e.exception))
        self.assertIn(
            'Results for evaluated unopt IR (JIT) has 2 values, interpreted DSLX has 1',
            _read_file(sample_dir, 'exception.txt'))
Example #23
0
    def test_interpret_opt_ir_miscompare(self):
        sample_dir = self._make_sample_dir()
        runner = sample_runner.SampleRunner(sample_dir)
        dslx_text = 'fn main(x: u8, y: u8) -> u8 { x + y }'
        results = [
            (Value.make_ubits(8, 100), ),  # correct result
            (Value.make_ubits(8, 100), ),  # correct result
            (Value.make_ubits(8, 0), ),  # incorrect result
        ]

        def result_gen(*_):
            return results.pop(0)

        runner._evaluate_ir = result_gen
        with self.assertRaises(sample_runner.SampleError) as e:
            runner.run(
                sample.Sample(
                    dslx_text, sample.SampleOptions(),
                    [[Value.make_ubits(8, 40),
                      Value.make_ubits(8, 60)]]))
        self.assertIn('Result miscompare for sample 0', str(e.exception))
        self.assertIn('evaluated opt IR (JIT)', str(e.exception))
Example #24
0
 def test_evaluate_ir_miscompare_single_result(self):
     sample_dir = self._make_sample_dir()
     runner = sample_runner.SampleRunner(sample_dir)
     dslx_text = 'fn main(x: u8, y: u8) -> u8 { x + y }'
     runner._evaluate_ir = lambda *args: (interp_value_from_ir_string(
         'bits[8]:1'), )
     with self.assertRaises(sample_runner.SampleError) as e:
         runner.run(
             sample.Sample(dslx_text,
                           sample.SampleOptions(optimize_ir=False), [[
                               interp_value_from_ir_string('bits[8]:42'),
                               interp_value_from_ir_string('bits[8]:100')
                           ]]))
     self.assertIn(
         'Result miscompare for sample 0:\n'
         'args: bits[8]:0x2a; bits[8]:0x64\n'
         'evaluated unopt IR (JIT), evaluated unopt IR (interpreter) =\n'
         '   bits[8]:0x1\n'
         'interpreted DSLX =\n'
         '   bits[8]:0x8e', str(e.exception))
     self.assertIn('Result miscompare for sample 0',
                   _read_file(sample_dir, 'exception.txt'))
Example #25
0
 def test_evaluate_ir_miscompare_multiple_results(self):
     sample_dir = self._make_sample_dir()
     runner = sample_runner.SampleRunner(sample_dir)
     dslx_text = 'fn main(x: u8, y: u8) -> u8 { x + y }'
     results = (interp_value_from_ir_string('bits[8]:100'),
                interp_value_from_ir_string('bits[8]:1'))
     runner._evaluate_ir = lambda *args: results
     with self.assertRaises(sample_runner.SampleError) as e:
         runner.run(
             sample.Sample(dslx_text,
                           sample.SampleOptions(optimize_ir=False),
                           [[
                               interp_value_from_ir_string('bits[8]:40'),
                               interp_value_from_ir_string('bits[8]:60')
                           ],
                            [
                                interp_value_from_ir_string('bits[8]:2'),
                                interp_value_from_ir_string('bits[8]:1')
                            ]]))
     self.assertIn('Result miscompare for sample 1', str(e.exception))
     self.assertIn('Result miscompare for sample 1',
                   _read_file(sample_dir, 'exception.txt'))