Simple test function
    Taken from http://www.huyng.com/posts/python-performance-analysis/
555307
def primes(n):
    
    if n==2:
        return [2]
    elif n<2:
        return []
    s=list(range(3,n+1,2))
    mroot = n ** 0.5
    half=(n+1)//2-1
    i=0
    m=3
    while m <= mroot:
        if s[i]:
            j=(m*m-3)//2
            s[j]=0
            while j<half:
                s[j]=0
                j+=m
        i=i+1
        m=2*i+3
    return [2]+[x for x in s if x]
1195992
def confidenceInterval(n, k, alpha = 0.68, errorbar=False):
    
    try:
        e = float(k) / float(n)
    except ZeroDivisionError:
        return np.nan, [np.nan, np.nan]

    bins = 1000001
    dx = 1. / bins

    efficiency = np.linspace(0, 1, bins)

    # MODIFIED FOR LARGE NUMBERS
    if n + 2 > 1000:
        a = gammalnStirling(n + 2)
    else:
        a = scipy.special.gammaln(n + 2)
    if k + 1 > 1000:
        b = gammalnStirling(k + 1)
    else:
        b = scipy.special.gammaln(k + 1)
    if n - k + 1 > 1000:
        c = gammalnStirling(n - k + 1)
    else:
        c = scipy.special.gammaln(n - k + 1)

    if k == 0:
        p = np.concatenate([[np.exp(a - b - c)],
                               np.exp(a - b - c + (k * np.log(efficiency[1: -1])) + (n - k) * np.log(1. - efficiency[1: -1])),
                               [0.]])
    elif k == n:
        p = np.concatenate([[0.],
                               np.exp(a - b - c + (k * np.log(efficiency[1: -1])) + (n - k) * np.log(1. - efficiency[1: -1])),
                               [np.exp(a - b - c)]])
    else:
        p = np.concatenate([[0.],
                               np.exp(a - b - c + (k * np.log(efficiency[1: -1])) + (n - k) * np.log(1. - efficiency[1: -1])),
                               [0.]])

    i = np.argsort(p)[::-1]
    p_i = np.take(p, i)

    s = i[np.cumsum(p_i * dx) < alpha]

    low = min(np.min(s) * dx, e)
    high = max(np.max(s) * dx, e)

    if not errorbar:
        return e, [low, high]
    else:
        return e, [e - low, high - e]
1234384
function doAsyncBench(fn, callback) {

		var fnOverhead,
		    pretotal,
		    result,
		    args,
		    i;

		if (benchRunning > 0) {

			// Keep function optimized by not leaking the `arguments` object
			args = new Array(arguments.length);
			for (i = 0; i < args.length; i++) args[i] = arguments[i];

			benchQueue.push(args);
			return;
		}

		benchRunning++;

		// See how many times we can get it to run for 300ms
		Collection.Function.doTime(300, fn, function(err, runs, elapsed) {

			// See how the baseline latency is like
			Blast.getEventLatencyBaseline(function(err, median) {
				asyncTest(fn, runs, median+(getFunctionOverhead(runs)*8), function asyncDone(err, result) {

					var next,
					    name;

					// Call the callback
					if (callback) {
						result.name = fn.name || '';
						callback(err, result);
					} else {
						name = fn.name || '';
						if (name) name = 'for "' + name + '" ';

						console.log('Benchmark ' + name + 'did ' + Bound.Number.humanize(result.ops) + '/s (' + Bound.Number.humanize(result.iterations) + ' iterations)');
					}

					benchRunning--;

					// Schedule a next benchmark
					if (benchRunning == 0 && benchQueue.length > 0) {

						// Get the top of the queue
						next = benchQueue.shift();

						Blast.setImmediate(function() {
							doAsyncBench.apply(null, next);
						});
					}
				});
			});
		});
	}
398245
def timeit (func, log, limit):
    """"""

    def newfunc (*args, **kwargs):
        """Execute function and print execution time."""
        t = time.time()
        res = func(*args, **kwargs)
        duration = time.time() - t
        if duration > limit:
            print(func.__name__, "took %0.2f seconds" % duration, file=log)
            print(args, file=log)
            print(kwargs, file=log)
        return res
    return update_func_meta(newfunc, func)
113287
def check_perf():
    ""

    from PIL import features, Image
    from packaging import version

    print("Running performance checks.")

    # libjpeg_turbo check
    print("\n*** libjpeg-turbo status")
    if version.parse(Image.PILLOW_VERSION) >= version.parse("5.3.9"):
        if features.check_feature('libjpeg_turbo'):
            print("✔ libjpeg-turbo is on")
        else:
            print("✘ libjpeg-turbo is not on. It's recommended you install libjpeg-turbo to speed up JPEG decoding. See https://docs.fast.ai/performance.html#libjpeg-turbo")
    else:
        print(f"❓ libjpeg-turbo's status can't be derived - need Pillow(-SIMD)? >= 5.4.0 to tell, current version {Image.PILLOW_VERSION}")
        # XXX: remove this check/note once Pillow and Pillow-SIMD 5.4.0 is available
        pillow_ver_5_4_is_avail = pypi_module_version_is_available("Pillow", "5.4.0")
        if pillow_ver_5_4_is_avail == False:
            print("5.4.0 is not yet available, other than the dev version on github, which can be installed via pip from git+https://github.com/python-pillow/Pillow. See https://docs.fast.ai/performance.html#libjpeg-turbo")

    # Pillow-SIMD check
    print("\n*** Pillow-SIMD status")
    if re.search(r'\.post\d+', Image.PILLOW_VERSION):
        print(f"✔ Running Pillow-SIMD {Image.PILLOW_VERSION}")
    else:
        print(f"✘ Running Pillow {Image.PILLOW_VERSION}; It's recommended you install Pillow-SIMD to speed up image resizing and other operations. See https://docs.fast.ai/performance.html#pillow-simd")

    # CUDA version check
    # compatibility table: k: min nvidia ver is required for v: cuda ver
    # note: windows nvidia driver version is slightly higher, see:
    # https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html
    # note: add new entries if pytorch starts supporting new cudaXX
    nvidia2cuda = {
        "410.00": "10.0",
        "384.81":  "9.0",
        "367.48":  "8.0",
    }
    print("\n*** CUDA status")
    if torch.cuda.is_available():
        pynvml = load_pynvml_env()
        nvidia_ver = (pynvml.nvmlSystemGetDriverVersion().decode('utf-8') if platform.system() != "Darwin" else "Cannot be determined on OSX yet")
        cuda_ver   = torch.version.cuda
        max_cuda = "8.0"
        for k in sorted(nvidia2cuda.keys()):
            if version.parse(nvidia_ver) > version.parse(k): max_cuda = nvidia2cuda[k]
        if version.parse(str(max_cuda)) <= version.parse(cuda_ver):
            print(f"✔ Running the latest CUDA {cuda_ver} with NVIDIA driver {nvidia_ver}")
        else:
            print(f"✘ You are running pytorch built against cuda {cuda_ver}, your NVIDIA driver {nvidia_ver} supports cuda10. See https://pytorch.org/get-started/locally/ to install pytorch built against the faster CUDA version.")
    else:
        print(f"❓ Running cpu-only torch version, CUDA check is not relevant")

    print("\nRefer to https://docs.fast.ai/performance.html to make sense out of these checks and suggestions.")
1034645
def main(argv=None):
    
    import getopt

    # default values
    test_read = None
    test_write = None
    n = 3       # number of repeat

    if argv is None:
        argv = sys.argv[1:]

    try:
        opts, args = getopt.getopt(argv, 'hn:rw', [])

        for o,a in opts:
            if o == '-h':
                print(HELP)
                return 0
            elif o == '-n':
                n = int(a)
            elif o == '-r':
                test_read = True
            elif o == '-w':
                test_write = True

        if args:
            raise getopt.GetoptError('Arguments are not used.')
    except getopt.GetoptError:
        msg = sys.exc_info()[1]     # current exception
        txt = str(msg)
        print(txt)
        return 1

    if (test_read, test_write) == (None, None):
        test_read = test_write = True

    m = Measure(n, test_read, test_write)
    m.measure_all()
    m.print_report()

    return 0
927501
def run():
    

    print('Python ' + sys.version.replace('\n', ''))

    try:
        oscrypto_tests_module_info = imp.find_module('tests', [os.path.join(build_root, 'oscrypto')])
        oscrypto_tests = imp.load_module('oscrypto.tests', *oscrypto_tests_module_info)
        oscrypto = oscrypto_tests.local_oscrypto()
        print('\noscrypto backend: %s' % oscrypto.backend())
    except (ImportError):
        pass

    if run_lint:
        print('')
        lint_result = run_lint()
    else:
        lint_result = True

    if run_coverage:
        print('\nRunning tests (via coverage.py)')
        sys.stdout.flush()
        tests_result = run_coverage(ci=True)
    else:
        print('\nRunning tests')
        sys.stdout.flush()
        tests_result = run_tests()
    sys.stdout.flush()

    return lint_result and tests_result
1244018
def _compiled(self):
        """"""
        # Dev Notes:
        # Because of fast locals in functions in both CPython and PyPy, getting a
        # function to execute makes the code a few times faster than
        # just executing it in the global exec scope.
        prog = [self._prog_start]

        simple_func = {  # OPS
            'w': lambda x: x,
            'r': lambda x: x,
            '~': lambda x: '(~' + x + ')',
            '&': lambda l, r: '(' + l + '&' + r + ')',
            '|': lambda l, r: '(' + l + '|' + r + ')',
            '^': lambda l, r: '(' + l + '^' + r + ')',
            'n': lambda l, r: '(~(' + l + '&' + r + '))',
            '+': lambda l, r: '(' + l + '+' + r + ')',
            '-': lambda l, r: '(' + l + '-' + r + ')',
            '*': lambda l, r: '(' + l + '*' + r + ')',
            '<': lambda l, r: 'int(' + l + '<' + r + ')',
            '>': lambda l, r: 'int(' + l + '>' + r + ')',
            '=': lambda l, r: 'int(' + l + '==' + r + ')',
            'x': lambda sel, f, t: '({}) if ({}==0) else ({})'.format(f, sel, t),
        }

        def shift(value, direction, shift_amt):
            if shift_amt == 0:
                return value
            else:
                return '(%s %s %d)' % (value, direction, shift_amt)

        def make_split():
            if split_start_bit == 0:
                bit = '(%d & %s)' % ((1 << split_length) - 1, source)
            elif len(net.args[0]) - split_start_bit == split_length:
                bit = '(%s >> %d)' % (source, split_start_bit)
            else:
                bit = '(%d & (%s >> %d))' % ((1 << split_length) - 1, source, split_start_bit)
            return shift(bit, '<<', split_res_start_bit)

        for net in self.block:
            if net.op in simple_func:
                argvals = (self._arg_varname(arg) for arg in net.args)
                expr = simple_func[net.op](*argvals)
            elif net.op == 'c':
                expr = ''
                for i in range(len(net.args)):
                    if expr is not '':
                        expr += ' | '
                    shiftby = sum(len(j) for j in net.args[i+1:])
                    expr += shift(self._arg_varname(net.args[i]), '<<', shiftby)
            elif net.op == 's':
                source = self._arg_varname(net.args[0])
                expr = ''
                split_length = 0
                split_start_bit = -2
                split_res_start_bit = -1

                for i, b in enumerate(net.op_param):
                    if b != split_start_bit + split_length:
                        if split_start_bit >= 0:
                            # create a wire
                            expr += make_split() + '|'
                        split_length = 1
                        split_start_bit = b
                        split_res_start_bit = i
                    else:
                        split_length += 1
                expr += make_split()
            elif net.op == 'm':
                read_addr = self._arg_varname(net.args[0])
                mem = net.op_param[1]
                if isinstance(net.op_param[1], RomBlock):
                    expr = 'd["%s"]._get_read_data(%s)' % (self._mem_varname(mem), read_addr)
                else:  # memories act async for reads
                    expr = 'd["%s"].get(%s, %s)' % (self._mem_varname(mem),
                                                    read_addr, self.default_value)
            elif net.op == '@':
                mem = self._mem_varname(net.op_param[1])
                write_addr, write_val, write_enable = (self._arg_varname(a) for a in net.args)
                prog.append('    if {}:'.format(write_enable))
                prog.append('        mem_ws.append(("{}", {}, {}))'
                            .format(mem, write_addr, write_val))
                continue  # memwrites are special
            else:
                raise PyrtlError('FastSimulation cannot handle primitive "%s"' % net.op)

            # prog.append('    #  ' + str(net))
            result = self._dest_varname(net.dests[0])
            if len(net.dests[0]) == self._no_mask_bitwidth[net.op](net):
                prog.append("    %s = %s" % (result, expr))
            else:
                mask = str(net.dests[0].bitmask)
                prog.append('    %s = %s & %s' % (result, mask, expr))

        # add traced wires to dict
        if self.tracer is not None:
            for wire_name in self.tracer.trace:
                wire = self.block.wirevector_by_name[wire_name]
                if not isinstance(wire, (Input, Const, Register, Output)):
                    v_wire_name = self._varname(wire)
                    prog.append('    outs["%s"] = %s' % (wire_name, v_wire_name))

        prog.append("    return regs, outs, mem_ws")
        return '\n'.join(prog)
40293
function loadPerformance() {
    echo("");
    echo("Loading:");

    const results = [];

    for (let cnt = 0; cnt < 5; cnt++) {
        const loadPerfData = loadPerf({
            checkDependencies: false
        });

        echo(`  Load performance Run #${cnt + 1}:  %dms`, loadPerfData.loadTime);
        results.push(loadPerfData.loadTime);
    }

    results.sort((a, b) => a - b);
    const median = results[~~(results.length / 2)];

    echo("");
    echo("  Load Performance median:  %dms", median);
    echo("");
}
832206
def _cost_func(x, kernel_options, tuning_options, runner, results, cache):
    

    error_time = 1e20
    logging.debug('_cost_func called')
    logging.debug('x: ' + str(x))

    x_key = ",".join([str(i) for i in x])
    if x_key in cache:
        return cache[x_key]

    #snap values in x to nearest actual value for each parameter unscale x if needed
    if tuning_options.scaling:
        params = unscale_and_snap_to_nearest(x, tuning_options.tune_params, tuning_options.eps)
    else:
        params = snap_to_nearest_config(x, tuning_options.tune_params)

    logging.debug('params ' + str(params))

    x_int = ",".join([str(i) for i in params])
    if x_int in cache:
        return cache[x_int]

    #check if this is a legal (non-restricted) parameter instance
    if tuning_options.restrictions:
        legal = util.check_restrictions(tuning_options.restrictions, params, tuning_options.tune_params.keys(), tuning_options.verbose)
        if not legal:
            cache[x_int] = error_time
            cache[x_key] = error_time
            return error_time

    #compile and benchmark this instance
    res, _ = runner.run([params], kernel_options, tuning_options)

    #append to tuning results
    if res:
        results.append(res[0])
        cache[x_int] = res[0]['time']
        cache[x_key] = res[0]['time']
        return res[0]['time']

    cache[x_int] = error_time
    cache[x_key] = error_time
    return error_time
1373201
def __score_method(X, y, fcounts, model_generator, score_function, method_name, nreps=10, test_size=100, cache_dir="/tmp"):
    

    old_seed = np.random.seed()
    np.random.seed(3293)

    # average the method scores over several train/test splits
    method_reps = []

    data_hash = hashlib.sha256(__toarray(X).flatten()).hexdigest() + hashlib.sha256(__toarray(y)).hexdigest()
    for i in range(nreps):
        X_train, X_test, y_train, y_test = train_test_split(__toarray(X), y, test_size=test_size, random_state=i)

        # define the model we are going to explain, caching so we onlu build it once
        model_id = "model_cache__v" + "__".join([__version__, data_hash, model_generator.__name__])+".pickle"
        cache_file = os.path.join(cache_dir, model_id + ".pickle")
        if os.path.isfile(cache_file):
            with open(cache_file, "rb") as f:
                model = pickle.load(f)
        else:
            model = model_generator()
            model.fit(X_train, y_train)
            with open(cache_file, "wb") as f:
                pickle.dump(model, f)

        attr_key = "_".join([model_generator.__name__, method_name, str(test_size), str(nreps), str(i), data_hash])
        def score(attr_function):
            def cached_attr_function(X_inner):
                if attr_key not in _attribution_cache:
                    _attribution_cache[attr_key] = attr_function(X_inner)
                return _attribution_cache[attr_key]

            #cached_attr_function = lambda X: __check_cache(attr_function, X)
            if fcounts is None:
                return score_function(X_train, X_test, y_train, y_test, cached_attr_function, model, i)
            else:
                scores = []
                for f in fcounts:
                    scores.append(score_function(f, X_train, X_test, y_train, y_test, cached_attr_function, model, i))
                return np.array(scores)

        # evaluate the method (only building the attribution function if we need to)
        if attr_key not in _attribution_cache:
            method_reps.append(score(getattr(methods, method_name)(model, X_train)))
        else:
            method_reps.append(score(None))

    np.random.seed(old_seed)
    return np.array(method_reps).mean(0)
519896
def _evaluate_f(self, n, xdata, p=None):
        
        # by default, use the fit values, otherwise, use the guess values.
        if   p is None and self.results is not None: p = self.results[0]
        elif p is None and self.results is None:     p = self._pguess

        # assemble the arguments for the function
        args = (xdata,) + tuple(p)

        # evaluate this function.
        return self.f[n](*args)
53289
def min_func(fun, bounds_min, bounds_max, d=None, rmax=10,
             n0=64, nswp=10, verb=True, smooth_fun=None):
    """"""
    if d is None:
        d = len(bounds_min)
        a = np.asanyarray(bounds_min).copy()
        b = np.asanyarray(bounds_max).copy()
    else:
        a = np.ones(d) * bounds_min
        b = np.ones(d) * bounds_max

    if smooth_fun is None:
        smooth_fun = lambda p, lam: (math.pi / 2 - np.arctan(p - lam))
    #smooth_fun = lambda p, lam: np.exp(-10*(p - lam))

    # We do not need to store the cores, only the interfaces!
    Rx = [[]] * (d + 1)  # Python list for the interfaces
    Rx[0] = np.ones((1, 1))
    Rx[d] = np.ones((1, 1))
    Jy = [np.empty(0, dtype=np.int)] * (d + 1)
    ry = rmax * np.ones(d + 1, dtype=np.int)
    ry[0] = 1
    ry[d] = 1
    n = n0 * np.ones(d, dtype=np.int)
    fun_evals = 0

    grid = [np.reshape(np.linspace(a[i], b[i], n[i]), (n[i], 1))
            for i in xrange(d)]
    for i in xrange(d - 1):
        #cr1 = y[i]
        ry[i + 1] = min(ry[i + 1], n[i] * ry[i])
        cr1 = np.random.randn(ry[i], n[i], ry[i + 1])
        cr1 = reshape(cr1, (ry[i] * n[i], ry[i + 1]))
        q, r = np.linalg.qr(cr1)
        ind = maxvol(q)
        w1 = mkron(np.ones((n[i], 1), dtype=np.int), Jy[i])
        w2 = mkron(grid[i], np.ones((ry[i], 1), dtype=np.int))
        Jy[i + 1] = np.hstack((w1, w2))
        Jy[i + 1] = reshape(Jy[i + 1], (ry[i] * n[i], -1))
        Jy[i + 1] = Jy[i + 1][ind, :]

        # Jy{i+1} = [kron(ones(n(i),1), Jy{i}), kron((1:n(i))', ones(ry(i),1))];
        # Jy{i+1} = Jy{i+1}(ind,:);
    swp = 0
    dirn = -1
    i = d - 1
    lm = float('Inf')
    while swp < nswp:
        # Right-to-left sweep
        # The idea: compute the current core; compute the function of it;
        # Shift locally or globally? Local shift would be the first try
        # Compute the current core

        if np.size(Jy[i]) == 0:
            w1 = np.zeros((ry[i] * n[i] * ry[i + 1], 0), dtype=np.int)
        else:
            w1 = mkron(np.ones((n[i] * ry[i + 1], 1), dtype=np.int), Jy[i])
        w2 = mkron(mkron(np.ones((ry[i + 1], 1), dtype=np.int),
                         grid[i]), np.ones((ry[i], 1), dtype=np.int))
        if np.size(Jy[i + 1]) == 0:
            w3 = np.zeros((ry[i] * n[i] * ry[i + 1], 0), dtype=np.int)
        else:
            w3 = mkron(Jy[i + 1], np.ones((ry[i] * n[i], 1), dtype=np.int))

        J = np.hstack((w1, w2, w3))
        # Just add some random indices to J, which is rnr x d, need to make rn (r + r0) x add,
        # i.e., just generate random r, random n and random multiindex

        cry = fun(J)
        fun_evals += cry.size
        cry = reshape(cry, (ry[i], n[i], ry[i + 1]))
        min_cur = np.min(cry.flatten("F"))
        ind_cur = np.argmin(cry.flatten("F"))
        if lm > min_cur:
            lm = min_cur
            x_full = J[ind_cur, :]
            val = fun(x_full)
            if verb:
                print('New record:', val, 'Point:', x_full, 'fevals:', fun_evals)
        cry = smooth_fun(cry, lm)
        if (dirn < 0 and i > 0):
            cry = reshape(cry, (ry[i], n[i] * ry[i + 1]))
            cry = cry.T
            #q, r = np.linalg.qr(cry)
            u, s, v = mysvd(cry, full_matrices=False)
            ry[i] = min(ry[i], rmax)
            q = u[:, :ry[i]]
            ind = rect_maxvol(q)[0]  # maxvol(q)
            ry[i] = ind.size
            w1 = mkron(np.ones((ry[i + 1], 1), dtype=np.int), grid[i])
            if np.size(Jy[i + 1]) == 0:
                w2 = np.zeros((n[i] * ry[i + 1], 0), dtype=np.int)
            else:
                w2 = mkron(Jy[i + 1], np.ones((n[i], 1), dtype=np.int))
            Jy[i] = np.hstack((w1, w2))
            Jy[i] = reshape(Jy[i], (n[i] * ry[i + 1], -1))
            Jy[i] = Jy[i][ind, :]

        if (dirn > 0 and i < d - 1):
            cry = reshape(cry, (ry[i] * n[i], ry[i + 1]))
            q, r = np.linalg.qr(cry)
            #ind = maxvol(q)
            ind = rect_maxvol(q)[0]
            ry[i + 1] = ind.size
            w1 = mkron(np.ones((n[i], 1), dtype=np.int), Jy[i])
            w2 = mkron(grid[i], np.ones((ry[i], 1), dtype=np.int))
            Jy[i + 1] = np.hstack((w1, w2))
            Jy[i + 1] = reshape(Jy[i + 1], (ry[i] * n[i], -1))
            Jy[i + 1] = Jy[i + 1][ind, :]

        i += dirn
        if i == d or i == -1:
            dirn = -dirn
            i += dirn
            swp = swp + 1
    return val, x_full
116246
def estimate_global_norm_range(N_t, func, num_of_sample=10, func_args={},
                               percen_lower=1, percen_upper=99, show_progress=True):
    

    ## Check input arguments
    for arg in [N_t, num_of_sample]:
        assert is_integer_valued_real(arg)
    assert num_of_sample <= N_t
    for arg in [percen_lower, percen_upper]:
        assert is_real_number(arg)
        assert (0 <= arg) and (arg <= 100)
    assert percen_lower <= percen_upper

    assert callable(func)
    assert type(func_args) is dict

    assert type(show_progress) is bool

    sample_indices = np.random.randint(0, N_t-1, num_of_sample)

    if show_progress:
        progress_bar = Progress_Bar(num_of_sample)
    uppers = []
    lowers = []

    for idx, sample_index in enumerate(sample_indices):
        frame_data = func(sample_index, **func_args)
        lowers.append(np.percentile(frame_data, percen_lower))
        uppers.append(np.percentile(frame_data, percen_upper))
        if show_progress:
            progress_bar.print(idx)

    vmin = np.percentile(lowers, percen_lower)
    vmax = np.percentile(uppers, percen_upper)

    return vmin, vmax
865251
def statistics(cls, function, group=None):
        
        benchmark = cls.results(function, group)
        results = {}
        for name, stat in {'avg': numpy.average, 'max': numpy.amax, 'med': numpy.median, 'min': numpy.amin, 'sum': numpy.sum}.items():
            results[name] = stat(benchmark, axis=0)
        return results
866580
def benchmark_setup(self):
        
        def f():
            self._setup()
            self.mod_ext.synchronize(**self.ext_kwargs)
        f()  # Ignore first
        self.setup_stat = self._calc_benchmark_stat(f)
1106037
def main():
    
    if len(argv) < 3:
        print 'Usage for getting CFG: %s CFG_fileA CFG ' % argv[0]
        print 'Usage for getting STR: %s CFG_fileA STR ' \
              'Optimize[0 or 1] splitstring[0 or 1] ' % argv[0]
        print ''
        print 'For example: python pdacnf.py grammar.y STR 1 0'
        print '             python pdacnf.py grammar.y STR 1 1'
        print '             python pdacnf.py grammar.y CFG'
        return

    alphabet = createalphabet()

    mode = argv[2]

    optimized = 0
    splitstring = 0
    if mode == 'STR':
        optimized = int(argv[3])
        splitstring = int(argv[4])

    cfgtopda = CfgPDA(alphabet)
    print '* Parsing Grammar:',
    mma = cfgtopda.yyparse(argv[1])
    print 'OK'
    print ' - Total PDA states are ' + repr(len(mma.s))

    print '* Simplify State IDs:',
    simple_a = SimplifyStateIDs()
    mma.s, biggestid, newaccepted = simple_a.get(mma.s)
    if newaccepted:
        print 'OK'
    else:
        print 'OK'

    print '* Eliminate READ states:',
    replace = ReadReplace(mma.s, biggestid)
    mma.s = replace.replace_read()
    print 'OK'
    print ' - Total PDA states now are ' + repr(len(mma.s))
    maxstate = replace.nextstate() - 1

    print '* Reduce PDA:',
    simple_b = ReducePDA()
    mma.s = simple_b.get(mma.s)
    print 'OK'
    print ' - Total PDA states now are ' + repr(len(mma.s))

    print '* PDA to CFG transformation:',
    cnfgenerator = PdaCnf(mma.s)
    grammar = cnfgenerator.get_rules(optimized)
    print 'OK'
    print ' - Total CFG rules generated: ' + repr(len(grammar))

    if mode == 'STR':
        gen = CFGGenerator(CNFGenerator(grammar),
                           optimized=optimized,
                           splitstring=splitstring,
                           maxstate=maxstate)
        print gen.generate()
    else:
        print grammar