00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef TORC_PLACER_PLACEMENT_HPP
00020 #define TORC_PLACER_PLACEMENT_HPP
00021
00022
00023 #include "torc/physical/Design.hpp"
00024 #include "torc/placer/DeviceWrapper.hpp"
00025 #include "torc/placer/PlacerAnnotations.hpp"
00026 #include "torc/placer/PlacerHeuristicBase.hpp"
00027 #include "torc/placer/PlacerHelpers.hpp"
00028 #include <boost/timer.hpp>
00029
00030 #include <boost/random/mersenne_twister.hpp>
00031 #include <boost/random/uniform_int.hpp>
00032 #include <boost/random/variate_generator.hpp>
00033
00034 namespace torc {
00035 namespace placer {
00036
00037
00038
00039 class Placement {
00040 protected:
00041
00042 typedef architecture::DDB DDB;
00043 typedef architecture::Sites Sites;
00044 typedef architecture::Site Site;
00045 typedef std::vector<const Site*> SitePtrVector;
00046 typedef std::vector<SitePtrVector> SitePtrVectorVector;
00047
00048 typedef physical::DesignSharedPtr DesignSharedPtr;
00049 typedef boost::uint32_t uint32;
00050 typedef boost::uint64_t uint64;
00051
00052 typedef physical::ENetType ENetType;
00053 typedef physical::NetSharedPtr NetSharedPtr;
00054 typedef physical::NetSharedPtrVector NetSharedPtrVector;
00055 typedef physical::InstanceSharedPtr InstanceSharedPtr;
00056 typedef physical::InstanceSharedPtrVector InstanceSharedPtrVector;
00057 typedef std::vector<InstanceSharedPtrVector> InstanceSharedPtrVectorVector;
00058 typedef physical::InstancePinSharedPtr InstancePinSharedPtr;
00059 typedef physical::InstancePinSharedPtrVector InstancePinSharedPtrVector;
00060
00061 typedef boost::unordered_map<const Site*, uint32> SitePtrToIntMap;
00062 typedef boost::unordered_map<const Site*, InstanceSharedPtr> SitePtrToInstanceSharedPtrMap;
00063 typedef boost::unordered_map<InstanceSharedPtr, Site*> InstanceSharedPtrToSitePtrMap;
00064
00065 typedef boost::mt19937 mt19937;
00066 typedef boost::uniform_int<uint32> uinform_range;
00067 typedef boost::variate_generator<mt19937&, uinform_range> random_generator;
00068
00069
00070
00071
00072
00073 DeviceWrapper& mDevice;
00074
00075
00076
00077
00078
00079 DesignSharedPtr mDesign;
00080
00081
00082
00083
00084
00085
00086 const architecture::Array<const Site>& mAllSites;
00087 SitePtrVectorVector mAllSitesByType;
00088 SitePtrVectorVector mCandidatesByType;
00089 SitePtrToIntMap mSiteTypeLookup;
00090
00091
00092 SitePtrToInstanceSharedPtrMap mAssignedSites;
00093
00094
00095 InstanceSharedPtrVector mAllInstances;
00096 InstanceSharedPtrVectorVector mAllInstancesByType;
00097
00098
00099 NetSharedPtrVector mAllNets;
00100
00101
00102
00103
00104
00105 boost::mt19937 mRandomSource;
00106 boost::uniform_int<uint32> mUniformInstanceRange;
00107 boost::variate_generator<mt19937&, boost::uniform_int<uint32> > mInstanceRandomGen;
00108
00109 std::vector<boost::uniform_int<uint32> > mUniformTypeRanges;
00110
00111 std::vector<boost::variate_generator<mt19937&,
00112 boost::uniform_int<uint32> >* > mTypeRandomGen;
00113
00114 uint32 mCost;
00115
00116
00117 bool mDebug;
00118
00119
00120 InstanceSharedPtr mSelectedInstance;
00121 InstanceSharedPtr mEvictedInstance;
00122 Site* mDepartureSite;
00123 Site* mTargetSite;
00124
00125 public:
00126 Placement(DeviceWrapper& inDevice, DesignSharedPtr inDesign)
00127 : mDevice(inDevice), mDesign(inDesign), mAllSites(mDevice.mSites.getSites()),
00128 mRandomSource(42), mUniformInstanceRange(0, mDesign->getInstanceCount() - 1),
00129 mInstanceRandomGen(mRandomSource, mUniformInstanceRange),
00130 mCost(0), mDebug(false) {
00131 std::cout << "PLACEMENT CONSTRUCTOR" << std::endl;
00132
00133 for (uint32 t = 0; t < mDevice.mSites.getSiteTypeCount(); t++) {
00134 mAllSitesByType.push_back(SitePtrVector());
00135 mCandidatesByType.push_back(SitePtrVector());
00136 mAllInstancesByType.push_back(InstanceSharedPtrVector());
00137 }
00138 std::cout << "Prepped for " << mDevice.mSites.getSiteTypeCount() << " types" << std::endl;
00139
00140
00141
00142 InstanceSharedPtrVector::iterator p = mDesign->instancesBegin();
00143 InstanceSharedPtrVector::iterator e = mDesign->instancesEnd();
00144 for ( ; p != e; p++) {
00145 InstanceSharedPtr instance = *p;
00146 uint32 typeIndex = mDevice.mTypeMapping.getTypeIndex(instance->getType());
00147 instance->setAnnotation(ePlacerInstanceTypeIndex, typeIndex);
00148
00149 mAllInstances.push_back(instance);
00150 mAllInstancesByType[typeIndex].push_back(instance);
00151 }
00152
00153
00154 NetSharedPtrVector::iterator q = mDesign->netsBegin();
00155 NetSharedPtrVector::iterator f = mDesign->netsEnd();
00156 for ( ; q != f; q++) {
00157 NetSharedPtr net = *q;
00158 mAllNets.push_back(net);
00159 }
00160
00161 uint32 a = 0;
00162 for (uint32 i = 0; i < mAllInstancesByType.size(); i++) {
00163 uint32 b = mAllInstancesByType[i].size();
00164 if (b != 0)
00165 std::cout << mDevice.mTypeMapping.getName(i) << ": " << b << std::endl;
00166 a += b;
00167
00168 }
00169 std::cout << "Summary INSTANCES: " << a << " = " << mAllInstances.size() << std::endl;
00170
00171
00172 std::cout << "There are " << mAllSites.getSize() << " sites" << std::endl;
00173 for (uint32 i = 0; i < mAllSites.getSize(); i++) {
00174
00175 const architecture::Site& site = mAllSites[i];
00176
00177 const architecture::PrimitiveDef* siteType = site.getPrimitiveDefPtr();
00178 uint32 typeIndex = mDevice.mTypeMapping.getTypeIndex(siteType->getName());
00179 std::vector<uint32>& map = mDevice.mTypeMapping.getLegalInstancesForSite(typeIndex);
00180
00181
00182 mAllSitesByType[typeIndex].push_back(&site);
00183 mSiteTypeLookup[&site] = typeIndex;
00184
00185
00186 for (uint32 j = 0; j < map.size(); j++) {
00187 mCandidatesByType[map[j]].push_back(&site);
00188 }
00189 }
00190
00191
00192 for (uint32 i = 0; i < mCandidatesByType.size(); i++) {
00193 uint32 x = mCandidatesByType[i].size();
00194 mUniformTypeRanges.push_back(boost::uniform_int<uint32>(0, x - 1));
00195
00196 mTypeRandomGen.push_back(new boost::variate_generator<mt19937&,
00197 boost::uniform_int<uint32> >(mRandomSource, mUniformTypeRanges[i]));
00198 }
00199
00200 for (uint32 t = 0; t < mDevice.mSites.getSiteTypeCount(); t++) {
00201 std::cout << mDevice.mTypeMapping.getName(t) << " has "
00202 << mAllSitesByType[t].size() << " sites, " << mCandidatesByType[t].size()
00203 << " is the candidate count for this type" << std::endl;
00204 }
00205
00206 initialPlacement();
00207
00208 }
00209 ~Placement() {
00210 }
00211 void initialPlacement() {
00212 std::cout << "INITIAL PLACEMENT" << std::endl;
00213
00214 boost::mt19937 gen;
00215
00216
00217
00218
00219
00220
00221
00222 std::vector<std::vector<const Site*> > sitesByType;
00223
00224 for (uint32 t = 0; t < mAllSitesByType.size(); t++) {
00225 sitesByType.push_back(std::vector<const Site*>());
00226 for (uint32 i = 0; i < mAllSitesByType[t].size(); i++) {
00227 sitesByType[t].push_back(mAllSitesByType[t][i]);
00228 }
00229 }
00230
00231
00232
00233 for (uint32 i = 0; i < mAllInstances.size(); i++) {
00234
00235 InstanceSharedPtr instance = mAllInstances[i];
00236 std::cout << "Placing instance: " << instance->getName() << std::endl;
00237
00238
00239 uint32 typeIndex = getInstanceTypeIndex(instance);
00240
00241 std::cout << "\tInstance type index: " << typeIndex << " ("
00242 << mDevice.mTypeMapping.getName(typeIndex) << ")" << std::endl;
00243
00244
00245
00246 uint32 siteTypeIndex = typeIndex;
00247 if (sitesByType[siteTypeIndex].size() == 0) {
00248
00249 std::vector<uint32>& map = mDevice.mTypeMapping.getLegalSitesForInstance(
00250 siteTypeIndex);
00251 for (uint32 j = 0; j < map.size(); j++) {
00252 siteTypeIndex = map[j];
00253 if (sitesByType[siteTypeIndex].size() > 0) break;
00254 }
00255 }
00256 std::cout << "\tSite type index: " << siteTypeIndex << " ("
00257 << mDevice.mTypeMapping.getName(siteTypeIndex) << ")" << std::endl;
00258
00259
00260
00261
00262 boost::uniform_int<uint32> range(0, sitesByType[siteTypeIndex].size() - 1);
00263 boost::variate_generator<mt19937&, boost::uniform_int<uint32> > random(gen, range);
00264
00265 uint32 r = random();
00266 std::cout << "\tSelected index " << r << " from " << sitesByType[siteTypeIndex].size() << std::endl;
00267
00268 const Site* selectedSite = sitesByType[siteTypeIndex][r];
00269
00270 std::cout << "\tSelected Site: " << selectedSite->getName() << std::endl;
00271
00272 instance->setAnnotation(ePlacerInstanceSitePtr, selectedSite);
00273 mAssignedSites[selectedSite] = instance;
00274
00275
00276
00277
00278 sitesByType[siteTypeIndex].erase(sitesByType[siteTypeIndex].begin() + r);
00279
00280
00281 }
00282
00283 }
00284 void writePlacementToDesign() {
00285 std::cout << "WRITING PLACEMENT TO DESIGN" << std::endl;
00286 for (uint32 i = 0; i < mAllInstances.size(); i++) {
00287 InstanceSharedPtr instance = mAllInstances[i];
00288
00289 const Site* site = boost::any_cast<const Site*>(
00290 instance->getAnnotation(ePlacerInstanceSitePtr));
00291 std::string siteName = site->getName();
00292 std::string tileName = mDevice.mDB.getTiles().getTileInfo(
00293 site->getTileIndex()).getName();
00294
00295 instance->setSite(siteName);
00296 instance->setTile(tileName);
00297
00298 }
00299 }
00300 uint32 getCost() {
00301 return mCost;
00302 }
00303 void updateCostFull(bool debug) {
00304
00305 mCost = 0;
00306 for (uint32 i = 0; i < mAllNets.size(); i++) {
00307 NetSharedPtr net = mAllNets[i];
00308 if (debug) std::cout << "net : " << net->getName() << std::endl;
00309 if (net->getSourceCount() != 1 || net->getSinkCount() < 1) {
00310 if (debug) std::cout << "\tEmpty!" << std::endl;
00311 continue;
00312 }
00313 if (net->getNetType() != physical::eNetTypeNormal) {
00314
00315 continue;
00316 }
00317 InstancePinSharedPtr pinPtr = *net->sourcesBegin();
00318 InstanceSharedPtr instance = pinPtr->getInstancePtr().lock();
00319 if (debug) std::cout << "\tsource instance: " << instance->getName() << std::endl;
00320 const Site* site = boost::any_cast<const Site*>(instance->getAnnotation(
00321 ePlacerInstanceSitePtr));
00322 if (site == NULL) {
00323 std::cout << instance->getName() << " doesn't have a site." << std::endl;
00324 continue;
00325 }
00326 if (debug) std::cout << "\t\tsource instance site: " << site->getName()
00327 << std::endl;
00328
00329 uint32 sum = 0;
00330
00331
00332 uint32 row1 = mDevice.mDB.getTiles().getTileInfo(site->getTileIndex()).getRow();
00333 uint32 col1 = mDevice.mDB.getTiles().getTileInfo(site->getTileIndex()).getCol();
00334 uint32 row2 = row1;
00335 uint32 col2 = col1;
00336 InstancePinSharedPtrVector::iterator p = net->sinksBegin();
00337 InstancePinSharedPtrVector::iterator e = net->sinksEnd();
00338 for ( ; p != e; p++) {
00339 instance = (*p)->getInstancePtr().lock();
00340 if (debug) std::cout << "\tsink instance: " << instance->getName() << std::endl;
00341 const Site* sinkSite = boost::any_cast<const Site*>(instance->getAnnotation(
00342 ePlacerInstanceSitePtr));
00343 if (sinkSite == NULL) {
00344 std::cout << instance->getName() << " doesn't have a site (sink)."
00345 << std::endl;
00346 return;
00347 }
00348
00349 uint32 trow =
00350 mDevice.mDB.getTiles().getTileInfo(sinkSite->getTileIndex()).getRow();
00351 uint32 tcol =
00352 mDevice.mDB.getTiles().getTileInfo(sinkSite->getTileIndex()).getCol();
00353 if (trow < row1) row1 = trow;
00354 if (tcol < col1) col1 = tcol;
00355 if (trow > row2) row2 = trow;
00356 if (tcol > col2) col2 = tcol;
00357 }
00358 if (debug) std::cout << "\t\tcost reported: " << sum << " / " << net->getSinkCount()
00359 << " = " << ((float)sum / (float)net->getSinkCount()) << std::endl;
00360 mCost += (row2 - row1) + (col2 - col1);
00361 if (debug) std::cout << "\t\t" << mCost << std::endl;
00362 }
00363 std::cout << "updateCostFull: " << mCost << std::endl;
00364 }
00365 bool randomMove(bool debug) {
00366 if (debug) std::cout << "randomMove: " << std::endl;
00367
00368 uint32 r = mInstanceRandomGen();
00369 mSelectedInstance = mAllInstances[r];
00370 if (debug) std::cout << "\tselected inst: "
00371 << mSelectedInstance->getName() << std::endl;
00372 mDepartureSite = const_cast<Site*>(boost::any_cast<const Site*>(
00373 mSelectedInstance->getAnnotation(ePlacerInstanceSitePtr)));
00374 if (debug) std::cout << "\tdeparture site: " << mDepartureSite->getName() << std::endl;
00375 uint32 instanceType = getInstanceTypeIndex(mSelectedInstance);
00376 if (debug) std::cout << "\tinstance type: " << instanceType << std::endl;
00377 uint32 s = (*mTypeRandomGen[instanceType])();
00378 if (debug) std::cout << "\tselected: " << s << " of "
00379 << mCandidatesByType[instanceType].size() << std::endl;
00380 mTargetSite = const_cast<Site*>(mCandidatesByType[instanceType][s]);
00381 if (debug) std::cout << "\ttarget site: " << mTargetSite->getName() << std::endl;
00382 SitePtrToInstanceSharedPtrMap::iterator p = mAssignedSites.find(mTargetSite);
00383 mEvictedInstance = InstanceSharedPtr();
00384 if (p != mAssignedSites.end()) {
00385 mEvictedInstance = p->second;
00386
00387 uint32 evictedType = getInstanceTypeIndex(mEvictedInstance);
00388 uint32 departureSiteType = mSiteTypeLookup[mDepartureSite];
00389 bool illegalMapping = true;
00390 std::vector<uint32>& v = mDevice.mTypeMapping.getLegalSitesForInstance(evictedType);
00391 for (uint32 i = 0; i < v.size(); i++) {
00392 if (departureSiteType == v[i]) illegalMapping = false;
00393 }
00394 if (illegalMapping) return false;
00395 }
00396 if (debug) mEvictedInstance == 0 ? std::cout << "\tEMPTY " << std::endl
00397 : std::cout << "\t" << mEvictedInstance->getName() << std::endl;
00398
00399
00400 if (debug) std::cout << "\tCost before move: " << mCost << std::endl;
00401 updateCostRemovePair(mSelectedInstance, mEvictedInstance);
00402 if (debug) std::cout << "\tCost without instance nets: " << mCost << std::endl;
00403
00404 mSelectedInstance->setAnnotation(ePlacerInstanceSitePtr,
00405 const_cast<const Site*>(mTargetSite));
00406 mAssignedSites[mTargetSite] = mSelectedInstance;
00407 if (mEvictedInstance != 0) {
00408 mEvictedInstance->setAnnotation(ePlacerInstanceSitePtr,
00409 const_cast<const Site*>(mDepartureSite));
00410 mAssignedSites[mDepartureSite] = mEvictedInstance;
00411 } else {
00412 mAssignedSites.erase(mDepartureSite);
00413 }
00414
00415 updateCostAddPair(mSelectedInstance, mEvictedInstance);
00416 if (debug) std::cout << "\tCost after move: " << mCost << std::endl;
00417 return true;
00418 }
00419 void undoMove(bool debug) {
00420 if (debug) {
00421 std::cout << "undoMove: " << std::endl;
00422 std::cout << "\tinstance: " << mSelectedInstance->getName() << std::endl;
00423 std::cout << "\tdeparturesite: " << mDepartureSite->getName() << std::endl;
00424 std::cout << "\ttargetsite: " << mTargetSite->getName() << std::endl;
00425 if (mEvictedInstance != 0) std::cout << "\tevictedinstance: "
00426 << mEvictedInstance->getName() << std::endl;
00427 }
00428
00429 updateCostRemovePair(mSelectedInstance, mEvictedInstance);
00430
00431 mSelectedInstance->setAnnotation(ePlacerInstanceSitePtr,
00432 const_cast<const Site*>(mDepartureSite));
00433 mAssignedSites[mDepartureSite] = mSelectedInstance;
00434
00435 if (mEvictedInstance != 0) {
00436 mEvictedInstance->setAnnotation(ePlacerInstanceSitePtr,
00437 const_cast<const Site*>(mTargetSite));
00438 mAssignedSites[mTargetSite] = mEvictedInstance;
00439 } else {
00440 mAssignedSites.erase(mTargetSite);
00441 }
00442
00443 updateCostAddPair(mSelectedInstance, mEvictedInstance);
00444 }
00445
00446 void updateCostRemoveInstances(InstanceSharedPtrVector& inInstances) {
00447
00448 updateCostHelper(inInstances, false);
00449 }
00450 void updateCostRemovePair(InstanceSharedPtr inInstance1, InstanceSharedPtr inInstance2) {
00451
00452 updateCostHelper(inInstance1, inInstance2, false);
00453 }
00454 void updateCostAddInstances(InstanceSharedPtrVector& inInstances) {
00455
00456 updateCostHelper(inInstances, true);
00457 }
00458 void updateCostAddPair(InstanceSharedPtr inInstance1, InstanceSharedPtr inInstance2) {
00459
00460 updateCostHelper(inInstance1, inInstance2, true);
00461 }
00462
00463 void updateCostHelper(InstanceSharedPtrVector& inInstances, bool addCost) {
00464 torc::physical::Circuit::InstanceSharedPtrIterator p = inInstances.begin();
00465 torc::physical::Circuit::InstanceSharedPtrIterator e = inInstances.end();
00466
00467 std::set<NetSharedPtr> modifiedNets;
00468
00469 for ( ; p != e; p++) {
00470 if ((*p) != 0) {
00471 torc::physical::Instance::InstancePinSharedPtrIterator q = (*p)->pinsBegin();
00472 torc::physical::Instance::InstancePinSharedPtrIterator f = (*p)->pinsEnd();
00473 for ( ; q != f; q++) {
00474 NetSharedPtr n = (*q).second->getParentWeakPtr().lock();
00475 modifiedNets.insert(n);
00476 }
00477 }
00478 }
00479
00480 std::set<NetSharedPtr>::iterator r = modifiedNets.begin();
00481 std::set<NetSharedPtr>::iterator g = modifiedNets.end();
00482 for ( ; r != g; r++) {
00483 addCost ? mCost += getNetCost(*r) : mCost -= getNetCost(*r);
00484 }
00485 }
00486 void updateCostHelper(InstanceSharedPtr inInstance1, InstanceSharedPtr inInstance2,
00487 bool addCost) {
00488
00489 std::set<NetSharedPtr> modifiedNets;
00490
00491 torc::physical::Instance::InstancePinSharedPtrIterator q;
00492 torc::physical::Instance::InstancePinSharedPtrIterator f;
00493
00494 if (inInstance1 != 0) {
00495 q = inInstance1->pinsBegin();
00496 f = inInstance1->pinsEnd();
00497 for ( ; q != f; q++) {
00498 NetSharedPtr n = (*q).second->getParentWeakPtr().lock();
00499 modifiedNets.insert(n);
00500 }
00501 }
00502 if (inInstance2 != 0) {
00503 q = inInstance2->pinsBegin();
00504 f = inInstance2->pinsEnd();
00505 for ( ; q != f; q++) {
00506 NetSharedPtr n = (*q).second->getParentWeakPtr().lock();
00507 modifiedNets.insert(n);
00508 }
00509 }
00510 std::set<NetSharedPtr>::iterator r = modifiedNets.begin();
00511 std::set<NetSharedPtr>::iterator g = modifiedNets.end();
00512 for ( ; r != g; r++) {
00513 addCost ? mCost += getNetCost(*r) : mCost -= getNetCost(*r);
00514 }
00515 }
00516
00517 uint32 getNetCost(NetSharedPtr inNet) {
00518 uint32 returnCost = 0;
00519
00520 if (mDebug) std::cout << "getNetCost - net : " << inNet->getName() << std::endl;
00521 if (inNet->getSourceCount() != 1 || inNet->getSinkCount() < 1) {
00522 if (mDebug) std::cout << "\tEmpty!" << std::endl;
00523 return returnCost;
00524 }
00525 if (inNet->getNetType() != physical::eNetTypeNormal) {
00526
00527 return returnCost;
00528 }
00529 InstancePinSharedPtr pinPtr = *inNet->sourcesBegin();
00530 InstanceSharedPtr instance = pinPtr->getInstancePtr().lock();
00531 if (mDebug) std::cout << "\tsource instance: " << instance->getName() << std::endl;
00532 const Site* site = boost::any_cast<const Site*>(instance->getAnnotation(
00533 ePlacerInstanceSitePtr));
00534 if (site == NULL) {
00535 std::cout << instance->getName() << " doesn't have a site." << std::endl;
00536 return returnCost;
00537 }
00538 if (mDebug) std::cout << "\t\tsource instance site: " << site->getName()
00539 << std::endl;
00540
00541 uint32 sum = 0;
00542
00543
00544 uint32 row1 = mDevice.mDB.getTiles().getTileInfo(site->getTileIndex()).getRow();
00545 uint32 col1 = mDevice.mDB.getTiles().getTileInfo(site->getTileIndex()).getCol();
00546 uint32 row2 = row1;
00547 uint32 col2 = col1;
00548 InstancePinSharedPtrVector::iterator p = inNet->sinksBegin();
00549 InstancePinSharedPtrVector::iterator e = inNet->sinksEnd();
00550 for ( ; p != e; p++) {
00551 instance = (*p)->getInstancePtr().lock();
00552 if (mDebug) std::cout << "\tsink instance: " << instance->getName() << std::endl;
00553 const Site* sinkSite = boost::any_cast<const Site*>(instance->getAnnotation(
00554 ePlacerInstanceSitePtr));
00555 if (sinkSite == NULL) {
00556 std::cout << instance->getName() << " doesn't have a site (sink)."
00557 << std::endl;
00558 return returnCost;
00559 }
00560
00561 uint32 trow =
00562 mDevice.mDB.getTiles().getTileInfo(sinkSite->getTileIndex()).getRow();
00563 uint32 tcol =
00564 mDevice.mDB.getTiles().getTileInfo(sinkSite->getTileIndex()).getCol();
00565 if (trow < row1) row1 = trow;
00566 if (tcol < col1) col1 = tcol;
00567 if (trow > row2) row2 = trow;
00568 if (tcol > col2) col2 = tcol;
00569 }
00570 if (mDebug) std::cout << "\t\tcost reported: " << sum << " / " << inNet->getSinkCount()
00571 << " = " << ((float)sum / (float)inNet->getSinkCount()) << std::endl;
00572 returnCost = (row2 - row1) + (col2 - col1);
00573 if (mDebug) std::cout << "\t\t" << mCost << std::endl;
00574
00575 return returnCost;
00576 }
00577
00578 };
00579 }
00580 }
00581
00582 #endif // TORC_PLACER_PLACEMENT_HPP