double
Spacetime::IterateOptimization_discrete(void)
{	
	//----------------------------------------------------------------------------------------------//
	// clear the state and costate sequences from the last solver iteration							//
	//----------------------------------------------------------------------------------------------//

	setState(state_0);
	GSequence.clear();
	CSequence.clear();
	MSequence.clear();
	MInvSequence.clear();
	stateSequence.clear();
	costateSequence.clear();

	//----------------------------------------------------------------------------------------------//
	// compute the G, C, and M matrices for each timestep before the backwards sweep				//
	//----------------------------------------------------------------------------------------------//

	setState(state_0);
	stateSequence.push_back(state_0);
	for (int t = 0; t < numTimeSteps; t++) 
	{	
		// compute G, C, M, and MInv state matrices
		matrix<double> G = computeG_discrete();
		matrix<double> M = computeM_discrete();
		matrix<double> C = computeC_discrete();
		matrix<double> MInv = !M;
		
		// store G, C, M, and MInv state matrices
		GSequence.push_back(G);
		CSequence.push_back(C);
		MSequence.push_back(M);
		MInvSequence.push_back(MInv);
		
		// apply torque and advance system
		stepPhysics_discrete(uSequence[t]);
		
		// store current state
		stateSequence.push_back(getState());
	}

	//----------------------------------------------------------------------------------------------//
	// backwards sweep																				//
	//----------------------------------------------------------------------------------------------//

	// clear values from previous pass
	kSequence.clear();
	KSequence.clear();
	valueSequence.clear();

	// declare V derivative values
	matrix<double> Vx = -1.0 * ~(state_d - stateSequence[numTimeSteps-1]);
	matrix<double> Vxx = I(4);
	
	// backward pass
	double final_error = 0.5 * (~(state_d - stateSequence[numTimeSteps-1])*(state_d - stateSequence[numTimeSteps-1]))(0,0);
	valueSequence.push_back(final_error);
	for (int t = numTimeSteps-1; t >= 0; t--) 
	{
		// compute value V = cost-to-go function = 
		// sum of u^2 values for all successive timesteps + final error
		matrix<double> cost_t = ~uSequence[t]*uSequence[t];
		valueSequence.push_back(cost_t(0,0) + valueSequence[t]);

		// compute first derivative values at current timestep
		matrix<double> Lu = compute_Lu(t);
		matrix<double> Lx = compute_Lx(t);
		matrix<double> Fx = compute_Fx(t);
		matrix<double> Fu = compute_Fu(t);

		// compute second derivative values at current timestep
		matrix<double> Luu = compute_Luu(t);
		matrix<double> Lxx = compute_Lxx(t);
		matrix<double> Lux = compute_Lux(t);
		matrix<double> Lxu = compute_Lxu(t);
		std::vector<matrix<double>> Fuu = compute_Fuu(t);
		std::vector<matrix<double>> F*x = compute_Fux(t);
		std::vector<matrix<double>> Fxu = compute_Fxu(t);
		std::vector<matrix<double>> Fxx = compute_Fxx(t);

		// compute expansion coefficients for current timestep
		matrix<double> Qx = Lx + Vx*Fx;
		matrix<double> Qu = Lu + Vx*Fu;
		matrix<double> Qxx = Lxx + ~Fx*Vxx*Fx + vec2mat(vectorMatrixProduct(vectorTranspose(Fxx), ~Vx));
		matrix<double> Quu = Luu + ~Fu*Vxx*Fu + vec2mat(vectorMatrixProduct(vectorTranspose(Fuu), ~Vx));
		matrix<double> Qux = Lux + ~Fu*Vxx*Fx + vec2mat(vectorMatrixProduct(vectorTranspose(F*x), ~Vx));
		matrix<double> Qxu = Lxu + ~Fx*Vxx*Fu + vec2mat(vectorMatrixProduct(vectorTranspose(Fxu), ~Vx));

		// compute k and K terms for current timestep
		kSequence.push_back(-(!Quu)*(~Qu));
		KSequence.push_back(-(!Quu)*Qux);

		// compute Vx and Vxx terms for current timestep
		Vx  = Qx  - Qu*!Quu*Qux;
		Vxx = Qxx - Qxu*!Quu*Qux;
	}

	// reverse sequences for forward pass
	std::reverse(kSequence.begin(), KSequence.end());
	std::reverse(KSequence.begin(), KSequence.end());
	std::reverse(valueSequence.begin(), valueSequence.end());

	// forward pass
	std::vector<matrix<double>> xHatSequence;
	std::vector<matrix<double>> uHatSequence;
	xHatSequence.push_back(state_0);
	for (int t = 0; t < numTimeSteps; t++) {

		// compute uHat
		matrix<double> uHat = uSequence[t] + kSequence[t] + KSequence[t]*(xHatSequence[t] - stateSequence[t]);
		uHatSequence.push_back(uHat);
		
		// compute next xHat
		matrix<double> xHat = F(xHatSequence[t], uHat);
		xHatSequence.push_back(xHat);
	}

	double uDiff = SSDvector(uSequence, uHatSequence);
	stateSequence = xHatSequence;
	uSequence = uHatSequence;
	return uDiff;
}
示例#2
0
void FSISPOptimizerOLD::calculateFunctionBenefitsWithSCFGProperties(ControlFlowGraph scfg)
{
	// get node property structures
	property_map<ControlFlowGraph, nodetype_t>::type scfg_nodeTypeNProp = get(nodetype_t(), scfg);
	property_map<ControlFlowGraph, startaddr_t>::type scfg_startAddrNProp = get(startaddr_t(), scfg);
//	property_map<ControlFlowGraph, startaddrstring_t>::type scfg_startAddrStringNProp = get(startaddrstring_t(), scfg); // unused
//	property_map<ControlFlowGraph, bbsize_t>::type scfg_bbSizeNProp = get(bbsize_t(), scfg); // unused
//	property_map<ControlFlowGraph, calllabel_t>::type scfg_calllabel_t = get(calllabel_t(), scfg); // unused

	// get edge property structures
	property_map<ControlFlowGraph, cost_t>::type scfg_costEProp = get(cost_t(), scfg);
	property_map<ControlFlowGraph, cost_onchip_t>::type scfg_costOnChipEProp = get(cost_onchip_t(), scfg);
	property_map<ControlFlowGraph, cost_offchip_t>::type scfg_costOffChipEProp = get(cost_offchip_t(), scfg);
	property_map<ControlFlowGraph, mem_penalty_t>::type scfg_memPenaltyEProp = get(mem_penalty_t(), scfg);
	property_map<ControlFlowGraph, activation_t>::type scfg_actEProp = get(activation_t(), scfg);

	cfgVertexIter vp;
	cfgOutEdgeIter epo;
	cfgInEdgeIter epi;
	CFGVertex v;
	CFGEdge e;

	LOG_DEBUG(logger, function_data.size() << " functions found.");
	// cycle through all vertices of the supergraph and set the max flow (activation count) and the costs for each basic block for each function (stored in function_data) 
	for(vp = vertices(scfg); vp.first != vp.second; ++vp.first)
	{
		v = *vp.first;

		if(get(scfg_nodeTypeNProp, v) == BasicBlock)
		{
			uint32_t bb_addr = get(scfg_startAddrNProp, v);
			uint32_t affiliated_function=0;

			bool block_found = false;
			// assign the wcet costs for that block to the function it belongs to
			for(uint32_t i = 0; i < function_data.size(); i++)
			{
				if((bb_addr >= function_data[i].address) && (function_data[i].end_address > bb_addr))
				{

					block_found = true;
					LOG_DEBUG(logger, "Assigning block cost of bb: 0x" << hex << bb_addr << "  for function " <<  function_data[i].name);
					affiliated_function = i;
					break;
				}
			}

			assert(block_found);

			for(epo = out_edges(v, scfg); epo.first != epo.second; ++epo.first) 
			{
				e = *epo.first;
				uint32_t cur_cost = get(scfg_costEProp, e);
				uint32_t off_cost = get(scfg_costOffChipEProp, e);
				uint32_t on_cost = get(scfg_costOnChipEProp, e);
				uint32_t mem_penalty = get(scfg_memPenaltyEProp, e);
				uint32_t activation_count = get(scfg_actEProp,e);

				switch((analysis_metric_t) conf->getUint(CONF_USE_METRIC))
				{
					case WCET_RATIO_FILES:
					case WCET:
						{
							function_data[affiliated_function].cur_cost += activation_count * cur_cost;
							function_data[affiliated_function].offchip_cost += activation_count * off_cost;
							function_data[affiliated_function].onchip_cost += activation_count * on_cost;
							assert(mem_penalty == (off_cost - on_cost));
							function_data[affiliated_function].benefit += activation_count * (off_cost - on_cost);
							break;
						}
					case MDIC:
						{
							function_data[affiliated_function].cur_cost += activation_count * cur_cost;
							function_data[affiliated_function].offchip_cost += activation_count * off_cost;
							function_data[affiliated_function].onchip_cost += activation_count * on_cost;
							function_data[affiliated_function].benefit += function_data[affiliated_function].cur_cost;
							break;
						}
					case MPL:
						{
							function_data[affiliated_function].cur_cost += cur_cost;
							function_data[affiliated_function].offchip_cost += off_cost;
							function_data[affiliated_function].onchip_cost += on_cost;
							function_data[affiliated_function].benefit += function_data[affiliated_function].cur_cost;
							// this method is _not_ to be used, so fall down to assert(false)
//							break; 
						}
					default:
						{
							assert(false);
						}
				}

			}
		}
	}

	LOG_DEBUG(logger, function_data.size() << " functions found.");
	
	for(uint32_t i = 0; i < function_data.size(); i++)
	{
		LOG_DEBUG(logger, "Function id: " << function_data[i].id << " name: " << function_data[i].name << " addr: 0x" << hex << function_data[i].address << " end addr: 0x" << function_data[i].end_address << " size: "  << dec << function_data[i].size << " on/offchip cost: " << function_data[i].onchip_cost << "/" << function_data[i].offchip_cost << " benefit: " << function_data[i].benefit);
	} 
}