ExampleFunction.cpp

 avatar
user_9702121
c_cpp
7 months ago
12 kB
3
Indexable
Never
#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;
}
Leave a Comment