#!/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()