OpticalGraph.cc revision 10447:a465576671d4
1 2#include "model/optical_graph/OpticalGraph.h" 3 4#include "model/OpticalModel.h" 5#include "model/optical_graph/OpticalNode.h" 6#include "model/optical_graph/OpticalLaser.h" 7#include "model/optical_graph/OpticalModulator.h" 8#include "model/optical_graph/OpticalFilter.h" 9#include "model/optical_graph/OpticalDetector.h" 10#include "model/optical_graph/OpticalWavelength.h" 11 12namespace DSENT 13{ 14 // Initialize the next visited number to be one above the initial number 15 // used by OpticalNode 16 int OpticalGraph::msTreeNum = OpticalNode::OPTICAL_NODE_INIT_VISITED_NUM + 1; 17 18 OpticalGraph::OpticalGraph(const String& instance_name_, OpticalModel* model_) 19 : m_instance_name_(instance_name_), m_model_(model_) 20 { 21 22 } 23 24 OpticalGraph::~OpticalGraph() 25 { 26 27 } 28 29 const String& OpticalGraph::getInstanceName() const 30 { 31 return m_instance_name_; 32 } 33 34 //------------------------------------------------------------------------- 35 // Perform Datapath power optimization 36 //------------------------------------------------------------------------- 37 bool OpticalGraph::performPowerOpt(OpticalNode* node_, const WavelengthGroup& wavelengths_, unsigned int number_detectors_, double util_) 38 { 39 // Total number of iterations 40 unsigned int number_iterations = 1250; 41 // Maximum IL + ER 42 double IL_ER_max = 10; 43 // Figure out the step size used in the sweep 44 double step = (double) (IL_ER_max / sqrt(2 * number_iterations)); 45 46 // Assume it is possible 47 bool possible = true; 48 49 // Begin optical data path power optimization 50 Log::printLine(getInstanceName() + " -> Beginning optical data path power optimization"); 51 52 // Trace the specified wavelengths 53 OpticalWavelength* wavelength = traceWavelength(wavelengths_, node_); 54 55 // For each data path found in the wavelength 56 const vector<OpticalDataPath>* data_paths = wavelength->getDataPaths(); 57 for (unsigned int i = 0; i < data_paths->size(); ++i) 58 { 59 const OpticalDataPath& data_path = data_paths->at(i); 60 // Default to worst possible modulator 61 double best_power = 1e99; 62 double best_IL = IL_ER_max - step; 63 double best_ER = step; 64 65 // Perform power optimization for this data path 66 Log::printLine(getInstanceName() + " -> Optimize data path - Laser = " + data_path.laser->getInstanceName() 67 + ", Modulator = " + data_path.modulator->getInstanceName()); 68 69 if (data_path.modulator->canOptimizeLoss()) 70 { 71 // Iterate over IL and ER to find optimal set of IL and ER 72 for (double IL = step; IL < IL_ER_max; IL += step) 73 { 74 for (double ER = step; ER <= (IL_ER_max - IL); ER += step) 75 { 76 // Ask the modulator to try this new ER and IL 77 bool success = data_path.modulator->setModulatorSpec(IL, ER); 78 // If the modulator was successful 79 if (success) 80 { 81 double laser_power = wavelength->getLaserPower(number_detectors_); 82 double modulator_power = data_path.modulator->getPower(util_); 83 double total_power = laser_power + modulator_power; 84 // If this is the new lowest power point 85 if (total_power < best_power) 86 { 87 best_power = total_power; 88 best_IL = IL; 89 best_ER = ER; 90 } 91 } 92 } 93 } 94 95 // Set IL and ER to the best ones we found 96 bool success = data_path.modulator->setModulatorSpec(best_IL, best_ER); 97 // If the best one we found was still not possible... 98 possible = possible && success; 99 100 // Print best IL and ER 101 Log::printLine(getInstanceName() + " -> Best IL=" + (String) best_IL + ", Best ER=" + (String) best_ER + 102 ", Best Laser/Mod Power=" + (String) best_power); 103 } 104 else 105 { 106 // Perform power optimization for this data path 107 Log::printLine(getInstanceName() + " -> Data path not set to allow optimization"); 108 } 109 } 110 111 // End optical data path power optimization 112 Log::printLine(getInstanceName() + " -> End optical data path power optimization"); 113 114 delete wavelength; 115 return possible; 116 } 117 118 119 //------------------------------------------------------------------------- 120 // Trace wavelength(s), returning a wavelength data structure 121 //------------------------------------------------------------------------- 122 OpticalWavelength* OpticalGraph::traceWavelength(const WavelengthGroup& wavelengths_, OpticalNode* node_) 123 { 124 setTreeNum(getTreeNum() + 1); 125 OpticalWavelength* wavelength = new OpticalWavelength("TraceWavelength", wavelengths_); 126 return traceWavelength(wavelength, node_, NULL, NULL, 0.0); 127 } 128 129 OpticalWavelength* OpticalGraph::traceWavelength(OpticalWavelength* wavelength_, OpticalNode* node_, OpticalLaser* laser_, OpticalModulator* modulator_, double loss_) 130 { 131 // If the node has already been visited, don't do anything! 132 if (node_->getVisitedNum() != getTreeNum()) 133 { 134 // Set the new parity for this node 135 node_->setVisitedNum(getTreeNum()); 136 137 // Calculate the loss of the current path 138 double current_loss = loss_ + node_->getLoss(); 139 // Check if the current node is a laser, modulator or detector 140 if(node_->getType() == OpticalNode::LASER) 141 { 142 // Set the laser lighting up the wavelength 143 ASSERT(laser_ == NULL, "[Error] " + getInstanceName() + " -> Multiple " + 144 "Lasers lighting up the wavelength!"); 145 laser_ = (OpticalLaser*) node_; 146 } 147 else if (node_->getType() == OpticalNode::MODULATOR) 148 { 149 // Check that the path already lit up by a laser and there are no 150 // modulators already driving data 151 ASSERT(laser_ != NULL, "[Error] " + getInstanceName() + " -> Wavelength reaches a " + 152 "modulator (" + node_->getInstanceName() + ") prior to being lit up by a laser!"); 153 ASSERT(modulator_ == NULL, "[Error] " + getInstanceName() + " -> Two modulators are driving" + 154 " the same optical data path (" + node_->getInstanceName() + ")!"); 155 modulator_ = (OpticalModulator*) node_; 156 } 157 else if (node_->getType() == OpticalNode::DETECTOR) 158 { 159 // Check that the path is both lit up by a laser and there is 160 // a modulator driving data 161 ASSERT(laser_ != NULL, "[Error] " + getInstanceName() + " -> Wavelength reaches a " + 162 "detector (" + node_->getInstanceName() + ") prior to being lit up by a laser!"); 163 ASSERT(modulator_ != NULL, "[Error] " + getInstanceName() + " -> Wavelength reaches a " + 164 "detector (" + node_->getInstanceName() + ") prior to being driven by a modulator!"); 165 // Add a detector to the wavelength 166 wavelength_->addDataPath(laser_, modulator_, (OpticalDetector*) node_, current_loss); 167 } 168 169 // Traverse downstream nodes to calculate the delay through each downstream path 170 vector<OpticalNode*>* d_nodes = node_->getDownstreamNodes(); 171 bool trace_downstream = (node_->getType() != OpticalNode::DETECTOR); 172 // Do special things when traversing filters 173 if (node_->getType() == OpticalNode::FILTER) 174 { 175 OpticalFilter* filter_node = (OpticalFilter*) node_; 176 if (filter_node->isDropped(wavelength_->getWavelengths())) 177 traceWavelength(wavelength_, filter_node->getDropPort(), laser_, modulator_, loss_ + filter_node->getDropLoss()); 178 179 // If the filter is not modeled as a complete drop, continue tracing downstream 180 trace_downstream = !filter_node->getDropAll(); 181 } 182 183 if (trace_downstream) 184 { 185 // Trace downstream nodes 186 for (unsigned int i = 0; i < d_nodes->size(); ++i) 187 traceWavelength(wavelength_, d_nodes->at(i), laser_, modulator_, current_loss); 188 } 189 } 190 return wavelength_; 191 } 192 193 //------------------------------------------------------------------------- 194 OpticalGraph::OpticalGraph(const OpticalGraph& /* graph_ */) 195 { 196 // Disabled 197 } 198 199 OpticalModel* OpticalGraph::getModel() 200 { 201 return m_model_; 202 } 203 204 void OpticalGraph::setTreeNum(int tree_num_) 205 { 206 msTreeNum = tree_num_; 207 return; 208 } 209 210 int OpticalGraph::getTreeNum() 211 { 212 return msTreeNum; 213 } 214 215} // namespace DSENT 216 217