1
1
This commit was SVN r5372.
Этот коммит содержится в:
Tim Woodall 2005-04-15 13:28:17 +00:00
родитель 2b25046781
Коммит f4454823ff

Просмотреть файл

@ -60,134 +60,50 @@ int orte_ras_base_allocate_nodes(orte_jobid_t jobid, ompi_list_t* nodes)
/* sort the node list by proc slots inuse - lowest to highest */
ompi_list_sort(nodes, (ompi_list_item_compare_fn_t)orte_ras_base_node_compare);
/* if a specified number of nodes was requested - attempt to locate
* the number requested - selecting unused nodes first - then anything
* that can be oversubscribed
*/
OBJ_CONSTRUCT(&allocated, ompi_list_t);
num_allocated = 0;
if(orte_ras_base.ras_num_nodes != 0) {
size_t num_per_node = num_requested / orte_ras_base.ras_num_nodes;
if(num_per_node == 0)
num_per_node = 1;
/* are enough nodes available to satisfy the request */
if(ompi_list_get_size(nodes) < orte_ras_base.ras_num_nodes) {
return ORTE_ERR_OUT_OF_RESOURCE;
}
/* allocate nodes to the job */
item = ompi_list_get_first(nodes);
while(item != ompi_list_get_last(nodes) &&
ompi_list_get_size(&allocated) < orte_ras_base.ras_num_nodes) {
/* iterate through nodes until request is satisfied or all are oversubscribed */
while(num_allocated < num_requested) {
num_constrained = 0;
for(item = ompi_list_get_first(nodes);
item != ompi_list_get_end(nodes) && num_allocated < num_requested;
item = ompi_list_get_next(item)) {
orte_ras_base_node_t* node = (orte_ras_base_node_t*)item;
ompi_list_item_t* next = ompi_list_get_next(item);
if (num_requested - num_allocated < num_per_node)
num_per_node = num_requested - num_allocated;
if (node->node_slots_max &&
node->node_slots_max > num_per_node + node->node_slots_inuse) {
size_t num_avail = node->node_slots_max - node->node_slots_inuse;
num_allocated += num_avail;
node->node_slots_inuse += num_avail;
node->node_slots_alloc += num_avail;
num_constrained++;
} else {
num_allocated += num_per_node;
node->node_slots_inuse += num_per_node;
node->node_slots_alloc += num_per_node;
/* are any slots available */
if (node->node_slots_inuse >= node->node_slots) {
/* if there is a constraint on the max number of slots - skip this node */
if(node->node_slots_max && node->node_slots_max >= node->node_slots_inuse) {
num_constrained++;
continue;
}
}
ompi_list_remove_item(nodes, item);
ompi_list_append(&allocated, item);
item = next;
}
goto validate;
}
/* the number of nodes was not specified - so try to allocate the
* most available nodes to the request before oversubscribing
*/
for(item = ompi_list_get_first(nodes);
item != ompi_list_get_end(nodes) && num_allocated < num_requested;
) {
orte_ras_base_node_t* node = (orte_ras_base_node_t*)item;
ompi_list_item_t* next = ompi_list_get_next(item);
/* are any slots available */
if (node->node_slots_inuse >= node->node_slots) {
/* if there is a constraint on the max number of slots - skip this node */
if(node->node_slots_max && node->node_slots_max >= node->node_slots_inuse) {
item = next;
continue;
num_constrained++;
}
/* otherwise only take one slot on this node */
/* otherwise take one slot on this node */
num_allocated++;
node->node_slots_inuse++; /* running total */
node->node_slots_alloc++; /* this job */
}
/* take available slots on this node */
else {
size_t num_to_alloc = node->node_slots - node->node_slots_inuse;
if(num_to_alloc + num_allocated > num_requested)
num_to_alloc = num_requested - num_allocated;
num_allocated += num_to_alloc;
node->node_slots_inuse += num_to_alloc;
node->node_slots_alloc += num_to_alloc;
}
ompi_list_remove_item(nodes, item);
ompi_list_append(&allocated, item);
item = next;
}
/* if the requested number of process slots hasn't been satisfied
* must oversubscribe each of the nodes (where allowed)
*/
validate:
if(num_allocated < num_requested) {
size_t num_nodes = ompi_list_get_size(&allocated) - num_constrained;
size_t num_needed = num_requested - num_allocated;
size_t num_per_node;
/* are there any nodes that can be oversubscribed? */
if(num_nodes == 0) {
if(num_constrained == ompi_list_get_size(nodes)) {
rc = ORTE_ERR_OUT_OF_RESOURCE;
goto cleanup;
}
num_per_node = num_needed / num_nodes;
if(num_per_node == 0)
num_per_node = 1;
/* oversubscribe each of the nodes that allow it */
for(item = ompi_list_get_first(&allocated);
item != ompi_list_get_end(&allocated);
item = ompi_list_get_next(item)) {
orte_ras_base_node_t* node = (orte_ras_base_node_t*)item;
if(node->node_slots_max && node->node_slots_inuse >= node->node_slots_max)
continue;
if(num_allocated + num_per_node > num_requested) {
num_per_node = num_requested - num_allocated;
}
num_allocated += num_per_node;
node->node_slots_inuse += num_per_node; /* running total */
node->node_slots_alloc += num_per_node; /* this job */
}
}
/* If we still didn't get enough, it's an error */
if (num_allocated < num_requested) {
rc = ORTE_ERR_OUT_OF_RESOURCE;
goto cleanup;
/* move all nodes w/ allocations to the allocated list */
item = ompi_list_get_first(nodes);
while(item != ompi_list_get_end(nodes)) {
orte_ras_base_node_t* node = (orte_ras_base_node_t*)item;
ompi_list_item_t* next = ompi_list_get_next(item);
if(node->node_slots_alloc) {
ompi_list_remove_item(nodes, item);
ompi_list_append(&allocated, item);
}
item = next;
}
rc = orte_ras_base_node_assign(&allocated, jobid);
cleanup: