static unsigned long *read_states_file(char *name, int *state_count, int *core_count) { FILE *fp = NULL; char buf[512]; char *line, *token; int n, j; unsigned long *states = NULL, *state = NULL, *state_cursor; fp = fopen(name, "r"); fail_if(!fp, "could not open file"); line = fgets(buf, sizeof(buf), fp); fail_if(!line, "wrong format"); while ((token = strsep(&line, " \t")) != NULL) if (sscanf(token, "core%d", &n) >= 1) *core_count = n + 1; fail_if(*core_count < 1, "wrong format"); n = 1000; state = malloc(STATE_SIZE(*core_count)); state_cursor = states = malloc(STATE_SIZE(*core_count) * n); *state_count = 0; while (1) { if (fscanf(fp, "%lu\t%lu", &state[SPEED_IDX], &state[POWER_IDX]) < 2) goto end; for (j = 0; j < *core_count; j++) if (fscanf(fp, "\t%lu", &state[CORE_IDX(j)]) < 1) goto end; if (getc(fp) != '\n') goto end; if (*state_count >= n) { n *= 2; states = realloc(states, STATE_SIZE(*core_count) * n); state_cursor = states + STATE_LEN(*core_count) * *state_count; } (*state_count)++; memcpy(state_cursor, state, STATE_SIZE(*core_count)); state_cursor += STATE_LEN(*core_count); } end: if (fp) fclose(fp); if (state) free(state); return states; fail: if (states) free(states); states = NULL; goto end; }
int machine_speed_init (actuator_t *act) { machine_state_data_t *data; unsigned long *states, *all_states; unsigned long *in_state, *out_state; int state_count, filtered_count; int core_count, i; freq_scaler_data_t *freq_data; act->data = data = malloc(sizeof(machine_state_data_t)); fail_if(!data, "cannot allocate powerstate data block"); get_actuators(&data->core_act, NULL, 16, &data->freq_acts[0], NULL); fail_if(data->core_act->max > 16, "too many cores lol"); freq_data = data->freq_acts[0]->data; core_count = get_core_count(); all_states = create_machine_states(&state_count, core_count, freq_data->freq_count, freq_data->freq_array); fail_if(!all_states, "cannot generate machine states"); qsort(all_states, state_count, STATE_SIZE(core_count), compare_states_on_speed); states = malloc(STATE_SIZE(core_count) * state_count); for (i = 0, in_state = all_states, out_state = states, filtered_count = 0; i < state_count; i++, in_state+=STATE_LEN(core_count)) { if (!redundant_state(in_state, core_count) && !drop_equivalent(in_state, i, all_states, state_count, core_count) && pareto_optimal(in_state, i, all_states, state_count, core_count) && in_state[SPEED_IDX] > 0) { #if DEBUG int j; printf("%lu\t%lu", in_state[SPEED_IDX], in_state[POWER_IDX]); for (j = 0; j < core_count; j++) printf("\t%lu", in_state[CORE_IDX(j)]); printf("\n"); #endif memmove (out_state, in_state, STATE_SIZE(core_count)); out_state += STATE_LEN(core_count); filtered_count++; } } data->state_count = state_count = filtered_count; data->states = states = realloc(states, STATE_SIZE(core_count) * state_count); free(all_states); act->min = STATE_I(states, core_count, 0)[SPEED_IDX]; act->max = STATE_I(states, core_count, state_count-1)[SPEED_IDX]; data->scratch_state = malloc(STATE_SIZE(core_count)); act->value = act->set_value = get_current_speed(act); return 0; fail: return -1; }
int main(int argc, char **argv) { struct cpufreq_available_frequencies *freq_list; int core_count; int i, j; unsigned long *states, *state; int state_count; int opt; int skip_redundant = 0; int skip_unoptimal = 0; char *state_file_name = NULL; int skip_equivalent = 0; while ((opt = getopt(argc, argv, "rpf:u")) != -1) switch (opt) { case 'r': skip_redundant = 1; break; case 'p': skip_unoptimal = 1; break; case 'f': state_file_name = optarg; break; case 'u': skip_equivalent = 1; break; default: fprintf(stderr, "Usage: %s [-r] [-p] [-f file] [-u]\n", argv[0]); exit(1); } if (state_file_name) { states = read_states_file(state_file_name, &state_count, &core_count); } else { int freq_count; unsigned long *freq_array; core_count = get_core_count(); freq_list = cpufreq_get_available_frequencies(0); freq_count = create_freq_array(freq_list, &freq_array); states = create_machine_states(&state_count, core_count, freq_count, freq_array); } qsort(states, state_count, STATE_SIZE(core_count), compare_states_on_speed); printf("speed\tpower"); for (j = 0; j < core_count; j++) printf("\tcore%d", j); printf("\n"); for (i = 0, state = states; i < state_count; i++, state+=STATE_LEN(core_count)) { if (skip_redundant && redundant_state(state, core_count)) continue; if (skip_equivalent && drop_equivalent(state, i, states, state_count, core_count)) continue; if (skip_unoptimal && !pareto_optimal(state, i, states, state_count, core_count)) continue; printf("%lu\t%lu", state[SPEED_IDX], state[POWER_IDX]); for (j = 0; j < core_count; j++) printf("\t%lu", state[CORE_IDX(j)]); printf("\n"); } return 0; }
static bool float8_mregr_accum_get_args(FunctionCallInfo fcinfo, MRegrAccumArgs *outArgs) { float8 *stateData; uint32 len, i; uint64 statelen; /* We should be strict, but it doesn't hurt to be paranoid */ if (PG_ARGISNULL(0) || PG_ARGISNULL(1) || PG_ARGISNULL(2)) return false; outArgs->stateAsArray = PG_GETARG_ARRAYTYPE_P(0); outArgs->newY = PG_GETARG_FLOAT8(1); outArgs->newXAsArray = PG_GETARG_ARRAYTYPE_P(2); outArgs->newX = (float8*) ARR_DATA_PTR(outArgs->newXAsArray); /* Ensure that both arrays are single dimensional float8[] arrays */ if (ARR_NULLBITMAP(outArgs->stateAsArray) || ARR_NDIM(outArgs->stateAsArray) != 1 || ARR_ELEMTYPE(outArgs->stateAsArray) != FLOAT8OID || ARR_NDIM(outArgs->newXAsArray) != 1 || ARR_ELEMTYPE(outArgs->newXAsArray) != FLOAT8OID) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("transition function \"%s\" called with invalid parameters", format_procedure(fcinfo->flinfo->fn_oid)))); /* Only callable as a transition function */ if (!(fcinfo->context && IsA(fcinfo->context, AggState))) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("transition function \"%s\" not called from aggregate", format_procedure(fcinfo->flinfo->fn_oid)))); /* newXAsArray with nulls will be ignored */ if (ARR_NULLBITMAP(outArgs->newXAsArray)) return false; /* See MPP-14102. Avoid overflow while initializing len */ if (ARR_DIMS(outArgs->newXAsArray)[0] > UINT32_MAX) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("number of independent variables cannot exceed %lu", (unsigned long) UINT32_MAX))); len = ARR_DIMS(outArgs->newXAsArray)[0]; /* * See MPP-13580. At least on certain platforms and with certain versions, * LAPACK will run into an infinite loop if pinv() is called for non-finite * matrices. We extend the check also to the dependent variables. */ for (i = 0; i < len; i++) if (!isfinite(outArgs->newX[i])) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("design matrix is not finite"))); if (!isfinite(outArgs->newY)) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("dependent variables are not finite"))); /* * See MPP-14102. We want to avoid (a) long int overflows and (b) making * oversized allocation requests. * We could compute the maximum number of variables so that the transition- * state length still fits into MaxAllocSize, but (assuming MaxAllocSize may * change in the future) this calculation requires taking the root out of a * 64-bit long int. Since there is no standard library function for that, and * displaying this number of merely of theoretical interest (the actual * limit is a lot lower), we simply report that the number of independent * variables is too large. * Precondition: * len < 2^32. */ statelen = STATE_LEN(len); if (!IS_FEASIBLE_STATE_LEN(statelen)) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("number of independent variables is too large"))); /* * If length(outArgs->stateAsArray) == 1 then it is an unitialized state. * We extend as needed. */ if (ARR_DIMS(outArgs->stateAsArray)[0] == 1) { /* * Precondition: * IS_FEASIBLE_STATE_LEN(statelen) */ Size size = statelen * sizeof(float8) + ARR_OVERHEAD_NONULLS(1); outArgs->stateAsArray = (ArrayType *) palloc(size); SET_VARSIZE(outArgs->stateAsArray, size); outArgs->stateAsArray->ndim = 1; outArgs->stateAsArray->dataoffset = 0; outArgs->stateAsArray->elemtype = FLOAT8OID; ARR_DIMS(outArgs->stateAsArray)[0] = statelen; ARR_LBOUND(outArgs->stateAsArray)[0] = 1; stateData = (float8*) ARR_DATA_PTR(outArgs->stateAsArray); memset(stateData, 0, statelen * sizeof(float8)); stateData[0] = len; } /* * Contents of 'state' are as follows: * [0] = len(X[]) * [1] = count * [2] = sum(y) * [3] = sum(y*y) * [4:N] = sum(X'[] * y) * [N+1:M] = sum(X[] * X'[]) * N = 3 + len(X) * M = N + len(X)*len(X) */ outArgs->len = (float8*) ARR_DATA_PTR(outArgs->stateAsArray); outArgs->count = outArgs->len + 1; outArgs->sumy = outArgs->len + 2; outArgs->sumy2 = outArgs->len + 3; outArgs->Xty = outArgs->len + 4; outArgs->XtX = outArgs->len + 4 + len; /* It is an error if the number of indepent variables is not constant */ if (*outArgs->len != len) { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("transition function \"%s\" called with invalid parameters", format_procedure(fcinfo->flinfo->fn_oid)), errdetail("The independent-variable array is not of constant width."))); } /* Something is seriously fishy if our state has the wrong length */ if ((uint64) ARR_DIMS(outArgs->stateAsArray)[0] != statelen) { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("transition function \"%s\" called with invalid parameters", format_procedure(fcinfo->flinfo->fn_oid)))); } /* Okay... All's good now do the work */ return true; }
/* * Preliminary segment-level calculation function for multi-linear regression * aggregates. */ Datum float8_mregr_combine(PG_FUNCTION_ARGS) { ArrayType *state1, *state2, *result; float8 *state1Data, *state2Data, *resultData; uint32 len; uint64 statelen, i; Size size; /* We should be strict, but it doesn't hurt to be paranoid */ if (PG_ARGISNULL(0)) { if (PG_ARGISNULL(1)) PG_RETURN_NULL(); PG_RETURN_ARRAYTYPE_P(PG_GETARG_ARRAYTYPE_P(1)); } if (PG_ARGISNULL(1)) PG_RETURN_ARRAYTYPE_P(PG_GETARG_ARRAYTYPE_P(0)); state1 = PG_GETARG_ARRAYTYPE_P(0); state2 = PG_GETARG_ARRAYTYPE_P(1); /* Ensure that both arrays are single dimensional float8[] arrays */ if (ARR_NULLBITMAP(state1) || ARR_NULLBITMAP(state2) || ARR_NDIM(state1) != 1 || ARR_NDIM(state2) != 1 || ARR_ELEMTYPE(state1) != FLOAT8OID || ARR_ELEMTYPE(state2) != FLOAT8OID) { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("preliminary segment-level calculation function \"%s\" called with invalid parameters", format_procedure(fcinfo->flinfo->fn_oid)))); } /* * Remember that we initialized to {0}, so if either array is still at * the initial value then just return the other one */ if (ARR_DIMS(state1)[0] == 1) PG_RETURN_ARRAYTYPE_P(state2); if (ARR_DIMS(state2)[0] == 1) PG_RETURN_ARRAYTYPE_P(state1); state1Data = (float8*) ARR_DATA_PTR(state1); state2Data = (float8*) ARR_DATA_PTR(state2); if (ARR_DIMS(state1)[0] != ARR_DIMS(state2)[0] || state1Data[0] != state2Data[0]) { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("preliminary segment-level calculation function \"%s\" called with invalid parameters", format_procedure(fcinfo->flinfo->fn_oid)), errdetail("The independent-variable array is not of constant width."))); } len = state1Data[0]; statelen = STATE_LEN(len); /* * Violation of any of the following conditions indicates bogus inputs. */ if (state1Data[0] > UINT32_MAX || (uint64) ARR_DIMS(state1)[0] != statelen || !IS_FEASIBLE_STATE_LEN(statelen)) { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("preliminary segment-level calculation function \"%s\" called with invalid parameters", format_procedure(fcinfo->flinfo->fn_oid)))); } /* Validations pass, allocate memory for result and do work */ /* * Precondition: * IS_FEASIBLE_STATE_LEN(statelen) */ size = statelen * sizeof(float8) + ARR_OVERHEAD_NONULLS(1); result = (ArrayType *) palloc(size); SET_VARSIZE(result, size); result->ndim = 1; result->dataoffset = 0; result->elemtype = FLOAT8OID; ARR_DIMS(result)[0] = statelen; ARR_LBOUND(result)[0] = 1; resultData = (float8*) ARR_DATA_PTR(result); memset(resultData, 0, statelen * sizeof(float8)); /* * Contents of 'state' are as follows: * [0] = len(X[]) * [1] = count * [2] = sum(y) * [3] = sum(y*y) * [4:N] = sum(X'[] * y) * [N+1:M] = sum(X[] * X'[]) * N = 3 + len(X) * M = N + len(X)*len(X) */ resultData[0] = len; for (i = 1; i < statelen; i++) resultData[i] = state1Data[i] + state2Data[i]; PG_RETURN_ARRAYTYPE_P(result); }