#!/usr/bin/env python
#
# -*- python -*-
#
# Runs a .gyb scale-testing file repeatedly through swiftc while varying a
# scaling variable 'N', collects json stats from the compiler, transforms the
# problem to log-space and runs a linear regression to estimate the exponent on
# the stat's growth curve relative to N.
#
# The estimate will be more accurate as N increases, so if you get a
# not-terribly-convincing estimate, try increasing --begin and --end to larger
# values.
#

import gyb, os, os.path, subprocess

def find_which(p):
    for d in os.environ["PATH"].split(os.pathsep):
        full = os.path.join(d,p)
        if os.path.isfile(full) and os.access(full, os.X_OK):
            return full
    return p

# Evidently the debug-symbol reader in dtrace is sufficiently slow and/or buggy
# that attempting to inject probes into a binary w/ debuginfo is asking for a
# failed run (possibly racing with probe insertion, or probing the stabs
# entries, see rdar://problem/7037927 or rdar://problem/11490861 respectively),
# so we sniff the presence of debug symbols here.
def has_debuginfo(swiftc):
    swiftc = find_which(swiftc)
    for line in subprocess.check_output(["dwarfdump", "--file-stats", swiftc]).splitlines():
        if '%' not in line:
            continue
        fields = line.split()
        if fields[8] != '0.00%' or fields[10] != '0.00%':
            return True
    return False


def write_input_file(args, ast, d, n):
    ifile = os.path.join(d, "in%d.swift" % n)
    with open(ifile,'w+') as f:
        f.write(gyb.execute_template(ast, '', N=n))
    return ifile


def run_once(args, ast, rng):
    import sys, shutil, tempfile, json
    r = {}
    try:
        d = tempfile.mkdtemp()
        inputs = [write_input_file(args, ast, d, i) for i in rng]
        primary = inputs[-1]
        ofile = os.path.join(d, "out.o")
        mode = "-c"
        if args.parse:
            mode = "-parse"
        command = [args.swiftc_binary,
                   "-frontend", mode,
                   "-o", ofile,
                   "-primary-file", primary] + inputs
        if args.dtrace:
            trace = os.path.join(d, "trace.txt")
            script = "pid$target:swiftc:*%s*:entry { @[probefunc] = count() }" % args.select
            subprocess.check_call(
                ["sudo", "dtrace", "-q",
                 "-o", trace,
                 "-b", "256",
                 "-n", script,
                 "-c", " ".join(command)])
            r = {fields[0]: int(fields[1]) for fields in
                 [line.split() for line in open(trace)]
                 if len(fields) == 2}
        else:
            stats = os.path.join(d, "stats.json")
            subprocess.check_call(
                command + ["-Xllvm", "-stats",
                           "-Xllvm", "-stats-json",
                           "-Xllvm", "-info-output-file=" + stats])
            with open(stats) as f:
                r = json.load(f)
    finally:
        shutil.rmtree(d)

    return {k:v for (k,v) in r.items() if args.select in k}


def run_many(args):

    if args.dtrace and has_debuginfo(args.swiftc_binary):
        print ""
        print "**************************************************"
        print ""
        print "dtrace is unreliable on binaries w/ debug symbols"
        print "please run 'strip -S %s'" % args.swiftc_binary
        print "or pass a different --swiftc-binary"
        print ""
        print "**************************************************"
        print ""
        exit(1)

    ast = gyb.parse_template(args.file.name, args.file.read())
    rng = range(args.begin, args.end, args.step)
    if args.multi_file:
        return (rng, [run_once(args, ast, rng[0:i+1]) for i in range(len(rng))])
    else:
        return (rng, [run_once(args, ast, [r]) for r in rng])


def report(args, rng, runs):
    import numpy as np
    bad = False
    keys = set.intersection(*[set(j.keys()) for j in runs])
    A = np.vstack([np.log(rng), np.ones(len(rng))]).T
    rows = []
    for k in keys:
        vals = [r[k] for r in runs]
        bounded = [max(v, 1) for v in vals]
        b, a = np.linalg.lstsq(A, np.log(bounded))[0]
        b = 0 if np.isclose(b, 0) else b
        rows.append((b, k, vals))
    rows.sort()
    tolerance = 1.2
    for (b, k, vals) in rows:
        if b >= tolerance:
            bad = True
        if not args.quiet or b >= tolerance:
            print "O(n^%1.1f) : %s" % (b, k)
            if args.values:
                print "                = ", vals
    return bad


def main():
    import argparse, sys
    parser = argparse.ArgumentParser()
    parser.add_argument(
        'file', type=argparse.FileType(),
        help='Path to GYB template file (defaults to stdin)', nargs='?',
        default=sys.stdin)
    parser.add_argument(
        '--values', action='store_true',
        default=False, help='print stat values')
    parser.add_argument(
        '--quiet', action='store_true',
        default=False, help='only print superlinear stats')
    parser.add_argument(
        '--parse', action='store_true',
        default=False, help='only run compiler with -parse')
    parser.add_argument(
        '--dtrace', action='store_true',
        default=False, help='use dtrace to sample all functions')
    parser.add_argument(
        '--multi-file', action='store_true',
        default=False, help='vary number of input files as well')
    parser.add_argument(
        '--begin', type=int,
        default=10, help='first value for N')
    parser.add_argument(
        '--end', type=int,
        default=100, help='last value for N')
    parser.add_argument(
        '--step', type=int,
        default=10, help='step value for N')
    parser.add_argument(
        '--swiftc-binary',
        default="swiftc", help='swift binary to execute')
    parser.add_argument(
        '--select',
        default="", help='substring of counters/symbols to restrict attention to')

    args = parser.parse_args(sys.argv[1:])
    (rng, runs) = run_many(args)
    if report(args, rng, runs):
        exit(1)
    exit(0)

if __name__ == '__main__':
    main()
