def main(argv): if len(argv) != 2: raise app.UsageError('Too many command-line arguments.') subprocess.check_call( [runfiles.get_path(OPT_MAIN), runfiles.get_path(argv[1])])
def test_mandelbrot(self): translator = xlscc_translator.Translator("mypackage") my_parser = ext_c_parser.XLSccParser() source_path = runfiles.get_path( "xls/contrib/xlscc_obsolete/translate/testdata/mandelbrot_test.cc") binary_path = runfiles.get_path( "xls/contrib/xlscc_obsolete/translate/mandelbrot_test") nx = 48 ny = 32 with open(source_path) as f: content = f.read() # Hackily do the preprocessing, since in build environments we do not have a # cpp binary available (and if we did relying on it here without a # build-system-noted dependency would be non-hermetic). content = re.sub("^#if !NO_TESTBENCH$.*^#endif$", "", content, 0, re.MULTILINE | re.DOTALL) content = re.sub(re.compile("//.*?\n"), "", content) f = self.create_tempfile(content=content) ast = pycparser.parse_file(f.full_path, use_cpp=False, parser=my_parser) cpp_out = None with os.popen(binary_path) as osf: cpp_out = osf.read() parsed_cpp_out = eval(cpp_out) translator.parse(ast) p = translator.gen_ir() f = p.get_function("mandelbrot") result_arr = parsed_cpp_out for y in range(0, ny): for x in range(0, nx): xx = float(x) / nx yy = float(y) / ny xi = int(xx * 2.5 - 1.8) * (1 << 16) yi = int(yy * 2.2 - 1.1) * (1 << 16) args = dict(c_r=ir_value.Value( bits_mod.SBits(value=int(xi), bit_count=32)), c_i=ir_value.Value( bits_mod.SBits(value=int(yi), bit_count=32))) result = ir_interpreter.run_function_kwargs(f, args) result_sai32 = int(str(result)) result_arr[y][x] = result_sai32 self.assertEqual(parsed_cpp_out, result_arr)
def setUp(self): super().setUp() server_path = runfiles.get_path('xls/synthesis/dummy_synthesis_server_main') self.port = portpicker.pick_unused_port() self.lc = lec_characterizer.LecCharacterizer( [server_path, '--port={}'.format(self.port)], self.port) cell_lib_path = runfiles.get_path(self._CELL_LIBRARY_PATH) with gfile.open(cell_lib_path, 'r') as f: self.cell_lib_text = f.read()
def test_imports_private_enum(self): path = runfiles.get_path('xls/dslx/tests/imports_private_enum.x') with self.assertRaises(TypeInferenceError) as cm: parse_and_interpret.parse_and_test_path(path) self.assertIn('xls/dslx/tests/imports_private_enum.x:17:14-17:40', str(cm.exception.span))
def _start_server(self): port = portpicker.pick_unused_port() proc = subprocess.Popen([ runfiles.get_path(SERVER_PATH), f'--port={port}', f'--yosys_path={YOSYS_PATH}', f'--nextpnr_path={NEXTPNR_PATH}' ]) return port, proc
def setUp(self): super().setUp() server_path = runfiles.get_path('xls/synthesis/dummy_synthesis_server_main') self._port = portpicker.pick_unused_port() self._synthesis_server = subprocess.Popen( [server_path, '--port={}'.format(self._port)], self._port) cell_lib_path = runfiles.get_path(self._CELL_LIBRARY_PATH) with gfile.open(cell_lib_path, 'r') as f: self._cell_lib_text = f.read() self._lc = lec_characterizer.LecCharacterizer('localhost:{}'.format( self._port)) self._byte_type = xls_type_pb2.TypeProto( type_enum=xls_type_pb2.TypeProto.BITS, bit_count=8)
def test_colon_ref_builtin(self): path = runfiles.get_path('xls/dslx/tests/colon_ref_builtin.x') with self.assertRaises(TypeInferenceError) as cm: parse_and_interpret.parse_and_test_path(path) self.assertIn('xls/dslx/tests/colon_ref_builtin.x:16:9-16:25', str(cm.exception.span)) self.assertIn("Builtin 'update' has no attributes", str(cm.exception))
def _run(self, path: str) -> str: full_path = runfiles.get_path(path) p = subp.run([_INTERP_PATH, full_path], stderr=subp.PIPE, check=False, encoding='utf-8') self.assertNotEqual(p.returncode, 0) return p.stderr
def do_import( subject: import_fn.ImportTokens, cache: Dict[import_fn.ImportTokens, import_fn.ModuleInfo] ) -> import_fn.ModuleInfo: """Imports the module identified (globally) by 'subject'. Resolves against an existing import in 'cache' if it is present. Args: subject: Tokens that globally uniquely identify the module to import; e.g. something built-in like ('std',) for the standard library or something fully qualified like ('xls', 'lib', 'math'). cache: Cache that we resolve against so we don't waste resources re-importing things in the import DAG. Returns: The imported module information. """ assert subject if subject in cache: return cache[subject] if subject in [('std', ), ('float32', ), ('bfloat16', )]: path = 'xls/dslx/stdlib/{}.x'.format(subject[0]) else: path = os.path.join(*subject) + '.x' f_import = functools.partial(do_import, cache=cache) fully_qualified_name = '.'.join(subject) if os.path.exists(path): with open(path, mode='rb') as f: contents = f.read().decode('utf-8') elif os.path.exists(os.path.join(os.path.pardir, path)): # Genrules in-house execute inside a subdirectory, so we also search # starting from the parent directory for now. # # An alternative would be to explicitly note the DSLX_PATH when invoking the # tool in this special genrule context, but since we expect module paths to # be fully qualified at the moment, we opt for this kluge. path = os.path.join(os.path.pardir, path) with open(path, mode='rb') as f: contents = f.read().decode('utf-8') else: contents = runfiles.get_contents_as_text(path) path = runfiles.get_path(path) logging.vlog(3, 'Parsing and typechecking %r: start', fully_qualified_name) m, node_to_type = parse_and_typecheck.parse_text(contents, fully_qualified_name, f_import=f_import, filename=path, print_on_error=True) logging.vlog(3, 'Parsing and typechecking %r: done', fully_qualified_name) assert node_to_type is not None cache[subject] = (m, node_to_type) return m, node_to_type
def test_imports_module_with_type_error(self): path = runfiles.get_path('xls/dslx/tests/imports_has_type_error.x') with self.assertRaises(Exception) as cm: parse_and_interpret.parse_and_test_path(path) self.assertIn('xls/dslx/tests/has_type_error.x:16:3-16:4', str(cm.exception)) self.assertIn('did not match the annotated return type', str(cm.exception))
def test_imports_and_causes_ref_error(self): path = runfiles.get_path( 'xls/dslx/tests/imports_and_causes_ref_error.x') with self.assertRaises(CppParseError) as cm: parse_and_interpret.parse_and_test_path(path) self.assertIn('ParseError', str(cm.exception.message)) self.assertIn( 'xls/dslx/tests/imports_and_causes_ref_error.x:17:29-17:31', str(cm.exception.message))
def test_generates_sources(self): server_path = runfiles.get_path('xls/synthesis/dummy_synthesis_server_main') port = portpicker.pick_unused_port() lc = lec_characterizer.LecCharacterizer( [server_path, '--port={}'.format(port)], port) p = package.Package('the_package') ir_text, netlist_text = lc._generate_sources( op_pb2.OpProto.OP_ADD, [p.get_bits_type(8), p.get_bits_type(8)], p.get_bits_type(8)) self.assertIn('ret add.1: bits[8]', ir_text) self.assertEqual(netlist_text, '// NETLIST')
def test_imports_dne(self): path = runfiles.get_path( 'xls/dslx/tests/imports_and_typedefs_dne_type.x') with self.assertRaises(TypeInferenceError) as cm: parse_and_interpret.parse_and_test_path(path) self.assertIn( 'xls/dslx/tests/imports_and_typedefs_dne_type.x:17:12-17:48', str(cm.exception.span)) self.assertIn( "xls.dslx.tests.mod_private_enum member 'ReallyDoesNotExist' which does not exist", str(cm.exception))
def main(argv): if len(argv) != 2: raise app.UsageError('Too many command-line arguments.') f_import = import_helpers.Importer() text = argv[1] p = convert_helpers.convert_dslx_to_package(text, name='cli', f_import=f_import) entry = p.get_function_names()[0] opt_ir = convert_helpers.optimize_and_dump(p) benchmark_main_path = runfiles.get_path(BENCHMARK_MAIN_PATH) with tempfile.NamedTemporaryFile() as f: f.write(opt_ir.encode('utf-8')) f.flush() subprocess.check_call( [benchmark_main_path, f.name, '--entry={}'.format(entry)])
# distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Tests of the synthesis service: client and dummy server.""" import subprocess import portpicker from google.protobuf import text_format from absl.testing import absltest from xls.common import runfiles from xls.synthesis import synthesis_pb2 CLIENT_PATH = runfiles.get_path('xls/synthesis/synthesis_client_main') SERVER_PATH = runfiles.get_path('xls/synthesis/yosys/yosys_server_main') YOSYS_PATH = runfiles.get_path('xls/synthesis/yosys/bogusys') NEXTPNR_PATH = runfiles.get_path('xls/synthesis/yosys/nextpbr') VERILOG = """ module main( input wire [31:0] x, input wire [31:0] y, output wire [31:0] out ); assign out = x + y; endmodule """
# # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Tests for DSLX modules with various forms of errors.""" import subprocess as subp from xls.common import runfiles from xls.common import test_base _INTERP_PATH = runfiles.get_path('xls/dslx/interpreter_main') class ImportModuleWithTypeErrorTest(test_base.TestCase): def _run(self, path: str) -> str: full_path = runfiles.get_path(path) p = subp.run([_INTERP_PATH, full_path], stderr=subp.PIPE, check=False, encoding='utf-8') self.assertNotEqual(p.returncode, 0) return p.stderr def test_failing_test_output(self): stderr = self._run('xls/dslx/tests/errors/two_failing_tests.x') print(stderr)
from xls.common.xls_error import XlsError from xls.dslx import ast from xls.dslx import concrete_type as concrete_type_mod from xls.dslx import parse_and_typecheck from xls.dslx import type_info as type_info_mod from xls.dslx import typecheck from xls.dslx.concrete_type import ConcreteType from xls.dslx.fuzzer import sample from xls.dslx.interpreter.interpreter import Interpreter from xls.dslx.interpreter.value import Value from xls.dslx.interpreter.value_parser import value_from_string from xls.ir.python import ir_parser from xls.ir.python import value as ir_value_mod from xls.ir.python.format_preference import FormatPreference IR_CONVERTER_MAIN_PATH = runfiles.get_path('xls/dslx/ir_converter_main') EVAL_IR_MAIN_PATH = runfiles.get_path('xls/tools/eval_ir_main') IR_OPT_MAIN_PATH = runfiles.get_path('xls/tools/opt_main') CODEGEN_MAIN_PATH = runfiles.get_path('xls/tools/codegen_main') SIMULATE_MODULE_MAIN_PATH = runfiles.get_path('xls/tools/simulate_module_main') class SampleError(XlsError): """Error raised if any problem is encountered running the sample. These issues can include parsing errors, tools crashing, or result miscompares(among others). """ pass
# TODO(meheff): the function should be selectable via the UI. flags.DEFINE_string( 'entry', None, 'Name of function to visualize. If not given then the ' 'function is chosen heuristically (e.g., "main" if it exists).') flags.mark_flag_as_required('delay_model') IR_EXAMPLES_FILE_LIST = 'xls/visualization/ir_viz/ir_examples_file_list.txt' webapp = flask.Flask('XLS UI') webapp.debug = True # Set of pre-canned examples as a list of (name, IR text) tuples. By default # these are loaded from IR_EXAMPLES_FILE_LIST unless --example_ir_dir is given. examples = [] OPT_MAIN_PATH = runfiles.get_path('xls/tools/opt_main') def load_precanned_examples() -> List[Tuple[str, str]]: """Returns a list of examples as tuples of (name, IR text). Examples are loaded from the list of files in IR_EXAMPLES_FILE_LIST. Returns: List of tuples containing (name, IR text). """ irs = [] for ir_path in runfiles.get_contents_as_text( IR_EXAMPLES_FILE_LIST).split(): if not ir_path.endswith('.ir') or ir_path.endswith('.opt.ir'): continue
import stat import subprocess import tempfile import time from typing import Tuple, Text, Optional from absl import logging import termcolor from xls.common import runfiles from xls.dslx.fuzzer import ast_generator from xls.dslx.fuzzer import sample from xls.dslx.fuzzer import sample_generator from xls.dslx.fuzzer import sample_runner SAMPLE_RUNNER_MAIN_PATH = runfiles.get_path( 'xls/dslx/fuzzer/sample_runner_main') IR_MINIMIZER_MAIN_PATH = runfiles.get_path('xls/tools/ir_minimizer_main') SUMMARIZE_IR_MAIN_PATH = runfiles.get_path('xls/dslx/fuzzer/summarize_ir_main') FIND_FAILING_INPUT_MAIN = runfiles.get_path( 'xls/dslx/fuzzer/find_failing_input_main') def _write_to_file(dir_path: Text, filename: Text, content: Text, executable: bool = False): """Writes the content into a file of the given name in the directory.""" path = os.path.join(dir_path, filename) with open(path, 'w') as f: f.write(content) if executable:
# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Tests for xls.fuzzer.run_fuzz_multiprocess.""" import os import subprocess from xls.common import runfiles from xls.common import test_base RUN_FUZZ_MULTIPROCESS_PATH = runfiles.get_path( 'xls/fuzzer/run_fuzz_multiprocess') class RunFuzzMultiprocessTest(test_base.TestCase): def test_two_samples(self): crasher_path = self.create_tempdir().full_path samples_path = self.create_tempdir().full_path subprocess.check_call([ RUN_FUZZ_MULTIPROCESS_PATH, '--seed=42', '--crash_path=' + crasher_path, '--save_temps_path=' + samples_path, '--sample_count=2', '--calls_per_sample=3', '--worker_count=1' ]) # Crasher path should contain a single file 'test'. self.assertSequenceEqual(os.listdir(crasher_path), ('test', ))
# # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Tests for xls.tools.delay_info_main.""" import subprocess from xls.common import runfiles from xls.common import test_base DELAY_INFO_MAIN_PATH = runfiles.get_path('xls/tools/delay_info_main') NOT_ADD_IR = """package not_add fn not_add(x: bits[32], y: bits[32]) -> bits[32] { sum: bits[32] = add(x, y) ret not_sum: bits[32] = not(sum) } """ NOT_ADD_SCHEDULE = """ stages { stage: 0 nodes: "x" nodes: "y" } stages {
def runfile_contents(path): with open(runfiles.get_path(path), 'r') as f: return f.read()
def _start_server(self, args): port = portpicker.pick_unused_port() proc = subprocess.Popen( [runfiles.get_path(SERVER_PATH), f'--port={port}'] + args) return port, proc
# distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Tests of the synthesis service: client and dummy server.""" import subprocess import portpicker from google.protobuf import text_format from absl.testing import absltest from xls.common import runfiles from xls.synthesis import synthesis_pb2 CLIENT_PATH = runfiles.get_path('xls/synthesis/synthesis_client_main') SERVER_PATH = runfiles.get_path('xls/synthesis/dummy_synthesis_server_main') VERILOG = """ module main( input wire [31:0] x, input wire [31:0] y, output wire [31:0] out ); assign out = x + y; endmodule """ class SynthesisServerTest(absltest.TestCase): def _start_server(self, args):
# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import subprocess from xls.common import runfiles from xls.common import test_base from xls.ir.python import ir_parser from absl.testing import absltest EVAL_IR_MAIN_PATH = runfiles.get_path('xls/tools/eval_ir_main') ADD_IR = """package foo fn foo(x: bits[32], y: bits[32]) -> bits[32] { ret add.1: bits[32] = add(x, y) } """ TUPLE_IR = """package foo fn foo(x: (bits[8], bits[32])) -> ((bits[8], bits[32])) { ret tuple.1: ((bits[8], bits[32])) = tuple(x) } """
# # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Tests of logging flags.""" import subprocess from xls.common import runfiles from xls.common import test_base LOGGER_PATH = runfiles.get_path('xls/common/logging/logger') class LoggingFlagsTest(test_base.TestCase): def test_no_flags(self): comp = subprocess.run([LOGGER_PATH], check=True, encoding='utf-8', stdout=subprocess.PIPE, stderr=subprocess.PIPE) self.assertEmpty(comp.stdout) self.assertNotIn('INFO message', comp.stderr) self.assertNotIn('WARNING message', comp.stderr) self.assertIn('ERROR message', comp.stderr) self.assertNotIn('XLS_VLOG', comp.stderr)
# # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Tests for find_failing_input_main binary.""" import subprocess from xls.common import runfiles from xls.common import test_base FIND_FAILING_INPUT_MAIN = runfiles.get_path( 'xls/dslx/fuzzer/find_failing_input_main') ADD_IR = """package foo fn foo(x: bits[32], y: bits[32]) -> bits[32] { ret add.1: bits[32] = add(x, y) } """ class EvalMainTest(test_base.TestCase): def test_input_file_no_failure(self): ir_file = self.create_tempfile(content=ADD_IR) input_file = self.create_tempfile( content='\n'.join(('bits[32]:0x42; bits[32]:0x123', 'bits[32]:0x10; bits[32]:0xf0f')))
from xls.fuzzer.python import cpp_sample as sample flags.DEFINE_boolean('codegen', True, 'Whether to generate Verilog for generated samples.') FLAGS = flags.FLAGS X_SUB_Y_IR = """package x_sub_y fn main(x: bits[8], y: bits[8]) -> bits[8] { ret sub.1: bits[8] = sub(x, y) } """ # IR parser binary. Reads in a IR file and parses it. Raises an error on # failure. PARSE_IR = runfiles.get_path('xls/tools/parse_ir') class RunFuzzTest(parameterized.TestCase): KWARGS = { 'calls_per_sample': 4, 'save_temps': False, 'sample_count': 128, 'return_samples': True, 'codegen': True } def setUp(self): super(RunFuzzTest, self).setUp() self.KWARGS['codegen'] = FLAGS.codegen
def testNonexistantFile(self): with self.assertRaises(FileNotFoundError): runfiles.get_path('not/a/file.txt') with self.assertRaises(FileNotFoundError): runfiles.get_contents_as_text('not/a/file.txt')
# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import os import stat import subprocess from xls.common import runfiles from absl.testing import absltest IR_MINIMIZER_MAIN_PATH = runfiles.get_path('xls/tools/ir_minimizer_main') ADD_IR = """package foo fn foo(x: bits[32], y: bits[32]) -> bits[32] { not.1: bits[32] = not(x, id=1) add.2: bits[32] = add(not.1, y, id=2) ret not.3: bits[32] = not(add.2, id=3) } """ class IrMinimizerMainTest(absltest.TestCase): def _write_sh_script(self, path, commands): with open(path, 'w') as f: f.write('#!/bin/sh -e\n')