uint32_t powercap_get_cluster_adjusted_max_watts(void) { uint32_t adj_max_watts = 0,val; struct node_record *node_ptr; int i; if (!_powercap_enabled()) return 0; if (!power_layout_ready()) return 0; for (i = 0, node_ptr = node_record_table_ptr; i < node_record_count; i++, node_ptr++) { if (bit_test(power_node_bitmap, i)) { layouts_entity_pullget_kv(L_NAME, node_ptr->name, L_NODE_SAVE, &val, L_T_UINT32); } else if (!bit_test(up_node_bitmap, i)) { layouts_entity_pullget_kv(L_NAME, node_ptr->name, L_NODE_DOWN, &val, L_T_UINT32); } else { layouts_entity_pullget_kv(L_NAME, node_ptr->name, L_NODE_MAX, &val, L_T_UINT32); } adj_max_watts += val; } return adj_max_watts; }
uint32_t powercap_get_cluster_min_watts(void) { uint32_t min_watts = 0, tmp_watts, save_watts, down_watts; struct node_record *node_ptr; int i; if (!_powercap_enabled()) return 0; if (!power_layout_ready()) return 0; for (i = 0, node_ptr = node_record_table_ptr; i < node_record_count; i++, node_ptr++) { layouts_entity_pullget_kv(L_NAME, node_ptr->name, L_NODE_IDLE, &tmp_watts, L_T_UINT32); layouts_entity_pullget_kv(L_NAME, node_ptr->name, L_NODE_DOWN, &down_watts, L_T_UINT32); tmp_watts = MIN(tmp_watts, down_watts); layouts_entity_pullget_kv(L_NAME, node_ptr->name, L_NODE_SAVE, &save_watts, L_T_UINT32); tmp_watts = MIN(tmp_watts, save_watts); min_watts += tmp_watts; } return min_watts; }
int* powercap_get_job_nodes_numfreq(bitstr_t *select_bitmap, uint32_t cpu_freq_min, uint32_t cpu_freq_max) { uint16_t num_freq = 0; int i, p, *allowed_freqs = NULL, new_num_freq = 0; struct node_record *node_ptr; char ename[128]; uint32_t cpufreq; if (!_powercap_enabled()) return 0; if ((cpu_freq_min == NO_VAL) && (cpu_freq_max == NO_VAL)) { allowed_freqs = xmalloc(sizeof(int) * 2); /* allowed_freqs[0] = 0; Default value */ return allowed_freqs; } for (i = 0, node_ptr = node_record_table_ptr; i < node_record_count; i++, node_ptr++) { if (bit_test(select_bitmap, i)) { layouts_entity_pullget_kv(L_NAME, node_ptr->name, L_NUM_FREQ, &num_freq, L_T_UINT16); allowed_freqs = xmalloc(sizeof(int)*((int)num_freq+2)); allowed_freqs[-1] = (int) num_freq; for (p = num_freq; p > 0; p--) { sprintf(ename, "Cpufreq%d", p); layouts_entity_pullget_kv(L_NAME, node_ptr->name, ename, &cpufreq, L_T_UINT32); /* In case a job is submitted with flags Low,High, etc on * --cpu-freq parameter then we consider the whole range * of available frequencies on nodes */ if (((cpu_freq_min <= cpufreq) && (cpufreq <= cpu_freq_max)) || ((cpu_freq_min & CPU_FREQ_RANGE_FLAG) || (cpu_freq_max & CPU_FREQ_RANGE_FLAG))) { new_num_freq++; allowed_freqs[new_num_freq] = p; } } break; } } if (allowed_freqs) { allowed_freqs[0] = new_num_freq; } else { allowed_freqs = xmalloc(sizeof(int) * 2); /* allowed_freqs[0] = 0; Default value */ } return allowed_freqs; }
uint32_t powercap_get_node_bitmap_maxwatts(bitstr_t *idle_bitmap) { uint32_t max_watts = 0, val; struct node_record *node_ptr; int i; bitstr_t *tmp_bitmap = NULL; if (!_powercap_enabled()) return 0; if (!power_layout_ready()) return 0; /* if no input bitmap, consider the current idle nodes * bitmap as the input bitmap tagging nodes to consider * as idle while computing the max watts of the cluster */ if (idle_bitmap == NULL) { tmp_bitmap = bit_copy(idle_node_bitmap); idle_bitmap = tmp_bitmap; } for (i = 0, node_ptr = node_record_table_ptr; i < node_record_count; i++, node_ptr++) { /* non reserved node, evaluate the different cases */ if (bit_test(idle_bitmap, i)) { /* idle nodes, 2 cases : power save or not */ if (bit_test(power_node_bitmap, i)) { layouts_entity_pullget_kv(L_NAME, node_ptr->name, L_NODE_SAVE, &val, L_T_UINT32); } else { layouts_entity_pullget_kv(L_NAME, node_ptr->name, L_NODE_IDLE, &val, L_T_UINT32); } } else { /* non idle nodes, 2 cases : down or not */ if (!bit_test(up_node_bitmap, i)) { layouts_entity_pullget_kv(L_NAME, node_ptr->name, L_NODE_DOWN, &val, L_T_UINT32); } else { layouts_entity_pullget_kv(L_NAME, node_ptr->name, L_NODE_MAX, &val, L_T_UINT32); } } max_watts += val; } if (tmp_bitmap) bit_free(tmp_bitmap); return max_watts; }
int _which_power_layout(char *layout) { uint32_t max_watts; return layouts_entity_pullget_kv(layout, L_CLUSTER, L_SUM_MAX, &max_watts, L_T_UINT32); }
uint32_t powercap_get_cluster_max_watts(void) { uint32_t max_watts; if (!_powercap_enabled()) return 0; if (!power_layout_ready()) return 0; layouts_entity_pullget_kv(L_NAME, L_CLUSTER, L_SUM_MAX, &max_watts, L_T_UINT32); return max_watts; }
uint32_t powercap_get_cpufreq(bitstr_t *select_bitmap, int k) { int i; struct node_record *node_ptr; char ename[128]; uint32_t cpufreq = 0; if (!_powercap_enabled()) return cpufreq; for (i = 0, node_ptr = node_record_table_ptr; i < node_record_count; i++, node_ptr++) { if (bit_test(select_bitmap, i)) { sprintf(ename, "Cpufreq%d", k); layouts_entity_pullget_kv(L_NAME, node_ptr->name, ename, &cpufreq, L_T_UINT32); } break; } return cpufreq; }
uint32_t powercap_get_node_bitmap_maxwatts_dvfs(bitstr_t *idle_bitmap, bitstr_t *select_bitmap, uint32_t *max_watts_dvfs, int* allowed_freqs, uint32_t num_cpus) { uint32_t max_watts = 0, tmp_max_watts = 0, val = 0; uint32_t *tmp_max_watts_dvfs = NULL; struct node_record *node_ptr; int i, p; char ename[128], keyname[128]; bitstr_t *tmp_bitmap = NULL; uint32_t data[5], core_data[4]; if (!_powercap_enabled()) return 0; if (max_watts_dvfs != NULL) { tmp_max_watts_dvfs = xmalloc(sizeof(uint32_t)*(allowed_freqs[0]+1)); } /* if no input bitmap, consider the current idle nodes * bitmap as the input bitmap tagging nodes to consider * as idle while computing the max watts of the cluster */ if (idle_bitmap == NULL && select_bitmap == NULL) { tmp_bitmap = bit_copy(idle_node_bitmap); idle_bitmap = tmp_bitmap; select_bitmap = tmp_bitmap; } for (i = 0, node_ptr = node_record_table_ptr; i < node_record_count; i++, node_ptr++) { if (bit_test(idle_bitmap, i)) { /* idle nodes, 2 cases : power save or not */ if (bit_test(power_node_bitmap, i)) { layouts_entity_pullget_kv(L_NAME, node_ptr->name, L_NODE_SAVE, &val, L_T_UINT32); } else { layouts_entity_pullget_kv(L_NAME, node_ptr->name, L_NODE_IDLE, &val, L_T_UINT32); } } else if (bit_test(select_bitmap, i)) { layouts_entity_get_mkv(L_NAME, node_ptr->name, "IdleWatts,MaxWatts,CoresCount,LastCore,CurrentPower", data, (sizeof(uint32_t) * 5), L_T_UINT32); /* tmp_max_watts = IdleWatts - cpus*IdleCoreWatts * + cpus*MaxCoreWatts */ sprintf(ename, "virtualcore%u", data[3]); if (num_cpus == 0) num_cpus = data[2]; layouts_entity_get_mkv(L_NAME, ename, "IdleCoreWatts,MaxCoreWatts", core_data, (sizeof(uint32_t) * 2), L_T_UINT32); if (data[4] == 0) { tmp_max_watts += data[0] - num_cpus*core_data[0] + num_cpus*core_data[1]; } else if (data[4] > 0) { tmp_max_watts += data[4] - num_cpus*core_data[0] + num_cpus*core_data[1]; } else if (num_cpus == data[2]) tmp_max_watts += data[1]; if (!tmp_max_watts_dvfs) goto skip_dvfs; for (p = 1; p < (allowed_freqs[0] + 1); p++) { sprintf(keyname, "IdleCoreWatts,MaxCoreWatts," "Cpufreq%dWatts,CurrentCorePower", allowed_freqs[p]); layouts_entity_get_mkv(L_NAME, ename, keyname, core_data, (sizeof(uint32_t) * 4), L_T_UINT32); if (num_cpus == data[2]) { tmp_max_watts_dvfs[p] += num_cpus*core_data[2]; } else { if (data[4] == 0) { tmp_max_watts_dvfs[p] += data[0] - num_cpus*core_data[0] + num_cpus*core_data[2]; } else { tmp_max_watts_dvfs[p] += data[4] - num_cpus*core_data[0] + num_cpus*core_data[2]; } } } skip_dvfs: ; } else { /* non-idle nodes, 2 cases : down or not */ if (!bit_test(up_node_bitmap, i)) { layouts_entity_pullget_kv(L_NAME, node_ptr->name, L_NODE_DOWN, &val, L_T_UINT32); } else { layouts_entity_pullget_kv(L_NAME, node_ptr->name, L_NODE_CUR, &val, L_T_UINT32); } } max_watts += val; val = 0; } if (max_watts_dvfs) { for (p = 1; p < allowed_freqs[0] + 1; p++) { max_watts_dvfs[p] = max_watts + tmp_max_watts_dvfs[p]; } xfree(tmp_max_watts_dvfs); } max_watts += tmp_max_watts; if (tmp_bitmap) bit_free(tmp_bitmap); return max_watts; }
extern int adapt_layouts(job_resources_t *job_resrcs_ptr, uint32_t cpu_freq_max, uint32_t node_id, char* node_name, bool new_value) { int i, k = 0, bit_inx = 0, core_cnt = 0; uint32_t max_watts, zero = 0, der; uint32_t core_num,val = 0; uint16_t num_freq; char temp[128], ename[128], keyname[128]; uint32_t data[2], vals[2]; int num_counts = 0, activate = 0; int *desalloc_cores; xassert(job_resrcs_ptr); for (i = 0; i < job_resrcs_ptr->nhosts; i++) { if (job_resrcs_ptr->sock_core_rep_count[i] <= node_id) { bit_inx += job_resrcs_ptr->sockets_per_node[i] * job_resrcs_ptr->cores_per_socket[i] * job_resrcs_ptr->sock_core_rep_count[i]; node_id -= job_resrcs_ptr->sock_core_rep_count[i]; } else { bit_inx += job_resrcs_ptr->sockets_per_node[i] * job_resrcs_ptr->cores_per_socket[i] * node_id; core_cnt = job_resrcs_ptr->sockets_per_node[i] * job_resrcs_ptr->cores_per_socket[i]; break; } } if (core_cnt < 1) { error("count_job_resources_node: core_cnt=0"); return 0; } i = bit_size(job_resrcs_ptr->core_bitmap); if ((bit_inx + core_cnt) > i) { error("count_job_resources_node: offset > bitmap size " "(%d >= %d)", (bit_inx + core_cnt), i); return 0; } layouts_entity_get_kv("power", node_name, "NumFreqChoices", &num_freq, L_T_UINT16); layouts_entity_get_mkv("power", node_name, "CoresCount,LastCore", data, (sizeof(uint32_t)*2),L_T_UINT32); if (cpu_freq_max != 0) { for (i = 1; i < num_freq + 1; i++) { sprintf(temp, "Cpufreq%d", i); layouts_entity_pullget_kv("power", node_name, temp, &val, L_T_UINT32); if (val == cpu_freq_max) { k = i; break; } } } desalloc_cores = xmalloc ( sizeof (int) * (core_cnt)); for (i = 0; i < core_cnt; i++) { /*core_num=LastCore+1-CoresCount*/ core_num = data[1] + 1 - data[0] + i; sprintf(ename, "virtualcore%u", core_num); if (bit_test(job_resrcs_ptr->core_bitmap, bit_inx++)) { if (new_value) { if (cpu_freq_max != 0 && k != 0) { sprintf(keyname, "Cpufreq%dWatts", k); layouts_entity_get_kv("power", ename, keyname, &max_watts, L_T_UINT32); } else { layouts_entity_get_kv("power", ename, "MaxCoreWatts", &max_watts, L_T_UINT32); } layouts_entity_set_kv("power", ename, "CurrentCorePower", &max_watts, L_T_UINT32); } else { layouts_entity_set_kv("power", ename, "CurrentCorePower", &zero, L_T_UINT32); desalloc_cores[num_counts] = i; num_counts++; } } else { layouts_entity_get_mkv("power", ename, "CurrentCorePower,IdleCoreWatts", vals, (sizeof(uint32_t)*2) ,L_T_UINT32); if (new_value) { if (vals[0] == 0) { layouts_entity_set_kv( "power", ename, "CurrentCorePower", &vals[1], L_T_UINT32); } } else { if (vals[1] != vals[0]) { activate = 1; } else { desalloc_cores[num_counts] = i; num_counts++; layouts_entity_set_kv( "power", ename, "CurrentCorePower", &zero, L_T_UINT32); layouts_entity_get_kv("power", ename, "CurrentCorePower", &der, L_T_UINT32); } } } } if (activate == 1) { for (i = 0; i < num_counts; i++) { core_num = data[1] + 1- data[0] + desalloc_cores[i]; sprintf(ename, "virtualcore%u", core_num); layouts_entity_set_kv("power", ename, "CurrentCorePower", &vals[1], L_T_UINT32); } } return 1; }