Untitled

mail@pastecode.io avatar
unknown
plain_text
7 months ago
14 kB
5
Indexable
Never
#include "ExampleFunction.h"
#include <bits/stdc++.h>

// minimize 3*x^2 + 2*x*y + 2*y^2 + 7

ExampleFunction::ExampleFunction(wrapper::Placement& placement, GlobalPlacer& globalplacer)
    : _placement(placement), _globalplacer(globalplacer)
{
    bound_width = _placement.boundryRight() - _placement.boundryLeft();
    bound_height = _placement.boundryTop() - _placement.boundryBottom();
    core_area = bound_width * bound_height;
    num_modules = _placement.numModules();

    lambda = 0;
    eta = (bound_width + bound_height) / 100;
    // eta = 500;
    bin_cut = 15;

    grad.resize(num_modules * 2);
    x_exp.resize(num_modules * 4);

    bin_width = bound_width / bin_cut;
    bin_height = bound_height / bin_cut;
    bin_total_num = bin_cut * bin_cut;
    bin_area = bin_width * bin_height;
    bin_density.resize(bin_total_num);
    // binDensity.resize(bin_cut, vector<double>(bin_cut, 0.0));

    avg_density = 0.0;
    double total_area = 0;
    for (unsigned i = 0; i < num_modules; i++) {
        total_area += _placement.module(i).area();
    }
    avg_density = total_area / core_area;

    module_isPlaced = _globalplacer.module_isPlaced;
}

double ExampleFunction::calculateLSE_F(const vector<double>& x) {
    double total_LSE = 0.0;
    // LSE WL
    for (unsigned i = 0; i < num_modules; i++) {
        x_exp[4 * i] = exp(x[2 * i] / eta);
        x_exp[4 * i + 1] = exp(-x[2 * i] / eta);
        x_exp[4 * i + 2] = exp(x[2 * i + 1] / eta);
        x_exp[4 * i + 3] = exp(-x[2 * i + 1] / eta);
    }

    for (unsigned i = 0; i < _placement.numNets(); i++) {
        double sum_x1 = 0.0, sum_x2 = 0.0, sum_y1 = 0.0, sum_y2 = 0.0;

        for (unsigned j = 0; j < _placement.net(i).numPins(); j++) {
            int module_id = _placement.net(i).pin(j).moduleId();
            sum_x1 += x_exp[4 * module_id];
            sum_x2 += x_exp[4 * module_id + 1];
            sum_y1 += x_exp[4 * module_id + 2];
            sum_y2 += x_exp[4 * module_id + 3];
        }

        total_LSE += (log(sum_x1) + log(sum_x2) + log(sum_y1) + log(sum_y2));
        // total_LSE += (log(sum_x1) + log(sum_x2) + log(sum_y1) + log(sum_y2));
    }

    return eta * total_LSE;
}

double ExampleFunction::calculateLSE_FG(const vector<double>& x, vector<double>& g) {
    double total_LSE = 0.0;

    // LSE WL
    for (unsigned i = 0; i < num_modules; i++) {
        x_exp[4 * i] = exp(x[2 * i] / eta);
        x_exp[4 * i + 1] = exp(-x[2 * i] / eta);
        x_exp[4 * i + 2] = exp(x[2 * i + 1] / eta);
        x_exp[4 * i + 3] = exp(-x[2 * i + 1] / eta);
    }

    for (unsigned i = 0; i < _placement.numNets(); i++) {
        double sum_x1 = 0.0, sum_x2 = 0.0, sum_y1 = 0.0, sum_y2 = 0.0;

        for (unsigned j = 0; j < _placement.net(i).numPins(); j++) {
            int module_id = _placement.net(i).pin(j).moduleId();
            sum_x1 += x_exp[4 * module_id];
            sum_x2 += x_exp[4 * module_id + 1];
            sum_y1 += x_exp[4 * module_id + 2];
            sum_y2 += x_exp[4 * module_id + 3];
        }

        total_LSE += (log(sum_x1) + log(sum_x2) + log(sum_y1) + log(sum_y2));
        // total_LSE += (log(sum_x1) + log(sum_x2) + log(sum_y1) + log(sum_y2));

        for (unsigned j = 0; j < _placement.net(i).numPins(); j++) {
            int module_id = _placement.net(i).pin(j).moduleId();
            if (!_placement.module(module_id).isFixed()) {
                g[2 * module_id] += x_exp[4 * module_id] / (sum_x1);
                g[2 * module_id] -= x_exp[4 * module_id + 1] / (sum_x2);
                g[2 * module_id + 1] += x_exp[4 * module_id + 2] / (sum_y1);
                g[2 * module_id + 1] -= x_exp[4 * module_id + 3] / (sum_y2);

                // g[2 * module_id] += x_exp[4 * module_id] / (eta * sum_x1);
                // g[2 * module_id] -= x_exp[4 * module_id + 1] / (eta * sum_x2);
                // g[2 * module_id + 1] += x_exp[4 * module_id + 2] / (eta * sum_y1);
                // g[2 * module_id + 1] -= x_exp[4 * module_id + 3] / (eta * sum_y2);
            }
        }
    }

    // return total_LSE;
    return eta * total_LSE;
}


double ExampleFunction::calculateBinDensity_F(const vector<double>& x) {
    double total_bin_density = 0.0;
    if (lambda == 0) return total_bin_density;

    // bin density
    double boundary_left = _placement.boundryLeft(), boundary_bottom = _placement.boundryBottom();
    // bin_density.assign(bin_total_num, 0.0);

    // double m_w = 0.0, m_h = 0.0;
    // double c = 0.0;
    // double theta_x = 0.0, theta_y = 0.0, d_x = 0.0, d_y = 0.0, abs_d_x = 0.0, abs_d_y = 0.0, a_x = 0.0, b_x = 0.0, a_y = 0.0, b_y = 0.0;

    for (unsigned y_bin_id = 0; y_bin_id < bin_cut; y_bin_id++) {
        for (unsigned x_bin_id = 0; x_bin_id < bin_cut; x_bin_id++) {
            double bin_d = 0;

            for (unsigned i = 0; i < num_modules; i++) {
                const double m_w = _placement.module(i).width();
                const double m_h = _placement.module(i).height();

                if (!_placement.module(i).isFixed()) {
                    // c = _placement.module(i).area() / bin_area;

                    double d_x = _placement.module(i).centerX() - (((double)x_bin_id + 0.5) * bin_width + boundary_left);
                    double abs_d_x = abs(d_x);
                    
                    double d_y = _placement.module(i).centerY() - (((double)y_bin_id + 0.5) * bin_height + boundary_bottom);
                    double abs_d_y = abs(d_y);

                    double a_x = 4 / ((bin_width + m_w) * (2 * bin_width + m_w));
                    double b_x = 4 / (bin_width * (2 * bin_width + m_w));

                    double a_y = 4 / ((bin_height + m_h) * (2 * bin_height + m_h));
                    double b_y = 4 / (bin_height * (2 * bin_height + m_h));

                    double theta_x = (abs_d_x <= m_w / 2 + bin_width / 2) ? (1 - a_x * pow(abs_d_x, 2))
                        : (abs_d_x <= m_w / 2 + bin_width) ? (b_x * pow(abs_d_x - bin_width - m_w / 2, 2))
                        : 0;
                    double theta_y = (abs_d_y <= m_h / 2 + bin_height / 2) ? (1 - a_y * pow(abs_d_y, 2))
                        : (abs_d_y <= m_h / 2 + bin_height) ? (b_y * pow(abs_d_y - bin_height - m_h / 2, 2))
                        : 0;

                    // bin_density[x_bin_id + bin_cut * y_bin_id] += c * theta_x * theta_y;
                    bin_d += theta_x * theta_y;
                }
            }

            // total_bin_density += pow(bin_density[x_bin_id + bin_cut * y_bin_id] - avg_density, 2);
            // total_bin_density += pow(bin_density[x_bin_id + bin_cut * y_bin_id], 2);
            total_bin_density += pow(bin_d, 2);
        }
    }
    // cout << "Debug: bin density in F = " << total_bin_density << endl;
    return lambda * total_bin_density;
}

double ExampleFunction::calculateBinDensity_FG(const vector<double>& x, vector<double>& g) {
    double total_bin_density = 0.0;
    if (lambda == 0) return total_bin_density;

    // bin density
    double boundary_left = _placement.boundryLeft(), boundary_bottom = _placement.boundryBottom();
    // bin_density.assign(bin_total_num, 0.0);

    grad.assign(g.size(), 0.0);
    // double m_w = 0.0, m_h = 0.0;
    // double c = 0.0;
    // double theta_x = 0.0, theta_y = 0.0, d_x = 0.0, d_y = 0.0, abs_d_x = 0.0, abs_d_y = 0.0, a_x = 0.0, b_x = 0.0, a_y = 0.0, b_y = 0.0;

    for (unsigned y_bin_id = 0; y_bin_id < bin_cut; y_bin_id++) {
        for (unsigned x_bin_id = 0; x_bin_id < bin_cut; x_bin_id++) {
            // grad.assign(bin_total_num, 0.0);
            grad.assign(g.size(), 0.0);
            double bin_d = 0;

            for (unsigned i = 0; i < num_modules; i++) {
                double m_w = _placement.module(i).width();
                double m_h = _placement.module(i).height();

                if (!_placement.module(i).isFixed()) {
                    // c = _placement.module(i).area() / bin_area;

                    double d_x = _placement.module(i).centerX() - (((double)x_bin_id + 0.5) * bin_width + boundary_left);
                    // d_x = x[2 * i] - (((double)x_bin_id + 0.5) * bin_width + boundary_left);
                    double abs_d_x = abs(d_x);
                    double d_y = _placement.module(i).centerY() - (((double)y_bin_id + 0.5) * bin_height + boundary_bottom);
                    // d_y = x[2 * i + 1] - (((double)y_bin_id + 0.5) * bin_height + boundary_bottom);
                    double abs_d_y = abs(d_y);

                    double a_x = 4 / ((bin_width + m_w) * (2 * bin_width + m_w));
                    double b_x = 4 / (bin_width * (2 * bin_width + m_w));

                    double a_y = 4 / ((bin_height + m_h) * (2 * bin_height + m_h));
                    double b_y = 4 / (bin_height * (2 * bin_height + m_h));

                    double theta_x = (abs_d_x <= m_w / 2 + bin_width / 2) ? (1 - a_x * pow(abs_d_x, 2))
                        : (abs_d_x <= m_w / 2 + bin_width) ? (b_x * pow(abs_d_x - bin_width - m_w / 2, 2))
                        : 0;
                    double theta_y = (abs_d_y <= m_h / 2 + bin_height / 2) ? (1 - a_y * pow(abs_d_y, 2))
                        : (abs_d_y <= m_h / 2 + bin_height) ? (b_y * pow(abs_d_y - bin_height - m_h / 2, 2))
                        : 0;

                    // bin_density[x_bin_id + bin_cut * y_bin_id] += c * theta_x * theta_y;
                    // bin_d += c * theta_x * theta_y;
                    bin_d += theta_x * theta_y;

                    // if (!_placement.module(i).isFixed()) {
                    double sign_x = (d_x > 0) ? 1.0 : -1.0;
                    double sign_y = (d_y > 0) ? 1.0 : -1.0;
                    double theta_x_g = (abs_d_x <= m_w / 2 + bin_width / 2) ? (-2 * a_x * d_x)
                        : (abs_d_x <= m_w / 2 + bin_width) ? (2 * b_x * (d_x - bin_width - m_w / 2) * sign_x)
                        : 0;
                    double theta_y_g = (abs_d_y <= m_h / 2 + bin_height / 2) ? (-2 * a_y * d_y)
                        : (abs_d_y <= m_h / 2 + bin_height) ? (2 * b_y * (d_y - bin_height - m_h / 2) * sign_y)
                        : 0;

                    // grad[2 * i] += (abs_d_x <= m_w / 2 + bin_width / 2) ? (-2 * sign_x * c * a_x * abs_d_x * theta_y) : (abs_d_x <= m_w / 2 + bin_width) ? (2 * c * b_x * sign_x * (abs_d_x - m_w / 2 - bin_width) * theta_y) : 0;
                    // grad[2 * i + 1] += (abs_d_y <= m_h / 2 + bin_height / 2) ? (-2 * sign_y * c * a_y * abs_d_y * theta_x) : (abs_d_y <= m_h / 2 + bin_height) ? (2 * c * b_y * sign_y * (abs_d_y - m_h / 2 - bin_height) * theta_x) : 0;
                    // grad[2 * i] += (abs_d_x <= m_w / 2 + bin_width / 2) ? ((-2 * c * a_x * abs_d_x) * theta_y) : (abs_d_x <= m_w / 2 + bin_width) ? (2 * c * b_x * sign_x * (abs_d_x - m_w / 2 - bin_width) * theta_y) : 0;
                    // grad[2 * i + 1] += (abs_d_y <= m_h / 2 + bin_height / 2) ? ((-2 * c * a_y * abs_d_y) * theta_x) : (abs_d_y <= m_h / 2 + bin_height) ? (2 * c * b_y * sign_y * (abs_d_y - m_h / 2 - bin_height) * theta_x) : 0;
                    grad[2 * i] = theta_x_g * theta_y;
                    grad[2 * i + 1] = theta_x * theta_y_g;
                // }

                }
            }

            // total_bin_density += pow(bin_density[x_bin_id + bin_cut * y_bin_id] - avg_density, 2);
            total_bin_density += bin_d * bin_d;

            for (unsigned i = 0; i < num_modules; i++) {
                // g[2 * i] += lambda * 2 * (bin_density[x_bin_id + bin_cut * y_bin_id] - avg_density) * grad[2 * i];
                // g[2 * i + 1] += lambda * 2 * (bin_density[x_bin_id + bin_cut * y_bin_id] - avg_density) * grad[2 * i + 1];
                // g[2 * i] += lambda * 2 * (bin_density[x_bin_id + bin_cut * y_bin_id]) * grad[2 * i];
                // g[2 * i + 1] += lambda * 2 * (bin_density[x_bin_id + bin_cut * y_bin_id]) * grad[2 * i + 1];
                g[2 * i] += lambda * 2 * bin_d * grad[2 * i];
                g[2 * i + 1] += lambda * 2 * bin_d * grad[2 * i + 1];
            }

            // for (unsigned i = 0; i < num_modules; i++) {
            //     cout << "DEBUG: g[" << 2 * i << "] = " << g[2 * i] << endl;
            //     cout << "DEBUG: g[" << 2 * i + 1 << "] = " << g[2 * i + 1] << endl;
            // }
            // exit(0);
        }
    }
    // cout << "   Debug: bin density in FG = " << total_bin_density << endl;
    // cout << "   Debug: "
    return lambda * total_bin_density;
}

void ExampleFunction::evaluateFG(const vector<double>& x, double& f, vector<double>& g)
{
    // 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
    // cout << "Debug: evaluateFG is called\n";
    g.assign(g.size(), 0.0);
    // g = vector<double>(g.size(), 0);

    double LSE = calculateLSE_FG(x, g);
    double bin_density = calculateBinDensity_FG(x, g);

    if (bin_density != 0){
        // cout << "  Debug: calculateLSE_FG = " << LSE << endl;
        // cout << "  Debug: calculateBinDensity_FG = " << bin_density << endl;
    }

    f = LSE + bin_density;
}

void ExampleFunction::evaluateF(const vector<double>& x, double& f)
{
    // f = 3 * x[0] * x[0] + 2 * x[0] * x[1] + 2 * x[1] * x[1] + 7; // objective function
    // cout << "Debug: evaluateF is called\n";
    double LSE = calculateLSE_F(x);
    double bin_density = calculateBinDensity_F(x);

    if (bin_density != 0) {
        // cout << "  Debug: calculateLSE_F = " << LSE << endl;
        // cout << "  Debug: calculateBinDensity_F = " << bin_density << endl;
    }

    f = LSE + bin_density;
}

void ExampleFunction::increase_lambda() {
    int inc = 2500;
    lambda += inc;
    cout << "Debug: lambda increase " << inc << ", now = " << lambda << endl;
}

unsigned ExampleFunction::dimension()
{
    return 2 * num_modules; // num_blocks*2
    // each two dimension represent the X and Y dimensions of each block
}
Leave a Comment