Пример #1
0
	inline bool isCacheObject(hwloc_obj_t obj)
	{
#if HWLOC_API_VERSION >= 0x20000
		return hwloc_obj_type_is_cache(obj->type);
#else
		return obj->type == HWLOC_OBJ_CACHE;
#endif // HWLOC_API_VERSION
	}
Пример #2
0
static void print_task(hwloc_topology_t topology,
                       long pid_number, const char *name, hwloc_bitmap_t cpuset,
                       char *pidoutput,
                       int thread)
{
    printf("%s%ld\t", thread ? " " : "", pid_number);

    if (show_cpuset) {
        char *cpuset_str = NULL;
        hwloc_bitmap_asprintf(&cpuset_str, cpuset);
        printf("%s", cpuset_str);
        free(cpuset_str);
    } else {
        hwloc_bitmap_t remaining = hwloc_bitmap_dup(cpuset);
        int first = 1;
        while (!hwloc_bitmap_iszero(remaining)) {
            char type[64];
            unsigned idx;
            hwloc_obj_t obj = hwloc_get_first_largest_obj_inside_cpuset(topology, remaining);
            /* don't show a cache if there's something equivalent and nicer */
            while (hwloc_obj_type_is_cache(obj->type) && obj->arity == 1)
                obj = obj->first_child;
            hwloc_obj_type_snprintf(type, sizeof(type), obj, 1);
            idx = logical ? obj->logical_index : obj->os_index;
            if (idx == (unsigned) -1)
                printf("%s%s", first ? "" : " ", type);
            else
                printf("%s%s:%u", first ? "" : " ", type, idx);
            hwloc_bitmap_andnot(remaining, remaining, obj->cpuset);
            first = 0;
        }
        hwloc_bitmap_free(remaining);
    }

    printf("\t\t%s%s%s\n", name, pidoutput ? "\t" : "", pidoutput ? pidoutput : "");
}
Пример #3
0
int
hwloc_type_sscanf(const char *string, hwloc_obj_type_t *typep,
		  union hwloc_obj_attr_u *attrp, size_t attrsize)
{
  hwloc_obj_type_t type = (hwloc_obj_type_t) -1;
  unsigned depthattr = (unsigned) -1;
  hwloc_obj_cache_type_t cachetypeattr = (hwloc_obj_cache_type_t) -1; /* unspecified */
  hwloc_obj_bridge_type_t ubtype = (hwloc_obj_bridge_type_t) -1;
  hwloc_obj_osdev_type_t ostype = (hwloc_obj_osdev_type_t) -1;
  char *end;

  /* never match the ending \0 since we want to match things like core:2 too.
   * just use hwloc_strncasecmp() everywhere.
   */

  /* types without a custom depth */
  if (!hwloc_strncasecmp(string, "system", 2)) {
    type = HWLOC_OBJ_SYSTEM;
  } else if (!hwloc_strncasecmp(string, "machine", 2)) {
    type = HWLOC_OBJ_MACHINE;
  } else if (!hwloc_strncasecmp(string, "node", 2)
	     || !hwloc_strncasecmp(string, "numa", 2)) { /* matches node and numanode */
    type = HWLOC_OBJ_NUMANODE;
  } else if (!hwloc_strncasecmp(string, "package", 2)
	     || !hwloc_strncasecmp(string, "socket", 2)) { /* backward compat with v1.10 */
    type = HWLOC_OBJ_PACKAGE;
  } else if (!hwloc_strncasecmp(string, "core", 2)) {
    type = HWLOC_OBJ_CORE;
  } else if (!hwloc_strncasecmp(string, "pu", 2)) {
    type = HWLOC_OBJ_PU;
  } else if (!hwloc_strncasecmp(string, "misc", 4)) {
    type = HWLOC_OBJ_MISC;

  } else if (!hwloc_strncasecmp(string, "bridge", 4)) {
    type = HWLOC_OBJ_BRIDGE;
  } else if (!hwloc_strncasecmp(string, "hostbridge", 6)) {
    type = HWLOC_OBJ_BRIDGE;
    ubtype = HWLOC_OBJ_BRIDGE_HOST;
  } else if (!hwloc_strncasecmp(string, "pcibridge", 5)) {
    type = HWLOC_OBJ_BRIDGE;
    ubtype = HWLOC_OBJ_BRIDGE_PCI;

  } else if (!hwloc_strncasecmp(string, "pci", 3)) {
    type = HWLOC_OBJ_PCI_DEVICE;

  } else if (!hwloc_strncasecmp(string, "os", 2)) {
    type = HWLOC_OBJ_OS_DEVICE;
  } else if (!hwloc_strncasecmp(string, "bloc", 4)) {
    type = HWLOC_OBJ_OS_DEVICE;
    ostype = HWLOC_OBJ_OSDEV_BLOCK;
  } else if (!hwloc_strncasecmp(string, "net", 3)) {
    type = HWLOC_OBJ_OS_DEVICE;
    ostype = HWLOC_OBJ_OSDEV_NETWORK;
  } else if (!hwloc_strncasecmp(string, "openfab", 7)) {
    type = HWLOC_OBJ_OS_DEVICE;
    ostype = HWLOC_OBJ_OSDEV_OPENFABRICS;
  } else if (!hwloc_strncasecmp(string, "dma", 3)) {
    type = HWLOC_OBJ_OS_DEVICE;
    ostype = HWLOC_OBJ_OSDEV_DMA;
  } else if (!hwloc_strncasecmp(string, "gpu", 3)) {
    type = HWLOC_OBJ_OS_DEVICE;
    ostype = HWLOC_OBJ_OSDEV_GPU;
  } else if (!hwloc_strncasecmp(string, "copro", 5)
	     || !hwloc_strncasecmp(string, "co-pro", 6)) {
    type = HWLOC_OBJ_OS_DEVICE;
    ostype = HWLOC_OBJ_OSDEV_COPROC;

  /* types with depthattr */
  } else if ((string[0] == 'l' || string[0] == 'L') && string[1] >= '0' && string[1] <= '9') {
    depthattr = strtol(string+1, &end, 10);
    if (*end == 'i') {
      if (depthattr >= 1 && depthattr <= 3) {
	type = HWLOC_OBJ_L1ICACHE + depthattr-1;
	cachetypeattr = HWLOC_OBJ_CACHE_INSTRUCTION;
      } else
	return -1;
    } else {
      if (depthattr >= 1 && depthattr <= 5) {
	type = HWLOC_OBJ_L1CACHE + depthattr-1;
	cachetypeattr = *end == 'd' ? HWLOC_OBJ_CACHE_DATA : HWLOC_OBJ_CACHE_UNIFIED;
      } else
	return -1;
    }

  } else if (!hwloc_strncasecmp(string, "group", 2)) {
    size_t length;
    type = HWLOC_OBJ_GROUP;
    length = strcspn(string, "0123456789");
    if (length <= 5 && !hwloc_strncasecmp(string, "group", length)
	&& string[length] >= '0' && string[length] <= '9') {
      depthattr = strtol(string+length, &end, 10);
    }

  } else
    return -1;

  *typep = type;
  if (attrp) {
    if (hwloc_obj_type_is_cache(type) && attrsize >= sizeof(attrp->cache)) {
      attrp->cache.depth = depthattr;
      attrp->cache.type = cachetypeattr;
    } else if (type == HWLOC_OBJ_GROUP && attrsize >= sizeof(attrp->group)) {
      attrp->group.depth = depthattr;
    } else if (type == HWLOC_OBJ_BRIDGE && attrsize >= sizeof(attrp->bridge)) {
      attrp->bridge.upstream_type = ubtype;
      attrp->bridge.downstream_type = HWLOC_OBJ_BRIDGE_PCI; /* nothing else so far */
    } else if (type == HWLOC_OBJ_OS_DEVICE && attrsize >= sizeof(attrp->osdev)) {
      attrp->osdev.type = ostype;
    }
  }
  return 0;
}
Пример #4
0
int main(void)
{
    int depth;
    unsigned i, n;
    unsigned long size;
    int levels;
    char string[128];
    int topodepth;
    void *m;
    hwloc_topology_t topology;
    hwloc_cpuset_t cpuset;
    hwloc_obj_t obj;

    /* Allocate and initialize topology object. */
    hwloc_topology_init(&topology);

    /* ... Optionally, put detection configuration here to ignore
       some objects types, define a synthetic topology, etc....

       The default is to detect all the objects of the machine that
       the caller is allowed to access.  See Configure Topology
       Detection. */

    /* Perform the topology detection. */
    hwloc_topology_load(topology);

    /* Optionally, get some additional topology information
       in case we need the topology depth later. */
    topodepth = hwloc_topology_get_depth(topology);

    /*****************************************************************
     * First example:
     * Walk the topology with an array style, from level 0 (always
     * the system level) to the lowest level (always the proc level).
     *****************************************************************/
    for (depth = 0; depth < topodepth; depth++) {
        printf("*** Objects at level %d\n", depth);
        for (i = 0; i < hwloc_get_nbobjs_by_depth(topology, depth);
             i++) {
            hwloc_obj_type_snprintf(string, sizeof(string),
				    hwloc_get_obj_by_depth(topology, depth, i), 0);
            printf("Index %u: %s\n", i, string);
        }
    }

    /*****************************************************************
     * Second example:
     * Walk the topology with a tree style.
     *****************************************************************/
    printf("*** Printing overall tree\n");
    print_children(topology, hwloc_get_root_obj(topology), 0);

    /*****************************************************************
     * Third example:
     * Print the number of packages.
     *****************************************************************/
    depth = hwloc_get_type_depth(topology, HWLOC_OBJ_PACKAGE);
    if (depth == HWLOC_TYPE_DEPTH_UNKNOWN) {
        printf("*** The number of packages is unknown\n");
    } else {
        printf("*** %u package(s)\n",
               hwloc_get_nbobjs_by_depth(topology, depth));
    }

    /*****************************************************************
     * Fourth example:
     * Compute the amount of cache that the first logical processor
     * has above it.
     *****************************************************************/
    levels = 0;
    size = 0;
    for (obj = hwloc_get_obj_by_type(topology, HWLOC_OBJ_PU, 0);
         obj;
         obj = obj->parent)
      if (hwloc_obj_type_is_cache(obj->type)) {
        levels++;
        size += obj->attr->cache.size;
      }
    printf("*** Logical processor 0 has %d caches totaling %luKB\n",
           levels, size / 1024);

    /*****************************************************************
     * Fifth example:
     * Bind to only one thread of the last core of the machine.
     *
     * First find out where cores are, or else smaller sets of CPUs if
     * the OS doesn't have the notion of a "core".
     *****************************************************************/
    depth = hwloc_get_type_or_below_depth(topology, HWLOC_OBJ_CORE);

    /* Get last core. */
    obj = hwloc_get_obj_by_depth(topology, depth,
                   hwloc_get_nbobjs_by_depth(topology, depth) - 1);
    if (obj) {
        /* Get a copy of its cpuset that we may modify. */
        cpuset = hwloc_bitmap_dup(obj->cpuset);

        /* Get only one logical processor (in case the core is
           SMT/hyper-threaded). */
        hwloc_bitmap_singlify(cpuset);

        /* And try to bind ourself there. */
        if (hwloc_set_cpubind(topology, cpuset, 0)) {
            char *str;
            int error = errno;
            hwloc_bitmap_asprintf(&str, obj->cpuset);
            printf("Couldn't bind to cpuset %s: %s\n", str, strerror(error));
            free(str);
        }

        /* Free our cpuset copy */
        hwloc_bitmap_free(cpuset);
    }

    /*****************************************************************
     * Sixth example:
     * Allocate some memory on the last NUMA node, bind some existing
     * memory to the last NUMA node.
     *****************************************************************/
    /* Get last node. There's always at least one. */
    n = hwloc_get_nbobjs_by_type(topology, HWLOC_OBJ_NUMANODE);
    obj = hwloc_get_obj_by_type(topology, HWLOC_OBJ_NUMANODE, n - 1);

    size = 1024*1024;
    m = hwloc_alloc_membind_nodeset(topology, size, obj->nodeset,
                                    HWLOC_MEMBIND_BIND, 0);
    hwloc_free(topology, m, size);

    m = malloc(size);
    hwloc_set_area_membind_nodeset(topology, m, size, obj->nodeset,
                                   HWLOC_MEMBIND_BIND, 0);
    free(m);

    /* Destroy topology object. */
    hwloc_topology_destroy(topology);

    return 0;
}
Пример #5
0
/* Recurse into children to get their size.
 * Place them.
 * Save their position and the parent total size for later.
 */
static void
place_children(struct lstopo_output *loutput, hwloc_obj_t parent,
	       unsigned xrel, unsigned yrel /* position of children within parent */)
{
  struct lstopo_obj_userdata *plud = parent->userdata;
  enum lstopo_orient_e orient = loutput->force_orient[parent->type];
  unsigned border = loutput->gridsize;
  unsigned separator = loutput->gridsize;
  unsigned totwidth = plud->width, totheight = plud->height;
  unsigned children_width = 0, children_height = 0;
  unsigned above_children_width, above_children_height;
  hwloc_obj_t child;
  int ncstate;
  unsigned i;

  /* defaults */
  plud->children.box = 0;
  plud->above_children.box = 0;

  /* select which children kinds go where */
  if (loutput->plain_children_order)
    plud->children.kinds = LSTOPO_CHILD_KIND_ALL;
  else
    plud->children.kinds = LSTOPO_CHILD_KIND_ALL & ~LSTOPO_CHILD_KIND_MEMORY;
  if (parent->memory_arity && !(plud->children.kinds & LSTOPO_CHILD_KIND_MEMORY))
    plud->above_children.kinds = LSTOPO_CHILD_KIND_MEMORY;
  else
    plud->above_children.kinds = 0;

  /* bridge children always vertical */
  if (parent->type == HWLOC_OBJ_BRIDGE)
    orient = LSTOPO_ORIENT_VERT;

  /* recurse into children to prepare their sizes */
  for(i = 0, child = next_child(loutput, parent, LSTOPO_CHILD_KIND_ALL, NULL, &ncstate);
      child;
      i++, child = next_child(loutput, parent, LSTOPO_CHILD_KIND_ALL, child, &ncstate)) {
    get_type_fun(child->type)(loutput, child, 0, 0, 0);
  }
  if (!i)
    return;


  /* no separator between core or L1 children */
  if (parent->type == HWLOC_OBJ_CORE
      || (hwloc_obj_type_is_cache(parent->type) && parent->attr->cache.depth == 1))
    separator = 0;

  /* place non-memory children */
  if (parent->arity + parent->io_arity + parent->misc_arity)
    place__children(loutput, parent, plud->children.kinds, &orient, 0, separator, &children_width, &children_height);

  /* place memory children */
  if (plud->above_children.kinds) {
    enum lstopo_orient_e morient = LSTOPO_ORIENT_HORIZ;
    unsigned memory_border;

    assert(plud->above_children.kinds == LSTOPO_CHILD_KIND_MEMORY);
    memory_border = parent->memory_arity > 1 ? border : 0;

    place__children(loutput, parent, plud->above_children.kinds, &morient, memory_border, separator, &above_children_width, &above_children_height);

    if (parent->memory_arity > 1) {
      /* if there are multiple memory children, add a box, as large as the parent */
      if (above_children_width < children_width) {
	above_children_width = children_width;
      }
      plud->above_children.boxcolor = MEMORIES_COLOR;
      plud->above_children.box = 1;

    } else {
      /* if there's a single memory child without wide memory box, enlarge that child */
      struct lstopo_obj_userdata *clud = parent->memory_first_child->userdata;
      if (clud->width < children_width) {
	clud->width = children_width;
	above_children_width = children_width;
      }
    }
  }

  /* adjust parent size */
  if (hwloc_obj_type_is_cache(parent->type)) {
    /* cache children are below */
    if (children_width > totwidth)
      totwidth = children_width;
    if (children_height)
      totheight += children_height + border;
    if (plud->above_children.kinds) {
      totheight += above_children_height + separator;
      if (above_children_width > totwidth)
	totwidth = above_children_width;
    }
  } else if (parent->type == HWLOC_OBJ_BRIDGE) {
    /* bridge children are on the right, within any space between bridge and children */
    if (children_width)
      totwidth += children_width;
    if (children_height > totheight)
      totheight = children_height;
  } else {
    /* normal objects have children inside their box, with space around them */
    if (children_width + 2*border > totwidth)
      totwidth = children_width + 2*border;
    if (children_height)
      totheight += children_height + border;
    if (plud->above_children.kinds) {
      totheight += above_children_height + separator;
      if (above_children_width + 2*border > totwidth)
	totwidth = above_children_width + 2*border;
    }
  }

  /* save config for draw_children() later */
  plud->orient = orient;
  plud->width = totwidth;
  plud->height = totheight;
  plud->children.width = children_width;
  plud->children.height = children_height;
  plud->children.xrel = xrel;
  plud->children.yrel = yrel;
  if (plud->above_children.kinds) {
    plud->above_children.width = above_children_width;
    plud->above_children.height = above_children_height;
    plud->above_children.xrel = xrel;
    plud->above_children.yrel = yrel;
    plud->children.yrel += above_children_height + separator;
  }
}