text: 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
  
  
  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):
      db = prjxray.db.Database(db_root)
      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 open(fname, 'r') as f:
          return json5.load(f)
  
  
  def main():
      parser = argparse.ArgumentParser(
          description="Tests database against raw node list.")
      parser.add_argument('--db_root', required=True)
      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)
  
      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 open(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 open(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()
  