Beispiel #1
0
/*
 * Select some resources from the found tree
 * frt is found resource tree
 * prt is selected resource tree parent
 */
static resrc_tree_t *test_select_resources (resrc_tree_t *frt, resrc_tree_t *prt,
                                            int select)
{
    resrc_tree_t *selected_res = NULL;

    if (frt) {
        resrc_t *resrc = resrc_tree_resrc (frt);

        if (!strcmp (resrc_type(resrc), "core")) {
            if (resrc_id (resrc) == select)
                resrc_stage_resrc (resrc, 1, NULL);
            else
                goto ret;
        } else if (!strcmp (resrc_type(resrc), "memory"))
            resrc_stage_resrc (resrc, 100, NULL);

        selected_res = resrc_tree_new (prt, resrc);
        if (resrc_tree_num_children (frt)) {
            resrc_tree_t *child = resrc_tree_list_first (
                resrc_tree_children (frt));
            while (child) {
                (void) test_select_resources (child, selected_res, select);
                child = resrc_tree_list_next (resrc_tree_children (frt));
            }
        }
    }
ret:
    return selected_res;
}
Beispiel #2
0
int resrc_flow_stage_resources (resrc_flow_t *resrc_flow, size_t size)
{
    int rc =-1;

    if (resrc_flow) {
        rc = resrc_stage_resrc (resrc_flow->flow_resrc, size, NULL);
        if (!rc && resrc_flow->parent)
            rc = resrc_flow_stage_resources (resrc_flow->parent, size);
    }
    return rc;
}
Beispiel #3
0
static void test_temporal_allocation ()
{
    int rc = 0;
    size_t available;
    resrc_t *resource = resrc_new_resource ("custom", "/test", "test", "test1",
                                            NULL, 1, NULL, 10);

    available = resrc_available_at_time (resource, 0);
    rc = (rc || !(available == 10));
    available = resrc_available_during_range (resource, 0, 1000, false);
    rc = (rc || !(available == 10));
    ok (!rc, "resrc_available...(time/range) on unallocated resource work");

    // Setup the resource allocations for the rest of the tests
    resrc_stage_resrc (resource, 5, NULL);
    rc = (rc || resrc_allocate_resource (resource, 1, 1, 1000));
    resrc_stage_resrc (resource, 10, NULL);
    rc = (rc || resrc_allocate_resource (resource, 2, 2000, 3000));
    ok (!rc, "Temporal allocation setup works");
    if (rc) {
        return;
    }

    // Start the actual testing
    resrc_stage_resrc (resource, 1, NULL);
    // This should fail
    rc = (rc || !resrc_allocate_resource (resource, 3, 10, 3000));
    // This should work
    rc = (rc || resrc_allocate_resource (resource, 3, 10, 1999));
    ok (!rc, "Overlapping temporal allocations work");
    if (rc) {
        return;
    }

    // Test "available at time"
    // Job 1
    available = resrc_available_at_time (resource, 1);
    rc = (rc || !(available == 5));
    // Jobs 1 & 3
    available = resrc_available_at_time (resource, 10);
    rc = (rc || !(available == 4));
    available = resrc_available_at_time (resource, 500);
    rc = (rc || !(available == 4));
    available = resrc_available_at_time (resource, 1000);
    rc = (rc || !(available == 4));
    // Job 3
    available = resrc_available_at_time (resource, 1500);
    rc = (rc || !(available == 9));
    available = resrc_available_at_time (resource, 1999);
    rc = (rc || !(available == 9));
    // Job 2
    available = resrc_available_at_time (resource, 2000);
    rc = (rc || !(available == 0));
    available = resrc_available_at_time (resource, 2500);
    rc = (rc || !(available == 0));
    available = resrc_available_at_time (resource, 3000);
    rc = (rc || !(available == 0));
    // No Jobs
    available = resrc_available_at_time (resource, 3001);
    rc = (rc || !(available == 10));
    ok (!rc, "resrc_available_at_time works");
    if (rc) {
        return;
    }

    // Test "available during range"

    // Range == job window (both edges are the same)
    available = resrc_available_during_range (resource, 2000, 3000, false);
    rc = (rc || !(available == 0));
    available = resrc_available_during_range (resource, 0, 1000, false);
    rc = (rc || !(available == 4));
    available = resrc_available_during_range (resource, 10, 1999, false);
    rc = (rc || !(available == 4));
    ok (!rc, "resrc_available_during_range: range == job window works");
    rc = 0;

    // Range is a subset of job window (no edges are the same)
    available = resrc_available_during_range (resource, 4, 6, false);
    rc = (rc || !(available == 5));
    available = resrc_available_during_range (resource, 20, 999, false);
    rc = (rc || !(available == 4));
    available = resrc_available_during_range (resource, 1001, 1998, false);
    rc = (rc || !(available == 9));
    available = resrc_available_during_range (resource, 2500, 2600, false);
    rc = (rc || !(available == 0));
    ok (!rc, "resrc_available_during_range: range is a subset (no edges) works");
    rc = 0;

    // Range is a subset of a job window (one edge is the same)
    available = resrc_available_during_range (resource, 0, 999, false);
    rc = (rc || !(available == 4));
    available = resrc_available_during_range (resource, 10, 999, false);
    rc = (rc || !(available == 4));
    available = resrc_available_during_range (resource, 20, 1000, false);
    rc = (rc || !(available == 4));
    available = resrc_available_during_range (resource, 1001, 1999, false);
    rc = (rc || !(available == 9));
    available = resrc_available_during_range (resource, 1001, 1999, false);
    rc = (rc || !(available == 9));
    ok (!rc, "resrc_available_during_range: range is a subset (1 edge) works");
    rc = 0;

    // Range overlaps 1 job window
    //     (no edges are exactly equal)
    available = resrc_available_during_range (resource, 2500, 4000, false);
    rc = (rc || !(available == 0));
    //     (1 edge is exactly equal)
    available = resrc_available_during_range (resource, 3000, 5000, false);
    rc = (rc || !(available == 0));
    ok (!rc, "resrc_available_during_range: range overlaps 1 job works");
    rc = 0;

    // Range overlaps multiple job windows
    //     (no edges are exactly equal)
    available = resrc_available_during_range (resource, 100, 1500, false);
    rc = (rc || !(available == 4));
    available = resrc_available_during_range (resource, 1500, 2500, false);
    rc = (rc || !(available == 0));
    //     (some edges are exactly equal)
    available = resrc_available_during_range (resource, 1000, 2000, false);
    rc = (rc || !(available == 0));
    ok (!rc, "resrc_available_during_range: range overlaps multiple job works");
    rc = 0;

    // Range overlaps all job windows (edges exactly equal)
    available = resrc_available_during_range (resource, 0, 3000, false);
    rc = (rc || !(available == 0));
    available = resrc_available_during_range (resource, 0, 2000, false);
    rc = (rc || !(available == 0));
    // Range overlaps no job windows
    available = resrc_available_during_range (resource, 3001, 5000, false);
    rc = (rc || !(available == 10));
    ok (!rc, "resrc_available_during_range: range overlaps all job works");

    resrc_resource_destroy (resource);
}
Beispiel #4
0
/*
 * select_resources() selects from the set of resource candidates the
 * best resources for the job.
 *
 * Inputs:  found_tree      - tree of resource tree candidates
 *          resrc_reqst     - the resources the job requests
 *          selected_parent - parent of the selected resource tree
 * Returns: a resource tree of however many resources were selected
 */
resrc_tree_t *select_resources (flux_t *h, resrc_tree_t *found_tree,
                                resrc_reqst_t *resrc_reqst,
                                resrc_tree_t *selected_parent)
{
    resrc_t *resrc;
    resrc_tree_list_t *children = NULL;
    resrc_tree_t *child_tree;
    resrc_tree_t *selected_tree = NULL;

    if (!resrc_reqst) {
        flux_log (h, LOG_ERR, "%s: called with empty request", __FUNCTION__);
        return NULL;
    }

    /*
     * 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))
        return NULL;

    resrc = resrc_tree_resrc (found_tree);
    if (resrc_match_resource (resrc, resrc_reqst, true)) {
        if (resrc_reqst_num_children (resrc_reqst)) {
            if (resrc_tree_num_children (found_tree)) {
                selected_tree = resrc_tree_new (selected_parent, resrc);
                if (select_children (h, resrc_tree_children (found_tree),
                                     resrc_reqst_children (resrc_reqst),
                                     selected_tree)) {
                    resrc_stage_resrc (resrc,
                                       resrc_reqst_reqrd_size (resrc_reqst),
                                       resrc_reqst_graph_reqs (resrc_reqst));
                    resrc_reqst_add_found (resrc_reqst, 1);
                    flux_log (h, LOG_DEBUG, "selected %s", resrc_name (resrc));
                } else {
                    resrc_tree_destroy (selected_tree, false);
                }
            }
        } else {
            selected_tree = resrc_tree_new (selected_parent, resrc);
            resrc_stage_resrc (resrc, resrc_reqst_reqrd_size (resrc_reqst),
                               resrc_reqst_graph_reqs (resrc_reqst));
            resrc_reqst_add_found (resrc_reqst, 1);
            flux_log (h, LOG_DEBUG, "selected %s", resrc_name (resrc));
        }
    } else if (resrc_tree_num_children (found_tree)) {
        /*
         * This clause visits the children of the current resource
         * searching for a match to the resource request.  The selected
         * 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.
         */
        selected_tree = resrc_tree_new (selected_parent, resrc);
        children = resrc_tree_children (found_tree);
        child_tree = resrc_tree_list_first (children);
        while (child_tree) {
            if (select_resources (h, child_tree, resrc_reqst, selected_tree) &&
                resrc_reqst_nfound (resrc_reqst) >=
                resrc_reqst_reqrd_qty (resrc_reqst))
                break;
            child_tree = resrc_tree_list_next (children);
        }
    }

    return selected_tree;
}