static int hwloc_aix_prepare_membind(hwloc_topology_t topology, rsethandle_t *rad, hwloc_const_nodeset_t nodeset, int flags __hwloc_attribute_unused) { rsethandle_t rset, noderad; int MCMlevel; int node; MCMlevel = rs_getinfo(NULL, R_MCMSDL, 0); if ((topology->flags & HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM)) rset = rs_alloc(RS_ALL); else rset = rs_alloc(RS_PARTITION); *rad = rs_alloc(RS_EMPTY); noderad = rs_alloc(RS_EMPTY); hwloc_bitmap_foreach_begin(node, nodeset) rs_getrad(rset, noderad, MCMlevel, node, 0); rs_op(RS_UNION, noderad, *rad, 0, 0); hwloc_bitmap_foreach_end(); rs_free(rset); rs_free(noderad); return 0; }
/****** shepherd_binding/create_binding_env() **************************** * NAME * create_binding_env() -- Creates SGE_BINDING env variable. * * SYNOPSIS * bool create_binding_env(hwloc_const_bitmap_t set) * * FUNCTION * Creates the SGE_BINDING environment variable. * This environment variable contains a space-separated list of * internal processor ids given as input parameter. * * INPUTS * hwloc_const_bitmap_t set - CPU set to use * * RESULT * bool - true when SGE_BINDING env var could be generated false if not * * NOTES * MT-NOTE: create_binding_env() is MT safe * *******************************************************************************/ static bool create_binding_env(hwloc_const_bitmap_t set) { bool retval = true; dstring sge_binding = DSTRING_INIT; dstring proc = DSTRING_INIT; unsigned i; bool first = true; hwloc_bitmap_foreach_begin(i, set) if (first) { first = false; sge_dstring_sprintf(&proc, "%d", i); } else { sge_dstring_sprintf(&proc, " %d", i); } sge_dstring_append_dstring(&sge_binding, &proc); hwloc_bitmap_foreach_end(); if (sge_setenv("SGE_BINDING", sge_dstring_get_string(&sge_binding)) != 1) { /* settting env var was not successful */ retval = false; shepherd_trace("create_binding_env: Couldn't set environment variable!"); } sge_dstring_free(&sge_binding); sge_dstring_free(&proc); return retval; }
static int hwloc_aix_set_sth_cpubind(hwloc_topology_t topology, rstype_t what, rsid_t who, hwloc_const_bitmap_t hwloc_set, int flags __hwloc_attribute_unused) { rsethandle_t rad; int res; unsigned cpu; if (flags & HWLOC_CPUBIND_NOMEMBIND) { errno = ENOSYS; return -1; } /* The resulting binding is always strict */ if (hwloc_bitmap_isequal(hwloc_set, hwloc_topology_get_complete_cpuset(topology))) { if (ra_detachrset(what, who, 0)) return -1; return 0; } rad = rs_alloc(RS_EMPTY); hwloc_bitmap_foreach_begin(cpu, hwloc_set) rs_op(RS_ADDRESOURCE, rad, NULL, R_PROCS, cpu); hwloc_bitmap_foreach_end(); res = ra_attachrset(what, who, rad, 0); rs_free(rad); return res; }
static int prepare_radset(hwloc_topology_t topology __hwloc_attribute_unused, radset_t *radset, hwloc_const_bitmap_t hwloc_set) { unsigned cpu; cpuset_t target_cpuset; cpuset_t cpuset, xor_cpuset; radid_t radid; int ret = 0; int ret_errno = 0; int nbnodes = rad_get_num(); cpusetcreate(&target_cpuset); cpuemptyset(target_cpuset); hwloc_bitmap_foreach_begin(cpu, hwloc_set) cpuaddset(target_cpuset, cpu); hwloc_bitmap_foreach_end(); cpusetcreate(&cpuset); cpusetcreate(&xor_cpuset); for (radid = 0; radid < nbnodes; radid++) { cpuemptyset(cpuset); if (rad_get_cpus(radid, cpuset)==-1) { fprintf(stderr,"rad_get_cpus(%d) failed: %s\n",radid,strerror(errno)); continue; } cpuxorset(target_cpuset, cpuset, xor_cpuset); if (cpucountset(xor_cpuset) == 0) { /* Found it */ radsetcreate(radset); rademptyset(*radset); radaddset(*radset, radid); ret = 1; goto out; } } /* radset containing exactly this set of CPUs not found */ ret_errno = EXDEV; out: cpusetdestroy(&target_cpuset); cpusetdestroy(&cpuset); cpusetdestroy(&xor_cpuset); errno = ret_errno; return ret; }
static int hwloc_aix_set_sth_cpubind(hwloc_topology_t topology, rstype_t what, rsid_t who, pid_t pid, hwloc_const_bitmap_t hwloc_set, int flags __hwloc_attribute_unused) { rsethandle_t rad; int res; unsigned cpu; if (flags & HWLOC_CPUBIND_NOMEMBIND) { errno = ENOSYS; return -1; } /* The resulting binding is always strict */ if (hwloc_bitmap_isequal(hwloc_set, hwloc_topology_get_complete_cpuset(topology))) { if (ra_detachrset(what, who, 0)) return -1; return 0; } rad = rs_alloc(RS_EMPTY); hwloc_bitmap_foreach_begin(cpu, hwloc_set) rs_op(RS_ADDRESOURCE, rad, NULL, R_PROCS, cpu); hwloc_bitmap_foreach_end(); res = ra_attachrset(what, who, rad, 0); if (res < 0 && errno == EPERM) { /* EPERM may mean that one thread has ben bound with bindprocessor(). * Unbind the entire process (we can't unbind individual threads) * and try again. */ bindprocessor(BINDPROCESS, pid, PROCESSOR_CLASS_ANY); res = ra_attachrset(what, who, rad, 0); } rs_free(rad); return res; }
static int hwloc_osf_prepare_mattr(hwloc_topology_t topology __hwloc_attribute_unused, memalloc_attr_t *mattr, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags __hwloc_attribute_unused) { unsigned long osf_policy; int node; switch (policy) { case HWLOC_MEMBIND_FIRSTTOUCH: osf_policy = MPOL_THREAD; break; case HWLOC_MEMBIND_DEFAULT: case HWLOC_MEMBIND_BIND: osf_policy = MPOL_DIRECTED; break; case HWLOC_MEMBIND_INTERLEAVE: osf_policy = MPOL_STRIPPED; break; case HWLOC_MEMBIND_REPLICATE: osf_policy = MPOL_REPLICATED; break; default: errno = ENOSYS; return -1; } memset(mattr, 0, sizeof(*mattr)); mattr->mattr_policy = osf_policy; mattr->mattr_rad = RAD_NONE; radsetcreate(&mattr->mattr_radset); rademptyset(mattr->mattr_radset); hwloc_bitmap_foreach_begin(node, nodeset) radaddset(mattr->mattr_radset, node); hwloc_bitmap_foreach_end(); return 0; }
static int hwloc_look_windows(struct hwloc_backend *backend) { struct hwloc_topology *topology = backend->topology; hwloc_bitmap_t groups_pu_set = NULL; SYSTEM_INFO SystemInfo; DWORD length; if (topology->levels[0][0]->cpuset) /* somebody discovered things */ return -1; hwloc_alloc_obj_cpusets(topology->levels[0][0]); GetSystemInfo(&SystemInfo); if (!GetLogicalProcessorInformationExProc && GetLogicalProcessorInformationProc) { PSYSTEM_LOGICAL_PROCESSOR_INFORMATION procInfo, tmpprocInfo; unsigned id; unsigned i; struct hwloc_obj *obj; hwloc_obj_type_t type; length = 0; procInfo = NULL; while (1) { if (GetLogicalProcessorInformationProc(procInfo, &length)) break; if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) return -1; tmpprocInfo = realloc(procInfo, length); if (!tmpprocInfo) { free(procInfo); goto out; } procInfo = tmpprocInfo; } assert(!length || procInfo); for (i = 0; i < length / sizeof(*procInfo); i++) { /* Ignore unknown caches */ if (procInfo->Relationship == RelationCache && procInfo->Cache.Type != CacheUnified && procInfo->Cache.Type != CacheData && procInfo->Cache.Type != CacheInstruction) continue; id = -1; switch (procInfo[i].Relationship) { case RelationNumaNode: type = HWLOC_OBJ_NUMANODE; id = procInfo[i].NumaNode.NodeNumber; break; case RelationProcessorPackage: type = HWLOC_OBJ_PACKAGE; break; case RelationCache: type = (procInfo[i].Cache.Type == CacheInstruction ? HWLOC_OBJ_L1ICACHE : HWLOC_OBJ_L1CACHE) + procInfo[i].Cache.Level - 1; break; case RelationProcessorCore: type = HWLOC_OBJ_CORE; break; case RelationGroup: default: type = HWLOC_OBJ_GROUP; break; } if (!hwloc_filter_check_keep_object_type(topology, type)) continue; obj = hwloc_alloc_setup_object(topology, type, id); obj->cpuset = hwloc_bitmap_alloc(); hwloc_debug("%s#%u mask %lx\n", hwloc_type_name(type), id, procInfo[i].ProcessorMask); /* ProcessorMask is a ULONG_PTR */ hwloc_bitmap_set_ith_ULONG_PTR(obj->cpuset, 0, procInfo[i].ProcessorMask); hwloc_debug_2args_bitmap("%s#%u bitmap %s\n", hwloc_type_name(type), id, obj->cpuset); switch (type) { case HWLOC_OBJ_NUMANODE: { ULONGLONG avail; obj->nodeset = hwloc_bitmap_alloc(); hwloc_bitmap_set(obj->nodeset, id); if ((GetNumaAvailableMemoryNodeExProc && GetNumaAvailableMemoryNodeExProc(id, &avail)) || (GetNumaAvailableMemoryNodeProc && GetNumaAvailableMemoryNodeProc(id, &avail))) obj->memory.local_memory = avail; obj->memory.page_types_len = 2; obj->memory.page_types = malloc(2 * sizeof(*obj->memory.page_types)); memset(obj->memory.page_types, 0, 2 * sizeof(*obj->memory.page_types)); obj->memory.page_types_len = 1; obj->memory.page_types[0].size = SystemInfo.dwPageSize; #if HAVE_DECL__SC_LARGE_PAGESIZE obj->memory.page_types_len++; obj->memory.page_types[1].size = sysconf(_SC_LARGE_PAGESIZE); #endif break; } case HWLOC_OBJ_L1CACHE: case HWLOC_OBJ_L2CACHE: case HWLOC_OBJ_L3CACHE: case HWLOC_OBJ_L4CACHE: case HWLOC_OBJ_L5CACHE: case HWLOC_OBJ_L1ICACHE: case HWLOC_OBJ_L2ICACHE: case HWLOC_OBJ_L3ICACHE: obj->attr->cache.size = procInfo[i].Cache.Size; obj->attr->cache.associativity = procInfo[i].Cache.Associativity == CACHE_FULLY_ASSOCIATIVE ? -1 : procInfo[i].Cache.Associativity ; obj->attr->cache.linesize = procInfo[i].Cache.LineSize; obj->attr->cache.depth = procInfo[i].Cache.Level; switch (procInfo->Cache.Type) { case CacheUnified: obj->attr->cache.type = HWLOC_OBJ_CACHE_UNIFIED; break; case CacheData: obj->attr->cache.type = HWLOC_OBJ_CACHE_DATA; break; case CacheInstruction: obj->attr->cache.type = HWLOC_OBJ_CACHE_INSTRUCTION; break; default: hwloc_free_unlinked_object(obj); continue; } break; case HWLOC_OBJ_GROUP: obj->attr->group.kind = procInfo[i].Relationship == RelationGroup ? HWLOC_GROUP_KIND_WINDOWS_PROCESSOR_GROUP : HWLOC_GROUP_KIND_WINDOWS_RELATIONSHIP_UNKNOWN; break; default: break; } hwloc_insert_object_by_cpuset(topology, obj); } free(procInfo); } if (GetLogicalProcessorInformationExProc) { PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX procInfoTotal, tmpprocInfoTotal, procInfo; unsigned id; struct hwloc_obj *obj; hwloc_obj_type_t type; length = 0; procInfoTotal = NULL; while (1) { if (GetLogicalProcessorInformationExProc(RelationAll, procInfoTotal, &length)) break; if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) return -1; tmpprocInfoTotal = realloc(procInfoTotal, length); if (!tmpprocInfoTotal) { free(procInfoTotal); goto out; } procInfoTotal = tmpprocInfoTotal; } for (procInfo = procInfoTotal; (void*) procInfo < (void*) ((uintptr_t) procInfoTotal + length); procInfo = (void*) ((uintptr_t) procInfo + procInfo->Size)) { unsigned num, i; GROUP_AFFINITY *GroupMask; /* Ignore unknown caches */ if (procInfo->Relationship == RelationCache && procInfo->Cache.Type != CacheUnified && procInfo->Cache.Type != CacheData && procInfo->Cache.Type != CacheInstruction) continue; id = -1; switch (procInfo->Relationship) { case RelationNumaNode: type = HWLOC_OBJ_NUMANODE; num = 1; GroupMask = &procInfo->NumaNode.GroupMask; id = procInfo->NumaNode.NodeNumber; break; case RelationProcessorPackage: type = HWLOC_OBJ_PACKAGE; num = procInfo->Processor.GroupCount; GroupMask = procInfo->Processor.GroupMask; break; case RelationCache: type = (procInfo->Cache.Type == CacheInstruction ? HWLOC_OBJ_L1ICACHE : HWLOC_OBJ_L1CACHE) + procInfo->Cache.Level - 1; num = 1; GroupMask = &procInfo->Cache.GroupMask; break; case RelationProcessorCore: type = HWLOC_OBJ_CORE; num = procInfo->Processor.GroupCount; GroupMask = procInfo->Processor.GroupMask; break; case RelationGroup: /* So strange an interface... */ for (id = 0; id < procInfo->Group.ActiveGroupCount; id++) { KAFFINITY mask; hwloc_bitmap_t set; set = hwloc_bitmap_alloc(); mask = procInfo->Group.GroupInfo[id].ActiveProcessorMask; hwloc_debug("group %u %d cpus mask %lx\n", id, procInfo->Group.GroupInfo[id].ActiveProcessorCount, mask); /* KAFFINITY is ULONG_PTR */ hwloc_bitmap_set_ith_ULONG_PTR(set, id, mask); /* FIXME: what if running 32bits on a 64bits windows with 64-processor groups? * ULONG_PTR is 32bits, so half the group is invisible? * maybe scale id to id*8/sizeof(ULONG_PTR) so that groups are 64-PU aligned? */ hwloc_debug_2args_bitmap("group %u %d bitmap %s\n", id, procInfo->Group.GroupInfo[id].ActiveProcessorCount, set); /* save the set of PUs so that we can create them at the end */ if (!groups_pu_set) groups_pu_set = hwloc_bitmap_alloc(); hwloc_bitmap_or(groups_pu_set, groups_pu_set, set); if (hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_GROUP)) { obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_GROUP, id); obj->cpuset = set; obj->attr->group.kind = HWLOC_GROUP_KIND_WINDOWS_PROCESSOR_GROUP; hwloc_insert_object_by_cpuset(topology, obj); } else hwloc_bitmap_free(set); } continue; default: /* Don't know how to get the mask. */ hwloc_debug("unknown relation %d\n", procInfo->Relationship); continue; } if (!hwloc_filter_check_keep_object_type(topology, type)) continue; obj = hwloc_alloc_setup_object(topology, type, id); obj->cpuset = hwloc_bitmap_alloc(); for (i = 0; i < num; i++) { hwloc_debug("%s#%u %d: mask %d:%lx\n", hwloc_type_name(type), id, i, GroupMask[i].Group, GroupMask[i].Mask); /* GROUP_AFFINITY.Mask is KAFFINITY, which is ULONG_PTR */ hwloc_bitmap_set_ith_ULONG_PTR(obj->cpuset, GroupMask[i].Group, GroupMask[i].Mask); /* FIXME: scale id to id*8/sizeof(ULONG_PTR) as above? */ } hwloc_debug_2args_bitmap("%s#%u bitmap %s\n", hwloc_type_name(type), id, obj->cpuset); switch (type) { case HWLOC_OBJ_NUMANODE: { ULONGLONG avail; obj->nodeset = hwloc_bitmap_alloc(); hwloc_bitmap_set(obj->nodeset, id); if ((GetNumaAvailableMemoryNodeExProc && GetNumaAvailableMemoryNodeExProc(id, &avail)) || (GetNumaAvailableMemoryNodeProc && GetNumaAvailableMemoryNodeProc(id, &avail))) obj->memory.local_memory = avail; obj->memory.page_types = malloc(2 * sizeof(*obj->memory.page_types)); memset(obj->memory.page_types, 0, 2 * sizeof(*obj->memory.page_types)); obj->memory.page_types_len = 1; obj->memory.page_types[0].size = SystemInfo.dwPageSize; #if HAVE_DECL__SC_LARGE_PAGESIZE obj->memory.page_types_len++; obj->memory.page_types[1].size = sysconf(_SC_LARGE_PAGESIZE); #endif break; } case HWLOC_OBJ_L1CACHE: case HWLOC_OBJ_L2CACHE: case HWLOC_OBJ_L3CACHE: case HWLOC_OBJ_L4CACHE: case HWLOC_OBJ_L5CACHE: case HWLOC_OBJ_L1ICACHE: case HWLOC_OBJ_L2ICACHE: case HWLOC_OBJ_L3ICACHE: obj->attr->cache.size = procInfo->Cache.CacheSize; obj->attr->cache.associativity = procInfo->Cache.Associativity == CACHE_FULLY_ASSOCIATIVE ? -1 : procInfo->Cache.Associativity ; obj->attr->cache.linesize = procInfo->Cache.LineSize; obj->attr->cache.depth = procInfo->Cache.Level; switch (procInfo->Cache.Type) { case CacheUnified: obj->attr->cache.type = HWLOC_OBJ_CACHE_UNIFIED; break; case CacheData: obj->attr->cache.type = HWLOC_OBJ_CACHE_DATA; break; case CacheInstruction: obj->attr->cache.type = HWLOC_OBJ_CACHE_INSTRUCTION; break; default: hwloc_free_unlinked_object(obj); continue; } break; default: break; } hwloc_insert_object_by_cpuset(topology, obj); } free(procInfoTotal); } if (groups_pu_set) { /* the system supports multiple Groups. * PU indexes may be discontiguous, especially if Groups contain less than 64 procs. */ hwloc_obj_t obj; unsigned idx; hwloc_bitmap_foreach_begin(idx, groups_pu_set) { obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_PU, idx); obj->cpuset = hwloc_bitmap_alloc(); hwloc_bitmap_only(obj->cpuset, idx); hwloc_debug_1arg_bitmap("cpu %u has cpuset %s\n", idx, obj->cpuset); hwloc_insert_object_by_cpuset(topology, obj); } hwloc_bitmap_foreach_end(); hwloc_bitmap_free(groups_pu_set); } else {
int main(void) { hwloc_bitmap_t set; int i, cpu, expected_cpu = 0; /* empty set */ set = hwloc_bitmap_alloc(); assert(hwloc_bitmap_first(set) == -1); assert(hwloc_bitmap_last(set) == -1); assert(hwloc_bitmap_next(set, 0) == -1); assert(hwloc_bitmap_next(set, -1) == -1); assert(hwloc_bitmap_weight(set) == 0); /* full set */ hwloc_bitmap_fill(set); assert(hwloc_bitmap_first(set) == 0); assert(hwloc_bitmap_last(set) == -1); assert(hwloc_bitmap_next(set, -1) == 0); assert(hwloc_bitmap_next(set, 0) == 1); assert(hwloc_bitmap_next(set, 1) == 2); assert(hwloc_bitmap_next(set, 2) == 3); assert(hwloc_bitmap_next(set, 30) == 31); assert(hwloc_bitmap_next(set, 31) == 32); assert(hwloc_bitmap_next(set, 32) == 33); assert(hwloc_bitmap_next(set, 62) == 63); assert(hwloc_bitmap_next(set, 63) == 64); assert(hwloc_bitmap_next(set, 64) == 65); assert(hwloc_bitmap_next(set, 12345) == 12346); assert(hwloc_bitmap_weight(set) == -1); /* custom sets */ hwloc_bitmap_zero(set); hwloc_bitmap_set_range(set, 36, 59); assert(hwloc_bitmap_first(set) == 36); assert(hwloc_bitmap_last(set) == 59); assert(hwloc_bitmap_next(set, -1) == 36); assert(hwloc_bitmap_next(set, 0) == 36); assert(hwloc_bitmap_next(set, 36) == 37); assert(hwloc_bitmap_next(set, 59) == -1); assert(hwloc_bitmap_weight(set) == 24); hwloc_bitmap_set_range(set, 136, 259); assert(hwloc_bitmap_first(set) == 36); assert(hwloc_bitmap_last(set) == 259); assert(hwloc_bitmap_next(set, 59) == 136); assert(hwloc_bitmap_next(set, 259) == -1); assert(hwloc_bitmap_weight(set) == 148); hwloc_bitmap_clr(set, 199); assert(hwloc_bitmap_first(set) == 36); assert(hwloc_bitmap_last(set) == 259); assert(hwloc_bitmap_next(set, 198) == 200); assert(hwloc_bitmap_next(set, 199) == 200); assert(hwloc_bitmap_weight(set) == 147); i = 0; hwloc_bitmap_foreach_begin(cpu, set) { if (0 <= i && i < 24) expected_cpu = i + 36; else if (24 <= i && i < 87) expected_cpu = i + 112; else if (87 <= i && i < 147) expected_cpu = i + 113; assert(expected_cpu == cpu); i++; } hwloc_bitmap_foreach_end(); hwloc_bitmap_free(set); return 0; }
static int hwloc_aix_set_thread_cpubind(hwloc_topology_t topology, hwloc_thread_t pthread, hwloc_const_bitmap_t hwloc_set, int flags) { struct __pthrdsinfo info; int size; if ((errno = pthread_getthrds_np(&pthread, PTHRDSINFO_QUERY_TID, &info, sizeof(info), NULL, &size))) return -1; { rsid_t who = { .at_tid = info.__pi_tid }; return hwloc_aix_set_sth_cpubind(topology, R_THREAD, who, hwloc_set, flags); } } static int hwloc_aix_get_thread_cpubind(hwloc_topology_t topology, hwloc_thread_t pthread, hwloc_bitmap_t hwloc_set, int flags) { struct __pthrdsinfo info; int size; if (pthread_getthrds_np(&pthread, PTHRDSINFO_QUERY_TID, &info, sizeof(info), NULL, &size)) return -1; { rsid_t who; who.at_tid = info.__pi_tid; return hwloc_aix_get_sth_cpubind(topology, R_THREAD, who, hwloc_set, flags); } } #endif /* HWLOC_HAVE_PTHREAD_GETTHRDS_NP */ #endif /* R_THREAD */ #ifdef P_DEFAULT static int hwloc_aix_membind_policy_from_hwloc(uint_t *aix_policy, int policy) { switch (policy) { case HWLOC_MEMBIND_DEFAULT: case HWLOC_MEMBIND_BIND: *aix_policy = P_DEFAULT; break; case HWLOC_MEMBIND_FIRSTTOUCH: *aix_policy = P_FIRST_TOUCH; break; case HWLOC_MEMBIND_INTERLEAVE: *aix_policy = P_BALANCED; break; default: errno = ENOSYS; return -1; } return 0; } static int hwloc_aix_prepare_membind(hwloc_topology_t topology, rsethandle_t *rad, hwloc_const_nodeset_t nodeset, int flags __hwloc_attribute_unused) { rsethandle_t rset, noderad; int MCMlevel; int node; MCMlevel = rs_getinfo(NULL, R_MCMSDL, 0); if ((topology->flags & HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM)) rset = rs_alloc(RS_ALL); else rset = rs_alloc(RS_PARTITION); *rad = rs_alloc(RS_EMPTY); noderad = rs_alloc(RS_EMPTY); hwloc_bitmap_foreach_begin(node, nodeset) rs_getrad(rset, noderad, MCMlevel, node, 0); rs_op(RS_UNION, noderad, *rad, 0, 0); hwloc_bitmap_foreach_end(); rs_free(rset); rs_free(noderad); return 0; }