diff --git a/hwloc/distrib.c b/hwloc/distrib.c index 9d81889f9b..311999bb4b 100644 --- a/hwloc/distrib.c +++ b/hwloc/distrib.c @@ -5,72 +5,87 @@ * See COPYING in top-level directory. ****************************************************************************/ +#include +#include #include "private/autogen/config.h" #include "hwloc.h" struct hwloc_distrib_level{ hwloc_obj_type_t type; // level type. unsigned depth; // level depth. - size_t user_index; // Index of this level as provided by user order. - size_t arity; // Number of children of this level below parent. - size_t coord; // The current level object index [0..arity[. + unsigned user_index; // Index of this level as provided by user order. + unsigned arity; // Number of children of this level below parent. + unsigned coord; // The current level object index [0..arity[. // Iteration order of this level objects. index[coord] give logical_index below parent. - size_t *index; + unsigned *index; }; struct hwloc_distrib_iterator{ hwloc_obj_t *roots; - size_t n_roots; - size_t root_coord; + unsigned n_roots; + unsigned root_coord; struct hwloc_distrib_level ** levels; // n_roots * n_levels - size_t n_levels; + unsigned n_levels; }; -static size_t* range(const size_t n){ - size_t* r = malloc(n*sizeof(*r)); +static unsigned* range(const unsigned n){ + unsigned i,*r = malloc(n*sizeof(*r)); - if(r==NULL) return NULL; - for(size_t i=0; i0;i--){ val = rand()%(i); ret[i-1] = index[val]; index[val] = index[i-1]; - } - free(index); - return ret; + } + free(index); + return ret; } static int hwloc_distrib_level_cmp_depth(const void *la, const void* lb){ const struct hwloc_distrib_level *a = (struct hwloc_distrib_level *)la; const struct hwloc_distrib_level *b = (struct hwloc_distrib_level *)lb; - if(a->depth > b->depth) { return 1; } - if(a->depth < b->depth) { return -1; } + if(a->depth > b->depth) + return 1; + if(a->depth < b->depth) + return -1; return 0; } static int hwloc_distrib_level_cmp_user_index(const void *la, const void* lb){ const struct hwloc_distrib_level *a = (struct hwloc_distrib_level *)la; const struct hwloc_distrib_level *b = (struct hwloc_distrib_level *)lb; - if(a->user_index > b->user_index) { return 1; } - if(a->user_index < b->user_index) { return -1; } + if(a->user_index > b->user_index) + return 1; + if(a->user_index < b->user_index) + return -1; return 0; } @@ -78,19 +93,23 @@ static struct hwloc_distrib_level * hwloc_distrib_root_levels(hwloc_topology_t topology, const hwloc_obj_t root, const hwloc_obj_type_t *types, - const size_t n_types, + const unsigned n_types, const unsigned long flags) { - struct hwloc_distrib_level *levels = malloc(n_types * sizeof(*levels)); + unsigned i; + unsigned arity; + hwloc_obj_t parent; + struct hwloc_distrib_level *levels; + + levels = malloc(n_types * sizeof(*levels)); if(levels == NULL) return NULL; - for (size_t i=0; icpuset, - levels[i].depth); + arity = hwloc_get_nbobjs_inside_cpuset_by_depth(topology, parent->cpuset, levels[i].depth); levels[i].arity = arity > levels[i].arity ? arity : levels[i].arity; - parent = hwloc_get_next_obj_inside_cpuset_by_depth(topology, - root->cpuset, - parent->depth, parent); + parent = hwloc_get_next_obj_inside_cpuset_by_depth(topology, root->cpuset, parent->depth, parent); } if (levels[i].arity == 0) { - fprintf(stderr, "No object of type %s below level %s.\n", - hwloc_obj_type_string(levels[i].type), - hwloc_obj_type_string(levels[i-1].type)); + fprintf(stderr, "No object of type %s below level %s.\n", hwloc_obj_type_string(levels[i].type), hwloc_obj_type_string(levels[i-1].type)); goto failure; } - parent = hwloc_get_obj_inside_cpuset_by_depth(topology, - root->cpuset, - levels[i].depth, - 0); + parent = hwloc_get_obj_inside_cpuset_by_depth(topology, root->cpuset, levels[i].depth, 0); } // Allocate levels index. - for (size_t i=0; ilevels) * n_roots); - if(it == NULL) return NULL; + unsigned i; + struct hwloc_distrib_iterator *it = malloc(sizeof(*it) + sizeof(*it->levels) * n_roots); + if(it == NULL) + return NULL; it->roots = roots; it->n_roots = n_roots; @@ -180,10 +186,11 @@ hwloc_distrib_build_iterator(hwloc_topology_t topology, it->n_levels = n_levels; it->levels = (struct hwloc_distrib_level **)((char*)it + sizeof(*it)); - for(size_t i=0; ilevels[i] = hwloc_distrib_root_levels(topology, roots[i], levels, n_levels, flags); if(it->levels[i] == NULL){ - while(i--){ hwloc_distrib_destroy_level(it->levels[i]); } + while(i--) + hwloc_distrib_destroy_level(it->levels[i]); goto failure; } } @@ -200,19 +207,18 @@ hwloc_distrib_iterator_round_robin(hwloc_topology_t topology, const hwloc_obj_type_t type, const unsigned long flags){ hwloc_obj_t root = hwloc_get_obj_by_depth(topology, 0, 0); - struct hwloc_distrib_iterator *it = malloc(sizeof(*it) + - sizeof(hwloc_obj_t) + - sizeof(struct hwloc_distrib_level*)); - if(it == NULL) return NULL; + struct hwloc_distrib_iterator *it; + + it = malloc(sizeof(*it) + sizeof(hwloc_obj_t) + sizeof(struct hwloc_distrib_level*)); + if(it == NULL) + return NULL; it->roots = (hwloc_obj_t*) ((char*)it + sizeof(*it)); *it->roots = root; it->n_roots = 1; it->root_coord = 0; it->n_levels = 1; - it->levels = (struct hwloc_distrib_level **)((char*)it + - sizeof(*it) + - sizeof(hwloc_obj_t)); + it->levels = (struct hwloc_distrib_level **)((char*)it + sizeof(*it) + sizeof(hwloc_obj_t)); *it->levels = hwloc_distrib_root_levels(topology, root, &type, 1, flags); if (*it->levels == NULL){ free(it); return NULL; } @@ -224,26 +230,26 @@ hwloc_distrib_iterator_scatter(hwloc_topology_t topology, const hwloc_obj_type_t type, const unsigned long flags){ - size_t i=0, n=0; + unsigned i=0, n=0; hwloc_obj_t obj, root = hwloc_get_obj_by_depth(topology, 0, 0); - obj = root; + hwloc_obj_type_t *levels; + struct hwloc_distrib_iterator *it; // Count depths with a non empty cpuset. + obj = root; while(obj){ - if ((obj->cpuset != NULL && !hwloc_bitmap_iszero(obj->cpuset)) && - hwloc_get_type_depth(topology, obj->type) >= 0) + if ((obj->cpuset != NULL && !hwloc_bitmap_iszero(obj->cpuset)) && hwloc_get_type_depth(topology, obj->type) >= 0) n++; if (obj->type == type) break; obj = obj->first_child; } - - obj = root; - hwloc_obj_type_t levels[n]; + // fill levels array. + levels = malloc(sizeof(*levels) * n); + obj = root; while(obj){ - if( obj->cpuset != NULL && !hwloc_bitmap_iszero(obj->cpuset) && - hwloc_get_type_depth(topology, obj->type) >= 0){ + if( obj->cpuset != NULL && !hwloc_bitmap_iszero(obj->cpuset) && hwloc_get_type_depth(topology, obj->type) >= 0){ levels[n-1-i] = obj->type; i++; } @@ -252,28 +258,37 @@ hwloc_distrib_iterator_scatter(hwloc_topology_t topology, obj = obj->first_child; } - struct hwloc_distrib_iterator *it = malloc(sizeof(*it) + - sizeof(hwloc_obj_t) + - sizeof(struct hwloc_distrib_level*)); - if(it == NULL) return NULL; + it = malloc(sizeof(*it) + sizeof(hwloc_obj_t) + sizeof(struct hwloc_distrib_level*)); + + if(it == NULL) + goto failure; it->roots = (hwloc_obj_t*) ((char*)it + sizeof(*it)); *it->roots = root; it->n_roots = 1; it->root_coord = 0; it->n_levels = n; - it->levels = (struct hwloc_distrib_level **)((char*)it + - sizeof(*it) + - sizeof(hwloc_obj_t)); + it->levels = (struct hwloc_distrib_level **)((char*)it + sizeof(*it) + sizeof(hwloc_obj_t)); *it->levels = hwloc_distrib_root_levels(topology, root, levels, n, flags); - if (*it->levels == NULL){ free(it); return NULL; } + if (*it->levels == NULL) + goto failure_with_it; + + free(levels); return it; + + failure_with_it: + free(it); + failure: + free(levels); + return NULL; } void hwloc_distrib_destroy_iterator(struct hwloc_distrib_iterator *it){ - for(size_t i=0; in_roots; i++) + unsigned i; + + for(i=0; in_roots; i++) hwloc_distrib_destroy_level(it->levels[i]); free(it); } @@ -288,10 +303,7 @@ hwloc_distrib_iterator_inc(struct hwloc_distrib_iterator *it){ do_root: // Sort by user_index to increment coordinates. levels = it->levels[it->root_coord]; - qsort(levels, - it->n_levels, - sizeof(*levels), - hwloc_distrib_level_cmp_user_index); + qsort(levels, it->n_levels, sizeof(*levels), hwloc_distrib_level_cmp_user_index); for (i=it->n_levels-1; i>=0; i--){ if(++levels[i].coord >= levels[i].arity) @@ -314,22 +326,17 @@ int hwloc_distrib_iterator_next(hwloc_topology_t topology, struct hwloc_distrib_iterator *it, hwloc_obj_t *next){ + unsigned i; struct hwloc_distrib_level *levels = it->levels[it->root_coord]; hwloc_obj_t obj = it->roots[it->root_coord]; - size_t coord; + unsigned coord; // Sort by depth to walk objects at set coordinates. - qsort(levels, - it->n_levels, - sizeof(*levels), - hwloc_distrib_level_cmp_depth); + qsort(levels, it->n_levels, sizeof(*levels), hwloc_distrib_level_cmp_depth); - for(size_t i=0; in_levels; i++){ + for(i=0; in_levels; i++){ coord = levels[i].index[levels[i].coord]; - obj = hwloc_get_obj_inside_cpuset_by_depth(topology, - obj->cpuset, - levels[i].depth, - coord); + obj = hwloc_get_obj_inside_cpuset_by_depth(topology, obj->cpuset, levels[i].depth, coord); if( obj == NULL) return hwloc_distrib_iterator_inc(it) && hwloc_distrib_iterator_next(topology, it, next); diff --git a/include/hwloc/helper.h b/include/hwloc/helper.h index 9e8b60b0c0..2fa24d728a 100644 --- a/include/hwloc/helper.h +++ b/include/hwloc/helper.h @@ -1217,9 +1217,9 @@ hwloc_distrib_iterator_scatter(hwloc_topology_t topology, HWLOC_DECLSPEC struct hwloc_distrib_iterator * hwloc_distrib_build_iterator(hwloc_topology_t topology, hwloc_obj_t *roots, - const size_t n_roots, + const unsigned n_roots, const hwloc_obj_type_t *levels, - const size_t n_levels, + const unsigned n_levels, const unsigned long flags); /** \brief Free memory allocated for \p it **/ diff --git a/utils/hwloc/hwloc-distrib.c b/utils/hwloc/hwloc-distrib.c index dcef3b3453..eb8144b436 100644 --- a/utils/hwloc/hwloc-distrib.c +++ b/utils/hwloc/hwloc-distrib.c @@ -72,6 +72,9 @@ static hwloc_obj_type_t parse_policy_type(const char* type){ // Parse string in arg_types after topology create, load, filter etc... static void parse_policy(void){ + size_t i; + char *type; + if (policy == ROUND_ROBIN){ num_types = 1; policy_types = malloc(sizeof(*policy_types)); @@ -83,9 +86,6 @@ static void parse_policy(void){ *policy_types = parse_policy_type(arg_types); } else { - size_t i; - char *type; - for(i=0; i 0 && next->logical_index != from_index ); + while ( hwloc_distrib_iterator_next(topology, it, &next) && from_index > 0 && next->logical_index != from_index ) {} - int continue_it = 1; do { if (logical_index) { printf("%d\n", next->logical_index); @@ -333,10 +329,9 @@ int main(int argc, char *argv[]) printf("%d\n", next->os_index); } else { hwloc_bitmap_copy(cpuset, next->cpuset); - char *str = NULL; if (singlify) { if (dflags & HWLOC_DISTRIB_FLAG_REVERSE) { - unsigned last = hwloc_bitmap_last(cpuset); + last = hwloc_bitmap_last(cpuset); hwloc_bitmap_only(cpuset, last); } else { hwloc_bitmap_singlify(cpuset); @@ -352,11 +347,10 @@ int main(int argc, char *argv[]) if ((! continue_it && n < 0) || --n == 0) break; continue_it = hwloc_distrib_iterator_next(topology, it, &next); - } while (1); - hwloc_bitmap_free(cpuset); - hwloc_distrib_destroy_iterator(it); - free(policy_types); - } + } while (1); + hwloc_bitmap_free(cpuset); + hwloc_distrib_destroy_iterator(it); + free(policy_types); hwloc_topology_destroy(topology);