예제 #1
0
def main():
  logging.basicConfig(filename='test_loops.log', filemode='w')
  logger = logging.getLogger('test_loops')
  logger.setLevel(logging.INFO)
  logging.getLogger('loops.compose').setLevel(logging.INFO)

  parser = argparse.ArgumentParser()
  parser.add_argument('-t', '--tests', action='store_true',
    help='run the test suite')
  parser.add_argument('-c', '--compose', action='append',
    type=argparse.FileType('r'), default=[], nargs='*',
    metavar='file',
    help='count how many ways this file can be composed into a single opt')
  parser.add_argument('-l', '--loop', action='append', 
    type=argparse.FileType('r'), default=[], nargs='*',
    metavar='file',
    help='check whether each file describes a cycle')
  parser.add_argument('-v', '--verify', action='store_true',
    help='if present, verify all composed optimizations')
  parser.add_argument('--log', action='append', nargs=2,
    metavar=('logger', 'level'),
    help='set the logging threshold for a logging subtree')

  args = parser.parse_args()

  if args.log:
    for tree,level in args.log:
      level = level.upper()
      if level not in ['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL']:
        sys.stderr.write('{} is not a valid logging level\n'.format(level))
        sys.stderr.write('Use: DEBUG, INFO, WARNING, ERROR, CRITICAL\n')
        exit(-1)

      logging.getLogger(tree).setLevel(getattr(logging, level))
      logger.info('logging %s at %s', tree, level)

  for f in itertools.chain.from_iterable(args.compose):
    opts = loops.parse_transforms(f.read())
    comps = test_composition(opts, f.name, verify=args.verify, quiet=False)
    print '{}: got {} composition{}'.format(f.name, comps,
      '' if comps == 1 else 's')
  
  for f in itertools.chain.from_iterable(args.loop):
    opts = loops.parse_transforms(f.read())
    loop =  test_loop(opts, f.name, verify=args.verify, quiet=False)
    print '{}: {}loop'.format(f.name, '' if loop else 'no ')

  if args.tests or not (args.compose or args.loop):
    if not run_tests(verify=args.verify):
      exit(1)
예제 #2
0
def search_process(suite, limit, sequence_queue, result_queue, status_queue, log_config):
  logging.config.dictConfig(log_config)
  log = logger.getChild('search_process')
  log.info('Worker thread started, limit %s', limit)
  opts = loops.parse_transforms(open(suite).read())

  log.debug('%s optimizations', len(opts))

  info = [0,0,0,0]
  
  def count_error(e,o1,o2):
    info[ERRORS] += 1
  
  while info[COUNT] < limit:
    s = sequence_queue.get()
    if s is None:
      log.info('Worker exiting %s', info)
      status_queue.put(info)
      return
    
    log.debug('Checking sequence %s', s)
    
    os = tuple(opts[i] for i in s)
    for o in loops.all_compositions(os):
      if info[COUNT] >= limit:
        break

      o_src = count_src(o)
      
      for oo in loops.all_bin_compositions(o, o, count_error):
        if info[COUNT] >= limit:
          break

        if info[COUNT] % 1000 == 0:
          log.info('Tested %s SatChecks %s Loops %s Errors %s', *info)
  
        info[COUNT] += 1
        
        oo_src = count_src(oo)
        
        if o_src < oo_src:
          continue
        
        info[SAT_CHECKS] += 1
        if not loops.satisfiable(oo):
          continue
        
        info[CYCLES] += 1

        # TODO: put found loops into a queue
        result = 'Loop: {}\n{}\n\n{}'.format(o.name, '\n\n'.join(str(op) for op in os), o)
        result_queue.put(result)
        log.info(result)

  log.info('Worker exiting %s', info)
  status_queue.put(info)
예제 #3
0
def main():
  logging.basicConfig(filename='find-loops.log', filemode='w')

  parser = argparse.ArgumentParser()
  parser.add_argument('length', type=int,
    help='Length of cycles to search for')
  parser.add_argument('file', type=argparse.FileType('r'),
    help='optimization suite to analyze')

  args = parser.parse_args()

  if args.length < 1:
    sys.stderr.write('cycle length must be positive\n')
    exit(1)

  sys.stderr.write('Reading ' + args.file.name + '\n')
  opts = loops.parse_transforms(args.file.read())
  sys.stderr.write('{} optimizations'.format(len(opts)))

  count = 0
  sat_checks = 0
  cycles = 0
  errors = [0]
  
  def count_error(e,o1,o2):
    errors[0] += 1

  for o,_,os in search(opts, args.length):
    o_src = count_src(o)
    for oo in loops.all_bin_compositions(o,o,count_error):
      sys.stderr.write(status.format(count, sat_checks, cycles))
      count += 1

      oo_src = count_src(oo)

      if o_src < oo_src:
        continue

      sat_checks += 1
      if not loops.satisfiable(oo):
        continue

      cycles += 1
      print '\n-----\nLoop: ', o.name
      for opt in os:
        opt.dump()
        print
      o.dump()
  
  sys.stderr.write(status.format(count, sat_checks, cycles))
  sys.stderr.write('\n')
  print
  print 'final count', count
  print 'loops', cycles
  print 'sat_checks', sat_checks
  print 'errors', errors[0]
예제 #4
0
def search_process(suite, length, prefix_queue, result_queue, status_queue, log_config):
    logging.config.dictConfig(log_config)
    log = logger.getChild("search_process")
    log.info("Worker thread started")
    opts = loops.parse_transforms(open(suite).read())

    log.debug("%s optimizations", len(opts))

    info = [0] * INFO_FLDS

    def count_error(e, o1, o2):
        info[ERRORS] += 1

    while info[COMPS] < MAX_TESTS:
        p = prefix_queue.get()
        if p is None:
            log.info("Worker exiting %s", info)
            status_queue.put(info)
            prefix_queue.task_done()  # make sure this happens after putting the info
            return

        log.info("Checking prefix %s", p)

        for o, os in search_after_prefix(opts, length, p, count_error):
            o_src = count_src(o)

            info[COMPS] += 1

            if info[COMPS] % 1000 == 0:
                log.info("Seqs %s Comps %s SelfComps %s SatChecks %s Loops %s Errors %s", *info)

            for oo in loops.all_bin_compositions(o, o, count_error):

                info[SELF_COMPS] += 1

                oo_src = count_src(oo)

                if o_src < oo_src:
                    continue

                info[SAT_CHECKS] += 1
                if not loops.satisfiable(oo):
                    continue

                info[CYCLES] += 1

                # TODO: put found loops into a queue
                result = "Loop: {}\n{}\n\n{}".format(o.name, "\n\n".join(str(op) for op in os), o)
                result_queue.put(result)
                log.info(result)

        info[SEQS] += prefix_size(p, length, len(opts))
        prefix_queue.task_done()

    log.info("Worker exiting %s", info)
    status_queue.put(info)
예제 #5
0
def count_opts(suite):
  opts = loops.parse_transforms(open(suite).read())
  return len(opts)
예제 #6
0
def search_process(suite, length, limit, prefix_queue, result_queue, status_queue, log_config):
  logging.config.dictConfig(log_config)
  log = logger.getChild('search_process')
  log.info('Worker thread started')
  opts = loops.parse_transforms(open(suite).read())

  log.debug('%s optimizations', len(opts))

  info = [0] * INFO_FLDS
  
  def count_error(e,o1,o2):
    info[ERRORS] += 1
  
  complete = True

  while info[COMPS] < limit:
    p = prefix_queue.get()
    if p is None:
      log.info('Worker exiting %s', info)
      status_queue.put(info)
      prefix_queue.task_done() # make sure this happens after putting the info
      return
    
    log.info('Checking prefix %s; %s remaining', p, limit-info[COMPS])
    
    counters = [0] * length
    
    for o,os in search_after_prefix(opts, length, p, counters, count_error):
      o_src = count_src(o)

      info[COMPS] += 1
      
      if info[COMPS] % 1000 == 0:
        log.info('Paths %s Comps %s Selfcomps %s SatChecks %s Loops %s Errors %s', *info)
      
      for oo in loops.all_bin_compositions(o, o, count_error):
        # TODO: can this just be compose?
        info[SELFCOMPS] += 1

        oo_src = count_src(oo)

        if o_src < oo_src:
          continue

        info[SAT_CHECKS] += 1
        if not loops.satisfiable(oo):
          continue

        info[CYCLES] += 1

        # TODO: put found loops into a queue
        result = 'Loop: {}\n{}\n\n{}'.format(o.name, '\n\n'.join(str(op) for op in os), o)
        result_queue.put(result)
        log.info(result)
      
      if info[COMPS] >= limit:
        complete = False
        break

    if complete:
      psize = prefix_size(p, length, len(opts))
      log.debug('Prefix %s size %s counters %s', p, psize, counters)
      info[SEQS] += psize
    else:
      psize = partial_prefix_size(p, counters, len(opts))
      info[SEQS] += psize
      log.debug('Prefix %s size %s Info %s Counters %s', p, psize, info, counters)

    prefix_queue.task_done()

  log.info('Worker exiting %s', info)
  status_queue.put(info)
예제 #7
0
def run_tests(verify=False):
  logger = logging.getLogger('test_loops')

  complete = 0
  failed = 0
  errors = [0]
  test_names = filter(lambda f: not f.startswith('unknown'),
                      os.listdir('looptests'))
  tests = len(test_names)
  sys.stderr.write(str(tests) + ' tests\n')

  label = re.compile(r'^; expect (\d+) (comp|loop)')

  def count_error(*args):
    errors[0] += 1

  def statusmsg():
    sys.stderr.write(
      '\r{}% complete, {} failed, {} errors'.format(
        complete*100/tests, failed, errors[0]))

  for f in test_names:
    logger.info('reading looptests/%s', f)
    statusmsg()
    complete += 1

    text = open('looptests/' + f).read()
    expects = label.match(text)

    if not expects:
      logger.warning('%s: no expectations', f)
      errors += 1
      continue

    expected = int(expects.group(1))
    expecting = expects.group(2)

    opts = loops.parse_transforms(text)

    try:
      if expecting == 'comp':
        comps = test_composition(opts, f, verify=verify, on_error=count_error)
        if comps != expected:
          logger.warning('%s: Got %r comps, expected %r',
                         f, comps, expected)
          failed += 1
        continue

      if expecting == 'loop':
        got = test_loop(opts, f, verify=verify, on_error=count_error)
        if got and not expected:
          logger.warning('%s: Unexpected loop', f)
          failed += 1
        elif not got and expected:
          logger.warning('%s: Expected loop', f)
          failed += 1

    except Exception as e:
      logger.exception('Got %r while testing %s', e, f)
      errors[0] += 1

  statusmsg()
  sys.stderr.write('\n')
  return not failed and not errors[0]