ExampleFunction.cpp
user_9702121
c_cpp
2 years ago
12 kB
12
Indexable
#include "ExampleFunction.h"
#include <cmath>
// minimize 3*x^2 + 2*x*y + 2*y^2 + 7
ExampleFunction::ExampleFunction(wrapper::Placement &_placement, double Eta, double Beta, int BinDiv) :placement(_placement)
{
printf("numModules %d \n", _placement.numModules()) ;
// for(unsigned int i = 0; i < _placement.numModules(); i++) {
// cout << _placement.module(i).name() << " " << _placement.module(i).x() << " " << _placement.module(i).y() << endl;
// }
// std::cout << _placement.numModules();
eta = Eta;
paras.assign(placement.numModules() * 4, 0);
ci.assign(placement.numModules(), 0);
beta = Beta;
avDens = 0.0;
binDiv = BinDiv;
numBins = binDiv * binDiv;
binH = (placement.boundryTop() - placement.boundryBottom()) / binDiv;
binW = (placement.boundryRight() - placement.boundryLeft()) / binDiv;
binSize = binH * binW;
bins.resize(numBins);
cout << "chip height: " << (placement.boundryTop() - placement.boundryBottom()) << endl;
cout << "chip width: " << (placement.boundryRight() - placement.boundryLeft()) << endl;
cout << "chip left bottom: " << placement.boundryLeft() << " " << placement.boundryBottom() << endl;
cout << "bin height: " << binH << '\n';
cout << "bin width: " << binW << '\n';
for(unsigned int i = 0; i < binDiv; i++) {
for(unsigned int j = 0; j < binDiv; j++) {
bins[i * binDiv + j].xb = (1 + j * 2) * (binW / 2) + placement.boundryLeft();
bins[i * binDiv + j].yb = (1 + i * 2) * (binH / 2) + placement.boundryBottom();
// cout << "bin center " << i * binDiv + j << " : " << bins[i * binDiv + j].xb << " " << bins[i * binDiv + j].yb << endl;
}
}
for(unsigned int i = 0; i < placement.numModules(); i++) {
avDens += placement.module(i).area();
}
avDens /= (placement.boundryRight() - placement.boundryLeft()) * (placement.boundryTop() - placement.boundryBottom());
cout << binSize << '\n';
}
void ExampleFunction::thetaX(int binID, int moduleID, double &thetaXF, double &thetaXG, const vector<double> &x) {
double moduleW = placement.module(moduleID).width();
// double moduleX = placement.module(moduleID).x();
double moduleX = x[2 * moduleID];
double a = 4/((binW + moduleW) * (2 * binW + moduleW)); //a = 4/((wb + wi)(2wb + wi))
double b = 4/(binW * (2 * binW + moduleW)); // b = 4/(wb(2wb + wi))
double signedDx = (moduleX - bins[binID].xb);
double dx = abs(moduleX - bins[binID].xb); //dx = |xi - xb|
if(0 <= dx && dx <= binW/2 + moduleW/2) {
thetaXF = 1 - a * (dx * dx);
if(signedDx > 0)
thetaXG = -2 * a * dx;
else
thetaXG = 2 * b * (dx - binW - moduleW/2);
}
else if(binW/2 + moduleW/2 <= dx && dx <= binW + moduleW/2) {
thetaXF = b * (dx - binW - moduleW/2) * (dx - binW - moduleW/2);
if(signedDx > 0)
thetaXG = 2 * b * (dx - binW - moduleW/2);
else
thetaXG = -2 * b * (dx - binW - moduleW/2);
// thetaXG = 2 * b * (dx - binW - moduleW/2);
}
else{
thetaXF = 0;
thetaXG = 0;
}
}
void ExampleFunction::thetaY(int binID, int moduleID, double &thetaYF, double &thetaYG, const vector<double> &x) {
double moduleH = placement.module(moduleID).height();
// double moduleY = placement.module(moduleID).y();
double moduleY = x[2 * moduleID + 1];
double a = 4/((binH + moduleH) * (2 * binH + moduleH)); //a = 4/((hb + hi)(2hb + hi))
double b = 4/(binH * (2 * binH + moduleH)); // b = 4/(hb(2hb + hi))
double signedDy = moduleY - bins[binID].yb;
double dy = abs(moduleY - bins[binID].yb); // dy = |yi - hb|
if(0 <= dy && dy <= binH/2 + moduleH/2) {
thetaYF = 1 - a * (dy * dy);
if(signedDy > 0)
thetaYG = -2 * a * dy;
else
thetaYG = 2 * b * (dy - binW - moduleH/2);
}
else if(binH/2 + moduleH/2 <= dy && dy <= binH + moduleH/2) {
thetaYF = b * (dy - binH - moduleH/2) * (dy - binH - moduleH/2);
if(signedDy > 0)
thetaYG = 2 * b * (dy - binH - moduleH/2);
else
thetaYG = -2 * b * (dy - binH - moduleH/2);
// thetaYG = 2 * b * (dy - binH - moduleH/2);
}
else{
thetaYF = 0;
thetaYG = 0;
}
}
void ExampleFunction::thetaX(int binID, int moduleID, double &thetaXF, const vector<double> &x) {
double moduleW = placement.module(moduleID).width();
// double moduleX = placement.module(moduleID).x();
double moduleX = x[2 * moduleID];
double a = 4/((binW + moduleW) * (2 * binW + moduleW)); //a = 4/((wb + wi)(2wb + wi))
double b = 4/(binW * (2 * binW + moduleW)); // b = 4/(wb(2wb + wi))
double dx = abs(moduleX - bins[binID].xb); //dx = |xi - xb|
if(0 <= dx && dx <= binW/2 + moduleW/2) {
thetaXF = 1 - a * (dx * dx);
}
else if(binW/2 + moduleW/2 <= dx && dx <= binW + moduleW/2) {
thetaXF = b * (dx - binW - moduleW/2) * (dx - binW - moduleW/2);
}
else{
thetaXF = 0;
}
}
void ExampleFunction::thetaY(int binID, int moduleID, double &thetaYF, const vector<double> &x) {
double moduleH = placement.module(moduleID).height();
// double moduleY = placement.module(moduleID).y();
double moduleY = x[2 * moduleID + 1];
double a = 4/((binH + moduleH) * (2 * binH + moduleH)); //a = 4/((hb + hi)(2hb + hi))
double b = 4/(binH * (2 * binH + moduleH)); // b = 4/(hb(2hb + hi))
double dy = abs(moduleY - bins[binID].yb); // dy = |yi - hb|
if(0 <= dy && dy <= binH/2 + moduleH/2) {
thetaYF = 1 - a * (dy * dy);
}
else if(binH/2 + moduleH/2 <= dy && dy <= binH + moduleH/2) {
thetaYF = b * (dy - binH - moduleH/2) * (dy - binH - moduleH/2);
}
else {
thetaYF = 0;
}
}
void ExampleFunction::ComputeCi(const vector<double> &x) {
for(uint i = 0; i < placement.numModules(); i++) {
ci[i] = 0.0;
double unNormOverlap = 0.0;
for(uint j = 0; j < numBins; j++) {
double thetaXValue = 0.0;
double thetaYValue = 0.0;
thetaX(j, i, thetaXValue, x);
thetaY(j, i, thetaYValue, x);
unNormOverlap += thetaXValue * thetaYValue;
}
ci[i] = placement.module(i).area() / unNormOverlap;
}
}
void ExampleFunction::evaluateFG(const vector<double> &x, double &f, vector<double> &g)
{
// for LSE
f = 0.0;
g.assign(2 * placement.numModules(), 0);
for(uint i = 0; i < numBins; i++) {
bins[i].binDens = 0.0;
}
for(unsigned int i = 0; i < placement.numModules(); i++) {
paras[4 * i] = exp(x[2 * i]/eta); //exp(xk/eta)
paras[4 * i + 1] = exp(-x[2 * i]/eta); //exp(-xk/eta)
paras[4 * i + 2] = exp(x[2 * i + 1]/eta); //exp(yk/eta)
paras[4 * i + 3] = exp(-x[2 * i + 1]/eta); //exp(-yk/eta)
}
for(unsigned int i = 0; i < placement.numNets(); i++) {
double sumx = 0.0, minusSumx = 0.0, sumy = 0.0, minusSumy = 0.0;
for(unsigned int j = 0; j < placement.net(i).numPins(); j++) {
unsigned int moduleID = placement.net(i).pin(j).moduleId();
sumx += paras[4 * moduleID]; //sum(exp(xk/eta))
minusSumx += paras[4 * moduleID + 1]; //sum(exp(-xk/eta))
sumy += paras[4 * moduleID + 2]; //sum(exp(yk/eta))
minusSumy += paras[4 * moduleID + 3]; //sum(exp(-yk/eta))
if(placement.module(moduleID).isFixed()) {
continue;
}
else {
g[2 * moduleID] += paras[4 * moduleID]/sumx;
g[2 * moduleID] += -paras[4 * moduleID + 1]/minusSumx;
g[2 * moduleID + 1] += paras[4 * moduleID + 2]/sumy;
g[2 * moduleID + 1] += -paras[4 * moduleID + 3]/minusSumy;
}
}
f += eta * (log(sumx) + log(minusSumx) + log(sumy) + log(minusSumy));
}
//density
// ComputeCi(x);
for(uint i = 0; i < numBins; i++) {
vector<double> tempG;
tempG.assign(placement.numModules() * 2, 0);
for(uint j = 0; j < placement.numModules(); j++) {
double thetaXValue = 0.0;
double thetaYValue = 0.0;
double thetaXG = 0.0;
double thetaYG = 0.0;
thetaX(j, i, thetaXValue, thetaXG, x);
thetaX(j, i, thetaYValue, thetaYG, x);
if(!placement.module(j).isFixed()) {
tempG[2 * j] += thetaXG * thetaYValue;
tempG[2 * j + 1] += thetaXValue * thetaYG;
}
bins[i].binDens += thetaXValue * thetaYValue;
}
// cout << "bins " << i << " dens: " << bins[i].binDens << " bin Size: " << binW * binH << " utilzation: " << bins[i].binDens/binSize << '\n';
f += beta * bins[i].binDens * bins[i].binDens;
// cout << "bins[0].binDens " << bins[i].binDens << '\n';
for(uint j = 0; j < placement.numModules(); j++) {
g[2 * j] += 2 * beta * bins[i].binDens * tempG[2 * j];
g[2 * j + 1] += 2 * beta * bins[i].binDens * tempG[2 * j + 1];
}
}
cout << "f: " << f << endl;
for(uint i = 0; i < numBins; i++) {
cout << "bin" << i << ": " << bins[i].binDens << endl;
}
///////////////////////////////////example
f = 3 * x[0] * x[0] + 2 * x[0] * x[1] + 2 * x[1] * x[1] + 7; // objective function
g[0] = 6 * x[0] + 2 * x[1]; // gradient function of X
g[1] = 2 * x[0] + 4 * x[1]; // gradient function of Y
}
void ExampleFunction::evaluateF(const vector<double> &x, double &f)
{
// for LSE
f = 0.0;
for(uint i = 0; i < numBins; i++) {
bins[i].binDens = 0.0;
}
for(unsigned int i = 0; i < placement.numModules(); i++) {
paras[4 * i] = exp(x[2 * i]/eta); //exp(xk/eta)
paras[4 * i + 1] = exp(-x[2 * i]/eta); //exp(-xk/eta)
paras[4 * i + 2] = exp(x[2 * i + 1]/eta); //exp(yk/eta)
paras[4 * i + 3] = exp(-x[2 * i + 1]/eta); //exp(-yk/eta)
}
for(unsigned int i = 0; i < placement.numNets(); i++) {
double sumx = 0.0, minusSumx = 0.0, sumy = 0.0, minusSumy = 0.0;
for(unsigned int j = 0; j < placement.net(i).numPins(); j++) {
unsigned int moduleID = placement.net(i).pin(j).moduleId();
sumx += paras[4 * moduleID]; //sum(exp(xk/eta))
minusSumx += paras[4 * moduleID + 1]; //sum(exp(-xk/eta))
sumy += paras[4 * moduleID + 2]; //sum(exp(yk/eta))
minusSumy += paras[4 * moduleID + 3]; //sum(exp(-yk/eta))
}
f += eta * (log(sumx) + log(minusSumx) + log(sumy) + log(minusSumy));
}
//density
// ComputeCi(x);
for(uint i = 0; i < numBins; i++) {
for(uint j = 0; j < placement.numModules(); j++) {
double thetaXValue = 0.0;
double thetaYValue = 0.0;
double thetaXG = 0.0;
double thetaYG = 0.0;
thetaX(j, i, thetaXValue, thetaXG, x);
thetaX(j, i, thetaYValue, thetaYG, x);
bins[i].binDens += thetaXValue * thetaYValue;
}
// cout << "bins " << i << " dens: " << bins[i].binDens << " bin Size: " << binW * binH << " utilzation: " << bins[i].binDens/binSize << '\n';
// cout << "target: " << binSize << endl;
f += beta * bins[i].binDens * bins[i].binDens;
}
// cout << "evaluateF: " << f << '\n';
}
unsigned ExampleFunction::dimension()
{
return placement.numModules()*2; // num_blocks*2
// each two dimension represent the X and Y dimensions of each block
// return 2;
}
Editor is loading...
Leave a Comment