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