Exemple #1
0
    def run_tests(self, experiment, run):
        exp = experiment(self.run_f)

        pg_ctl = local[path.join(self.builddir, "pg_ctl")]
        dropdb = local[path.join(self.builddir, "dropdb")]
        createdb = local[path.join(self.builddir, "createdb")]
        pgbench = local[path.join(self.builddir, "pgbench")]

        bin_name = path.join(self.builddir, self.name + ".sh")
        test_data = path.join(self.testdir, "test-data")

        (echo["#!/bin/sh"] >> bin_name)()
        (echo[str(exp)] >> bin_name)()
        chmod("+x", bin_name)

        num_clients = 1
        num_transactions = 1000000

        pg_ctl("stop", "-t", 360, "-w", "-D", test_data, retcode=None)
        try:
            with local.cwd(test_data):
                pg_ctl("start", "-p", bin_name, "-w", "-D", test_data)
            dropdb["pgbench"] & FG(retcode=None)
            createdb("pgbench")
            run(pgbench["-i", "pgbench"])
            run(pgbench["-c", num_clients, "-S", "-t", num_transactions,
                        "pgbench"])
            dropdb("pgbench")
            pg_ctl("stop", "-t", 360, "-w", "-D", test_data)
        except Exception:
            pg_ctl("stop", "-t", 360, "-w", "-D", test_data)
            raise
Exemple #2
0
def wrap_dynamic(project,
                 name,
                 sprefix=None,
                 python=sys.executable,
                 name_filters=None):
    """
    Wrap the binary :name with the function :runner.

    This module generates a python tool :name: that can replace
    a yet unspecified binary.
    It behaves similar to the :wrap: function. However, the first
    argument is the actual binary name.

    Args:
        name: name of the python module
        runner: Function that should run the real binary
        sprefix: Prefix that should be used for commands.
        python: The python executable that should be used.
        name_filters:
            List of regex expressions that are used to filter the
            real project name. Make sure to include a match group named
            'name' in the regex, e.g.,
            [
                r'foo(?P<name>.)-flt'
            ]

    Returns: plumbum command, readty to launch.

    """
    from jinja2 import Environment, PackageLoader
    env = Environment(trim_blocks=True,
                      lstrip_blocks=True,
                      loader=PackageLoader('benchbuild', 'utils/templates'))
    template = env.get_template('run_dynamic.py.inc')

    name_absolute = os.path.abspath(name)
    real_f = name_absolute + PROJECT_BIN_F_EXT

    project_file = persist(project, suffix=".project")

    bin_path = list_to_path(CFG["env"]["path"].value())
    bin_path = list_to_path([bin_path, os.environ["PATH"]])

    bin_lib_path = \
        list_to_path(CFG["env"]["ld_library_path"].value())
    bin_lib_path = \
        list_to_path([bin_lib_path, os.environ["LD_LIBRARY_PATH"]])

    with open(name_absolute, 'w') as wrapper:
        wrapper.write(
            template.render(runf=strip_path_prefix(real_f, sprefix),
                            project_file=strip_path_prefix(
                                project_file, sprefix),
                            path=str(bin_path),
                            ld_library_path=str(bin_lib_path),
                            python=python,
                            name_filters=name_filters))

    chmod("+x", name_absolute)
    return local[name_absolute]
Exemple #3
0
def wrap_dynamic(project,
                 name,
                 sprefix=None,
                 python=sys.executable,
                 name_filters=None):
    """
    Wrap the binary :name with the function :runner.

    This module generates a python tool :name: that can replace
    a yet unspecified binary.
    It behaves similar to the :wrap: function. However, the first
    argument is the actual binary name.

    Args:
        name: name of the python module
        runner: Function that should run the real binary
        sprefix: Prefix that should be used for commands.
        python: The python executable that should be used.
        name_filters:
            List of regex expressions that are used to filter the
            real project name. Make sure to include a match group named
            'name' in the regex, e.g.,
            [
                r'foo(?P<name>.)-flt'
            ]

    Returns: plumbum command, readty to launch.

    """
    env = __create_jinja_env()
    template = env.get_template('run_dynamic.py.inc')

    name_absolute = os.path.abspath(name)
    real_f = name_absolute + PROJECT_BIN_F_EXT

    project_file = persist(project, suffix=".project")

    env = CFG['env'].value

    bin_path = list_to_path(env.get('PATH', []))
    bin_path = list_to_path([bin_path, os.environ["PATH"]])

    bin_lib_path = \
        list_to_path(env.get('LD_LIBRARY_PATH', []))
    bin_lib_path = \
        list_to_path([bin_lib_path, os.environ["LD_LIBRARY_PATH"]])

    with open(name_absolute, 'w') as wrapper:
        wrapper.write(
            template.render(
                runf=strip_path_prefix(real_f, sprefix),
                project_file=strip_path_prefix(project_file, sprefix),
                path=str(bin_path),
                ld_library_path=str(bin_lib_path),
                python=python,
                name_filters=name_filters))

    chmod("+x", name_absolute)
    return local[name_absolute]
Exemple #4
0
def wrap_dynamic(self, name, runner, sprefix=None, **template_vars):
    """
    Wrap the binary :name with the function :runner.

    This module generates a python tool :name: that can replace
    a yet unspecified binary.
    It behaves similar to the :wrap: function. However, the first
    argument is the actual binary name.

    Args:
        name: name of the python module
        runner: Function that should run the real binary
        base_class: The base_class of our project.
        base_module: The module of base_class.

    Returns: plumbum command, readty to launch.

    """
    base_class = self.__class__.__name__
    base_module = self.__module__

    name_absolute = os.path.abspath(name)
    blob_f = name_absolute + PROJECT_BLOB_F_EXT
    real_f = name_absolute + PROJECT_BIN_F_EXT
    with open(blob_f, 'wb') as blob:
        blob.write(dill.dumps(runner))

    bin_path = list_to_path(CFG["env"]["binary_path"].value())
    bin_path = list_to_path([bin_path, os.environ["PATH"]])

    bin_lib_path = list_to_path(CFG["env"]["binary_ld_library_path"].value())
    bin_lib_path = list_to_path([bin_lib_path, os.environ["LD_LIBRARY_PATH"]])

    template_vars['db_host'] = str(CFG["db"]["host"])
    template_vars['db_name'] = str(CFG["db"]["name"])
    template_vars['db_port'] = str(CFG["db"]["port"])
    template_vars['db_pass'] = str(CFG["db"]["pass"])
    template_vars['db_user'] = str(CFG["db"]["user"])
    template_vars['path'] = bin_path
    template_vars['ld_lib_path'] = bin_lib_path
    template_vars['blobf'] = strip_path_prefix(blob_f, sprefix)
    template_vars['runf'] = strip_path_prefix(real_f, sprefix)
    template_vars['base_class'] = base_class
    template_vars['base_module'] = base_module

    if 'python' not in template_vars:
        template_vars['python'] = sys.executable

    with open(name_absolute, 'w') as wrapper:
        lines = template_str("templates/run_dynamic.py.inc")
        lines = lines.format(**template_vars)
        wrapper.write(lines)
    chmod("+x", name_absolute)
    return local[name_absolute]
Exemple #5
0
def __save__(script_name, benchbuild, experiment, projects):
    """
    Dump a bash script that can be given to SLURM.

    Args:
        script_name (str): name of the bash script.
        commands (list(benchbuild.utils.cmd)):
            List of plumbum commands to write to the bash script.
        **kwargs: Dictionary with all environment variable bindings we should
            map in the bash script.
    """
    from jinja2 import Environment, PackageLoader

    logs_dir = os.path.dirname(CFG['slurm']['logs'].value)
    node_command = str(benchbuild["-E", experiment.name, "$_project"])
    env = Environment(
        trim_blocks=True,
        lstrip_blocks=True,
        loader=PackageLoader('benchbuild', 'utils/templates'))
    template = env.get_template('slurm.sh.inc')

    with open(script_name, 'w') as slurm2:
        slurm2.write(
            template.render(
                config=["export " + x for x in repr(CFG).split('\n')],
                clean_lockdir=str(CFG["slurm"]["node_dir"]),
                clean_lockfile=str(CFG["slurm"]["node_dir"]) + \
                    ".clean-in-progress.lock",
                cpus=int(CFG['slurm']['cpus_per_task']),
                exclusive=bool(CFG['slurm']['exclusive']),
                lockfile=str(CFG['slurm']["node_dir"]) + ".lock",
                log=local.path(logs_dir) / str(experiment.id),
                max_running=int(CFG['slurm']['max_running']),
                name=experiment.name,
                nice=int(CFG['slurm']['nice']),
                nice_clean=int(CFG["slurm"]["nice_clean"]),
                node_command=node_command,
                no_multithreading=not CFG['slurm']['multithread'],
                ntasks=1,
                prefix=str(CFG["slurm"]["node_dir"]),
                projects=projects,
                slurm_account=str(CFG["slurm"]["account"]),
                slurm_partition=str(CFG["slurm"]["partition"]),
                timelimit=str(CFG['slurm']['timelimit']),
            )
        )

    chmod("+x", script_name)
    if not __verify__(script_name):
        LOG.error("SLURM script failed verification.")
    print("SLURM script written to {0}".format(script_name))
    return script_name
Exemple #6
0
def __save__(script_name, benchbuild, experiment, projects):
    """
    Dump a bash script that can be given to SLURM.

    Args:
        script_name (str): name of the bash script.
        commands (list(benchbuild.utils.cmd)):
            List of plumbum commands to write to the bash script.
        **kwargs: Dictionary with all environment variable bindings we should
            map in the bash script.
    """
    from jinja2 import Environment, PackageLoader

    logs_dir = os.path.dirname(CFG['slurm']['logs'].value)
    node_command = str(benchbuild["-E", experiment.name, "$_project"])
    env = Environment(trim_blocks=True,
                      lstrip_blocks=True,
                      loader=PackageLoader('benchbuild', 'utils/templates'))
    template = env.get_template('slurm.sh.inc')

    with open(script_name, 'w') as slurm2:
        slurm2.write(
            template.render(
                config=["export " + x for x in repr(CFG).split('\n')],
                clean_lockdir=str(CFG["slurm"]["node_dir"]),
                clean_lockfile=str(CFG["slurm"]["node_dir"]) + \
                    ".clean-in-progress.lock",
                cpus=int(CFG['slurm']['cpus_per_task']),
                exclusive=bool(CFG['slurm']['exclusive']),
                lockfile=str(CFG['slurm']["node_dir"]) + ".lock",
                log=local.path(logs_dir) / str(experiment.id),
                max_running=int(CFG['slurm']['max_running']),
                name=experiment.name,
                nice=int(CFG['slurm']['nice']),
                nice_clean=int(CFG["slurm"]["nice_clean"]),
                node_command=node_command,
                no_multithreading=not CFG['slurm']['multithread'],
                ntasks=1,
                prefix=str(CFG["slurm"]["node_dir"]),
                projects=projects,
                slurm_account=str(CFG["slurm"]["account"]),
                slurm_partition=str(CFG["slurm"]["partition"]),
                timelimit=str(CFG['slurm']['timelimit']),
            )
        )

    chmod("+x", script_name)
    if not __verify__(script_name):
        LOG.error("SLURM script failed verification.")
    print("SLURM script written to {0}".format(script_name))
    return script_name
Exemple #7
0
def wrap_cc(filepath,
            compiler,
            project,
            python=sys.executable,
            detect_project=False):
    """
    Substitute a compiler with a script that hides CFLAGS & LDFLAGS.

    This will generate a wrapper script in the current directory
    and return a complete plumbum command to it.

    Args:
        filepath (str): Path to the wrapper script.
        compiler (benchbuild.utils.cmd):
            Real compiler command we should call in the script.
        project (benchbuild.project.Project):
            The project this compiler will be for.
        python (str): Path to the python interpreter we should use.
        detect_project: Should we enable project detection or not.

    Returns (benchbuild.utils.cmd):
        Command of the new compiler we can call.
    """
    env = __create_jinja_env()
    template = env.get_template('run_compiler.py.inc')

    cc_fname = local.path(filepath).with_suffix(".benchbuild.cc", depth=0)
    cc_f = persist(compiler, filename=cc_fname)

    project_file = persist(project, suffix=".project")

    with open(filepath, 'w') as wrapper:
        wrapper.write(
            template.render(
                cc_f=cc_f,
                project_file=project_file,
                python=python,
                detect_project=detect_project))

    chmod("+x", filepath)
    LOG.debug("Placed wrapper in: %s for compiler %s", local.path(filepath),
              str(compiler))
    LOG.debug("Placed project in: %s", local.path(project_file))
    LOG.debug("Placed compiler command in: %s", local.path(cc_f))
    return local[filepath]
Exemple #8
0
def wrap_cc(filepath,
            compiler,
            project,
            compiler_ext_name=None,
            python=sys.executable,
            detect_project=False):
    """
    Substitute a compiler with a script that hides CFLAGS & LDFLAGS.

    This will generate a wrapper script in the current directory
    and return a complete plumbum command to it.

    Args:
        filepath (str): Path to the wrapper script.
        compiler (benchbuild.utils.cmd): Real compiler command we should call in the
            script.
        project (benchbuild.project.Project): The project this compiler will be for.
        experiment (benchbuild.experiment.Experiment): The experiment this compiler will be for.
        extension: A function that will be pickled alongside the compiler.
            It will be called before the actual compilation took place. This
            way you can intercept the compilation process with arbitrary python
            code.
        compiler_ext_name: The name that we should give to the generated
            dill blob for :func:
        detect_project: Should we enable project detection or not.

    Returns (benchbuild.utils.cmd):
        Command of the new compiler we can call.
    """
    from jinja2 import Environment, PackageLoader
    env = Environment(trim_blocks=True,
                      lstrip_blocks=True,
                      loader=PackageLoader('benchbuild', 'utils/templates'))
    template = env.get_template('run_compiler.py.inc')

    cc_f = persist(compiler(),
                   filename=os.path.abspath(filepath + ".benchbuild.cc"))
    project_file = persist(project, suffix=".project")
    #experiment_file = persist(experiment, suffix=".experiment")

    # Change name if necessary (UCHROOT support, host <-> guest).
    if compiler_ext_name is not None:
        project_file = compiler_ext_name(".project")
        #experiment_file = compiler_ext_name(".experiment")
        cc_f = compiler_ext_name(".benchbuild.cc")

    # Update LDFLAGS with configure ld_library_path. This way
    # the libraries found in LD_LIBRARY_PATH are available at link-time too.
    #lib_path_list = CFG["env"]["ld_library_path"].value()
    #ldflags = ldflags + ["-L" + pelem for pelem in lib_path_list if pelem]

    with open(filepath, 'w') as wrapper:
        wrapper.write(
            template.render(
                cc_f=cc_f,
                project_file=project_file,
                #experiment_file=experiment_file,
                python=python,
                detect_project=detect_project))

    chmod("+x", filepath)
    LOG.debug("Placed wrapper in: {wrapper} for compiler {compiler}".format(
        wrapper=os.path.abspath(filepath), compiler=compiler()))
    return local[filepath]
Exemple #9
0
def wrap_cc(filepath,
            cflags,
            ldflags,
            compiler,
            extension,
            compiler_ext_name=None,
            **template_vars):
    """
    Substitute a compiler with a script that hides CFLAGS & LDFLAGS.

    This will generate a wrapper script in the current directory
    and return a complete plumbum command to it.

    Args:
        filepath (str): Path to the wrapper script.
        cflags (list(str)): The CFLAGS we want to hide.
        ldflags (list(str)): The LDFLAGS we want to hide.
        compiler (benchbuild.utils.cmd): Real compiler command we should call in the
            script.
        extension: A function that will be pickled alongside the compiler.
            It will be called before the actual compilation took place. This
            way you can intercept the compilation process with arbitrary python
            code.
        compiler_ext_name: The name that we should give to the generated
            dill blob for :func:

    Returns (benchbuild.utils.cmd):
        Command of the new compiler we can call.
    """
    cc_f = os.path.abspath(filepath + ".benchbuild.cc")
    with open(cc_f, 'wb') as cc:
        cc.write(dill.dumps(compiler()))
        if compiler_ext_name is not None:
            cc_f = compiler_ext_name(".benchbuild.cc")

    blob_f = os.path.abspath(filepath + PROJECT_BLOB_F_EXT)
    if extension is not None:
        with open(blob_f, 'wb') as blob:
            blob.write(dill.dumps(extension))
        if compiler_ext_name is not None:
            blob_f = compiler_ext_name(PROJECT_BLOB_F_EXT)

    # Update LDFLAGS with configure compiler_ld_library_path. This way
    # the libraries found in LD_LIBRARY_PATH are available at link-time too.
    lib_path_list = CFG["env"]["compiler_ld_library_path"].value()
    ldflags = ldflags + ["-L" + pelem for pelem in lib_path_list if pelem]

    template_vars['db_host'] = str(CFG["db"]["host"])
    template_vars['db_name'] = str(CFG["db"]["name"])
    template_vars['db_port'] = str(CFG["db"]["port"])
    template_vars['db_pass'] = str(CFG["db"]["pass"])
    template_vars['db_user'] = str(CFG["db"]["user"])
    template_vars['CFG_FILE'] = CFG["config_file"].value()
    template_vars['CC_F'] = cc_f
    template_vars['CFLAGS'] = cflags
    template_vars['LDFLAGS'] = ldflags
    template_vars['BLOB_F'] = blob_f

    if 'python' not in template_vars:
        template_vars['python'] = sys.executable

    with open(filepath, 'w') as wrapper:
        lines = template_str("templates/compiler.py.inc")
        lines = lines.format(**template_vars)
        wrapper.write(lines)
        chmod("+x", filepath)
Exemple #10
0
def dump_slurm_script(script_name, benchbuild, experiment, projects):
    """
    Dump a bash script that can be given to SLURM.

    Args:
        script_name (str): name of the bash script.
        commands (list(benchbuild.utils.cmd)):
            List of plumbum commands to write to the bash script.
        **kwargs: Dictionary with all environment variable bindings we should
            map in the bash script.
    """
    log_path = os.path.join(CFG['slurm']['logs'].value())
    max_running_jobs = CFG['slurm']['max_running'].value()
    with open(script_name, 'w') as slurm:
        lines = """#!/bin/bash
#SBATCH -o /dev/null
#SBATCH -t \"{timelimit}\"
#SBATCH --ntasks 1
#SBATCH --cpus-per-task {cpus}
"""

        slurm.write(lines.format(log=str(log_path),
                                 timelimit=str(CFG['slurm']['timelimit']),
                                 cpus=str(CFG['slurm']['cpus_per_task'])))

        if not CFG['slurm']['multithread'].value():
            slurm.write("#SBATCH --hint=nomultithread\n")
        if CFG['slurm']['exclusive'].value():
            slurm.write("#SBATCH --exclusive\n")
        slurm.write("#SBATCH --array=0-{0}".format(len(projects) - 1))
        slurm.write("%{0}\n".format(max_running_jobs) if max_running_jobs > 0
                    else '\n')
        slurm.write("#SBATCH --nice={0}\n".format(
            CFG["slurm"]["nice"].value()))

        slurm.write("projects=(\n")
        for project in projects:
            slurm.write("'{0}'\n".format(str(project)))
        slurm.write(")\n")
        slurm.write("_project=\"${projects[$SLURM_ARRAY_TASK_ID]}\"\n")
        slurm_log_path = os.path.join(
            os.path.dirname(CFG['slurm']['logs'].value()),
            str(CFG['experiment_id'].value()) + '-$_project')
        slurm.write("exec 1> {log}\n".format(log=slurm_log_path))
        slurm.write("exec 2>&1\n")

        slurm.write(__prepare_node_commands(experiment))
        slurm.write("\n")
        cfg_vars = repr(CFG).split('\n')
        cfg_vars = "\nexport ".join(cfg_vars)
        slurm.write("export ")
        slurm.write(cfg_vars)
        slurm.write("\n")
        slurm.write("scontrol update JobId=${SLURM_ARRAY_JOB_ID}_${SLURM_ARRAY_TASK_ID} ")
        slurm.write("JobName=\"{0} $_project\"\n".format(experiment))
        slurm.write("\n")
        slurm.write("srun -c 1 hostname\n")

        # Write the experiment command.
        extra_logs = CFG["slurm"]["extra_log"].value()
        slurm.write(__cleanup_node_commands(slurm_log_path))
        slurm.write("srun -c 1 rm -f {0}\n".format(extra_logs))
        slurm.write(
            str(benchbuild["-P", "$_project", "-E", experiment]) + "\n")

        # Append the polyjit log to the slurm log.
        slurm.write("srun -c 1 cat {0}\n".format(extra_logs))

    bash("-n", script_name)
    chmod("+x", script_name)