LLVM: include/llvm/CodeGen/PBQP/Graph.h Source File (original) (raw)

27 public:

30

31

33 return std::numeric_limits::max();

34 }

35

36

38 return std::numeric_limits::max();

39 }

40 };

47 private:

48 using CostAllocator = typename SolverT::CostAllocator;

49

50 public:

51 using RawVector = typename SolverT::RawVector;

52 using RawMatrix = typename SolverT::RawMatrix;

53 using Vector = typename SolverT::Vector;

54 using Matrix = typename SolverT::Matrix;

55 using VectorPtr = typename CostAllocator::VectorPtr;

56 using MatrixPtr = typename CostAllocator::MatrixPtr;

60

61 private:

62 class NodeEntry {

63 public:

64 using AdjEdgeList = std::vector;

65 using AdjEdgeIdx = AdjEdgeList::size_type;

66 using AdjEdgeItr = AdjEdgeList::const_iterator;

67

68 NodeEntry(VectorPtr Costs) : Costs(std::move(Costs)) {}

69

70 static AdjEdgeIdx getInvalidAdjEdgeIdx() {

71 return std::numeric_limits::max();

72 }

73

74 AdjEdgeIdx addAdjEdgeId(EdgeId EId) {

75 AdjEdgeIdx Idx = AdjEdgeIds.size();

76 AdjEdgeIds.push_back(EId);

77 return Idx;

78 }

79

80 void removeAdjEdgeId(Graph &G, NodeId ThisNId, AdjEdgeIdx Idx) {

81

82

83

84

85

86

87 G.getEdge(AdjEdgeIds.back()).setAdjEdgeIdx(ThisNId, Idx);

88 AdjEdgeIds[Idx] = AdjEdgeIds.back();

89 AdjEdgeIds.pop_back();

90 }

91

92 const AdjEdgeList& getAdjEdgeIds() const { return AdjEdgeIds; }

93

96

97 private:

98 AdjEdgeList AdjEdgeIds;

99 };

100

101 class EdgeEntry {

102 public:

103 EdgeEntry(NodeId N1Id, NodeId N2Id, MatrixPtr Costs)

104 : Costs(std::move(Costs)) {

105 NIds[0] = N1Id;

106 NIds[1] = N2Id;

107 ThisEdgeAdjIdxs[0] = NodeEntry::getInvalidAdjEdgeIdx();

108 ThisEdgeAdjIdxs[1] = NodeEntry::getInvalidAdjEdgeIdx();

109 }

110

111 void connectToN(Graph &G, EdgeId ThisEdgeId, unsigned NIdx) {

112 assert(ThisEdgeAdjIdxs[NIdx] == NodeEntry::getInvalidAdjEdgeIdx() &&

113 "Edge already connected to NIds[NIdx].");

114 NodeEntry &N = G.getNode(NIds[NIdx]);

115 ThisEdgeAdjIdxs[NIdx] = N.addAdjEdgeId(ThisEdgeId);

116 }

117

118 void connect(Graph &G, EdgeId ThisEdgeId) {

119 connectToN(G, ThisEdgeId, 0);

120 connectToN(G, ThisEdgeId, 1);

121 }

122

123 void setAdjEdgeIdx(NodeId NId, typename NodeEntry::AdjEdgeIdx NewIdx) {

124 if (NId == NIds[0])

125 ThisEdgeAdjIdxs[0] = NewIdx;

126 else {

127 assert(NId == NIds[1] && "Edge not connected to NId");

128 ThisEdgeAdjIdxs[1] = NewIdx;

129 }

130 }

131

132 void disconnectFromN(Graph &G, unsigned NIdx) {

133 assert(ThisEdgeAdjIdxs[NIdx] != NodeEntry::getInvalidAdjEdgeIdx() &&

134 "Edge not connected to NIds[NIdx].");

135 NodeEntry &N = G.getNode(NIds[NIdx]);

136 N.removeAdjEdgeId(G, NIds[NIdx], ThisEdgeAdjIdxs[NIdx]);

137 ThisEdgeAdjIdxs[NIdx] = NodeEntry::getInvalidAdjEdgeIdx();

138 }

139

141 if (NId == NIds[0])

142 disconnectFromN(G, 0);

143 else {

144 assert(NId == NIds[1] && "Edge does not connect NId");

145 disconnectFromN(G, 1);

146 }

147 }

148

149 NodeId getN1Id() const { return NIds[0]; }

150 NodeId getN2Id() const { return NIds[1]; }

151

154

155 private:

157 typename NodeEntry::AdjEdgeIdx ThisEdgeAdjIdxs[2];

158 };

159

160

161

163 CostAllocator CostAlloc;

164 SolverT *Solver = nullptr;

165

166 using NodeVector = std::vector;

167 using FreeNodeVector = std::vector;

168 NodeVector Nodes;

169 FreeNodeVector FreeNodeIds;

170

171 using EdgeVector = std::vector;

172 using FreeEdgeVector = std::vector;

173 EdgeVector Edges;

174 FreeEdgeVector FreeEdgeIds;

175

177

178

179

180 NodeEntry &getNode(NodeId NId) {

181 assert(NId < Nodes.size() && "Out of bound NodeId");

182 return Nodes[NId];

183 }

184 const NodeEntry &getNode(NodeId NId) const {

185 assert(NId < Nodes.size() && "Out of bound NodeId");

186 return Nodes[NId];

187 }

188

189 EdgeEntry& getEdge(EdgeId EId) { return Edges[EId]; }

190 const EdgeEntry& getEdge(EdgeId EId) const { return Edges[EId]; }

191

192 NodeId addConstructedNode(NodeEntry N) {

194 if (!FreeNodeIds.empty()) {

195 NId = FreeNodeIds.back();

196 FreeNodeIds.pop_back();

197 Nodes[NId] = std::move(N);

198 } else {

199 NId = Nodes.size();

200 Nodes.push_back(std::move(N));

201 }

202 return NId;

203 }

204

205 EdgeId addConstructedEdge(EdgeEntry E) {

207 "Attempt to add duplicate edge.");

209 if (!FreeEdgeIds.empty()) {

210 EId = FreeEdgeIds.back();

211 FreeEdgeIds.pop_back();

212 Edges[EId] = std::move(E);

213 } else {

214 EId = Edges.size();

215 Edges.push_back(std::move(E));

216 }

217

218 EdgeEntry &NE = getEdge(EId);

219

220

221 NE.connect(*this, EId);

222 return EId;

223 }

224

225 void operator=(const Graph &Other) {}

226

227 public:

228 using AdjEdgeItr = typename NodeEntry::AdjEdgeItr;

229

231 public:

237

239 : CurNId(CurNId), EndNId(G.Nodes.size()), FreeNodeIds(G.FreeNodeIds) {

240 this->CurNId = findNextInUse(CurNId);

241 }

242

247

248 private:

250 while (NId < EndNId && is_contained(FreeNodeIds, NId)) {

251 ++NId;

252 }

253 return NId;

254 }

255

256 NodeId CurNId, EndNId;

257 const FreeNodeVector &FreeNodeIds;

258 };

259

261 public:

263 : CurEId(CurEId), EndEId(G.Edges.size()), FreeEdgeIds(G.FreeEdgeIds) {

264 this->CurEId = findNextInUse(CurEId);

265 }

266

271

272 private:

274 while (EId < EndEId && is_contained(FreeEdgeIds, EId)) {

275 ++EId;

276 }

277 return EId;

278 }

279

280 EdgeId CurEId, EndEId;

281 const FreeEdgeVector &FreeEdgeIds;

282 };

283

285 public:

287

290

291 bool empty() const { return G.Nodes.empty(); }

292

293 typename NodeVector::size_type size() const {

294 return G.Nodes.size() - G.FreeNodeIds.size();

295 }

296

297 private:

298 const Graph& G;

299 };

300

302 public:

304

307

308 bool empty() const { return G.Edges.empty(); }

309

310 typename NodeVector::size_type size() const {

311 return G.Edges.size() - G.FreeEdgeIds.size();

312 }

313

314 private:

315 const Graph& G;

316 };

317

319 public:

321

322 typename NodeEntry::AdjEdgeItr begin() const {

323 return NE.getAdjEdgeIds().begin();

324 }

325

326 typename NodeEntry::AdjEdgeItr end() const {

327 return NE.getAdjEdgeIds().end();

328 }

329

330 bool empty() const { return NE.getAdjEdgeIds().empty(); }

331

332 typename NodeEntry::AdjEdgeList::size_type size() const {

333 return NE.getAdjEdgeIds().size();

334 }

335

336 private:

337 const NodeEntry &NE;

338 };

339

340

342

343

345

346

348

349

351

352

353

354

355

357 assert(!Solver && "Solver already set. Call unsetSolver().");

358 Solver = &S;

359 for (auto NId : nodeIds())

360 Solver->handleAddNode(NId);

361 for (auto EId : edgeIds())

362 Solver->handleAddEdge(EId);

363 }

364

365

367 assert(Solver && "Solver not set.");

368 Solver = nullptr;

369 }

370

371

372

373

374 template

376

377 VectorPtr AllocatedCosts = CostAlloc.getVector(std::move(Costs));

378 NodeId NId = addConstructedNode(NodeEntry(AllocatedCosts));

379 if (Solver)

380 Solver->handleAddNode(NId);

381 return NId;

382 }

383

384

385

386

387

388

389

390

391

392

393

394

395 template

397 NodeId NId = addConstructedNode(NodeEntry(Costs));

398 if (Solver)

399 Solver->handleAddNode(NId);

400 return NId;

401 }

402

403

404

405

406

407

408 template

411 getNodeCosts(N2Id).getLength() == Costs.getCols() &&

412 "Matrix dimensions mismatch.");

413

414 MatrixPtr AllocatedCosts = CostAlloc.getMatrix(std::move(Costs));

415 EdgeId EId = addConstructedEdge(EdgeEntry(N1Id, N2Id, AllocatedCosts));

416 if (Solver)

417 Solver->handleAddEdge(EId);

418 return EId;

419 }

420

421

422

423

424

425

426

427

428

429

430

431

432

433 template

435 OtherMatrixPtrT Costs) {

437 getNodeCosts(N2Id).getLength() == Costs->getCols() &&

438 "Matrix dimensions mismatch.");

439

440 EdgeId EId = addConstructedEdge(EdgeEntry(N1Id, N2Id, Costs));

441 if (Solver)

442 Solver->handleAddEdge(EId);

443 return EId;

444 }

445

446

447 bool empty() const { return NodeIdSet(*this).empty(); }

448

449 NodeIdSet nodeIds() const { return NodeIdSet(*this); }

450 EdgeIdSet edgeIds() const { return EdgeIdSet(*this); }

451

452 AdjEdgeIdSet adjEdgeIds(NodeId NId) { return AdjEdgeIdSet(getNode(NId)); }

453

454

455

456 unsigned getNumNodes() const { return NodeIdSet(*this).size(); }

457

458

459

460 unsigned getNumEdges() const { return EdgeIdSet(*this).size(); }

461

462

463

464

465 template

467 VectorPtr AllocatedCosts = CostAlloc.getVector(std::move(Costs));

468 if (Solver)

469 Solver->handleSetNodeCosts(NId, *AllocatedCosts);

470 getNode(NId).Costs = AllocatedCosts;

471 }

472

473

474

475

476

477

478

479

480

482 return getNode(NId).Costs;

483 }

484

485

486

487

491

493 return getNode(NId).Metadata;

494 }

495

497 return getNode(NId).Metadata;

498 }

499

501 return getNode(NId).getAdjEdgeIds().size();

502 }

503

504

505

506

507 template

509 MatrixPtr AllocatedCosts = CostAlloc.getMatrix(std::move(Costs));

510 if (Solver)

511 Solver->handleUpdateCosts(EId, *AllocatedCosts);

512 getEdge(EId).Costs = AllocatedCosts;

513 }

514

515

516

517

518

519

520

521

522

524 return getEdge(EId).Costs;

525 }

526

527

528

529

531 return *getEdge(EId).Costs;

532 }

533

535 return getEdge(EId).Metadata;

536 }

537

539 return getEdge(EId).Metadata;

540 }

541

542

543

544

546 return getEdge(EId).getN1Id();

547 }

548

549

550

551

553 return getEdge(EId).getN2Id();

554 }

555

556

557

558

559

561 EdgeEntry &E = getEdge(EId);

562 if (E.getN1Id() == NId) {

563 return E.getN2Id();

564 }

565 return E.getN1Id();

566 }

567

568

569

570

571

572

577 return AEId;

578 }

579 }

581 }

582

583

584

586 if (Solver)

587 Solver->handleRemoveNode(NId);

588 NodeEntry &N = getNode(NId);

589

590 for (AdjEdgeItr AEItr = N.adjEdgesBegin(),

591 AEEnd = N.adjEdgesEnd();

592 AEItr != AEEnd;) {

594 ++AEItr;

596 }

597 FreeNodeIds.push_back(NId);

598 }

599

600

601

602

603

604

605

606

607

608

609

610

611

612

613

614

615

616

617

618

619

620

621

622

623

624

626 if (Solver)

627 Solver->handleDisconnectEdge(EId, NId);

628

629 EdgeEntry &E = getEdge(EId);

630 E.disconnectFrom(*this, NId);

631 }

632

633

634

639

640

641

642

643

645 EdgeEntry &E = getEdge(EId);

646 E.connectTo(*this, EId, NId);

647 if (Solver)

648 Solver->handleReconnectEdge(EId, NId);

649 }

650

651

652

654 if (Solver)

655 Solver->handleRemoveEdge(EId);

656 EdgeEntry &E = getEdge(EId);

657 E.disconnect();

658 FreeEdgeIds.push_back(EId);

659 Edges[EId].invalidate();

660 }

661

662

664 Nodes.clear();

665 FreeNodeIds.clear();

666 Edges.clear();

667 FreeEdgeIds.clear();

668 }

669 };