| #!/usr/bin/env python3 |
| # -*- coding: utf-8 -*- |
| # |
| # Copyright (C) 2017-2020 The Project X-Ray Authors. |
| # |
| # Use of this source code is governed by a ISC-style |
| # license that can be found in the LICENSE file or at |
| # https://opensource.org/licenses/ISC |
| # |
| # SPDX-License-Identifier: ISC |
| from __future__ import print_function |
| import prjxray.db |
| import prjxray.lib |
| import argparse |
| import datetime |
| import progressbar |
| import multiprocessing |
| import pyjson5 as json5 |
| import json |
| import sys |
| from prjxray.util import OpenSafeFile, db_root_arg, part_arg |
| |
| |
| def full_wire_name(wire_in_grid): |
| return '{}/{}'.format(wire_in_grid.tile, wire_in_grid.wire) |
| |
| |
| def make_connection(wires, connection): |
| wire_a = full_wire_name(connection.wire_a) |
| wire_b = full_wire_name(connection.wire_b) |
| |
| if wire_a not in wires: |
| wires[wire_a] = set((wire_a, )) |
| |
| if wire_b not in wires: |
| wires[wire_b] = set((wire_b, )) |
| |
| wire_a_set = wires[wire_a] |
| wire_b_set = wires[wire_b] |
| |
| if wire_a_set is wire_b_set: |
| return |
| |
| wire_a_set |= wire_b_set |
| |
| for wire in wire_a_set: |
| wires[wire] = wire_a_set |
| |
| |
| def make_connections(db_root, part): |
| db = prjxray.db.Database(db_root, part) |
| c = db.connections() |
| |
| wires = {} |
| for connection in c.get_connections(): |
| make_connection(wires, connection) |
| |
| nodes = {} |
| |
| for wire_node in wires.values(): |
| nodes[id(wire_node)] = wire_node |
| |
| return nodes.values() |
| |
| |
| def read_json5(fname): |
| with OpenSafeFile(fname, 'r') as f: |
| return json5.load(f) |
| |
| |
| def main(): |
| parser = argparse.ArgumentParser( |
| description="Tests database against raw node list.") |
| |
| db_root_arg(parser) |
| part_arg(parser) |
| parser.add_argument('--raw_node_root', required=True) |
| parser.add_argument('--error_nodes', default="error_nodes.json") |
| parser.add_argument('--ignored_wires') |
| |
| args = parser.parse_args() |
| |
| processes = min(multiprocessing.cpu_count(), 10) |
| |
| print('{} Running {} processes'.format(datetime.datetime.now(), processes)) |
| pool = multiprocessing.Pool(processes=processes) |
| print( |
| '{} Reading raw data index'.format(datetime.datetime.now(), processes)) |
| _, nodes = prjxray.lib.read_root_csv(args.raw_node_root) |
| print('{} Reading raw_node_data'.format(datetime.datetime.now())) |
| raw_node_data = [] |
| with progressbar.ProgressBar(max_value=len(nodes)) as bar: |
| for idx, node in enumerate(pool.imap_unordered( |
| read_json5, |
| nodes, |
| chunksize=20, |
| )): |
| bar.update(idx) |
| raw_node_data.append( |
| (node['node'], tuple(wire['wire'] for wire in node['wires']))) |
| bar.update(idx + 1) |
| |
| print('{} Creating connections'.format(datetime.datetime.now())) |
| generated_nodes = make_connections(args.db_root, args.part) |
| |
| print('{} Verifying connections'.format(datetime.datetime.now())) |
| error_nodes = [] |
| prjxray.lib.verify_nodes(raw_node_data, generated_nodes, error_nodes) |
| |
| if len(error_nodes) > 0: |
| if args.ignored_wires: |
| with OpenSafeFile(args.ignored_wires, 'r') as f: |
| ignored_wires = [l.strip() for l in f.readlines()] |
| |
| print( |
| '{} Found {} errors, writing errors to {}'.format( |
| datetime.datetime.now(), |
| len(error_nodes), |
| args.error_nodes, |
| )) |
| |
| with OpenSafeFile(args.error_nodes, 'w') as f: |
| json.dump(error_nodes, f, indent=2) |
| |
| if not args.ignored_wires: |
| sys.exit(1) |
| |
| if not prjxray.lib.check_errors(error_nodes, ignored_wires): |
| print( |
| '{} Errors were not ignored via ignored_wires {}'.format( |
| datetime.datetime.now(), |
| args.ignored_wires, |
| )) |
| sys.exit(1) |
| else: |
| print( |
| '{} All errors were via ignored_wires {}'.format( |
| datetime.datetime.now(), |
| args.ignored_wires, |
| )) |
| |
| |
| if __name__ == '__main__': |
| main() |