Esempio n. 1
0
int hpx_main(boost::program_options::variables_map& vm)
{
    std::size_t num_samples = 1000;
    std::size_t num_tasks = 100;
    std::size_t num_chunks = 1;
    std::size_t delay = 0;
    bool header = true;

    if (vm.count("no-header"))
        header = false;
    if (vm.count("samples"))
        num_samples = vm["samples"].as<std::size_t>();
    if (vm.count("futures"))
        num_tasks = vm["futures"].as<std::size_t>();
    if (vm.count("chunks"))
        num_chunks = vm["chunks"].as<std::size_t>();
    if (vm.count("delay"))
        delay = vm["delay"].as<std::size_t>();

    if (num_chunks == 0)
        num_chunks = 1;

    // wait for all of the tasks sequentially
    double elapsed_seq = wait_tasks(num_samples, num_tasks, 1, delay);

    // wait of tasks in chunks
    double elapsed_chunks = 0;
    if (num_chunks != 1)
        elapsed_chunks = wait_tasks(num_samples, num_tasks, num_chunks, delay);

    if (header)
    {
        hpx::cout
            << "Tasks,Chunks,Delay[s],Total Walltime[s],Walltime per Task[s]"
             << hpx::endl;
    }

    std::string const tasks_str = hpx::util::format("{}", num_tasks);
    std::string const chunks_str = hpx::util::format("{}", num_chunks);
    std::string const delay_str = hpx::util::format("{}", delay);

    hpx::util::format_to(hpx::cout, "{:10},{:10},{:10},{:10},{:10.12}\n",
        tasks_str, std::string("1"), delay_str, elapsed_seq,
        elapsed_seq / num_tasks)
        << hpx::endl;
    hpx::util::print_cdash_timing("WaitAll", elapsed_seq / num_tasks);

    if (num_chunks != 1)
    {
        hpx::util::format_to(hpx::cout,
            "{:10},{:10},{:10},{:10},{:10.12},{:10.12}\n",
            tasks_str, chunks_str, delay_str,
            elapsed_chunks, elapsed_chunks / num_tasks) << hpx::endl;
        hpx::util::print_cdash_timing("WaitAllChunks", elapsed_chunks / num_tasks);
    }
    return hpx::finalize();
}
Esempio n. 2
0
int hpx_main(boost::program_options::variables_map& vm)
{
    std::size_t num_samples = 1000;
    std::size_t num_tasks = 100;
    std::size_t num_chunks = 1;
    std::size_t delay = 0;
    bool header = true;

    if (vm.count("no-header"))
        header = false;
    if (vm.count("samples"))
        num_samples = vm["samples"].as<std::size_t>();
    if (vm.count("futures"))
        num_tasks = vm["futures"].as<std::size_t>();
    if (vm.count("chunks"))
        num_chunks = vm["chunks"].as<std::size_t>();
    if (vm.count("delay"))
        delay = vm["delay"].as<std::size_t>();

    if (num_chunks == 0)
        num_chunks = 1;

    // wait for all of the tasks sequentially
    double elapsed_seq = wait_tasks(num_samples, num_tasks, 1, delay);

    // wait of tasks in chunks
    double elapsed_chunks = 0;
    if (num_chunks != 1)
        elapsed_chunks = wait_tasks(num_samples, num_tasks, num_chunks, delay);

    if (header)
    {
        hpx::cout
            << "Tasks,Chunks,Delay[s],Total Walltime[s],Walltime per Task[s]"
             << hpx::endl;
    }

    std::string const tasks_str = boost::str(boost::format("%lu") % num_tasks);
    std::string const chunks_str = boost::str(boost::format("%lu") % num_chunks);
    std::string const delay_str = boost::str(boost::format("%lu") % delay);

    hpx::cout
        << (boost::format("%10s,%10s,%10s,%10.12s,%10.12s")
            % tasks_str % std::string("1") % delay_str
            % elapsed_seq % (elapsed_seq / num_tasks))
        << hpx::endl;
    if (num_chunks != 1)
    {
        hpx::cout
            << (boost::format("%10s,%10s,%10s,%10.12s,%10.12s")
                % tasks_str % chunks_str % delay_str
                % elapsed_chunks % (elapsed_chunks / num_tasks))
            << hpx::endl;
    }
    return hpx::finalize();
}
Esempio n. 3
0
File: exedist.c Progetto: hocks/TSCC
/*
 * Overall executable distribution using fast.
 */
int
distribute_executable(void)
{
    int ret = 1;  /* failure */

#if HAVE_FAST_DIST
    const char *fast_command = FAST_DIST_PATH;  /* from configure */
    int i;
    int numtasks_save;
    int local_numtasks;
    tasks_t *tasks_save;
    cl_args_t cl_args_save;
    config_spec_t cs, root_cs;
    growstr_t *g, *root_g;
    int temp_fd;
    char *file_template;
    int port_num;
    FILE *fp;
    const char *exec_to_dist;
    int *usenodes;

    exec_to_dist = config_get_unique_executable();
    if (!exec_to_dist)
        return ret;

    if (!stat_exe(fast_command, 0))
        return ret;

    /* analyze nodes */
    usenodes = Malloc(numnodes * sizeof(*usenodes));
    memset(usenodes, 0, numnodes * sizeof(*usenodes));
    local_numtasks = 0;
    for (i=0; i<numtasks; i++) {
        if (!usenodes[tasks[i].node]) {
            usenodes[tasks[i].node] = 1;
            ++local_numtasks;
        }
    }

    /* don't bother if there is only one node */
    if (local_numtasks <= 1) {
        free(usenodes);
        return ret;
    }

    /* create temporary node file */
    file_template = strsave("/tmp/mpiexec-fast-XXXXXX");
    temp_fd = mkstemp(file_template);
    if (!temp_fd)
        goto out;
    debug(1, "%s: temp node list file is %d",__func__, temp_fd);
    fp = fdopen(temp_fd, "w");
    if (!fp)
        goto out;

    /* add nodes to the node file */
    for (i=0; i<numnodes; i++) {
        if (!usenodes[i])
            continue;
        if (fprintf(fp, "%s\n", nodes[i].name) <= 0) {
            fclose(fp);
            goto out;
        }
    }
    if (fclose(fp) != 0)
        goto out;

    /* pick a random port number between 6 and 8 thousand */
    srand(time(NULL));
    port_num = rand() % 2000 + 6000;

    /*
     * Back up the tasks structure and number of tasks as well as command
     * line args.
     */
    tasks_save = tasks;
    numtasks_save = numtasks;
    memcpy(&cl_args_save, cl_args, sizeof(*cl_args));

    /* set the fast_dist executable name */
    cs.exe = fast_command;
    root_cs.exe = cs.exe;

    /* set up the args to pass to the non-root nodes */
    g = growstr_init();
    growstr_printf(g, "-p %d", port_num);
    cs.args = g->s;
    debug(1, "%s: arg string for non root: %s", __func__, g->s);

    /* and to the root node */
    root_g = growstr_init();
    growstr_printf(root_g, "-p %d -r %s -e %s -n %s",
                   port_num, nodes[tasks[0].node].name, exec_to_dist, file_template);
    root_cs.args = root_g->s;
    debug(1, "%s: arg string for root: %s", __func__, root_g->s);

    /* build new tasks */
    cl_args->which_stdin = STDIN_NONE;
    cl_args->comm = COMM_NONE;
    tasks = Malloc(local_numtasks * sizeof(*tasks));
    numtasks = local_numtasks;
    for (i=0; i < numtasks; i++) {
        tasks[i].num_copies = 1;
        tasks[i].done = DONE_NOT_STARTED;
        *tasks[i].status = -1;
        /*
         * Slight race condition in that the root wants to actively connect
         * to some other nodes, but it will retry a bit.  Put root last to
         * hope that there is a bit of delay in startup.
         */
        if (i == numtasks - 1) {
            tasks[i].node = tasks_save[0].node;
            tasks[i].conf = &root_cs;
        } else {
            tasks[i].node = tasks_save[i+1].node;
            tasks[i].conf = &cs;
        }
        debug(1, "%s: task %d on %d", __func__, i, tasks[i].node);
    }

    /* spawn tasks */
    start_tasks(0);
    debug(1, "%s: tasks started", __func__);

    /* wait for them to exit */
    wait_tasks();

    /* make sure everyone finished successfully */
    ret = 0;
    for (i=0; i<numtasks; i++) {
        if (tasks[i].done == DONE_NO_EXIT_STATUS)
            continue;
        if (*tasks[i].status != 0) {
            ret = 1;
            break;
        }
    }
    debug(1, "%s: done, ret = %d", __func__, ret);

    /* put back original tasks structures */
    free(tasks);
    tasks = tasks_save;
    numtasks = numtasks_save;
    memcpy(cl_args, &cl_args_save, sizeof(*cl_args));
    growstr_free(g);
    growstr_free(root_g);

    /*
     * Update executable in old config structure to point to new /tmp exec,
     * using the same algorithm as fast_dist.  It is not deleted upon
     * completion but relies on $TMPDIR being deleted when PBS cleans up the
     * job or normal /tmp cleaning.
     */
    if (ret == 0) {
        const char *cp, *base;
        growstr_t *h;

        h = growstr_init();
        cp = getenv("TMPDIR");
        if (!cp || !*cp)
            cp = "/tmp";
        growstr_append(h, cp);

        for (cp=base=exec_to_dist; *cp; cp++)
            if (*cp == '/')
                base = cp+1;
        growstr_append(h, "/");
        growstr_append(h, base);

        config_set_unique_executable(strsave(h->s));
        growstr_free(h);
    }

out:
    unlink(file_template);
    free(file_template);
    free(usenodes);
#endif /* HAVE_FAST_DIST */

    return ret;
}