int main(void) { hwloc_topology_t topology; struct hwloc_distances_s *distances[2]; hwloc_obj_t objs[16]; uint64_t values[16*16]; unsigned depth, topodepth; unsigned i, j, k, nr; int err; hwloc_topology_init(&topology); hwloc_topology_set_synthetic(topology, "node:4 core:4 pu:1"); hwloc_topology_load(topology); nr = 0; err = hwloc_distances_get(topology, &nr, distances, 0, 0); assert(!err); assert(!nr); if (!nr) printf("No distance\n"); printf("\nInserting NUMA distances\n"); for(i=0; i<4; i++) objs[i] = hwloc_get_obj_by_type(topology, HWLOC_OBJ_NUMANODE, i); /* matrix 2*2 */ for(i=0; i<16; i++) values[i] = 8; values[0+4*1] = 4; values[1+4*0] = 4; values[2+4*3] = 4; values[3+4*2] = 4; for(i=0; i<4; i++) values[i+4*i] = 1; err = hwloc_distances_add(topology, 4, objs, values, HWLOC_DISTANCES_KIND_MEANS_LATENCY|HWLOC_DISTANCES_KIND_FROM_USER, HWLOC_DISTANCES_FLAG_GROUP); assert(!err); topodepth = hwloc_topology_get_depth(topology); for(depth=0; depth<topodepth; depth++) { nr = 0; err = hwloc_distances_get_by_depth(topology, depth, &nr, distances, 0, 0); assert(!err); if (depth == 2) assert(nr == 1); else assert(!nr); if (!nr) { printf("No distance at depth %u\n", depth); continue; } nr = 1; err = hwloc_distances_get_by_depth(topology, depth, &nr, distances, 0, 0); assert(!err); printf("distance matrix for depth %u:\n", depth); print_distances(distances[0]); hwloc_distances_release(topology, distances[0]); } /* check numa distances */ printf("Checking NUMA distances\n"); nr = 1; err = hwloc_distances_get_by_type(topology, HWLOC_OBJ_NUMANODE, &nr, distances, 0, 0); assert(!err); assert(nr == 1); assert(distances[0]); assert(distances[0]->objs); assert(distances[0]->values); assert(distances[0]->kind == (HWLOC_DISTANCES_KIND_MEANS_LATENCY|HWLOC_DISTANCES_KIND_FROM_USER)); /* check that some random values are ok */ assert(distances[0]->values[0] == 1); /* diagonal */ assert(distances[0]->values[4] == 4); /* same group */ assert(distances[0]->values[6] == 8); /* different group */ assert(distances[0]->values[9] == 8); /* different group */ assert(distances[0]->values[10] == 1); /* diagonal */ assert(distances[0]->values[14] == 4); /* same group */ hwloc_distances_release(topology, distances[0]); printf("\nInserting PU distances\n"); /* matrix 4*2*2 */ for(i=0; i<16; i++) objs[i] = hwloc_get_obj_by_type(topology, HWLOC_OBJ_PU, i); for(i=0; i<256; i++) values[i] = 8; for(i=0; i<4; i++) { for(j=0; j<4; j++) for(k=0; k<4; k++) values[i*64+i*4+16*j+k] = 4; values[i*64+i*4+1] = 2; values[i*64+i*4+16] = 2; values[i*64+i*4+2*16+3] = 2; values[i*64+i*4+3*16+2] = 2; } for(i=0; i<16; i++) values[i+16*i] = 1; err = hwloc_distances_add(topology, 16, objs, values, HWLOC_DISTANCES_KIND_MEANS_LATENCY|HWLOC_DISTANCES_KIND_FROM_USER, HWLOC_DISTANCES_FLAG_GROUP); assert(!err); topodepth = hwloc_topology_get_depth(topology); for(depth=0; depth<topodepth; depth++) { nr = 0; err = hwloc_distances_get_by_depth(topology, depth, &nr, distances, 0, 0); assert(!err); if (depth == 2 || depth == 5) assert(nr == 1); else assert(!nr); if (!nr) { printf("No distance at depth %u\n", depth); continue; } nr = 1; err = hwloc_distances_get_by_depth(topology, depth, &nr, distances, 0, 0); assert(!err); printf("distance matrix for depth %u:\n", depth); print_distances(distances[0]); hwloc_distances_release(topology, distances[0]); } /* check PU distances */ printf("Checking PU distances\n"); nr = 1; err = hwloc_distances_get_by_type(topology, HWLOC_OBJ_PU, &nr, distances, 0, 0); assert(!err); assert(nr == 1); assert(distances[0]); assert(distances[0]->values); assert(distances[0]->kind == (HWLOC_DISTANCES_KIND_MEANS_LATENCY|HWLOC_DISTANCES_KIND_FROM_USER)); /* check that some random values are ok */ assert(distances[0]->values[0] == 1); /* diagonal */ assert(distances[0]->values[1] == 2); /* same group */ assert(distances[0]->values[3] == 4); /* same biggroup */ assert(distances[0]->values[15] == 8); /* different biggroup */ assert(distances[0]->values[250] == 8); /* different biggroup */ assert(distances[0]->values[253] == 4); /* same group */ assert(distances[0]->values[254] == 2); /* same biggroup */ assert(distances[0]->values[255] == 1); /* diagonal */ hwloc_distances_release(topology, distances[0]); printf("\nInserting 2nd PU distances\n"); /* matrix 4*1 */ for(i=0; i<4; i++) objs[i] = hwloc_get_obj_by_type(topology, HWLOC_OBJ_PU, i); for(i=0; i<16; i++) values[i] = 3; for(i=0; i<4; i++) values[i+4*i] = 7; err = hwloc_distances_add(topology, 4, objs, values, HWLOC_DISTANCES_KIND_MEANS_BANDWIDTH|HWLOC_DISTANCES_KIND_FROM_USER, HWLOC_DISTANCES_FLAG_GROUP); assert(!err); topodepth = hwloc_topology_get_depth(topology); for(depth=0; depth<topodepth; depth++) { nr = 0; err = hwloc_distances_get_by_depth(topology, depth, &nr, distances, 0, 0); assert(!err); if (depth == 2) assert(nr == 1); else if (depth == 5) assert(nr == 2); else assert(!nr); if (!nr) { printf("No distance at depth %u\n", depth); continue; } nr = 2; err = hwloc_distances_get_by_depth(topology, depth, &nr, distances, 0, 0); assert(!err); printf("distance matrix for depth %u:\n", depth); print_distances(distances[0]); hwloc_distances_release(topology, distances[0]); if (nr > 1) { print_distances(distances[1]); hwloc_distances_release(topology, distances[1]); } } /* check PU distances */ printf("Checking 2nd PU distances\n"); nr = 2; err = hwloc_distances_get_by_type(topology, HWLOC_OBJ_PU, &nr, distances, 0, 0); assert(!err); assert(nr == 2); assert(distances[1]); assert(distances[1]->values); assert(distances[1]->kind == (HWLOC_DISTANCES_KIND_MEANS_BANDWIDTH|HWLOC_DISTANCES_KIND_FROM_USER)); /* check that some random values are ok */ assert(distances[1]->values[0] == 7); /* diagonal */ assert(distances[1]->values[1] == 3); /* other */ assert(distances[1]->values[3] == 3); /* other */ assert(distances[1]->values[15] == 7); /* diagonal */ hwloc_distances_release(topology, distances[0]); hwloc_distances_release(topology, distances[1]); /* check distances by kind */ nr = 2; err = hwloc_distances_get(topology, &nr, distances, HWLOC_DISTANCES_KIND_MEANS_BANDWIDTH, 0); assert(!err); assert(nr == 1); hwloc_distances_release(topology, distances[0]); nr = 2; err = hwloc_distances_get(topology, &nr, distances, HWLOC_DISTANCES_KIND_MEANS_LATENCY|HWLOC_DISTANCES_KIND_FROM_OS, 0); assert(!err); assert(nr == 0); nr = 2; err = hwloc_distances_get(topology, &nr, distances, HWLOC_DISTANCES_KIND_MEANS_LATENCY|HWLOC_DISTANCES_KIND_FROM_USER, 0); assert(!err); assert(nr == 2); hwloc_distances_release(topology, distances[0]); hwloc_distances_release(topology, distances[1]); /* remove distances */ printf("Removing distances\n"); /* remove both PU distances */ err = hwloc_distances_remove_by_type(topology, HWLOC_OBJ_PU); assert(!err); nr = 0; err = hwloc_distances_get_by_type(topology, HWLOC_OBJ_PU, &nr, distances, 0, 0); assert(!err); assert(!nr); nr = 0; err = hwloc_distances_get_by_type(topology, HWLOC_OBJ_NUMANODE, &nr, distances, 0, 0); assert(!err); assert(nr == 1); /* remove all distances */ err = hwloc_distances_remove(topology); assert(!err); nr = 0; err = hwloc_distances_get(topology, &nr, distances, 0, 0); assert(!err); assert(!nr); nr = 0; err = hwloc_distances_get_by_type(topology, HWLOC_OBJ_PU, &nr, distances, 0, 0); assert(!err); assert(!nr); nr = 0; err = hwloc_distances_get_by_type(topology, HWLOC_OBJ_NUMANODE, &nr, distances, 0, 0); assert(!err); assert(!nr); hwloc_topology_destroy(topology); return 0; }
int main(int argc, char *argv[]) { static hwloc_topology_t orig; hwloc_obj_t nodes[3]; uint64_t node_distances[9]; unsigned i,j; int err, ret, ret2; if (argc > 1) { int fd; unsigned long forced_addr; unsigned long fileoffset; size_t shmem_length; int synthetic_with_distances; if (argc < 6) { printf("needs 5 arguments\n"); return EXIT_FAILURE; } printf(" opening %s\n", argv[1]); fd = open(argv[1], O_RDONLY); if (fd < 0) { perror("open"); return EXIT_FAILURE; } fileoffset = strtoul(argv[2], NULL, 0); forced_addr = strtoul(argv[3], NULL, 0); shmem_length = strtoul(argv[4], NULL, 0); synthetic_with_distances = atoi(argv[5]); ret = adopt(fd, fileoffset, forced_addr, shmem_length, synthetic_with_distances); close(fd); exit(ret); } printf("########################\n"); printf("creating native topology\n"); err = hwloc_topology_init(&orig); assert(!err); err = hwloc_topology_set_all_types_filter(orig, HWLOC_TYPE_FILTER_KEEP_ALL); assert(!err); err = hwloc_topology_load(orig); assert(!err); ret = test(orig, argv[0]); printf("destroying original\n"); hwloc_topology_destroy(orig); printf("###############################################\n"); printf("creating synthetic topo with distances topology\n"); err = hwloc_topology_init(&orig); assert(!err); err = hwloc_topology_set_synthetic(orig, "node:3 core:2 pu:4"); assert(!err); err = hwloc_topology_load(orig); assert(!err); printf("adding distance matrix\n"); for(i=0; i<3; i++) { nodes[i] = hwloc_get_obj_by_type(orig, HWLOC_OBJ_NUMANODE, i); for(j=0; j<3; j++) node_distances[i*3+j] = (i == j ? 10 : 20); } err = hwloc_distances_add(orig, 3, nodes, node_distances, HWLOC_DISTANCES_KIND_MEANS_LATENCY|HWLOC_DISTANCES_KIND_FROM_USER, HWLOC_DISTANCES_ADD_FLAG_GROUP); assert(!err); ret2 = test(orig, argv[0]); printf("destroying original\n"); hwloc_topology_destroy(orig); /* we caught errors above. * return SKIP if both returned SKIP. otherwise SUCCESS */ if (ret == EXIT_SKIP && ret2 == EXIT_SKIP) ret = EXIT_SKIP; else ret = EXIT_SUCCESS; return ret; }
int main(void) { static hwloc_topology_t oldtopology, topology; hwloc_bitmap_t cpuset = hwloc_bitmap_alloc(); struct hwloc_distances_s *distances; hwloc_obj_t nodes[3], cores[6]; uint64_t node_distances[9], core_distances[36]; unsigned i,j,nr; int err; hwloc_topology_init(&oldtopology); hwloc_topology_set_synthetic(oldtopology, "node:3 core:2 pu:4"); hwloc_topology_load(oldtopology); for(i=0; i<3; i++) { nodes[i] = hwloc_get_obj_by_type(oldtopology, HWLOC_OBJ_NUMANODE, i); for(j=0; j<3; j++) node_distances[i*3+j] = (i == j ? 10 : 20); } err = hwloc_distances_add(oldtopology, 3, nodes, node_distances, HWLOC_DISTANCES_KIND_MEANS_LATENCY|HWLOC_DISTANCES_KIND_FROM_USER, HWLOC_DISTANCES_FLAG_GROUP); assert(!err); for(i=0; i<6; i++) { cores[i] = hwloc_get_obj_by_type(oldtopology, HWLOC_OBJ_CORE, i); for(j=0; j<6; j++) core_distances[i*6+j] = (i == j ? 4 : 8); } err = hwloc_distances_add(oldtopology, 6, cores, core_distances, HWLOC_DISTANCES_KIND_MEANS_LATENCY|HWLOC_DISTANCES_KIND_FROM_USER, HWLOC_DISTANCES_FLAG_GROUP); assert(!err); printf("duplicating\n"); err = hwloc_topology_dup(&topology, oldtopology); assert(!err); printf("destroying the old topology\n"); hwloc_topology_destroy(oldtopology); /* remove the entire third node */ printf("removing one node\n"); hwloc_bitmap_fill(cpuset); hwloc_bitmap_clr_range(cpuset, 16, 23); err = hwloc_topology_restrict(topology, cpuset, HWLOC_RESTRICT_FLAG_REMOVE_CPULESS); assert(!err); printf("checking the result\n"); assert(hwloc_get_nbobjs_by_type(topology, HWLOC_OBJ_NUMANODE) == 2); nr = 1; err = hwloc_distances_get_by_type(topology, HWLOC_OBJ_NUMANODE, &nr, &distances, 0, 0); assert(!err); assert(nr == 1); assert(distances->nbobjs == 2); assert(distances->kind == (HWLOC_DISTANCES_KIND_MEANS_LATENCY|HWLOC_DISTANCES_KIND_FROM_USER)); hwloc_distances_release(topology, distances); nr = 1; err = hwloc_distances_get_by_type(topology, HWLOC_OBJ_CORE, &nr, &distances, 0, 0); assert(!err); assert(nr == 1); assert(distances->nbobjs == 4); assert(distances->kind == (HWLOC_DISTANCES_KIND_MEANS_LATENCY|HWLOC_DISTANCES_KIND_FROM_USER)); hwloc_distances_release(topology, distances); hwloc_topology_destroy(topology); hwloc_bitmap_free(cpuset); return 0; }