#!/usr/bin/env python
# encoding: utf-8

"""
The 'polly' Experiment
====================

This experiment applies polly's transformations to all projects and measures
the runtime.

This forms the baseline numbers for the other experiments.


Measurements
------------

3 Metrics are generated during this experiment:
    time.user_s - The time spent in user space in seconds (aka virtual time)
    time.system_s - The time spent in kernel space in seconds (aka system time)
    time.real_s - The time spent overall in seconds (aka Wall clock)
"""

from pprof.experiment import step, substep, RuntimeExperiment
from pprof.settings import config
from os import path


class Polly(RuntimeExperiment):

    """ The polly experiment. """

    def run_project(self, p):
        llvm_libs = path.join(config["llvmdir"], "lib")

        with step("Polly, no parallel -O3"):
            p.ldflags = ["-L" + llvm_libs]
            p.cflags = ["-O3",
                        "-Xclang", "-load",
                        "-Xclang", "LLVMPolyJIT.so",
                        "-mllvm", "-polly"]
            with substep("reconf & rebuild"):
                p.download()
                p.configure()
                p.build()
            with substep("run {}".format(p.name)):
                def run_with_time(run_f, args, **kwargs):
                    """
                    Function runner for the raw experiment.

                    This executes the given project command wrapped in the
                    time command. Afterwards the result is sent to the
                    database.

                    3 Metrics are generated during this experiment:
                        time.user_s - The time spent in user space in
                                      seconds (aka virtual time)
                        time.system_s - The time spent in kernel space in
                                        seconds (aka system time)
                        time.real_s - The time spent overall in seconds
                                      (aka Wall clock)

                    :run_f:
                        The file we actually execute.
                    :args:
                        Arguments to forwards to :run_f:
                    :has_stdin:
                        If the program requires access to a file redirected
                        via stdin, say so.
                    :project_name:
                        Name of the project to enter into the db.
                    :kwargs:
                        Rest.
                    """
                    from plumbum.cmd import time
                    from pprof.utils.run import fetch_time_output, handle_stdin

                    project_name = kwargs.get("project_name", p.name)

                    run_cmd = handle_stdin(
                        time["-f", "PPROF-POLLY: %U-%S-%e", run_f, args],
                        kwargs)

                    _, _, stderr = run_cmd.run()
                    timings = fetch_time_output("PPROF-POLLY: ",
                                                "PPROF-POLLY: {:g}-{:g}-{:g}",
                                                stderr.split("\n"))
                    if len(timings) == 0:
                        return

                    self.persist_run(str(run_cmd), project_name, p.run_uuid,
                                     timings)

                p.run(run_with_time)

@@ -1276,2094 +1276,244 @@
     
-def run_with_time(run_f, args, **kwargs):%0A                    %22%22%22%0A                    Function runner for the raw experiment.%0A%0A                    This executes the given project command wrapped in the%0A                    time command. Afterwards the result is sent to the%0A                    database.%0A%0A                    3 Metrics are generated during this experiment:%0A                        time.user_s - The time spent in user space in%0A                                      seconds (aka virtual time)%0A                        time.system_s - The time spent in kernel space in%0A                                        seconds (aka system time)%0A                        time.real_s - The time spent overall in seconds%0A                                      (aka Wall clock)%0A%0A                    :run_f:%0A                        The file we actually execute.%0A                    :args:%0A                        Arguments to forwards to :run_f:%0A                    :has_stdin:%0A                        If the program requires access to a file redirected%0A                        via stdin, say so.%0A                    :project_name:%0A                        Name of the project to enter into the db.%0A                    :kwargs:%0A                        Rest.%0A                    %22%22%22%0A                    from plumbum.cmd import time%0A                    from pprof.utils.run import fetch_time_output, handle_stdin%0A%0A                    project_name = kwargs.get(%22project_name%22, p.name)%0A%0A                    run_cmd = handle_stdin(%0A                        time%5B%22-f%22, %22PPROF-POLLY: %25U-%25S-%25e%22, run_f, args%5D,%0A                        kwargs)%0A%0A                    _, _, stderr = run_cmd.run()%0A                    timings = fetch_time_output(%22PPROF-POLLY: %22,%0A                                                %22PPROF-POLLY: %7B:g%7D-%7B:g%7D-%7B:g%7D%22,%0A                                                stderr.split(%22%5Cn%22))%0A                    if len(timings) == 0:%0A                        return%0A%0A                    self.persist_run(str(run_cmd), project_name, p.run_uuid,%0A                                     timings)%0A
+from pprof.experiments.raw import run_with_time%0A%0A                run_with_time.config = config%0A                run_with_time.experiment = self%0A                run_with_time.project = p%0A                run_with_time.jobs = config%5B%22jobs%22%5D
 %0A   

use raw's timing function