static void regular_nodes_init(void) { int i, node = 0, nodes_num = numa_num_configured_nodes(); struct bitmask *node_cpus = numa_allocate_cpumask(); regular_nodes_mask = numa_allocate_nodemask(); for (i = 0; i < nodes_num; i++) { numa_node_to_cpus(node, node_cpus); if (numa_bitmask_weight(node_cpus)) numa_bitmask_setbit(regular_nodes_mask, i); } numa_bitmask_free(node_cpus); }
///This function tries to fill bandwidth array based on knowledge about known CPU models static int fill_bandwidth_values_heuristically(int* bandwidth, int bandwidth_len) { int ret = MEMKIND_ERROR_UNAVAILABLE; // Default error returned if heuristic aproach fails int i, nodes_num, memory_only_nodes_num = 0; struct bitmask *memory_only_nodes, *node_cpus; if (is_cpu_xeon_phi_x200() == 0) { log_info("Known CPU model detected: Intel(R) Xeon Phi(TM) x200."); nodes_num = numa_num_configured_nodes(); // Check if number of numa-nodes meets expectations for // supported configurations of Intel Xeon Phi x200 if( nodes_num != 2 && nodes_num != 4 && nodes_num!= 8 ) { return ret; } memory_only_nodes = numa_allocate_nodemask(); node_cpus = numa_allocate_cpumask(); for(i=0; i<nodes_num; i++) { numa_node_to_cpus(i, node_cpus); if(numa_bitmask_weight(node_cpus) == 0) { memory_only_nodes_num++; numa_bitmask_setbit(memory_only_nodes, i); } } // Check if number of memory-only nodes is equal number of memory+cpu nodes // If it passes change ret to 0 (success) and fill bw table if ( memory_only_nodes_num == (nodes_num - memory_only_nodes_num) ) { ret = 0; assign_arbitrary_bandwidth_values(bandwidth, bandwidth_len, memory_only_nodes); } numa_bitmask_free(memory_only_nodes); numa_bitmask_free(node_cpus); } return ret; }
/* * Function: _get_numa_nodes * Description: * Returns a count of the NUMA nodes that the application is running on. * * Returns an array of NUMA nodes that the application is running on. * * * IN char* path -- The path to the directory containing the files containing * information about NUMA nodes. * * OUT *cnt -- The number of NUMA nodes in the array * OUT **numa_array -- An integer array containing the NUMA nodes. * This array must be xfreed by the caller. * * RETURN * 0 on success and -1 on failure. */ static int _get_numa_nodes(char *path, int *cnt, int32_t **numa_array) { struct bitmask *bm; int i, index, rc = 0; int lsz; size_t sz; char buffer[PATH_MAX]; FILE *f = NULL; char *lin = NULL; rc = snprintf(buffer, sizeof(buffer), "%s/%s", path, "mems"); if (rc < 0) { CRAY_ERR("snprintf failed. Return code: %d", rc); } f = fopen(buffer, "r"); if (f == NULL ) { CRAY_ERR("Failed to open file %s: %m", buffer); return -1; } lsz = getline(&lin, &sz, f); if (lsz > 0) { if (lin[strlen(lin) - 1] == '\n') { lin[strlen(lin) - 1] = '\0'; } bm = numa_parse_nodestring(lin); if (bm == NULL ) { CRAY_ERR("Error numa_parse_nodestring:" " Invalid node string: %s", lin); free(lin); return SLURM_ERROR; } } else { CRAY_ERR("Reading %s failed", buffer); return SLURM_ERROR; } free(lin); *cnt = numa_bitmask_weight(bm); if (*cnt == 0) { CRAY_ERR("No NUMA Nodes found"); return -1; } if (debug_flags & DEBUG_FLAG_TASK) { info("Bitmask %#lx size: %lu sizeof(*(bm->maskp)): %zd" " weight: %u", *(bm->maskp), bm->size, sizeof(*(bm->maskp)), *cnt); } *numa_array = xmalloc(*cnt * sizeof(int32_t)); index = 0; for (i = 0; i < bm->size; i++) { if (*(bm->maskp) & ((long unsigned) 1 << i)) { if (debug_flags & DEBUG_FLAG_TASK) { info("(%s: %d: %s) NUMA Node %d is present", THIS_FILE, __LINE__, __FUNCTION__, i); } (*numa_array)[index++] = i; } } numa_free_nodemask(bm); return 0; }