Пример #1
0
static int find_all_sockets_cores (resrc_api_ctx_t *rsapi, resrc_t *node,
               int *nsocks, int *ncs)
{
    json_t *reqobj= NULL;
    resrc_reqst_t *req = NULL;
    resrc_tree_t *st = NULL;
    resrc_tree_t *ct = NULL;

    reqobj = Jnew ();
    create_req4allsocks (reqobj);
    req = resrc_reqst_from_json (rsapi, reqobj, NULL);
    *nsocks = resrc_tree_search (rsapi, node, req, &st, false);
    resrc_reqst_destroy (rsapi, req);
    resrc_tree_destroy (rsapi, st, false, false);
    Jput (reqobj);

    reqobj = Jnew ();
    create_req4allcores (reqobj);
    req = resrc_reqst_from_json (rsapi, reqobj, NULL);
    *ncs = resrc_tree_search (rsapi, node, req, &ct, false);
    resrc_reqst_destroy (rsapi, req);
    resrc_tree_destroy (rsapi, ct, false, false);
    Jput (reqobj);

    return (*nsocks > 0 && *ncs > 0) ? 0 : -1;
}
Пример #2
0
/*
 * find_resources() identifies the all of the resource candidates for
 * the job.  The set of resources returned could be more than the job
 * requires.  A later call to select_resources() will cull this list
 * down to the most appropriate set for the job.
 *
 * Inputs:  resrcs      - hash table of all resources
 *          resrc_reqst - the resources the job requests
 * Returns: nfound      - the number of resources found
 *          found_tree  - a resource tree containing resources that satisfy the
 *                        job's request or NULL if none are found
 */
int64_t find_resources (flux_t *h, resrc_t *resrc, resrc_reqst_t *resrc_reqst,
                        resrc_tree_t **found_tree)
{
    int64_t nfound = 0;

    if (!resrc || !resrc_reqst) {
        flux_log (h, LOG_ERR, "%s: invalid arguments", __FUNCTION__);
        goto ret;
    }
    /*
     * A start time of zero is used to restrict the search to now
     * (appropriate for FCFS) and prevent any search into the future.
     */
    if (resrc_reqst_set_starttime (resrc_reqst, 0) ||
        resrc_reqst_set_endtime (resrc_reqst, 0))
        goto ret;

    *found_tree = NULL;
    nfound = resrc_tree_search (resrc, resrc_reqst, found_tree, true);

    if (!nfound && *found_tree) {
        resrc_tree_destroy (*found_tree, false);
        *found_tree = NULL;
    }
ret:
    return nfound;
}
Пример #3
0
/* returns the number of resource or resource composites found */
int64_t resrc_tree_search (resrc_t *resrc_in, resrc_reqst_t *resrc_reqst,
                           resrc_tree_t **found_tree, bool available)
{
    int64_t nfound = 0;
    resrc_tree_list_t *children = NULL;
    resrc_tree_t *child_tree;
    resrc_tree_t *new_tree = NULL;

    if (!resrc_in || !found_tree || !resrc_reqst) {
        goto ret;
    }

    if (resrc_match_resource (resrc_in, resrc_reqst, available)) {
        if (resrc_reqst_num_children (resrc_reqst)) {
            if (resrc_tree_num_children (resrc_phys_tree (resrc_in))) {
                new_tree = resrc_tree_new (*found_tree, resrc_in);
                children = resrc_tree_children (resrc_phys_tree (resrc_in));
                if (match_children (children, resrc_reqst->children, new_tree,
                                    available)) {
                    nfound = 1;
                    resrc_reqst->nfound++;
                } else {
                    resrc_tree_destroy (new_tree, false);
                }
            }
        } else {
            (void) resrc_tree_new (*found_tree, resrc_in);
            nfound = 1;
            resrc_reqst->nfound++;
        }
    } else if (resrc_tree_num_children (resrc_phys_tree (resrc_in))) {
        /*
         * This clause visits the children of the current resource
         * searching for a match to the resource request.  The found
         * tree must be extended to include this intermediate
         * resource.
         *
         * This also allows the resource request to be sparsely
         * defined.  E.g., it might only stipulate a node with 4 cores
         * and omit the intervening socket.
         */
        if (*found_tree)
            new_tree = resrc_tree_new (*found_tree, resrc_in);
        else {
            new_tree = resrc_tree_new (NULL, resrc_in);
            *found_tree = new_tree;
        }
        children = resrc_tree_children (resrc_phys_tree (resrc_in));
        child_tree = resrc_tree_list_first (children);
        while (child_tree) {
            nfound += resrc_tree_search (resrc_tree_resrc (child_tree),
                                         resrc_reqst, &new_tree, available);
            child_tree = resrc_tree_list_next (children);
        }
    }
ret:
    return nfound;
}
Пример #4
0
static int find_all_nodes (resrc_api_ctx_t *rsapi, resrc_t *root,
               resrc_tree_t **ot)
{
    json_t *reqobj = NULL;
    int64_t size = 0;
    resrc_reqst_t *req = NULL;

    reqobj = Jnew ();
    create_req4allnodes (reqobj);
    req = resrc_reqst_from_json (rsapi, reqobj, NULL);
    size = resrc_tree_search (rsapi, root, req, ot, false);
    resrc_reqst_destroy (rsapi, req);
    Jput (reqobj);

    return (size > 0) ? 0 : -1;
}
Пример #5
0
/*
 * cycles through all of the resource children and returns the number of
 * requested resources found
 */
static int64_t match_child (resrc_tree_list_t *r_trees,
                            resrc_reqst_t *resrc_reqst,
                            resrc_tree_t *found_parent, bool available)
{
    int64_t nfound = 0;
    resrc_t *resrc = NULL;
    resrc_tree_t *resrc_tree = NULL;

    resrc_tree = resrc_tree_list_first (r_trees);
    while (resrc_tree) {
        resrc = resrc_tree_resrc (resrc_tree);
        nfound += resrc_tree_search (resrc, resrc_reqst, &found_parent,
                                     available);
        resrc_tree = resrc_tree_list_next (r_trees);
    }

    return nfound;
}
Пример #6
0
/*
 * find_resources() identifies the all of the resource candidates for
 * the job.  The set of resources returned could be more than the job
 * requires.  A later call to select_resources() will cull this list
 * down to the most appropriate set for the job.
 *
 * Inputs:  resrcs      - hash table of all resources
 *          resrc_reqst - the resources the job requests
 * Returns: nfound      - the number of resources found
 *          found_tree  - a resource tree containing resources that satisfy the
 *                        job's request or NULL if none are found
 */
int64_t find_resources (flux_t h, resrc_t *resrc, resrc_reqst_t *resrc_reqst,
                        resrc_tree_t **found_tree)
{
    int64_t nfound = 0;

    if (!resrc || !resrc_reqst) {
        flux_log (h, LOG_ERR, "%s: invalid arguments", __FUNCTION__);
        goto ret;
    }

    *found_tree = NULL;
    nfound = resrc_tree_search (resrc, resrc_reqst, found_tree, true);

    if (!nfound && *found_tree) {
        resrc_tree_destroy (*found_tree, false);
        *found_tree = NULL;
    }
ret:
    return nfound;
}
Пример #7
0
static int test_a_resrc (resrc_t *resrc, bool rdl)
{
    int found = 0;
    int rc = 0;
    int64_t nowtime = epochtime ();
    JSON o = NULL;
    JSON req_res = NULL;
    resrc_reqst_t *resrc_reqst = NULL;
    resrc_tree_t *deserialized_tree = NULL;
    resrc_tree_t *found_tree = NULL;
    resrc_tree_t *resrc_tree = NULL;
    resrc_tree_t *selected_tree = NULL;

    resrc_tree = resrc_phys_tree (resrc);
    ok ((resrc_tree != NULL), "resource tree valid");
    if (!resrc_tree)
        goto ret;

    if (verbose) {
        printf ("Listing resource tree\n");
        resrc_tree_print (resrc_tree);
        printf ("End of resource tree\n");
    }

    /*
     *  Build a resource composite to search for.  Two variants are
     *  constructed depending on whether the loaded resources came
     *  from the sample RDL file or from the hwloc.  The hwloc request
     *  does not span multiple nodes or contain the localid property.
     */
    req_res = Jnew ();

    if (rdl) {
        JSON bandwidth = Jnew ();
        JSON child_core = Jnew ();
        JSON child_sock = Jnew ();
        JSON graph_array = Jnew_ar ();
        JSON ja = Jnew_ar ();
        JSON jpropo = Jnew (); /* json property object */
        JSON memory = Jnew ();
        JSON power = Jnew ();

        /* JSON jtago = Jnew ();  /\* json tag object *\/ */
        /* Jadd_bool (jtago, "maytag", true); */
        /* Jadd_bool (jtago, "yourtag", true); */

        Jadd_str (memory, "type", "memory");
        Jadd_int (memory, "req_qty", 1);
        Jadd_int (memory, "size", 100);
        json_object_array_add (ja, memory);

        Jadd_str (child_core, "type", "core");
        Jadd_int (child_core, "req_qty", 6);
        Jadd_bool (child_core, "exclusive", true);
        Jadd_int (jpropo, "localid", 1);
        json_object_object_add (child_core, "properties", jpropo);
        json_object_array_add (ja, child_core);

        Jadd_str (child_sock, "type", "socket");
        Jadd_int (child_sock, "req_qty", 2);
        json_object_object_add (child_sock, "req_children", ja);

        Jadd_str (bandwidth, "type", "bandwidth");
        Jadd_int (bandwidth, "size", 100);
        json_object_array_add (graph_array, bandwidth);

        Jadd_str (power, "type", "power");
        Jadd_int (power, "size", 10);
        json_object_array_add (graph_array, power);

        Jadd_str (req_res, "type", "node");
        Jadd_int (req_res, "req_qty", 2);
        Jadd_int64 (req_res, "starttime", nowtime);
        /* json_object_object_add (req_res, "tags", jtago); */
        json_object_object_add (req_res, "req_child", child_sock);
        json_object_object_add (req_res, "graphs", graph_array);
    } else {
        Jadd_str (req_res, "type", "core");
        Jadd_int (req_res, "req_qty", 2);
        Jadd_bool (req_res, "exclusive", true);
    }

    resrc_reqst = resrc_reqst_from_json (req_res, NULL);
    Jput (req_res);
    ok ((resrc_reqst != NULL), "resource request valid");
    if (!resrc_reqst)
        goto ret;

    if (verbose) {
        printf ("Listing resource request tree\n");
        resrc_reqst_print (resrc_reqst);
        printf ("End of resource request tree\n");
    }

    init_time ();
    found = resrc_tree_search (resrc, resrc_reqst, &found_tree, true);

    ok (found, "found %d requested resources in %lf", found,
        ((double)get_time ())/1000000);
    if (!found)
        goto ret;

    if (verbose) {
        printf ("Listing found tree\n");
        resrc_tree_print (found_tree);
        printf ("End of found tree\n");
    }

    o = Jnew ();
    init_time ();
    rc = resrc_tree_serialize (o, found_tree);
    ok (!rc, "found resource serialization took: %lf",
        ((double)get_time ())/1000000);

    if (verbose) {
        printf ("The found resources serialized: %s\n", Jtostr (o));
    }

    deserialized_tree = resrc_tree_deserialize (o, NULL);
    if (verbose) {
        printf ("Listing deserialized tree\n");
        resrc_tree_print (deserialized_tree);
        printf ("End of deserialized tree\n");
    }
    Jput (o);

    init_time ();

    /*
     * Exercise time-based allocations for the rdl case and
     * now-based allocations for the hwloc case
     */
    selected_tree = test_select_resources (found_tree, NULL, 1);
    if (rdl)
        rc = resrc_tree_allocate (selected_tree, 1, nowtime, nowtime + 3600);
    else
        rc = resrc_tree_allocate (selected_tree, 1, 0, 0);
    ok (!rc, "successfully allocated resources for job 1");
    resrc_tree_destroy (selected_tree, false);
    resrc_tree_unstage_resources (found_tree);

    selected_tree = test_select_resources (found_tree, NULL, 2);
    if (rdl)
        rc = resrc_tree_allocate (selected_tree, 2, nowtime, nowtime + 3600);
    else
        rc = resrc_tree_allocate (selected_tree, 2, 0, 0);
    ok (!rc, "successfully allocated resources for job 2");
    resrc_tree_destroy (selected_tree, false);
    resrc_tree_unstage_resources (found_tree);

    selected_tree = test_select_resources (found_tree, NULL, 3);
    if (rdl)
        rc = resrc_tree_allocate (selected_tree, 3, nowtime, nowtime + 3600);
    else
        rc = resrc_tree_allocate (selected_tree, 3, 0, 0);
    ok (!rc, "successfully allocated resources for job 3");
    resrc_tree_destroy (selected_tree, false);
    resrc_tree_unstage_resources (found_tree);

    selected_tree = test_select_resources (found_tree, NULL, 4);
    if (rdl)
        rc = resrc_tree_reserve (selected_tree, 4, nowtime, nowtime + 3600);
    else
        rc = resrc_tree_reserve (selected_tree, 4, 0, 0);
    ok (!rc, "successfully reserved resources for job 4");
    resrc_tree_destroy (selected_tree, false);
    resrc_tree_unstage_resources (found_tree);

    printf ("        allocate and reserve took: %lf\n",
            ((double)get_time ())/1000000);

    if (verbose) {
        printf ("Allocated and reserved resources\n");
        resrc_tree_print (resrc_tree);
    }

    init_time ();
    rc = resrc_tree_release (found_tree, 1);
    ok (!rc, "resource release of job 1 took: %lf",
        ((double)get_time ())/1000000);

    if (verbose) {
        printf ("Same resources without job 1\n");
        resrc_tree_print (resrc_tree);
    }

    init_time ();
    resrc_reqst_destroy (resrc_reqst);
    resrc_tree_destroy (deserialized_tree, true);
    resrc_tree_destroy (found_tree, false);
    printf ("        destroy took: %lf\n", ((double)get_time ())/1000000);
ret:
    return rc;
}
Пример #8
0
/*
 * reserve_resources() reserves resources for the specified job id.
 * Unlike the FCFS version where selected_tree provides the tree of
 * resources to reserve, this backfill version will search into the
 * future to find a time window when all of the required resources are
 * available, reserve those, and return the pointer to the selected
 * tree.
 */
int reserve_resources (flux_t h, resrc_tree_t **selected_tree, int64_t job_id,
                       int64_t starttime, int64_t walltime, resrc_t *resrc,
                       resrc_reqst_t *resrc_reqst)
{
    int rc = -1;
    int64_t *completion_time = NULL;
    int64_t nfound = 0;
    int64_t prev_completion_time = -1;
    resrc_tree_t *found_tree = NULL;

    if (reservation_depth > 0 && (curr_reservation_depth >= reservation_depth)) {
        goto ret;
    } else if (!resrc || !resrc_reqst) {
        flux_log (h, LOG_ERR, "%s: invalid arguments", __FUNCTION__);
        goto ret;
    }

    if (*selected_tree) {
        resrc_tree_destroy (*selected_tree, false);
        *selected_tree = NULL;
    }
    zlist_sort (completion_times, compare_int64_ascending);

    for (completion_time = zlist_first (completion_times);
         completion_time;
         completion_time = zlist_next (completion_times)) {
        /* Purge past times from consideration */
        if (*completion_time < starttime) {
            zlist_remove (completion_times, completion_time);
            continue;
        }
        /* Don't test the same time multiple times */
        if (prev_completion_time == *completion_time)
            continue;

        resrc_reqst_set_starttime (resrc_reqst, *completion_time + 1);
        resrc_reqst_set_endtime (resrc_reqst, *completion_time + 1 + walltime);
        flux_log (h, LOG_DEBUG, "Attempting to reserve %"PRId64" nodes for job "
                  "%"PRId64" at time %"PRId64"",
                  resrc_reqst_reqrd_qty (resrc_reqst), job_id,
                  *completion_time + 1);

        nfound = resrc_tree_search (resrc, resrc_reqst, &found_tree, true);
        if (nfound >= resrc_reqst_reqrd_qty (resrc_reqst)) {
            *selected_tree = select_resources (h, found_tree, resrc_reqst, NULL);
            resrc_tree_destroy (found_tree, false);
            if (*selected_tree) {
                rc = resrc_tree_reserve (*selected_tree, job_id,
                                         *completion_time + 1,
                                         *completion_time + 1 + walltime);
                if (rc) {
                    resrc_tree_destroy (*selected_tree, false);
                    *selected_tree = NULL;
                } else {
                    curr_reservation_depth++;
                    flux_log (h, LOG_DEBUG, "Reserved %"PRId64" nodes for job "
                              "%"PRId64" from %"PRId64" to %"PRId64"",
                              resrc_reqst_reqrd_qty (resrc_reqst), job_id,
                              *completion_time + 1,
                              *completion_time + 1 + walltime);
                }
                break;
            }
        }
        prev_completion_time = *completion_time;
    }
ret:
    return rc;
}