Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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;
}
Esempio n. 4
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;
}
Esempio n. 5
0
/*
 * 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);
}