110448Snilay@cs.wisc.edu/* Copyright (c) 2012 Massachusetts Institute of Technology
210448Snilay@cs.wisc.edu *
310448Snilay@cs.wisc.edu * Permission is hereby granted, free of charge, to any person obtaining a copy
410448Snilay@cs.wisc.edu * of this software and associated documentation files (the "Software"), to deal
510448Snilay@cs.wisc.edu * in the Software without restriction, including without limitation the rights
610448Snilay@cs.wisc.edu * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
710448Snilay@cs.wisc.edu * copies of the Software, and to permit persons to whom the Software is
810448Snilay@cs.wisc.edu * furnished to do so, subject to the following conditions:
910448Snilay@cs.wisc.edu *
1010448Snilay@cs.wisc.edu * The above copyright notice and this permission notice shall be included in
1110448Snilay@cs.wisc.edu * all copies or substantial portions of the Software.
1210448Snilay@cs.wisc.edu *
1310448Snilay@cs.wisc.edu * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1410448Snilay@cs.wisc.edu * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1510448Snilay@cs.wisc.edu * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1610448Snilay@cs.wisc.edu * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1710448Snilay@cs.wisc.edu * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1810448Snilay@cs.wisc.edu * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
1910448Snilay@cs.wisc.edu * THE SOFTWARE.
2010448Snilay@cs.wisc.edu */
2110448Snilay@cs.wisc.edu
2210447Snilay@cs.wisc.edu
2310447Snilay@cs.wisc.edu#include "model/optical_graph/OpticalGraph.h"
2410447Snilay@cs.wisc.edu
2510447Snilay@cs.wisc.edu#include "model/OpticalModel.h"
2610447Snilay@cs.wisc.edu#include "model/optical_graph/OpticalNode.h"
2710447Snilay@cs.wisc.edu#include "model/optical_graph/OpticalLaser.h"
2810447Snilay@cs.wisc.edu#include "model/optical_graph/OpticalModulator.h"
2910447Snilay@cs.wisc.edu#include "model/optical_graph/OpticalFilter.h"
3010447Snilay@cs.wisc.edu#include "model/optical_graph/OpticalDetector.h"
3110447Snilay@cs.wisc.edu#include "model/optical_graph/OpticalWavelength.h"
3210447Snilay@cs.wisc.edu
3310447Snilay@cs.wisc.edunamespace DSENT
3410447Snilay@cs.wisc.edu{
3510447Snilay@cs.wisc.edu    // Initialize the next visited number to be one above the initial number
3610447Snilay@cs.wisc.edu    // used by OpticalNode
3710447Snilay@cs.wisc.edu    int OpticalGraph::msTreeNum = OpticalNode::OPTICAL_NODE_INIT_VISITED_NUM + 1;
3810447Snilay@cs.wisc.edu
3910447Snilay@cs.wisc.edu    OpticalGraph::OpticalGraph(const String& instance_name_, OpticalModel* model_)
4010447Snilay@cs.wisc.edu        : m_instance_name_(instance_name_), m_model_(model_)
4110447Snilay@cs.wisc.edu    {
4210447Snilay@cs.wisc.edu
4310447Snilay@cs.wisc.edu    }
4410447Snilay@cs.wisc.edu
4510447Snilay@cs.wisc.edu    OpticalGraph::~OpticalGraph()
4610447Snilay@cs.wisc.edu    {
4710447Snilay@cs.wisc.edu
4810447Snilay@cs.wisc.edu    }
4910447Snilay@cs.wisc.edu
5010447Snilay@cs.wisc.edu    const String& OpticalGraph::getInstanceName() const
5110447Snilay@cs.wisc.edu    {
5210447Snilay@cs.wisc.edu        return m_instance_name_;
5310447Snilay@cs.wisc.edu    }
5410447Snilay@cs.wisc.edu
5510447Snilay@cs.wisc.edu    //-------------------------------------------------------------------------
5610447Snilay@cs.wisc.edu    // Perform Datapath power optimization
5710447Snilay@cs.wisc.edu    //-------------------------------------------------------------------------
5810447Snilay@cs.wisc.edu    bool OpticalGraph::performPowerOpt(OpticalNode* node_, const WavelengthGroup& wavelengths_, unsigned int number_detectors_, double util_)
5910447Snilay@cs.wisc.edu    {
6010447Snilay@cs.wisc.edu        // Total number of iterations
6110447Snilay@cs.wisc.edu        unsigned int number_iterations = 1250;
6210447Snilay@cs.wisc.edu        // Maximum IL + ER
6310447Snilay@cs.wisc.edu        double IL_ER_max = 10;
6410447Snilay@cs.wisc.edu        // Figure out the step size used in the sweep
6510447Snilay@cs.wisc.edu        double step = (double) (IL_ER_max / sqrt(2 * number_iterations));
6610447Snilay@cs.wisc.edu
6710447Snilay@cs.wisc.edu        // Assume it is possible
6810447Snilay@cs.wisc.edu        bool possible = true;
6910447Snilay@cs.wisc.edu
7010447Snilay@cs.wisc.edu        // Begin optical data path power optimization
7110447Snilay@cs.wisc.edu        Log::printLine(getInstanceName() + " -> Beginning optical data path power optimization");
7210447Snilay@cs.wisc.edu
7310447Snilay@cs.wisc.edu        // Trace the specified wavelengths
7410447Snilay@cs.wisc.edu        OpticalWavelength* wavelength = traceWavelength(wavelengths_, node_);
7510447Snilay@cs.wisc.edu
7610447Snilay@cs.wisc.edu        // For each data path found in the wavelength
7710447Snilay@cs.wisc.edu        const vector<OpticalDataPath>* data_paths = wavelength->getDataPaths();
7810447Snilay@cs.wisc.edu        for (unsigned int i = 0; i < data_paths->size(); ++i)
7910447Snilay@cs.wisc.edu        {
8010447Snilay@cs.wisc.edu            const OpticalDataPath& data_path = data_paths->at(i);
8110447Snilay@cs.wisc.edu            // Default to worst possible modulator
8210447Snilay@cs.wisc.edu            double best_power = 1e99;
8310447Snilay@cs.wisc.edu            double best_IL = IL_ER_max - step;
8410447Snilay@cs.wisc.edu            double best_ER = step;
8510447Snilay@cs.wisc.edu
8610447Snilay@cs.wisc.edu            // Perform power optimization for this data path
8710447Snilay@cs.wisc.edu            Log::printLine(getInstanceName() + " -> Optimize data path - Laser = " + data_path.laser->getInstanceName()
8810447Snilay@cs.wisc.edu                + ", Modulator = " + data_path.modulator->getInstanceName());
8910447Snilay@cs.wisc.edu
9010447Snilay@cs.wisc.edu            if (data_path.modulator->canOptimizeLoss())
9110447Snilay@cs.wisc.edu            {
9210447Snilay@cs.wisc.edu                // Iterate over IL and ER to find optimal set of IL and ER
9310447Snilay@cs.wisc.edu                for (double IL = step; IL < IL_ER_max; IL += step)
9410447Snilay@cs.wisc.edu                {
9510447Snilay@cs.wisc.edu                    for (double ER = step; ER <= (IL_ER_max - IL); ER += step)
9610447Snilay@cs.wisc.edu                    {
9710447Snilay@cs.wisc.edu                        // Ask the modulator to try this new ER and IL
9810447Snilay@cs.wisc.edu                        bool success = data_path.modulator->setModulatorSpec(IL, ER);
9910447Snilay@cs.wisc.edu                        // If the modulator was successful
10010447Snilay@cs.wisc.edu                        if (success)
10110447Snilay@cs.wisc.edu                        {
10210447Snilay@cs.wisc.edu                            double laser_power = wavelength->getLaserPower(number_detectors_);
10310447Snilay@cs.wisc.edu                            double modulator_power = data_path.modulator->getPower(util_);
10410447Snilay@cs.wisc.edu                            double total_power = laser_power + modulator_power;
10510447Snilay@cs.wisc.edu                            // If this is the new lowest power point
10610447Snilay@cs.wisc.edu                            if (total_power < best_power)
10710447Snilay@cs.wisc.edu                            {
10810447Snilay@cs.wisc.edu                                best_power = total_power;
10910447Snilay@cs.wisc.edu                                best_IL = IL;
11010447Snilay@cs.wisc.edu                                best_ER = ER;
11110447Snilay@cs.wisc.edu                            }
11210447Snilay@cs.wisc.edu                        }
11310447Snilay@cs.wisc.edu                    }
11410447Snilay@cs.wisc.edu                }
11510447Snilay@cs.wisc.edu
11610447Snilay@cs.wisc.edu                // Set IL and ER to the best ones we found
11710447Snilay@cs.wisc.edu                bool success = data_path.modulator->setModulatorSpec(best_IL, best_ER);
11810447Snilay@cs.wisc.edu                // If the best one we found was still not possible...
11910447Snilay@cs.wisc.edu                possible = possible && success;
12010447Snilay@cs.wisc.edu
12110447Snilay@cs.wisc.edu                // Print best IL and ER
12210447Snilay@cs.wisc.edu                Log::printLine(getInstanceName() + " -> Best IL=" + (String) best_IL + ", Best ER=" + (String) best_ER +
12310447Snilay@cs.wisc.edu                    ", Best Laser/Mod Power=" + (String) best_power);
12410447Snilay@cs.wisc.edu            }
12510447Snilay@cs.wisc.edu            else
12610447Snilay@cs.wisc.edu            {
12710447Snilay@cs.wisc.edu                // Perform power optimization for this data path
12810447Snilay@cs.wisc.edu                Log::printLine(getInstanceName() + " -> Data path not set to allow optimization");
12910447Snilay@cs.wisc.edu            }
13010447Snilay@cs.wisc.edu        }
13110447Snilay@cs.wisc.edu
13210447Snilay@cs.wisc.edu        // End optical data path power optimization
13310447Snilay@cs.wisc.edu        Log::printLine(getInstanceName() + " -> End optical data path power optimization");
13410447Snilay@cs.wisc.edu
13510447Snilay@cs.wisc.edu        delete wavelength;
13610447Snilay@cs.wisc.edu        return possible;
13710447Snilay@cs.wisc.edu    }
13810447Snilay@cs.wisc.edu
13910447Snilay@cs.wisc.edu
14010447Snilay@cs.wisc.edu    //-------------------------------------------------------------------------
14110447Snilay@cs.wisc.edu    // Trace wavelength(s), returning a wavelength data structure
14210447Snilay@cs.wisc.edu    //-------------------------------------------------------------------------
14310447Snilay@cs.wisc.edu    OpticalWavelength* OpticalGraph::traceWavelength(const WavelengthGroup& wavelengths_, OpticalNode* node_)
14410447Snilay@cs.wisc.edu    {
14510447Snilay@cs.wisc.edu        setTreeNum(getTreeNum() + 1);
14610447Snilay@cs.wisc.edu        OpticalWavelength* wavelength = new OpticalWavelength("TraceWavelength", wavelengths_);
14710447Snilay@cs.wisc.edu        return traceWavelength(wavelength, node_, NULL, NULL, 0.0);
14810447Snilay@cs.wisc.edu    }
14910447Snilay@cs.wisc.edu
15010447Snilay@cs.wisc.edu    OpticalWavelength* OpticalGraph::traceWavelength(OpticalWavelength* wavelength_, OpticalNode* node_, OpticalLaser* laser_, OpticalModulator* modulator_, double loss_)
15110447Snilay@cs.wisc.edu    {
15210447Snilay@cs.wisc.edu        // If the node has already been visited, don't do anything!
15310447Snilay@cs.wisc.edu        if (node_->getVisitedNum() != getTreeNum())
15410447Snilay@cs.wisc.edu        {
15510447Snilay@cs.wisc.edu            // Set the new parity for this node
15610447Snilay@cs.wisc.edu            node_->setVisitedNum(getTreeNum());
15710447Snilay@cs.wisc.edu
15810447Snilay@cs.wisc.edu            // Calculate the loss of the current path
15910447Snilay@cs.wisc.edu            double current_loss = loss_ + node_->getLoss();
16010447Snilay@cs.wisc.edu            // Check if the current node is a laser, modulator or detector
16110447Snilay@cs.wisc.edu            if(node_->getType() == OpticalNode::LASER)
16210447Snilay@cs.wisc.edu            {
16310447Snilay@cs.wisc.edu                // Set the laser lighting up the wavelength
16410447Snilay@cs.wisc.edu                ASSERT(laser_ == NULL, "[Error] " + getInstanceName() + " -> Multiple " +
16510447Snilay@cs.wisc.edu                    "Lasers lighting up the wavelength!");
16610447Snilay@cs.wisc.edu                laser_ = (OpticalLaser*) node_;
16710447Snilay@cs.wisc.edu            }
16810447Snilay@cs.wisc.edu            else if (node_->getType() == OpticalNode::MODULATOR)
16910447Snilay@cs.wisc.edu            {
17010447Snilay@cs.wisc.edu                // Check that the path already lit up by a laser and there are no
17110447Snilay@cs.wisc.edu                // modulators already driving data
17210447Snilay@cs.wisc.edu                ASSERT(laser_ != NULL, "[Error] " + getInstanceName() + " -> Wavelength reaches a " +
17310447Snilay@cs.wisc.edu                    "modulator (" + node_->getInstanceName() + ") prior to being lit up by a laser!");
17410447Snilay@cs.wisc.edu                ASSERT(modulator_ == NULL, "[Error] " + getInstanceName() + " -> Two modulators are driving" +
17510447Snilay@cs.wisc.edu                    " the same optical data path (" + node_->getInstanceName() + ")!");
17610447Snilay@cs.wisc.edu                modulator_ = (OpticalModulator*) node_;
17710447Snilay@cs.wisc.edu            }
17810447Snilay@cs.wisc.edu            else if (node_->getType() == OpticalNode::DETECTOR)
17910447Snilay@cs.wisc.edu            {
18010447Snilay@cs.wisc.edu                // Check that the path is both lit up by a laser and there is
18110447Snilay@cs.wisc.edu                // a modulator driving data
18210447Snilay@cs.wisc.edu                ASSERT(laser_ != NULL, "[Error] " + getInstanceName() + " -> Wavelength reaches a " +
18310447Snilay@cs.wisc.edu                    "detector (" + node_->getInstanceName() + ") prior to being lit up by a laser!");
18410447Snilay@cs.wisc.edu                ASSERT(modulator_ != NULL, "[Error] " + getInstanceName() + " -> Wavelength reaches a " +
18510447Snilay@cs.wisc.edu                    "detector (" + node_->getInstanceName() + ") prior to being driven by a modulator!");
18610447Snilay@cs.wisc.edu                // Add a detector to the wavelength
18710447Snilay@cs.wisc.edu                wavelength_->addDataPath(laser_, modulator_, (OpticalDetector*) node_, current_loss);
18810447Snilay@cs.wisc.edu            }
18910447Snilay@cs.wisc.edu
19010447Snilay@cs.wisc.edu            // Traverse downstream nodes to calculate the delay through each downstream path
19110447Snilay@cs.wisc.edu            vector<OpticalNode*>* d_nodes = node_->getDownstreamNodes();
19210447Snilay@cs.wisc.edu            bool trace_downstream = (node_->getType() != OpticalNode::DETECTOR);
19310447Snilay@cs.wisc.edu            // Do special things when traversing filters
19410447Snilay@cs.wisc.edu            if (node_->getType() == OpticalNode::FILTER)
19510447Snilay@cs.wisc.edu            {
19610447Snilay@cs.wisc.edu                OpticalFilter* filter_node = (OpticalFilter*) node_;
19710447Snilay@cs.wisc.edu                if (filter_node->isDropped(wavelength_->getWavelengths()))
19810447Snilay@cs.wisc.edu                    traceWavelength(wavelength_, filter_node->getDropPort(), laser_, modulator_, loss_ + filter_node->getDropLoss());
19910447Snilay@cs.wisc.edu
20010447Snilay@cs.wisc.edu                // If the filter is not modeled as a complete drop, continue tracing downstream
20110447Snilay@cs.wisc.edu                trace_downstream = !filter_node->getDropAll();
20210447Snilay@cs.wisc.edu            }
20310447Snilay@cs.wisc.edu
20410447Snilay@cs.wisc.edu            if (trace_downstream)
20510447Snilay@cs.wisc.edu            {
20610447Snilay@cs.wisc.edu                // Trace downstream nodes
20710447Snilay@cs.wisc.edu                for (unsigned int i = 0; i < d_nodes->size(); ++i)
20810447Snilay@cs.wisc.edu                    traceWavelength(wavelength_, d_nodes->at(i), laser_, modulator_, current_loss);
20910447Snilay@cs.wisc.edu            }
21010447Snilay@cs.wisc.edu        }
21110447Snilay@cs.wisc.edu        return wavelength_;
21210447Snilay@cs.wisc.edu    }
21310447Snilay@cs.wisc.edu
21410447Snilay@cs.wisc.edu    //-------------------------------------------------------------------------
21510447Snilay@cs.wisc.edu    OpticalGraph::OpticalGraph(const OpticalGraph& /* graph_ */)
21610447Snilay@cs.wisc.edu    {
21710447Snilay@cs.wisc.edu        // Disabled
21810447Snilay@cs.wisc.edu    }
21910447Snilay@cs.wisc.edu
22010447Snilay@cs.wisc.edu    OpticalModel* OpticalGraph::getModel()
22110447Snilay@cs.wisc.edu    {
22210447Snilay@cs.wisc.edu        return m_model_;
22310447Snilay@cs.wisc.edu    }
22410447Snilay@cs.wisc.edu
22510447Snilay@cs.wisc.edu    void OpticalGraph::setTreeNum(int tree_num_)
22610447Snilay@cs.wisc.edu    {
22710447Snilay@cs.wisc.edu        msTreeNum = tree_num_;
22810447Snilay@cs.wisc.edu        return;
22910447Snilay@cs.wisc.edu    }
23010447Snilay@cs.wisc.edu
23110447Snilay@cs.wisc.edu    int OpticalGraph::getTreeNum()
23210447Snilay@cs.wisc.edu    {
23310447Snilay@cs.wisc.edu        return msTreeNum;
23410447Snilay@cs.wisc.edu    }
23510447Snilay@cs.wisc.edu
23610447Snilay@cs.wisc.edu} // namespace DSENT
23710447Snilay@cs.wisc.edu
238